59

Нейронная сеть, теперь и для Tower Defense, проверяю гибкость моего "детища"

Привет всем! В сегодняшнем посте я бы хотел вам расписать, что такое эта "нейросеть" обычными словами и рассказать про то, как я использовал ее в созданном на неделе Tower Defense'е(Жанр игр, где у игрока есть карта с дорогами, по которым враги пытаются добраться от начала до конца, а цель игрока ставить "башни", для того чтобы те всячески мешали недругам выполнить их задачу, отстреливая, замедляя их и т.д.), и примерчик, как я генерирую карты(это не рандомная генерация, а просто способ ускорено рисовать наброски уровней), может кому интересен будет.


Ссылка на прошлый пост


Для людей, которые хотели бы узнать что это за "магия" на тему которой некоторые свободно разговаривают, а у других при этом возникает чувство, что первые общаются на древне-руническом. Так вот, допустим, я хочу создать нейросеть, которая будет решать, есть ли мне что-то или нет. Сама сеть это такая коробка, в которую мы подаем информацию, в данном случае блюдо, а на выходе, т.к. я хочу получить ответ есть мне это или нет, будет вероятность того, съел бы я это блюдо. внутри этой коробки есть 2 анализатора(входа), это внешний вид блюда и его запах. Т.е. по сути мы имеем 2 нейрона, по 1 от каждого анализатора, а именно - первый нейрон имеет 2 значения, если он равен 1 значит блюдо "хорошо выглядит", а в случае 0 - блюдо "плохо выглядит" и, так же, есть второй нейрон, который при 1 говорит нам, что у блюда "хороший запах", а при 0 - "плохой запах", так же у каждого нейрона есть свой "вес", часто он находиться в промежутке от 0 до 1. Изначально я установлю вес каждого нейрона равным 0. И начинаю тренировать сеть, на собственном примере, ведь я хочу, чтобы она думала также, как и я. Беру блюдо1, оно на вид хорошее и запах приятный, "я б его съел" пронеслось в голове и я говорю сети, что в данном примере ответ "да". Сеть пробегается по нейронам "хорошо выглядит" и "хороший запах", и просчитывает по "грубой" формуле (значение_нейрона1 *умножить* на вес_нейрона1 + значение_нейрона2 *умножить* на вес_нейрона2), т.е. в нашем случае сеть говорит нам (1 * 0 + 1 * 0) = 0, т.е. по ее мнению, я бы это не стал есть, но т.к. это ответ не правильный(не совпадает с тем, что я ей сказал), она прибавляет ей 0.5 к весу, чем меньше это значение(0.5), тем больше мне потребуется опытов в процессе обучения, но и сеть будет точнее работать, но в данном примере я решил прибавлять по 0.5 в случае, если ответ совсем не совпадает. Далее рассмотрим блюдо2, оно выглядит ужасно, но вкусно пахнет, я сети говорю "да, я съел бы это", она проходит по нейронам и считает (0 * 0.5 + 1 * 0.5) = 0.5, т.е. есть вероятность что я съем, по ее мнению. Что не сильно, но отличается от вреного ответа, т.к. в нейроне вкуса был 0, а мой ответ был 1, то мы от этого веса отнимем примерно третью часть нашего числа(0.5) от веса, т.е. вес стал (0.5 - 0.15) = 0.35, а вот в нейроне запаха была 1, то мы прибавляем к весу 0.15 и получаем (0.5 + 0.15) = 0.65. Теперь, мои приоритеты вам известы, а известны ли они сети? Проверим, даем блюдо3 с хорошим видом и плохим запахом (1 * 0.35 + 0 * 0.65) = 0.35, т.е. маловероятно, что в принципе близко к моему ответу нет. И вот я иммею простецкую сеть, решающую тривиальную задачу.


Теперь приступим к рассмотрению нейросети в TD. Я набросал небольшой уровень который выглядит следующим образом.

Где желтые кубы - это места для строительства, белые шары это точки маршрута, или те самые дороги, по которым враги стремяться дойти до конца.(Вход ближняя к нам крайняя точка, выход дальняя крайняя). Так же "своял" три пушки, просто турель, стреляющая быстро по 1 врагу

Ракетная установка, которая бьет по сильнее, но медленнее и сразу по нескольким врагам.

И пушка-заморозка, которая при атаке замедляет скорость врага на 30%.

Взяв ту же сеть, что и в прошлом посте, я начал думать, какие данные давать боту, чтобы тот отталкивался от них. Решил основываться на том, где расположена точка постройки, а точнее сколько прилегает к этому кубику "точек маршрута", тэг выглядит следующим образом "build_2_3", где первая цифра это сколько точек прилегает с отступом в 1(т.е. сверху, снизу, слева, справа), а вторая цифра это сколько точек прилегает по диагонали, это можно назвать первым слоем, второй слой смотрит что за пушка(ее ID) и сколько таких уже построено, тэг выглядит так "tower_1_0". Т.е. теперь бот получает лучшую, по его мнению, точку, для постройки, основываясь на весе нейрона с тэгом "build_*_*" и далее прибавляет к нему вес нейрона вышки "tower_*_*" для каждой из пушек и так же добавляет все эти действия в пул, из которого бот уже выберет, какую пушку ему строить. После завершения составления этого списка, бот выбирает лучшие из них, так же с коэффициентом погрешности. И уже из лучших на основе рандома выбирает конечную. Если у него хватает денег, то он строит, если нет, то ничего не делает. Это позволит боту ждать, когда ему хватит денег на башню, а не плодить кучу дешевых.


