//pin defines

#define TURN_OUTPUT  5

#define TURN_INPUT   6

#define SECRET_SAUCE 25        //seeds the random function, change this every time you play a game

//makes it easier to read the code if we enumerate MY_TURN and OPPONENT_TURN

#define MY_TURN           0            


//tokens for the playfield to tell who took a spot

#define MY_MOVE   1

#define OPP_MOVE  -1

//timeout error

#define ERROR_FLAG 0

char i;

char j;

char oppI;

char oppJ;

int turn;

int field[3][3];

int errorCatchI;

int errorCatchJ;

void setup()


  //initialize pins and modules  


  Serial.setTimeout(1000);                //sets how long Serial.readBytes will last before it triggers a timeout



  //clear field

  for(i=0; i< 3; i++)

        for(j = 0; j<3; field[i][j++] = 0);

  //decide who goes first



void loop()


  if(turn == MY_TURN && !digitalRead(TURN_INPUT))


        //find open space

        for(i = 0; i <= 2; i++)


          for(j= 0; field[i][j] != 0 && j < 2; j++);




        //check to make sure all open spaces aren't taken or that we haven't gone outside the playfield

        if(field[i][j] || i > 2 || j > 2)



          Serial.print("Game Over");

          while(1); //end game stop here on infinite loop


        //set move on field

        field[i][j] = MY_MOVE;

        //send move to opponent




        //set to the opponets turn

        turn = OPPONENT_TURN;

        digitalWrite(TURN_OUTPUT, turn);


  else if(turn == OPPONENT_TURN && digitalRead(TURN_INPUT))


        //get opponents move, I used readBytes() instead of read() because it handles timeouts without extra code

         errorCatchI = Serial.readBytes( &oppI, 1);

         errorCatchJ = Serial.readBytes( &oppJ, 1);


         //check to see that we didn't get a timeout error

         if(errorCatchI == ERROR_FLAG || errorCatchJ == ERROR_FLAG)



           Serial.print("I wiated for one whole second and you didn't send me anything!");

           while(1); //stop here on error



         //check to make sure the space is open and they havent gone outside the playfield

        if(field[oppI][oppJ] || oppI > 2 || oppJ > 2)



          Serial.println("Spot is outside the playfield or already taken!");

          Serial.println("The game may have ended.");



          while(1); //end game, infinite loop



        //set their move on the field

        field[oppI][oppJ] = OPP_MOVE;


        //set to my turn

        turn = MY_TURN;

        digitalWrite(TURN_OUTPUT, turn);




        //you get here if you have changed your turn pin but your opponent hasn't

        //or vise-versa



void establishContact(void)


  int myScore,


  //generate a random number to see who goes first    


  myScore = random(0,255);

  //send my random number every 100ms until I recieve some data over the UART

  while (Serial.available() <= 0) {

        Serial.print(myScore);        //send my Score



  oppScore = Serial.read();

  //decide if it's my turn

  if(myScore > oppScore)

        turn = MY_TURN;


        turn = OPPONENT_TURN;

  digitalWrite(TURN_OUTPUT, turn);