Классический тетрис представляет собой головоломку, построенную на использовании геометрических фигур «тетрамино» — разновидности полимино, состоящих из четырёх квадратов. В нашей версии стакан имеет глубину в 2 квадрата (слоя), заполнять необходимо оба горизонтальных ряда из 10 клеток, расположенных на одной высоте. Управление на стрелках клавиатуры, переворот игрового поля на другой слой - Ctrl.
Язык C#, среда разработки - Unity.
Автор - Тихон, 13 лет ("Карандаш и Самоделкин")
Скачать можно c Яндекс.Диск, исходный код здесь
Прототип игры сначала написал на Python, исходники по ссылке
На самоизоляции сейчас непросто всем, но сидеть и унывать скучнее, чем заниматься любимым делом. Мы не сидим сложа руки и придумали довольно фановую штуку, назвав ее NeyroGamer.
NeyroGamer это своего рода бот, играющий в видео игры. Так как нам нравятся старые консоли, первая игра, в которую мы хотим научить играть нашего бота - гоночная аркада на Sega Genesis под названием Nigel Mansell's World Championship Racing. Игры запускаются на эмуляторе консоли (мы используем Fusion 3). Проект немного похож на один из наших прошлых проектов "Длинный хвост питона", так как использует машинное зрение с OpenCV.
В коде реализовано 2 класса, каждый из которых отвечает за свою область.
Класс ScreenReader содержит функциональность, позволяющую получать информацию о данных с экрана. Для этого делается скриншот. Мы пробовали множество вариантов — но самым быстрым был метод ImageGrab из модуля PIL. Он показал FPS в 25 кадров в секунду. Этого вполне достаточно для реагирования на повороты. После взятия изображения оно обрабатывается с помощью библиотеки OpenCV. Я накладываю маску, что бы выделить дорогу из кадра. Маска берётся не на всём кадре, а на 2 полосах экрана, первая из которых находится в самом низу кадра, а вторая почти под линией горизонта. Таким образом можно понять в какую сторону изгибается дорога. С помощью двух моментов можно притормаживать на поворотах и газовать максимально на прямых участках. Второй класс, Сontrol — отвечает за управление машинкой путем передачи в игру нажатия кнопок на виртуальном геймпаде.
Настройка эмулятора и виртуального геймпада.
Для управления игрой в эмуляторе была установлена программа Vjoy, с помощью которой к компьютеру был подключен виртуальный геймпад. На геймпаде 11 кнопок и 1 стик. Для управления этим геймпадом из программы я использую модуль PyVjoy. Для корректной работы модуля внутрь папки требуется положить специальный DLL-файл, который генерируется в папке, куда вы установили Vjoy. После этого вы сможете управлять виртуальным геймпадом из программы на Python. Необходимо установить в настройках эмулятора вход 1. На него следует поставить 3х кнопочный джойстик Genesis и выбрать в качестве него ваш виртуальный геймпад.
После этого надо запустить программу AssignKeys.py. Она будет нажимать кнопки виртуального геймпада в том порядке, какого требует эмулятор Fusion 3. Во время назначения клавиш фокус должен быть всё время на программе-эмуляторе. Когда эмулятор будет ждать клавиши старт, нажмите любую удобную кнопку на клавиатуре. Это нужно для возможности войти в гонку и поставить паузу. Всё готово! Вы можете запускать гонку в полноэкранном режиме предварительно запустив run.py.
У вас наверно возник вопрос - почему проект носит порядковый номер 1? Всё просто. В репозитории пока открыт только демо-код, алгоритм которого не идеальный. Гонку мы пока проходим на 8-9 месте, поэтому будем дорабатывать NeyroGamer. Первая часть проекта - научиться взаимодействовать с игрой, получать игровые события, передавать команды управления. Сейчас мы работаем над нейронной сетью, которая улучшит игровые результаты.
Язык Python.
Автор - Платон, 14 лет ("Карандаш и Самоделкин")
Чем заняться на самоизоляции? Как вариант - написать игру, в которую можно играть всей семьей.
Ремейк игры Lode Runner (Apple II) с оригинальным набором уровней. Главная фишка - режим hot seat до 4 человек, где остальные игроки играют за противников главного героя. Однако от уровня к уровню могут играть разное количество игроков, так как количество противников разное на разных уровнях.
Игрок управляет маленьким человечком и должен собрать всё золото, лежащее на данном уровне, избегая встречи с противниками. Весь уровень целиком виден на экране и состоит из кирпичных платформ, лестниц, а также натянутых верёвок, по которым можно двигаться, держась за них руками. Персонаж игры не может убивать роботов, но может создавать для них ямы в кирпичном полу — попавший в яму робот задерживается там на некоторое время. Герой может падать с любой высоты, не разбиваясь, но не может подпрыгивать. После того, как все ящики с золотом собраны, где-либо появляется лестница (или несколько), по которой нужно добраться до верха экрана — это приведёт к переходу на следующий уровень.
Всего в игре 150 уровней. На каждом новом уровне требуется более сложная стратегия в отношении того, в каком порядке обходить уровень и где прорыть ямы с тем, чтобы собрать все ящики с золотом и не попасться. Стратегия также может включать способы создания одной большой ямы из множества обычных, прорытых друг за другом.
С переходом на более высокие уровни игра становится более «головоломной» чем игрой на скорость реакции, хотя и то и другое остаётся важным.
Язык C#, среда разработки - Unity.
Автор - Платон, 14 лет ("Карандаш и Самоделкин")
Скачать можно c rutracker.org или c Яндекс.Диск
В последнее
время наш блог молчит и может показаться,
что «Карандаш и Самоделкин» все, сдулись.
На самом деле работа кипела, а отсутствие
публикуемых материалов было связано с
тем, что проекты раз за разом становятся
все сложнее и требуют все больше времени
на реализацию. Последние наши разработки
были так или иначе связаны с нейросетями,
поэтому логично было за это время
подтянуть скиллы по этой теме, что и
было сделано – был пройден ряд онлайн
курсов по и даже пара оффлайновых, из
которых особенно понравилась «Зимняя
школа машинного обучения» (MachineLearningWinterSchool).
Проект,
работа над которым шла больше 4 месяцев,
мы назвали Sudoku Hunter. Изначально была идея
собрать робота по мотивам NXTSudokuSolver,
однако постепенно она трансформировалось
в нечто иное, на наш взгляд не менее
интересное.
Итак,
Sudoku Hunter – это пистолет с EV3,
веб-камерой и RaspberryPi
на борту, из которого можно «стрелять»
по математическим головоломкам судоку,
получая на экране EV3-блока
их решение. В алгоритмической части
используются технологии машинного
зрения и машинного обучения, веб-технологии
для создания отладочной видеоконсоли.
Если
кто не помнит, судоку - головоломка на
бумаге, игровое поле которой представляет
собой квадрат размером 9×9, разделённый
на меньшие квадраты со стороной в 3
клетки. Таким образом всё игровое поле
состоит из 81 клетки. В них уже в начале
игры стоят некоторые числа (от 1 до 9),
называемые подсказками. От игрока
требуется заполнить свободные клетки
цифрами от 1 до 9 так, чтобы в каждой
строке, в каждом столбце и в каждом малом
квадрате 3×3 каждая цифра встречалась
бы только один раз.
Конструкция
нашего робота не особенно замысловата,
поэтому инструкцию по сборке мы решили не
делать – вы легко соберете что-то
подобное просто глядя на фото. Мы
использовали следующие компоненты:
Блок
LegoMindstromsEV3
и строительные детали из этого набора
RaspberryPi
Веб-камера
Sony Playstation
Eye
Wi-fi
адаптер для связи EV3
с RPi
Powerbank
для питания RPi
Программ,
которые необходимы для работы робота
- несколько, все они написаны на Python:
Программа
для EV3 - отвечает за вывод информации
на экран блока, связь с Raspberry Pi, передачу
на RPi
состояния датчика-кнопки
Программа для
RaspberryPi
- отвечает за обработку кадров с камеры,
распознаванием цифр с использованием
обученной нейросети, последующим
решением распознанного судоку, связь
с EV3,вывод
вспомогательной и отладочной информации
на веб-консоль,
Программа
для RaspberryPi,
предназначенная для создания дата сета
для обучения нейронной сети.
Программа
для ПК, используется для создания и
обучения нейросети на основе
подготовленного дата сета
Основная
программа для RaspberryPi
работает по следующему алгоритму:
Подключение
библиотеки машинного зрения OpenCV
Подключение
библиотек машинного обучения keras(tensorflow), sklearn
Процесс
1:
Взятие
кадра с камеры
Преобразование
изображения из BGR в HSV
Наложение
маски для фокусировки
на значимых элементах изображения
Запись
результирующего кадра в объект в памяти
Соединение
с EV3с
помощью протокола socket
Основной
цикл:
Чтение
кадра из объекта в памяти
Поиск
в изображении с наложенной
маской объектов, напоминающих
квадрат
Передача
данных о предполагаемом расположении
квадрата на EV3,
для вывода на экран блока
Приём
данных с EV3
о состоянии кнопки
Если
кнопка нажата:
Процесс
3:
Запуск
веб-сервера (используется модуль Flask)
Соединение
с RaspberryPi с
помощью протокола socket
Получение данных
о предполагаемом расположении квадрата
Подключение
библиотеки машинного зрения OpenCV
Подключение
библиотек машинного обучения keras(tensorflow), sklearn
Процесс
1:
Взятие
кадра с камеры
Преобразование
изображения из BGR в HSV
Наложение
маски для фокусировки
на значимых элементах изображения
Запись
результирующего кадра в объект в памяти
Соединение
с EV3с
помощью протокола socket
Чтение
кадра из объекта в памяти
Поиск
в изображении с наложенной
маской объектов, напоминающих
квадрат
Передача
данных о предполагаемом расположении
квадрата на EV3,
для вывода на экран блока
Приём
данных с EV3
о состоянии кнопки
Если
кнопка нажата:
Запуск
веб-сервера (используется модуль Flask)
Вывод
информации на веб-сервер - видеоконсоль
для удобства отладки
Подключение
библиотек машинного обучения
Загрузка
дата сета изображений
Разбиение
дата сета на учебные
и тренировочные данные
Создание
нейронной сети с заданными параметрами
Обучение
нейронной сети
Сохранение
модели
Процесс
2:
Изображение
обрабатывается и судоку «нарезается»
на 81 квадрат в каждом из которых одна
клетка головоломки
Каждый
из фрагментов проверяется на наличие
в нём цифры и если цифра обнаружена,
то клетка подаётся на распознавание
нейронной сети
Распознанная
цифра заноситься в массив. Когда массив
заполнен всеми цифрами, он подаётся в
алгоритм, решающий судоку
Массив содержащий
решённую головоломку передаётся на
EV3
для вывода на экран блока
Вывод
информации на веб-сервер - видеоконсоль
для удобства отладки
Программа на
EV3
работает по следующему алгоритму:
Вывод
контура квадрата на экран для
визуального контроля (размер квадрата,
угол разворота, степень его трапециевидности)
Передача
состояния датчика-кнопки
на Rpi
Если
от RPi
получен массив данных с решенной
головоломкой - вывод решённого судоку
на экран блока
Программа
создания дата сета для обучения нейронной
сети на RaspberryPi
имеет следующий алгоритм:
Процесс
2:
Изображение
обрабатывается и судоку «нарезается»
на 81 квадрат в каждом из которых одна
клетка головоломки
Каждый
квадрат сохраняется в папку, формируя
дата сет
Процесс 3:
Программа
на ПК, предназначенная для создания и
обучения нейросети на основе подготовленного
дата сета работает так:
Стандартный
алгоритм обучения нейронной сети мы
усовершенствовали
путём запуска функции обучения не на
заданное количество
эпох, а по одной эпохе, с проверкой
результата на проверочной выборке после
каждой. Если результат ухудшается
несколько эпох подряд — прекращаем
обучения с ошибкой. Если результаты на
тестовой выборке выше 95% -
прекращаем
обучения, проверяем модель на отдельной
выборке (которую она ещё не видела ни
при обучении,
ни
при проверках после каждой эпохи).
Нам очень нравятся игры для программистов, такие как например Colobot и Ceebot. Писать код, загружать его в своего бота и запускать его для выполнения миссий - что может быть интереснее? Поддержка сетевого режима, когда другие игроки запускают своих прокачанных кодом ботов против твоего? Несомненно. Однако еще более интересным нам показалось самим разработать игру для программистов и поиграть в нее с друзьями.
Серверный игровой движок, многопоточность, асинхронный обмен данными, объекты и классы - все это мы приправим поддержкой дополненной реальности с использованием машинного зрения c OpenCV.
Приставка Pi в названии проекта "PiTanks Online" однозначно намекает на то, что в качестве серверной платформы мы использовали Raspberry Pi. Игровое поле в нашем проекте нарисовано от руки на листе бумаги.
На него смотрит веб-камера, установленная на подставке, собранной из LEGO Technic. В качестве рисованного поля может использоваться также маркерная доска.
Каждый кадр, полученный с камеры, обрабатывается в реальном времени. Все нарисованные или размещенные на поле объекты становятся непроезжаемыми для ботов препятствиями. Игра полна интерактива - положенная на игровое поле спичка или монетка становится новым испытанием - с момента их появления на поле ботам игроков приходится думать как их объезжать. Игровое поле опубликовано на веб-сервере, любой игрок может наблюдать за ходом битвы в браузере.
Для участия в битве игрок может скачать одну из заготовок кода бота и, модифицировав ее, подключить бота к игровому серверу. Взаимодействие клиент-сервер организовано посредством socket-соединения. Все примеры ботов написаны на Python, хотя ничего не мешает использовать на клиентской стороне любой другой язык программирования, умеющий работать с сетевыми сокетами.
Наши примеры ботов имеют следующие наборы "команд":
forward()- бот смещается на 1 единицу дистанции вперед (в сторону, в которую он в данный момент развернут)
backward() - бот смещается на 1 единицу дистанции назад
right() - бот поворачивается на месте на 1 градус вправо
left() - бот поворачивается на месте на 1 градус влево
radar(a) - запросить данные с радара по направлению a (угла в градусах 0..359 от текущего направления бота). Функция возвращает кортеж из символа, обозначающего объект, который обнаружил радар (t - живой бот противника, w - стена или мертвый бот противника, n - "ничего нет") и числа - расстояния до обнаруженного объекта (0 в случае объекта "ничего нет")
fire() - бот производит выстрел, снаряд летит по направлению разворота бота
energy() - возвращает количество доступных очков действий. Очки действий тратятся на движение, стрельбу и работу радара. Пополняются каждую секунду. Введены, чтобы никто из игроков не мог получить приоритета в обработке его бота сервером.
exit() - отключиться от сервера, выйти из боя
Каждая из функций forward, backward, left и right возвращает True или False давая понять боту, была ли отработана команда. Это может быть удобным, например для понимания не застрял ли бот при маневре, упершись в препятствие.
При желании можно не использовать готовые функции из примеров, а написать свои. Например, доработать функции поворота возможностью принимать параметр "угол поворота", а функции движения - параметр "дистанция". Логику управления ботом в целом можно накрутить довольно сложную. Вполне адекватно работают, например, ПИД-регуляторы по дальномерам ботов, можно использовать элементы SLAM для локализации на карте.
Написанный на Python бот может работать не только на ПК, подходит практически любое устройство с интерпретатором этого языка, например LEGO EV3, ESP8266 или смартфон:
Исходный код сервера и примеры ботов доступны по ссылке.