Для обучения я наплодил 200 волн по 8 противников, каждая волна немного сильнее предыдущей. При первой итерации бот дожил аж до 58 волны, а уже при третьей "прошел" игру. Тут я понял, что проблема в балансе и боту слишком просто. ПО этому разницу между противниками в разных волнах я увеличил. Теперь бот уже испытал сложности и начал использовать все виды пушек. Но текущие данные не идеальны, ведь бот сейчас основывается, грубо говоря, на положении точек построек относительно "точек пути", а среди пушек выбирает те, которые ему нравятся(он использует ледяную и ракету, чаще чем пулемет), хотя в текущей версии, с одинаковыми врагами, эта стратегия хорошая. Но бот не создает комбинации из нескольких пушек (ракета, а рядом заморозка), точнее подобные связи получаются у него, но они не осознанные.


Но в итоге я решил вообще отойти от темы построения кучи вышек в ряд, а сделать 6-7 отдельных позиций. В текущей версии башенки уже приобрели по несколько улучшений, разные способности. Так что в ближайшие дни я по лучше разовью бота, научу его улучшать вышки и уже научиться распознавать что правильней сначала ракета, потом заморозка или наоборот.



А теперь я расскажу, как я генерирую уровень, для дальнейшего его редактирования. На самом деле, все довольно таки банально, я просто рисую в Paint'е вот такую карту, по пиксельно.

Где серые это просто блоки, черные - это места под строительство, зеленый - это выход. Соответственно я разбираю каждый пиксель и смотрю их цвет и в зависимости от него, я подгружаю нужный мне элемент(земля, выход и т.д.). Желтая и красные пиксели это пути, я разбираю их на 2 составляющие r и g, красный и зеленый цвет. Если зеленый цвет = 255, значит это спавн, точка старта для монстров, а вот красный цвет в зависимости от насыщенности меняется направление движения, т.е. при r=255 направление движения вправо, r = 196, направление движения вверх. Все это можно было оставить одним красным цветом и уже кодом искать ближайшие точки, но я захотел вообще упростить себе задачу). Соответственно позиция пикселя на картинке, является позицией подгружаемого объекта в мире.

Правила сообщества

ОБЩИЕ ПРАВИЛА:

- Уважайте чужой труд и используйте конструктивную критику

- Не занимайтесь саморекламой, пишите качественные и интересные посты

- Никакой политики


СТОИТ ПУБЛИКОВАТЬ:

- Посты о Вашей игре с историей её разработки и описанием полученного опыта

- Обучающие материалы, туториалы

- Интервью с опытными разработчиками

- Анонсы бесплатных мероприятий для разработчиков и истории их посещения;
- Ваши работы, если Вы художник/композитор и хотите поделиться ими на безвозмездной основе

НЕ СТОИТ ПУБЛИКОВАТЬ:

- Посты, содержащие только вопрос или просьбу помочь
- Посты, содержащие только идею игры

- Посты, единственная цель которых - набор команды для разработки игры

- Посты, не относящиеся к тематике сообщества

Подобные посты по решению администрации могут быть перемещены из сообщества в общую ленту.

ЗАПРЕЩЕНО:

- Публиковать бессодержательные посты с рекламой Вашего проекта (см. следующий пункт), а также все прочие посты, содержащие рекламу/рекламные интеграции

- Выдавать чужой труд за свой

Подобные посты будут перемещены из сообщества в общую ленту, а их авторы по решению администрации могут быть внесены в игнор-лист сообщества.


О РАЗМЕЩЕНИИ ССЫЛОК:

Ссылка на сторонний ресурс, связанный с игрой, допускается только при следующих условиях:

- Пост должен быть содержательным и интересным для пользователей, нести пользу для сообщества

- Ссылка должна размещаться непосредственно в начале или конце поста и только один раз

- Cсылка размещается в формате: "Страница игры в Steam: URL"

Темы

Политика

Теги

Популярные авторы

Сообщества

18+

Теги

Популярные авторы

Сообщества

Игры

Теги

Популярные авторы

Сообщества

Юмор

Теги

Популярные авторы

Сообщества

Отношения

Теги

Популярные авторы

Сообщества

Здоровье

Теги

Популярные авторы

Сообщества

Путешествия

Теги

Популярные авторы

Сообщества

Спорт

Теги

Популярные авторы

Сообщества

Хобби

Теги

Популярные авторы

Сообщества

Сервис

Теги

Популярные авторы

Сообщества

Природа

Теги

Популярные авторы

Сообщества

Бизнес

Теги

Популярные авторы

Сообщества

Транспорт

Теги

Популярные авторы

Сообщества

Общение

Теги

Популярные авторы

Сообщества

Юриспруденция

Теги

Популярные авторы

Сообщества

Наука

Теги

Популярные авторы

Сообщества

IT

Теги

Популярные авторы

Сообщества

Животные

Теги

Популярные авторы

Сообщества

Кино и сериалы

Теги

Популярные авторы

Сообщества

Экономика

Теги

Популярные авторы

Сообщества

Кулинария

Теги

Популярные авторы

Сообщества

История

Теги

Популярные авторы

Сообщества