Дата активности | Видеокурс | Прогресс | ||
---|---|---|---|---|
2017-01-05 | aspnet | Базовый ASP.ект | 42 % | |
2016-12-24 | task3 | Комбинаторика | 5 % | |
2016-12-24 | java2 | Игры на JavaScript | 10 % | |
2016-10-08 | gmaps | ASP.NET и GMaps | 19 % | |
2016-08-22 | soft0 | Демо софт | 29 % | |
2016-08-14 | image | Фотошарп | 100 % | |
2016-08-13 | thread | Бурные потоки | 100 % | |
2016-08-03 | biknight | Мат Конём и Слоном | 72 % | |
2016-06-11 | shifr | Шифрование | 40 % | |
2016-06-03 | bilife | Бинарная жизнь | 100 % | |
2016-05-30 | chess | НаноШахматы | 89 % | |
2016-05-29 | ef | Entity Framework | 100 % | |
2016-05-10 | saver | Хранитель экрана | 87 % | |
2016-05-08 | graf | Коллекция графов | 100 % | |
2016-05-06 | eshop | Интернет-магазин | 12 % | |
2016-05-06 | task1 | Семантика | 100 % | |
2016-05-01 | iterator | Итератор | 90 % | |
2016-04-28 | soft2 | Новые технологии | 7 % | |
2016-04-16 | webbot | Webbot On-Line | 9 % | |
2016-02-13 | game0 | Демо игры | 10 % | |
Итого: | 48 % |
Дата активности | Консольный раздел | Прогресс | ||
---|---|---|---|---|
2019-03-10 | book | 011. Циклы | 88 % | |
2018-09-25 | olimp | Олимпиада | 70 % | |
2018-05-23 | club | 10895 - Данил 42 | % | |
2018-05-23 | club | 24 - Муза Оля | 100 % | |
2018-05-23 | club | 8275 - Глушков Александр | 32 % | |
2017-01-30 | task2 | Матрицы | 25 % | |
2017-01-30 | task2 | Do-рацикл | 25 % | |
2017-01-08 | book | 111. Потоки | 13 % | |
2017-01-07 | book | 101. Математика | 15 % | |
2017-01-05 | book | 100. Массивы | 100 % | |
2017-01-05 | book | 010. Условия | 100 % | |
2017-01-03 | book | 000. Строки | 100 % | |
2017-01-03 | book | 001. Числа | 100 % | |
2017-01-02 | club | 10494 - Алексей Васюк | 84 % | |
2016-12-31 | club | 4004 - Елена Вставская | 89 % | |
2016-12-24 | task1 | Целые задачи | 100 % | |
2016-12-24 | solo | C# набор | 6 % | |
2016-10-17 | club | 10162 - Дмитрий Гринь | 60 % | |
2016-09-26 | club | 10670 - Сергей Соколов | 100 % | |
2016-09-26 | club | 5649 - Максим Лапшинов | 88 % | |
2016-09-09 | club | 6452 - Кирилл Шмойлов | 100 % | |
2016-09-05 | task2 | Точка и плоскость | 100 % | |
2016-09-03 | task2 | Матрёшки | 100 % | |
2016-08-30 | club | 10558 - Иван Воронин | 100 % | |
2016-08-27 | club | 7119 - Владимир Новопашин | 94 % | |
2016-08-13 | task2 | Условный оператор | 7 % | |
2016-08-12 | task2 | Логика | 8 % | |
2016-07-31 | task1 | Лирика | 93 % | |
2016-05-05 | task1 | Календарь | 100 % | |
2016-05-02 | task1 | Цифры | 92 % | |
2016-05-01 | task1 | Формулы | 100 % | |
2016-03-13 | task1 | Геометрия | 100 % | |
2016-03-10 | task1 | Символы | 100 % | |
2016-02-18 | task1 | Целые числа | 100 % | |
2016-02-14 | task1 | Строки | 100 % | |
2016-02-13 | task1 | Семантика | 100 % | |
Итого: | 73 % |
Вся оптимизация сводится к выводу формулы согласно свойств чисел. Например: сумма чисел от 1 до 10 равна 55.
Перебором всех решений можно, но уже 10-значные пары вычисляются более 2х часов на кора2дуба Е7500, на одном ядре.
Мой вариант брутфорса, вывел его от скуки:
public class Program
//заморочки с байтами для экономии памяти, решение проверялось в онлайн сервисах.
{ public static void Main()
// а в них сброс задачи при завышении потреблении памяти или процессорного времени.
{ uint st = uint.Parse(Console.ReadLine()); uint ylast = st-1;
byte[] sumA = new byte[st], sumB = new byte[st], cont = new byte[st+st];
sumA[ylast] = 1;
while (sumA[ylast] < 9)
{ Array.Clear(sumB, 0,sumB.Length); sumB[ylast] = 1;
while (sumB[ylast] < 9)
{ byte chk = 1; if (sumB[0] > 9) { rebild_mas(sumB); }
for (byte j = 0; j <= ylast; j++) { if (sumA[j] + sumB[j] > 9) { chk = 0; break;} }
if (chk == 1) { cont[0]++; if (cont[0] > 200) rebild_mas(cont); }
sumB[0]++;
}
sumA[0]++; if (sumA[0] > 9) { rebild_mas(sumA); }
}
Console.WriteLine("{0} ", otvet(rebild_mas(cont)));
}
static byte[] rebild_mas(byte[] summas)
{ byte z = 0; while (z < summas.Length-1)
{ if (summas[summas.Length-1] > 9) { Array.Resize(ref summas, summas.Length+1); }
summas[z + 1] += (byte)(summas[z] / 10);
summas[z] = (byte)(summas[z] % 10); z++;
} return summas; }
static string otvet(byte[] lon)
{ string rez =""; for (int x=lon.Length-1; x >= 0; x--)
{ if (lon[x] == 0 && x > lon.Length-2)continue; else rez += lon[x]; }
return rez; }
}
Хм мм, проверю завтра...
Интересно играете, сударь! savepic.ru/12891971.png
IRobot robot = (IRobot)currentPlayer;
всё, спасибо, понял теперь, теперь ещё всё проще, не глянул сразу, что это присвоение просто для удобства. сразу не увидел, мельком глянул. подумал что там "new ..." сказывается спешка и отсутствие времени.
Экземпляр бота создается один раз, а вот карта каждый раз передается новая - клонированная с рабочей
Каждый новый ход создаётся новый экземпляр бота и передаётся текущая карта, в итоге первая итерация это опять кот в мешке, только со второй итерации можно узнать, куда походило в прошлый раз и если там был неважный ход, тогда ладно, а если важный или даже критический, есть одна идея, надо проверить, по идее хорошее решение проблемы.
По поводу функции клонирования с возможностью реверса я сразу увидел, в любом случае после тестирования, я увидел потенциал для доработки идеи. Осталось найти время.
В классе Position, кстати, и метод для копирования поля есть (с возможностью реверса)
Провёл тестирование, да, точно, значит кое что проверю, если что, скину ещё одну версию бота. Спасибо.
Бот получает копию игрового поля, поэтому там можно делать какие угодно пометки, на "рабочее" поле они не повлияют.
Да, проверку на ничейный результат допилил только сегодня. ))
Евгений Витольдович указал неправильный ящик.
Правильный: formula_programmista@mail.ru
Подчеркивание вместо дефиса
Вот беда с отправкой, приходит уведомление, что нельзя доставить письмо. Три раза уже отправлял, возвращается отрицательный ответ. Завтра попробую еще направить. А вообще я сильно не расстроюсь, если не дойдет, это мой первый проект, связанный с ИИ, и он вряд ли удачен ;-)
Сергей, молодец!
Нужно теперь написанный класс прислать на указанный e-mail.
Ну конечно понимаю. А какая задача просто написать оценочную функцию или всё же более-менее полноценный ИИ?
Ну ты же понимаешь, что эту функцию мы можешь использовать в рекурсивном поиске лучшего хода, качество игры значительно улучшится.
Боты-комментаторы придумали прикольную идею?)))
Да, прикольную идею придумали, боты - комментаторы =)
Нет, не с точки зрения крестиков, а глобально.
больше нуля - крестики побеждают
меньше нуля - нолики побеждают
Они не программисты, у них другие задачи в команде.
Надо друзей привлекать к участию
Это не три случайных посетителя, а друзья с которыми я сейчас дискорде общаюсь
Сразу три случайных посетителя поставили оценки? Ай-яй-яй, Иван! :)
Надо бы рассылку сделать с приглашением, а то участников толком не будет.
Круто, мотивация хорошая, давно хотел пройти курс, наконец-то его приобрел и начал выполнять, осталось только доделать, еще 60%. Хотя не очень удачное время конкретно для меня вышло, гости и прочее отвлекало. Ну и + начал свой кое-какой проект.
Привет! Еще не занимался, но сегодня что-нибудь уже будет точно.
Андрей, привет. Как у тебя успехи с подготовкой к соревнованию 15 вряд?
Я тоже так думал, но запятая у меня и у робота шарпа, и это уже не впервые, поэтому я уже заранее код дорабатываю, чтобы точка была полюбому.
Запятая будет на твоем локальном ПК, а у робота Шарпа будет точка по-умолчанию.
Отлично, Андрей. SQL везде схож
Методы-расширения иногда бывают очень полезны, они позволяют сократить писанину, хотя на самом деле это обычный статический метод. Обязательное знание.
Без лямбд сейчас никуда, поэтому знать и любить их обязательно!
С помощью Linq решается, как обычно, в одну строчку.
Кирилл, а как удалять, если string - неизменяемый класс?
Первую версию этой задачи решил всего один человек, Сергей Соколов, для остальных её упростили 2 раза, проще уже некуда.
Это задача не по математике
С опытом эту задачу можно использовать как тренировку использования Linq
Написал красивое решение с использованием итератора, а робот шарп его не может переварить :(
Да, времени всегда не хватает =)
Осталось дождаться выходных, чтобы уже окончательно приступить
Логично. но тут идеальных программ нет, после окончания курса можно сделать репозиторий, как ты хочешь)
а что за красная буковка на заднем плане? уж очень она эмблему "videosharp" напоминает)))
Ну что ж, гифки так гифки)) котики так котики)
главное - начать! welcome!
Закончилось, в воскресенье на вебинаре подвели итоги, на выходных выложу видео и архив с ботами.
я сравнивал с одинаковыми по силе ботами, сделал 2 дубликата бота и с ними сравнивал, с разными по силе естественно разница будет не сильная, так как всё равно они выиграют, я о сравнении одинаковых ботов, клонов, ладно, я после соревнований сам сравню ещё раз.
Поменял местами циклы сегодня для эксперимента + добавил перед каждым кругом перемешивание ботов в коллекции, т.е. очередность каждый круг меняется - ничего в плане рейтинга не изменилось, сильнейший набирает все равно больше всех, второй - на втором месте и т.д.
Сделать игрока с функцией:
public int GetMove(...) => int.Parse(Console.ReadLine());
и можно тогда делать ходы ручным вводом, возможно действительно стоило об этом упомянуть в видео.
1, 2 - Для этого есть этот урок - можно вместо второго игрока запрашивать ввод с консоли.
Советы хороши, но, как говорится... да много как говорится, поговорок подходящих много.
Первый блин - комом. Одна голова хорошо, а две - лучше. Ложка хороша к обеду. И т.д.
3 - Здесь - да и с этим ничего не поделать.
То что сложно - да, поэтому особо не углублялся, лишь старался показать минимальный код, который позволит протестировать свою dll.
Комментарий дельный и полезный. Спасибо!
Ну еще есть пара дней, если вруг будут мыски как еще улучшить - можно прислать повторно
Максим, молодец, у тебя чуть менее двух суток, чтобы прислать своего бота!
Можно ли посмотреть исходник?
Теперь есть видео, на котором показано как протестировать своего бота, поэтому написать его стало немного проще.
Ну спасибо, только сейчас уже спать, а завтра на дачу(( так что не думаю, что успею потестить, лучше перенести на неделю)))
Ну, это, скорее, не урок, а так, введение в курс дела...
Вообще в папке с программой лежит отдельная dll - это движок игры (не знаю, для чего я его вынес отдельно, но можно теперь этим воспользоваться).
Нужно его подключить также как библиотеку FiaRPlayer.dll и сыграть следующим образом:
using System;
using FiaREngine;
using FiaRPlayer;
namespace MyApp
{
class Program
{
static void Main(string[] args)
{
IFiaRPlayer player1 = new MyPlayer();
IFiaRPlayer player2 = new MyPlayer();
FiaREngine.FiaREngine engine = new FiaREngine.FiaREngine(player1, player2);
engine.PrepareToPlay();
while (engine.GameState == GameState.MoveOfFirst || engine.GameState == GameState.MoveOfSecond)
engine.DoMove();
Console.WriteLine(engine.GameState);
}
}
}
Сюда скинул xml-ку, надо положить в папку с FiaREngine.dll для того, чтобы были русские комменты к методам и свойствам движка: rgho.st/6RdTRnXjg
Печально, пока ошибку найти не могу, а то что есть, жаде терменатора не выиграет, хотя моя реальная прога, вроде неплохо справляется
Напрямую - никак, только если добавить в солюшен какой-то запускаемый проект и из него работать с этой библиотекой
Андрей, а можно как то оттебажить dll??
Я вот написал свою прогу в которой всё работает, переношу методы в dll, а там работает некорректно, а брейкпоинта нигде не поставишь и не понятно, что именно там не отрабатывает, есть ли какие то методы?
Неочень ведь выйдит отсеять. Может случится зацыкливание при специальной комбинации которая небыла выевлена в переуд тестирование и получится зацыкливание на 1 партии из мильена партии
Именно поэтому его нет, потому что не определишь время оптимальное, то ли 1 сек ставить на ход, то ли 10, а может 60?
Просто в начале вручную всех зацикленных надо будет отсеить.
Как так? Должен быть таймоут. Ктото напишит хитро обработку массива клеток и программа зацыклится вечно. Что тогда будит? А ктото напишит что один ход обрабатывается скажем 1 секунду.
Таймаута нету, по крайней мере я о нем не знаю
Зы. Создание арены и ИИ к ней - это ну очень разные вещи, но с другой стороны, да, как минимум у меня должны быть временные преимущества, поэтому для себя я решил не участвовать в соревновании, либо если все-таки что-то у меня будет - все конкурса
О временных ограничениях я сначала думал, но потом решил от них уйти, так как непонятно сколько ставить - поставить 1 секунду, кому-то может вполне не хватить, поставить - больше? сколько тогда? 5? 10? 60?
С другой стороны, кто-то может впихнуть в своего бота бесконечный цикл, но я для себя решил, что таких мы просто вручную отсеим на предварительном этапе.
Чтобы посмотреть заголовок класса, метода, перечисления и прочего - нужно нажать F12, забыл сказать об это на видео, наверное.
По поводу того, то первый игрок всегда выигрывает - для человека может быть гораздо проще, а вот в коде это реализовать... Тут ведь даже мат конем и слоном покажется детским лепетом, здесь всего число комбинаций на доске ограничено сверху величиной 127^7 = 5.3*10^14 и в каждом случае до 7 вариантов хода, такое количество не то что перебрать во время игры, так даже заочно перебрать и составить словарь не предоставляется возможным - он будет занимать более 3 ПБ
чем тормознее, тем больше побед =) да, надо оптимизировать, времени небыло, но тормозных там реально 2, другие 3 сносные по скорости.
Там и бота то по сути нет, так посмотреть как работает))
Да, я понял, уже архив раздал, поэтому правила изменить можно будет после соревнований, ок, скоро скину письмо с ботами
В принципе, формула расчета рейтингов изаестна и смоделировать при желании можно и так. Примем, что у нас 5 ботов, например, #1 и #4 самые сильные, побеждают остальных, а между собой всегда играют вничью, #3 - самый слабый, проигрывает всем остальным, #2 чуть сильнее, #5 еще сильнее, но слабже чем #1 и #4. Теперь просто запускаем 1000 боев так и 1000 так и смотрим эффект. Если реально будет ощутимая разница, то я на подведении итогов это сообщу и прямо там заменим алгоритм, но менять архив уже выложенный - точно не будем.
Я понял, просто я проверял, запускал сразу 1000 боёв и вручную тыкал по 1 бою чтобы было 1000 =) и когда тыкал по 1 бою статистика у одинаковых ботов была одинаковая, +- 1-3 рейтинга, а при тыке в 1000 боёв сразу, один слил рейтинг у всех, отожлася, второму уже нечего было высасывать, так как разница в рейтинге была существенная и потом когда он совокупился с себе подобным, он чуток перелил и всё, не хватило сравняться, я просто с 2003 года изучаю этот рейтинг и работаю с ним часто, такая формула используется на соревнованиях 1х1 или командных, при этом чем разница в рейтинге больше, тем не выгоднее тем, у кого рейтинг выше, потому что они ничего не получат при победе, а при проигрыше потеряют больше обычного, ок, я после соревнований проведу доп. исследования, свопнув циклы, спасибо. Прикольно сделал, зацепила идея =)
Зато победа будет сладкой!
Интересный скрин, написать бота, который проигрывает "комплектным" - тоже надо уметь)
Привет, Иван!
Не думаю, что это значительно повлияет на результаты, так уж устроена эта формула, иначе ее бы повсеместно не использовали! Возможно мелкие погрешности будут из-за округления до целого, но в общем итог всё равно один, победитель от этого не изменится (да и второе-третье место при большом количестве ботов тоже). Тут ведь всё завязано на мат.ожидание количества набранных очков и оно не зависит от порядка партий, только от их числа. Ну и самая главная проблема в том, что архив выложен и "менять правила во время игры" как-то не правильно.
А вообще после подведения итогов у тебя будет возможность поменять последовательность боев.
Привет, уже 5 ботов между собой сталкиваю лбами и базовые 2, итого уже 7 штук у меня балуются, заметил погрешности в расчётах, проанализировав ситуацию увидел, что если долго тыкать по 1 бою между ботами, то статистика ровненькая идёт как надо, а если сразу ткнуть 1000, то самый крутой схавает у всех по очереди рейтинг, а другие потом с теми же играют и рейтинг чуть ниже отбирают, так как формула так устроена, что чем с более слабым противником играешь и побеждаешь, очков меньше получаешь или вовсе не получаешь, поэтому советую свопнуть циклы количества битв с циклами перебора противников, т.е. у тебя сейчас выбираешь один бот, потом другой, а потом они по циклу выбранного количества боёв сражаются, сливая друг другу рейтинг, если окажется, что один заведомо слабее, то слив будет критическим, потом выбирается другой и если первый оказался сливатором, то он уже второму и последующим ничего не сольёт, так как у него рейтинг упадёт ниже плинтуса, а если он был тот, кто вампирил рейтинг, то он схавает его у всех, кто попадётся, если они слабее, в итоге, последующий выбор бота уже с ослабленным рейтингом и сталкивание их лбами с другими будет приносить им мизер или вовсе ничего, если же сделать как я написал выше, а именно свопнуть циклы, то погрешность будет минимальной, так как в идеале, данный расчёт рейтингов рассчитан на балансировку противников, а именно, можно реализовать отсеивание и сталкивать лбами тех, у кого рейтинги минимально отличаются в первую очередь. это отдельная песня, хотябы просто свопни циклы.
Пока не анонсировано, но я думаю - подведение итогов будет в воскресенье
А когда будут проводиться соревнования и до какого числа принимаются боты?
Если будет время и желание - никто не запрещает прислать еще одного бота, чем больше ботов, тем веселее!
Главное чтобы имя у него другое было, в том сисле и у класса, а то там, вроде, коллизии могут быть.