Dear friends, welcome to another Arduino tutorial! In this detailed tutorial we are going to build an Arduino Tic-Tac-Toe game. As you can see, we are using a touch screen and we are playing against the computer. A simple game like Tic-Tac-Toe is is a great introduction to game programming and artificial intelligence. Even though we won’t be using any artificial intelligence algorithms in this game, we will understand why artificial intelligence algorithms are required in more complex games.
Developing games for Arduino is not easy and requires a lot of time. But we can build some simple games for Arduino because it is fun and it will allow us to explore some more advanced programming topics, like Artificial intelligence. It is a great learning experience and at the end you will have a nice game for the kids!
Let’s now build this project.
Step 1: Get All the PartsThe parts needed in order to build this project are the following:
The cost of the project is very low. It is only $15.
Before attempting to build this project please watch the video I have prepared about the touch display by clicking on the card here. It will help you understand the code, and calibrate the touch screen.
Step 2: The 2.8" Touch Color Display for ArduinoI discovered this touch screen on banggood.com and decided to buy it in order to try to use it in some of my projects. As you can see the display is inexpensive, it costs around $11.
The display offers a resolution of 320x240 pixels and it comes as a shield which makes the connection with Arduino extremely easy. As you can see, the display uses almost all of the digital and analog pins of the Arduino Uno. When using this shield we are left with only 2 digital pins and 1 analog pin for our projects. Fortunately, the display works fine with the Arduino Mega as well, so we when we need more pins we can use the Arduino Mega instead of the Arduino Uno. Unfortunately this display does not work with the Arduino Due or the Wemos D1 ESP8266 board. Another advantage of the shield is that it offers a micro SD slot which is very easy to use.
Step 3: Building the Project and Testing ItAfter connecting the screen to the Arduino Uno, we can load the code and we are ready to play.
At first, we press the “Start Game” button and the game starts. The Arduino plays first. We can then play our move simply by touching the screen. The Arduino then plays its move and so on. The player who succeeds in placing three of their marks in a horizontal, vertical, or diagonal row wins the game. When the game is over, the Game Over screen appears. We can then press the play again button to start the game again.
The Arduino is very good at this game. It will win most of the games, or if you are a very good player the game will end in a draw. I intentionally designed this algorithm to make some mistakes in order to give the human player a chance to win. By adding two more lines to the code of the game, we can make the Arduino impossible to lose the game. But how can a $2 chip, the Arduino CPU, beat the human brain? Is the program we developed smarter than the human brain?
Step 4: The Game AlgorithmTo answer this question, let’s look at the algorithm I have implemented.
The computer always plays first. This decision alone, makes the game much easier for the Arduino to win. The first move is always a corner. The, second move for the Arduino is also a random corner from the remaining without caring about the player move at all. From this point on, the Arduino first checks if the player can win in the next move and blocks that move. If the player can’t win in a single move, it plays a corner move if it is available or a random one from the remaining. That’s it, this simple algorithm can beat the human player every time or at the worst case scenario the game will result in a draw. This is not the best tic tac toe game algorithm, but one of the simplest.
This algorithm can be implemented in Arduino easily, because the Tic-Tac-Toe game is very simple, and we can easily analyze it and solve it. If we design the game tree we can discover some winning strategies and easily implement them in code or we can let the CPU compute the game tree in real time and chose the best move by itself. Of course, the algorithm we use in this game is very simple, because the game is very simple. If we try to design a winning algorithm for chess, even if we use the fastest computer we can’t compute the game tree in a thousand years! For games like this, we need another approach, we need some Artificial Intelligence algorithms and of course huge processing power. More on this in a future video.
Step 5: Code of the ProjectLet’s take a quick look at the code of the project. We need three libraries in order the code to compile.
As you can see, even a simple game like this, require more than 600 lines of code. The code is complex, so I won’t try to explain it in short tutorial. I will show you the implementation of the algorithm for the Arduino moves though.
At first, we play two random corners.
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;
}
}
Next, in each round we check if the player can win in the next move.
<p>int checkOpponent()<br>{
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;
}
If yes, we block that move, most of the times. We don’t block all the moves in order to give the human player a chance to win. Can you find which moves are not blocked? After blocking the move, we play a remaining corner, or a random move. You can study the code, and implement your own unbeatable algorithm easily. As always you can find the code of the project attached on this tutorial.
NOTE: Since Banggood offers the same display with two different display drivers, if the above code does not work, change the initDisplay function to the following:
void initDisplay()
{
tft.reset();
tft.begin(0x9341);tft.setRotation(3);
}
Step 6: Final Thoughts and ImprovementsAs you can see, even with an Arduino Uno, we can build an unbeatable algorithm for simple games. This project is great, because it is easy to build, and at the same time a great introduction to artificial intelligence and game programming. I will try to build some more advanced projects with artificial intelligence in the future using the more powerful Raspberry Pi so stay tuned! I would love to hear your opinion about this project.
Please post your comments below and don’t forget to like the tutorial if you find interesting. Thanks!
Comments