Играем в крестики-нолики против Ардуино

В этом уроке мы создадим игру крестики-нолики с использованием TFT-дисплея и Ардуино, и сыграем против компьютера.

В этом уроке мы собираемся сделать игру Arduino Крестики-Нолики. Мы будем использовать сенсорный экран, и сыграем против компьютера. Такая простая игра, как крестики-нолики, - это отличное введение в игровое программирование и искусственный интеллект.

Несмотря на то, что в этой игре мы не будем использовать алгоритмы искусственного интеллекта, мы поймем, почему алгоритмы искусственного интеллекта требуются в более сложных играх.

Разработка игр для Arduino непростая задача и требует много времени. Но мы можем создать несколько простых игр для Arduino, потому что это весело, и это позволит нам изучить некоторые более продвинутые темы программирования, такие как искусственный интеллект.

Это отличный учебный опыт, а в конце вы получите отличную игру для детей и друзей! Давайте теперь создадим этот проект.

Шаг 1. Комплектующие

Детали, необходимые для создания этого проекта, следующие:

  • Arduino Uno
  • 2,8-дюймовый сенсорный экран

Стоимость проекта очень низкая. Всего суммарно было потрачено примерно 15 долларов.

Сенсорный экран

Я обнаружил этот сенсорный экран на алиэкспресс и решили купить его, чтобы попытаться использовать его в некоторых наших проектах. Дисплей недорогой, он стоит около 11 долларов.

Дисплей имеет разрешение 320x240 точек, и поставляется в виде экрана, который делает соединение с Arduino чрезвычайно простым. Как вы можете видеть, на дисплее используются почти все цифровые и аналоговые выводы Arduino Uno. При использовании этого экрана мы оставляем всего 2 цифровых контакта и 1 аналоговый вывод для наших проектов.

К счастью, дисплей отлично работает с Arduino Mega, поэтому мы, когда нам нужно больше контактов, можем использовать Arduino Mega вместо Arduino Uno. К сожалению, этот дисплей не работает с платой Arduino Due или Wemos D1 ESP8266. Еще одним преимуществом экрана является то, что он предлагает слот для микро SD, который очень прост в использовании.

Шаг 2. Собираем детали вместе

После подключения экрана к Arduino Uno мы можем загрузить код, и всё будет готово к игре. Описание логики и кода ниже.

Шаг 3. Алгоритм игры

Чтобы ответить на этот вопрос, давайте посмотрим на алгоритм, который реализован в данной игре.

Компьютер всегда играет первым. Только это решение делает игру намного легче для Ардуино. Первым шагом всегда является угол. Второй ход для Arduino также является случайным углом от остальных, не заботясь о перемещении игрока. С этого момента Arduino сначала проверяет, может ли игрок выиграть на следующем ходе и блокирует это движение. Если игрок не может выиграть за один ход, он делает угловой ход, если он доступен, или случайный из оставшихся. Вот и все, этот простой алгоритм может победить человека-игрока каждый раз или в худшем случае, игра приведет к ничьей. Это не лучший игровой алгоритм крестики-нолики, но один из самых простых.

Этот алгоритм может быть легко реализован в Arduino, потому что игра очень проста, и мы можем легко проанализировать ее. Если мы создадим игровое "дерево" (см. выше), мы сможем найти некоторые выигрышные стратегии и сможем легко реализовать их в коде, или мы сможем позволить процессору вычислить игровое "дерево" в реальном времени и выбрать лучший вариант. Конечно, алгоритм, который мы используем в этой игре, очень прост, потому что игра очень проста. Если мы попытаемся разработать выигрышный алгоритм для шахмат, даже если мы используем самый быстрый компьютер, мы не сможем вычислить игровой алгоритм за тысячу лет! Для подобных игр нам нужен другой подход, нам нужны алгоритмы искусственного интеллекта и, конечно, огромная вычислительная мощность. Подробнее об этом в будущих видео.

Шаг 4. Код проекта

Давайте рассмотрим код проекта. Нам нужны три библиотеки для компиляции кода.


Adafruit GFX
Сенсорный экран

Как вы можете видеть, даже простая игра, подобная этой, требует более 600 строк кода. Код сложный, поэтому мы не будем пытаться объяснить его в кратком изложении. Я покажу вам реализацию алгоритма для движений Arduino.

Сначала мы играем два случайных угла.

int firstMoves[]={0,2,6,8}; // will use these positions first  
for(counter=0;counter<4;counter++) //Count first moves played
  {
    if(board[firstMoves[counter]]!=0) // First move is played by someone
    {
      movesPlayed++;
    }
  }  
  do
{
    if(moves<=2)
    {
      int randomMove =random(4); 
      int c=firstMoves[randomMove];
      
      if (board[c]==0)
      {  
        delay(1000);
        board[c]=2;
        Serial.print(firstMoves[randomMove]);
        Serial.println();
        drawCpuMove(firstMoves[randomMove]);
        b=1;
      }     
}

Затем в каждом раунде мы проверяем, может ли игрок выиграть в следующем ходу.

int checkOpponent()
{
  if(board[0]==1 && board[1]==1 && board[2]==0)
  return 2;
  else if(board[0]==1 && board[1]==0 && board[2]==1)
  return 1;
  else if (board[1]==1 && board [2]==1 && board[0]==0)
  return 0;
  else if (board[3]==1 && board[4]==1 && board[5]==0)
  return 5;
  else if (board[4]==1 && board[5]==1&& board[3]==0)
  return 3;
  else if (board[3]==1 && board[4]==0&& board[5]==1)
  return 4;
  else if (board[1]==0 && board[4]==1&& board[7]==1)
  return 1;
  else
  return 100;
}

Если да, мы блокируем этот ход в большинстве случаев. Мы не блокируем все ходы, чтобы дать игроку возможность выиграть. Можете ли вы найти, какие ходы не заблокированы? После блокировки перемещения мы играем в оставшийся угол или случайный ход. Вы можете изучить код и легко реализовать свой непобедимый алгоритм. Как всегда, вы можете скачать файл .ino с кодом проекта ниже.

Примечание. Поскольку, например, Banggood предлагает один и тот же дисплей с двумя разными драйверами дисплея, если приведенный выше код не работает, измените функцию initDisplay на следующее:

void initDisplay()
{
tft.reset();
tft.begin(0x9341);tft.setRotation(3);
}

Шаг 5. Итоговый результат

Сначала мы нажимаем кнопку «Начать игру» и игра начинается. Сначала играет Ардуино. Затем мы можем сыграть в наш ход, просто коснувшись экрана. Затем Arduino играет свой ход и так далее.

Игрок, которому удается разместить три своих знака в горизонтальном, вертикальном или диагональном ряду, выигрывает игру. Когда игра закончится, появится экран Game Over. Затем мы можем снова нажать кнопку воспроизведения, чтобы снова начать игру.

Arduino очень хорош в этой игре. Он выиграет большинство игр, или если вы очень хороший игрок, игра закончится вничью. Намеренно внесен в этот алгоритм то, что компьютер может совершить некоторые ошибки, чтобы дать игроку возможность выиграть. Добавив еще две строки в код игры, мы можем сделать так, что Arduino никогда не проиграет.

Как вы можете убедиться, даже с Arduino Uno мы можем создать непревзойденный алгоритм для простых игр. Этот проект хорош, потому что его легко создать, и в то же время это отличное введение в искусственный интеллект и игровое программирование. Мы постараемся сделать еще несколько продвинутых проектов с искусственным интеллектом в будущем, используя более мощную Raspberry Pi, поэтому следите за обновлениями!

Ардуино+