# Tic Tac Toe – TV out version

I sow several tic-tac-toe games for arduino. All of them were designed for GLCD library, and none was a "thinking" one, all were randomly chosen steps. At first this game was designed for GLCD, but when I sow the TVOUT library, I knew this will be my first trail with it, converting the tic tac toe to output on TV. You can see the setup in this photo: I used Duemilanove board, the keyboard you see is also home made. The arduino is connected to the computer since I was in the middle of working on the code when I took the photo.

And in this photo you can see Its still easy to beat the game, but that is true when playing against humans as well, If you go for 3 corners no one can stop you from winning.

If you are interested in the code, just drop me a line. I think I would like to add some sounds to it as well, which is available with the TVOUT library.

This looks really good. Do you have any videos showing it in action? Have you considered making a version with some form of AI, so that it's a real challenge?

I decently need to make a video, just don’t have a proper video camera to do it with.
It’s not Simple to beat it, but as you might know, if u played enough tic tac toe, that there are not as many options of winning.
And the chance of winning if u r second are close to none …
Basically what I did is to teach it all that I know about the game, it sues score point to choose the next move out of the possibilities, this is the part of code that is responsible fro the “thinking”.

``````// **********************************************************************************************************************
// Compute next move
// **********************************************************************************************************************
void computNextMove(){
// declare high points for tile
int highpoints = 0;
int highpointsRow = 4; //we use 4 as WAY bigger then the cube
int highpointsCol = 4; //we use 4 as WAY bigger then the cube

// lo0p over row
for(int row = 0; row < 3; row++) {
// loop over col
for (int col = 0; col < 3; col++) {
// if ZERO - free space
if (tiles[row][col] ==0) {
// Calc the total of the ROW
int totalRow = tiles[row][0] +tiles[row][1] + tiles[row][2] ;
int totalCol = tiles[0][col] +tiles[1][col] + tiles[2][col] ;
// declare the othe player for the math
int OtherPlayer = CurrentPlayer==0?1:0;
int CurrentPlayerPlaceHolder=placeHolder[CurrentPlayer];
int OtherPlayerPlaceHolder=placeHolder[OtherPlayer];
int totalTilePoints =0;
// make 2 for self = 1 point **  block 2 of oppisite = 3 **  make 3 (win) = 5
totalTilePoints = totalTilePoints + calcTotalPointsSetOfThree(totalRow);
totalTilePoints = totalTilePoints + calcTotalPointsSetOfThree(totalCol);

// check center
if (row ==1 && col ==1)  {
// on diag
int diagTotalONE =  tiles[0][0] +tiles[1][1] + tiles[2][2];
totalTilePoints = totalTilePoints + calcTotalPointsSetOfThree(diagTotalONE);
// secdiag
int diagTotalTWO =  tiles[2][0] +tiles[1][1] + tiles[0][2];
totalTilePoints = totalTilePoints + calcTotalPointsSetOfThree(diagTotalTWO);
} // end if (row ==1 && col ==1)

// check diagonals
if (row !=1 && col !=1)  {
// add extra point for crners
totalTilePoints = totalTilePoints + 1;
// to know in wich dirctio nto go
int rowDir =  row==0?1:-1;
int colDir =  col==0?1:-1;
int diagTotal =  tiles[row][col] +tiles[row+rowDir][col+colDir] + tiles[row+rowDir*2][col+colDir*2];
totalTilePoints = totalTilePoints + calcTotalPointsSetOfThree(diagTotal);
// add 1 more tests :
// 1, if the OTHER ROW  CORENER is your  opponenet add 1 point
if (tiles[row][col+colDir*2] == OtherPlayerPlaceHolder) {
totalTilePoints = totalTilePoints + 1; }

// 2, if the OTHERcol  CORENER is your  opponenet add 1 point
if (tiles[row+rowDir*2][col] == OtherPlayerPlaceHolder) {
totalTilePoints = totalTilePoints + 1; }
} // END if (row !=1 && col !=1)

// check if maxed  high point
if (highpoints<totalTilePoints)  {
highpoints =  totalTilePoints;
highpointsRow = row;
highpointsCol = col;
} // end if (highpoints<totalTilePoints)
} // end (tiles[j][k] =!=0)
} // end loop over col
} // end loop over row

// if found possible row
if (highpoints >0)  {
playMove(highpointsRow,highpointsCol);  }
// if not found match .. random choose one of the corners
else {
// first check fi (1,1) is avialble
int fodunfreespace =  0;
// lop over row
for(int j = 0; j < 3; j++) {
// loop over col
for (int k = 0; k < 3; k++) {
// set to zero = empty
if(tiles[j][k] == 0) {
fodunfreespace = 1;
playMove(j,k);
} // end if(tiles[j][k] == 0)
}  // end loop over col
} // end loop over row

// if not foudn any open space ... end game
if (fodunfreespace == 0) {
isGameOver = 1;
refreshDisplay = true;
} // end if (fodunfreespace == 0)
} // end if  (highpoints >0)
} // end void computNextMove
``````

If you got ideas to improve it I’m more then happy to hear …

Took a camera from a friend and here is the video. http://www.youtube.com/watch?v=DhaGLs2eESE

After sending the video to my brother he pointed out that the tic tac toe game when played by equal players will always end up in a tie.
I then remembered this scene from the “war games” movie from back in the 80’s (one of the best computer movies)

So I took the challenge and here is a revised version of the “thinking” part, I would love to get comment if any one can beat the computer now.
If u want the full code just drop me a line,

``````void computNextMove(){
// declare high points for tile
int highpoints = 0;
int highpointsRow = 4; //we use 4 as WAY bigger then the cube
int highpointsCol = 4; //we use 4 as WAY bigger then the cube

// lo0p over row
for(int row = 0; row < 3; row++) {
// loop over col
for (int col = 0; col < 3; col++) {
// if ZERO - free space
if (tiles[row][col] ==0) {
// Calc the total of the ROW
int totalRow = tiles[row][0] +tiles[row][1] + tiles[row][2] ;
int totalCol = tiles[0][col] +tiles[1][col] + tiles[2][col] ;
// declare the othe player for the math
int OtherPlayer = CurrentPlayer==0?1:0;
int CurrentPlayerPlaceHolder=placeHolder[CurrentPlayer];
int OtherPlayerPlaceHolder=placeHolder[OtherPlayer];
int totalTilePoints =0;
// make 2 for self = 1 point **  block 2 of oppisite = 3 **  make 3 (win) = 5
totalTilePoints = totalTilePoints + calcTotalPointsSetOfThree(totalRow);
totalTilePoints = totalTilePoints + calcTotalPointsSetOfThree(totalCol);
// check center
if (row ==1 && col ==1)  {
totalTilePoints = totalTilePoints + 3 ;
// on diag
int diagTotalONE =  tiles[0][0] +tiles[1][1] + tiles[2][2];
totalTilePoints = totalTilePoints + calcTotalPointsSetOfThree(diagTotalONE);
// secdiag
int diagTotalTWO =  tiles[2][0] +tiles[1][1] + tiles[0][2];
totalTilePoints = totalTilePoints + calcTotalPointsSetOfThree(diagTotalTWO);

} // end if (row ==1 && col ==1)

// check diagonals
if (row !=1 && col !=1)  {
// totalTilePoints = totalTilePoints +1 ;
// to know in wich dirctio nto go
int rowDir =  row==0?1:-1;
int colDir =  col==0?1:-1;
int diagTotal =  tiles[row][col] +tiles[row+rowDir][col+colDir] + tiles[row+rowDir*2][col+colDir*2];
totalTilePoints = totalTilePoints + calcTotalPointsSetOfThree(diagTotal);
// add 1 more tests :
} // END if (row !=1 && col !=1)

// any of the outer center cubes
if ((row == 1  && col != 1) || (row != 1  && col == 1))   {
// if u got the center, pick this one
if(tiles[1][1] == CurrentPlayerPlaceHolder)  {
totalTilePoints = totalTilePoints + 2 ;  }

} // end if ((row == 1  && col != 1) || (row != 1  && col == 1))

// check if maxed  high point
if (highpoints<totalTilePoints)  {
highpoints =  totalTilePoints;
highpointsRow = row;
highpointsCol = col;
} // end if (highpoints<totalTilePoints)
} // end (tiles[j][k] =!=0)
} // end loop over col
} // end loop over row

// if found possible row
if (highpoints >0)  {
playMove(highpointsRow,highpointsCol);  }
// if not found match .. random choose one of the corners
else {
// first check fi (1,1) is avialble
int fodunfreespace =  0;
// lop over row
for(int j = 0; j < 3; j++) {
// loop over col
for (int k = 0; k < 3; k++) {
// set to zero = empty
if(tiles[j][k] == 0 && fodunfreespace==0) {
fodunfreespace = 1;
playMove(j,k);
break;
} // end if(tiles[j][k] == 0)
}  // end loop over col
} // end loop over row

// if not foudn any open space ... end game
if (fodunfreespace == 0) {
isGameOver = 1;
refreshDisplay = true;
} // end if (fodunfreespace == 0)
} // end if  (highpoints >0)
} // end void computNextMove
``````