Paso 4: El código
El código completo está por debajo. Sin embargo, preste especial atención a las constantes declaradas en la parte superior del código. Para la versión de Arduino Mega, consulte las definiciones de pines de los LEDs rojo y verdes, la victoria de la roja y verde LEDs, los botones, el botón reset. La mayoría de ellos ha sido definida como matrices de 3D y he presentado el código como se muestra en las fotos se corresponden con los botones y LEDs. El botón superior izquierdo de la foto corresponde al primer elemento de la matriz. Luego trabajamos en a la derecha, hacia abajo de una fila a otra vez, una fila y a través otra vez. Recuerde, el diagrama de Fritzing se gira 90° hacia la derecha respecto a las fotos - pero yo he observado la "numeración" de los LEDs y botones en el diagrama.
Para la versión Arduino Uno, compruebe los pernos de Charlieplex en la parte superior del código, el pin analógico ("botón") y el botón de reset pin. No deberías tener ningún problema con la numeración de los LED y se puede dejar como-es. Si por alguna extraña razón, la matriz de botón no funciona, usted necesitará hacer su propia solución de problemas para comprobar los valores de voltaje que están entrando en el pin analógico en cada pulsación de botón y ajustan en consecuencia la matriz "resButtons".
No se olvide, para la versión Arduino Uno, usted necesita la biblioteca de Charlieplex adjunta como un archivo bajo el código. Descomprimirlo y colocarlo en la carpeta de bibliotecas de su IDE de Arduino (puede buscar en la web si no sabes cómo).
Los bits de inteligencia no es más que el Arduino comprobación de cada columna, fila y diagonales para ver si ya hay dos LEDs de color rojo encendidos y un espacio libre para colocar una pieza. Esto significa gana el Arduino y esto tiene prioridad. Si el Arduino no puede encontrar una línea, entonces hará lo mismo otra vez pero esta vez en busca de dos LED verdes y un espacio de repuesto. Esto significa que los humanos podrían ganar y Arduino por tanto colocará una pieza para bloquear al ser humano. Finalmente, si no se puede ganar o bloque, elegirá un lugar al azar al elegir uno de los espacios libres en el tablero.
Yo he comentado el código tanto como sea posible para ayudarle a entender lo que está sucediendo. Sé que el código podría ser mucho más eficiente. Creo que no está mal para un primer intento sin embargo. ¡Buena suerte!
Para el Arduino Mega: (Versión Arduino Uno está por debajo)
// TIC TAC TOE for Arduino Mega // by Nick Harvey // Include any libraries needed #include <liquidcrystal.h> // For the LCD // Define pins const int green[3][3] = { // Green is the player {30, 31, 32}, {33, 34, 35}, {36, 37, 38} }; const int red[3][3] = { // Red is the Arduino {40, 41, 42}, {43, 44, 45}, {46, 47, 48} }; const int button[3][3] = { // Buttons to choose position {2, 3, 4}, {5, 6, 7}, {8, 9, 10} }; const int greenWin = 50; // Lights if the player wins const int redWin = 51; // Lights if the Arduino wins const int resetButton = 11; // Button to start a new game const int win[8][3][3] = { // This 4D array defines all possible winning combinations { {1, 1, 1}, {0, 0, 0}, {0, 0, 0} }, { {0, 0, 0}, {1, 1, 1}, {0, 0, 0} }, { {0, 0, 0}, {0, 0, 0}, {1, 1, 1} }, { {1, 0, 0}, {1, 0, 0}, {1, 0, 0} }, { {0, 1, 0}, {0, 1, 0}, {0, 1, 0} }, { {0, 0, 1}, {0, 0, 1}, {0, 0, 1} }, { {1, 0, 0}, {0, 1, 0}, {0, 0, 1} }, { {0, 0, 1}, {0, 1, 0}, {1, 0, 0} } }; LiquidCrystal lcd(A4, A5, A3, A2, A1, A0); // Pins used for the LCD display (standard Arduino LCD library) // Global variables int gamePlay[3][3] = { // Holds the current game {0, 0, 0}, {0, 0, 0}, {0, 0, 0} }; int squaresLeft = 9; // The number of free squares left on the board int played = 0; // Has the Arduino played or not // Global constants const int startupFlashSpeed = 100; // The time in milliseconds the LEDs light for on startup const int arduinoDelay = 3000; // How long the Arduino waits before playing (simulates thought) void setup() { // put your setup code here, to run once: // Start serial comms Serial.begin(9600); // Initialise LCD lcd.begin(16, 2); // Define green and red pins as outputs for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { pinMode(green[i][j], OUTPUT); pinMode(red[i][j], OUTPUT); } } // Define green and red win lights as outputs pinMode(greenWin, OUTPUT); pinMode(redWin, OUTPUT); // Define buttons as inputs for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { pinMode(button[i][j], INPUT); } } //Define reset button as input pinMode(resetButton, INPUT); initialise(); // Do startup flash startupFlash(); } void initialise() { // Prepare the board for a game disp("TIC TAC TOE"); // Set green and red LEDs off for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { digitalWrite(green[i][j], LOW); digitalWrite(red[i][j], LOW); gamePlay[i][j] = 0; } } // Set win LEDs off digitalWrite(greenWin, LOW); digitalWrite(redWin, LOW); // Reset variables squaresLeft = 9; // Tell the player it's their turn disp("Your turn..."); } void loop() { // put your main code here, to run repeatedly: // Wait for an input and call the buttonPress routine if pressed for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { if ((digitalRead(button[i][j]) == HIGH) && (gamePlay[i][j] == 0)) { buttonPress(i, j); // Pass the x and y of the button pressed break; } } } } void buttonPress(int i, int j) { // Button pressed, light the green LED and note the square as taken Serial.print("Button press "); Serial.print(i); Serial.println(j); digitalWrite(green[i][j], HIGH); gamePlay[i][j] = 1; // Note the square played squaresLeft -= 1; // Update number of squares left printGame(); // Print the game to serial monitor checkGame(); // Check for a winner arduinosTurn(); // Arduino's turn } void arduinosTurn() { // Arduino takes a turn Serial.println("Arduino's turn"); disp("My turn..."); checkPossiblities(); // Check to see if a winning move can be played if (played == 0) { checkBlockers(); // If no winning move played, check to see if we can block a win } if (played == 0) { randomPlay(); // Otherwise, pick a random square } squaresLeft -= 1; // Update number of squares left played = 0; // Reset if played or not printGame(); // Print the games to serial monitor checkGame(); // Check for a winner disp("Your turn..."); // Tell the player it's their turn } void checkPossiblities() { // Check all rows, then columns, then diagonals to see if there are two reds lit and a free square to make a line of three Serial.println("Checking possibilities to win..."); disp("Can I win?"); int poss = 0; // Used to count if possible - if it gets to 2 then its a possiblity int x = 0; // The X position to play int y = 0; // The Y position to play int space = 0; // Is there a free square or not to play // Check rows for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { if (gamePlay[i][j] == 2) { poss += 1; // Square is red. Increment the possiblity counter } if (gamePlay[i][j] == 0) { space = 1; // Square is empty. Note this and the position x = i; y = j; } if ((poss == 2) && (space == 1)) { // 2 red squares and a free square Serial.print("Found an obvious row! "); Serial.print(x); Serial.println(y); playPoss(x, y); } } poss = 0; x = 0; y = 0; space = 0; } // Check columns - same as for rows but the "for" loops have been reversed to go to columns for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { if (gamePlay[j][i] == 2) { poss += 1; } if (gamePlay[j][i] == 0) { space = 1; x = j; y = i; } if ((poss == 2) && (space == 1) && (played == 0)) { // This time also check if we've already played Serial.print("Found an obvious column! "); Serial.print(x); Serial.println(y); playPoss(x, y); } } // Reset variables poss = 0; x = 0; y = 0; space = 0; } // Check crosses - as for rows and columns but "for" loops changed // Check diagonal top left to bottom right for (int i = 0; i < 3; i++) { if (gamePlay[i][i] == 2) { poss += 1; } if (gamePlay[i][i] == 0) { space = 1; x = i; y = i; } if ((poss == 2) && (space == 1) && (played == 0)) { Serial.print("Found an obvious cross! "); Serial.print(x); Serial.println(y); playPoss(x, y); } } // Reset variables poss = 0; x = 0; y = 0; space = 0; // Check diagonal top right to bottom left int row = 0; // Used to count up the rows for (int i = 2; i >= 0; i--) { // We count DOWN the columns if (gamePlay[row][i] == 2) { poss += 1; } if (gamePlay[row][i] == 0) { space = 1; x = row; y = i; } if ((poss == 2) && (space == 1) && (played == 0)) { Serial.print("Found an obvious cross! "); Serial.print(x); Serial.println(y); playPoss(x, y); } row += 1; // Increment the row counter } // Reset variables poss = 0; x = 0; y = 0; space = 0; } void checkBlockers() { // As for checkPossibilites() but this time checking the players squares for places to block a line of three Serial.println("Checking possibilities to block..."); disp("Can I block?"); int poss = 0; int x = 0; int y = 0; int space = 0; // Check rows for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { if (gamePlay[i][j] == 1) { poss += 1; } if (gamePlay[i][j] == 0) { space = 1; x = i; y = j; } if ((poss == 2) && (space == 1) && (played == 0)) { Serial.print("Found an blocker row! "); Serial.print(x); Serial.println(y); playPoss(x, y); } } poss = 0; x = 0; y = 0; space = 0; } // Check columns for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { if (gamePlay[j][i] == 1) { poss += 1; } if (gamePlay[j][i] == 0) { space = 1; x = j; y = i; } if ((poss == 2) && (space == 1) && (played == 0)) { Serial.print("Found an blocker column! "); Serial.print(x); Serial.println(y); playPoss(x, y); } } poss = 0; x = 0; y = 0; space = 0; } // Check crosses for (int i = 0; i < 3; i++) { if (gamePlay[i][i] == 1) { poss += 1; } if (gamePlay[i][i] == 0) { space = 1; x = i; y = i; } if ((poss == 2) && (space == 1) && (played == 0)) { Serial.print("Found an blocker cross! "); Serial.print(x); Serial.println(y); playPoss(x, y); } } poss = 0; x = 0; y = 0; space = 0; int row = 0; for (int i = 2; i >= 0; i--) { if (gamePlay[row][i] == 1) { poss += 1; } if (gamePlay[row][i] == 0) { space = 1; x = row; y = i; } if ((poss == 2) && (space == 1) && (played == 0)) { Serial.print("Found an blocker cross! "); Serial.print(x); Serial.println(y); playPoss(x, y); } row += 1; } poss = 0; x = 0; y = 0; space = 0; } void randomPlay() { // No win or block to play... Let's just pick a square at random Serial.println("Choosing randomly..."); int choice = random(1, squaresLeft); // We pick a number from 0 to the number of squares left on the board Serial.print("Arduino chooses "); Serial.println(choice); int pos = 1; // Stores the free square we're currently on for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { if (gamePlay[i][j] == 0) { // Check to see if square empty if (pos == choice) { // Play the empty square that corresponds to the random number playPoss(i, j); } pos += 1; // Increment the free square counter } } } } void playPoss(int x, int y) { // Simulate thought and then play the chosen square disp("Hmmm..."); delay(arduinoDelay); disp("OK"); digitalWrite(red[x][y], HIGH); gamePlay[x][y] = 2; // Update the game play array played = 1; // Note that we've played } void checkGame() { // Check the game for a winner // Check if the player has won Serial.println("Checking for a winner"); disp("Checking..."); int player = 1; int winner = 0; for (int i = 0; i < 8; i++) { // We cycle through all winning combinations in the 4D array and check if they correspond to the current game //Check game int winCheck = 0; for (int j = 0; j < 3; j++) { for (int k = 0; k < 3; k++) { if ((win[i][j][k] == 1) && (gamePlay[j][k] == player)) { winCheck += 1; } } } if (winCheck == 3) { winner = 1; Serial.print("Player won game "); Serial.println(i); endGame(1); } } // Do the same for to check if the Arduino has won player = 2; winner = 0; for (int i = 0; i < 8; i++) { //Check game int winCheck = 0; for (int j = 0; j < 3; j++) { for (int k = 0; k < 3; k++) { if ((win[i][j][k] == 1) && (gamePlay[j][k] == player)) { winCheck += 1; } } } if (winCheck == 3) { winner = 1; Serial.print("Arduino won game "); Serial.println(i); endGame(2); } } if (squaresLeft == -1) { endGame(0); } } void printGame() { // Prints the game to the serial monitor for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { Serial.print(gamePlay[i][j]); Serial.print(" "); } Serial.println(""); } Serial.print(squaresLeft); Serial.println(" squares left"); } void endGame(int winner) { // Is called when a winner is found switch (winner) { case 0: Serial.println("It's a draw"); digitalWrite(greenWin, HIGH); digitalWrite(redWin, HIGH); disp("It's a draw!"); break; case 1: Serial.println("Player wins"); digitalWrite(greenWin, HIGH); disp("You win!!!"); break; case 2: Serial.println("Arduino wins"); digitalWrite(redWin, HIGH); disp("I win!!!"); break; } lcd.setCursor(0, 1); lcd.print("Press reset..."); while (digitalRead(resetButton) == LOW) { } initialise(); } void disp(String message) { // Used to quickly display a message on the LCD lcd.clear(); lcd.setCursor(0, 0); lcd.print(message); } void startupFlash() { // Flash at the start for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { digitalWrite(green[i][j], HIGH); digitalWrite(greenWin, HIGH); delay(startupFlashSpeed); digitalWrite(green[i][j], LOW); digitalWrite(greenWin, LOW); digitalWrite(red[i][j], HIGH); digitalWrite(redWin, HIGH); delay(startupFlashSpeed); digitalWrite(red[i][j], LOW); digitalWrite(redWin, LOW); } } for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { digitalWrite(green[j][i], HIGH); delay(startupFlashSpeed); digitalWrite(green[j][i], LOW); } } for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { digitalWrite(red[i][j], HIGH); delay(startupFlashSpeed); digitalWrite(red[i][j], LOW); } } for (int i = 0; i < 3; i++) { digitalWrite(red[i][i], HIGH); delay(startupFlashSpeed); digitalWrite(red[i][i], LOW); } int row = 0; for (int i = 2; i >= 0; i--) { digitalWrite(green[row][i], HIGH); delay(startupFlashSpeed); digitalWrite(green[row][i], LOW); row += 1; } }
Para el Arduino Uno:
<p>// TIC TAC TOE for Arduino Uno<br>// by Nick Harvey</p><p>#include <charlieplex.h> byte pins[5] = {5, 6, 9, 10, 11}; Charlieplex charlie(pins, sizeof(pins));</charlieplex.h></p><p>// Define LEDs const int green[3][3] = { // Green is the player {0, 8, 14}, {2, 10, 16}, {4, 12, 6} }; const int red[3][3] = { // Red is the Arduino {1, 9, 15}, {3, 11, 17}, {5, 13, 7} }; const int button = A0; // The analog pin the button matrix is connected to</p><p>const int resButtons[3][3] = { // The resistance thresholds for the buttons {800, 400, 200}, {160, 140, 120}, {90, 85, 70} };</p><p>const int greenWin = 18; // Lights if the player wins const int redWin = 19; // Lights if the Arduino wins const int resetButton = 13; // Button to start a new game</p><p>const int win[8][3][3] = { // This 4D array defines all possible winning combinations { {1, 1, 1}, {0, 0, 0}, {0, 0, 0} }, { {0, 0, 0}, {1, 1, 1}, {0, 0, 0} }, { {0, 0, 0}, {0, 0, 0}, {1, 1, 1} }, { {1, 0, 0}, {1, 0, 0}, {1, 0, 0} }, { {0, 1, 0}, {0, 1, 0}, {0, 1, 0} }, { {0, 0, 1}, {0, 0, 1}, {0, 0, 1} }, { {1, 0, 0}, {0, 1, 0}, {0, 0, 1} }, { {0, 0, 1}, {0, 1, 0}, {1, 0, 0} } };</p><p>// Global variables int gamePlay[3][3] = { // Holds the current game {0, 0, 0}, {0, 0, 0}, {0, 0, 0} }; int squaresLeft = 9; // The number of free squares left on the board int played = 0; // Has the Arduino played or not</p><p>// Global constants const int arduinoDelay = 3000; // How long the Arduino waits before playing (simulates thought)</p><p>void setup() { // put your setup code here, to run once:</p><p> // Start serial comms Serial.begin(9600);</p><p> // Define buttons as inputs pinMode(button, INPUT);</p><p> //Define reset button as input pinMode(resetButton, INPUT);</p><p> initialise(); }</p><p>void initialise() { // Prepare the board for a game Serial.println("Initialising..."); // Set green and red LEDs off for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { charlie.setLed(green[i][j], false); charlie.setLed(red[i][j], false); gamePlay[i][j] = 0; } } // Set win LEDs off charlie.setLed(greenWin, false); charlie.setLed(redWin, false);</p><p> // Reset variables squaresLeft = 9; } void loop() { // put your main code here, to run repeatedly: // Wait for an input and call the buttonPress routine if pressed int upper = 10000; if (analogRead(button) != 0) { int x; int y; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { if (gamePlay[i][j] == 0) { if ((analogRead(button) > resButtons[i][j]) && (analogRead(button) < upper)) { buttonPress(i, j); } } upper = resButtons[i][j]; } } } charlie.loop(); }</p><p>void buttonPress(int i, int j) { // Button pressed, light the green LED and note the square as taken Serial.print("Button press "); Serial.print(i); Serial.print(":"); Serial.println(j); charlie.setLed(green[i][j], true); gamePlay[i][j] = 1; // Note the square played squaresLeft -= 1; // Update number of squares left printGame(); // Print the game to serial monitor checkGame(); // Check for a winner arduinosTurn(); // Arduino's turn }</p><p>void arduinosTurn() { // Arduino takes a turn Serial.println("Arduino's turn"); checkPossiblities(); // Check to see if a winning move can be played if (played == 0) { checkBlockers(); // If no winning move played, check to see if we can block a win } if (played == 0) { randomPlay(); // Otherwise, pick a random square } squaresLeft -= 1; // Update number of squares left played = 0; // Reset if played or not printGame(); // Print the games to serial monitor checkGame(); // Check for a winner }</p><p>void checkPossiblities() { // Check all rows, then columns, then diagonals to see if there are two reds lit and a free square to make a line of three Serial.println("Checking possibilities to win..."); int poss = 0; // Used to count if possible - if it gets to 2 then its a possiblity int x = 0; // The X position to play int y = 0; // The Y position to play int space = 0; // Is there a free square or not to play // Check rows for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { if (gamePlay[i][j] == 2) { poss += 1; // Square is red. Increment the possiblity counter } if (gamePlay[i][j] == 0) { space = 1; // Square is empty. Note this and the position x = i; y = j; } if ((poss == 2) && (space == 1)) { // 2 red squares and a free square Serial.print("Found an obvious row! "); Serial.print(x); Serial.println(y); playPoss(x, y); } } poss = 0; x = 0; y = 0; space = 0; }</p><p> // Check columns - same as for rows but the "for" loops have been reversed to go to columns for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { if (gamePlay[j][i] == 2) { poss += 1; } if (gamePlay[j][i] == 0) { space = 1; x = j; y = i; } if ((poss == 2) && (space == 1) && (played == 0)) { // This time also check if we've already played Serial.print("Found an obvious column! "); Serial.print(x); Serial.println(y); playPoss(x, y); } } // Reset variables poss = 0; x = 0; y = 0; space = 0; }</p><p> // Check crosses - as for rows and columns but "for" loops changed // Check diagonal top left to bottom right for (int i = 0; i < 3; i++) { if (gamePlay[i][i] == 2) { poss += 1; } if (gamePlay[i][i] == 0) { space = 1; x = i; y = i; } if ((poss == 2) && (space == 1) && (played == 0)) { Serial.print("Found an obvious cross! "); Serial.print(x); Serial.println(y); playPoss(x, y); } } // Reset variables poss = 0; x = 0; y = 0; space = 0; // Check diagonal top right to bottom left int row = 0; // Used to count up the rows for (int i = 2; i >= 0; i--) { // We count DOWN the columns if (gamePlay[row][i] == 2) { poss += 1; } if (gamePlay[row][i] == 0) { space = 1; x = row; y = i; } if ((poss == 2) && (space == 1) && (played == 0)) { Serial.print("Found an obvious cross! "); Serial.print(x); Serial.println(y); playPoss(x, y); } row += 1; // Increment the row counter } // Reset variables poss = 0; x = 0; y = 0; space = 0; }</p><p>void checkBlockers() { // As for checkPossibilites() but this time checking the players squares for places to block a line of three Serial.println("Checking possibilities to block..."); int poss = 0; int x = 0; int y = 0; int space = 0; // Check rows for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { if (gamePlay[i][j] == 1) { poss += 1; } if (gamePlay[i][j] == 0) { space = 1; x = i; y = j; } if ((poss == 2) && (space == 1) && (played == 0)) { Serial.print("Found an blocker row! "); Serial.print(x); Serial.println(y); playPoss(x, y); } } poss = 0; x = 0; y = 0; space = 0; }</p><p> // Check columns for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { if (gamePlay[j][i] == 1) { poss += 1; } if (gamePlay[j][i] == 0) { space = 1; x = j; y = i; } if ((poss == 2) && (space == 1) && (played == 0)) { Serial.print("Found an blocker column! "); Serial.print(x); Serial.println(y); playPoss(x, y); } } poss = 0; x = 0; y = 0; space = 0; }</p><p> // Check crosses for (int i = 0; i < 3; i++) { if (gamePlay[i][i] == 1) { poss += 1; } if (gamePlay[i][i] == 0) { space = 1; x = i; y = i; } if ((poss == 2) && (space == 1) && (played == 0)) { Serial.print("Found an blocker cross! "); Serial.print(x); Serial.println(y); playPoss(x, y); } } poss = 0; x = 0; y = 0; space = 0; int row = 0; for (int i = 2; i >= 0; i--) { if (gamePlay[row][i] == 1) { poss += 1; } if (gamePlay[row][i] == 0) { space = 1; x = row; y = i; } if ((poss == 2) && (space == 1) && (played == 0)) { Serial.print("Found an blocker cross! "); Serial.print(x); Serial.println(y); playPoss(x, y); } row += 1; } poss = 0; x = 0; y = 0; space = 0; }</p><p>void randomPlay() { // No win or block to play... Let's just pick a square at random Serial.println("Choosing randomly..."); int choice = random(1, squaresLeft); // We pick a number from 0 to the number of squares left on the board Serial.print("Arduino chooses "); Serial.println(choice); int pos = 1; // Stores the free square we're currently on for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { if (gamePlay[i][j] == 0) { // Check to see if square empty if (pos == choice) { // Play the empty square that corresponds to the random number playPoss(i, j); } pos += 1; // Increment the free square counter } } } }</p><p>void playPoss(int x, int y) { // Simulate thought and then play the chosen square int delayStop = millis() + arduinoDelay; while (millis() < delayStop) { charlie.loop(); } charlie.setLed(red[x][y], true); gamePlay[x][y] = 2; // Update the game play array played = 1; // Note that we've played }</p><p>void checkGame() { // Check the game for a winner // Check if the player has won Serial.println("Checking for a winner"); int player = 1; int winner = 0; for (int i = 0; i < 8; i++) { // We cycle through all winning combinations in the 4D array and check if they correspond to the current game //Check game int winCheck = 0; for (int j = 0; j < 3; j++) { for (int k = 0; k < 3; k++) { if ((win[i][j][k] == 1) && (gamePlay[j][k] == player)) { winCheck += 1; } } } if (winCheck == 3) { winner = 1; Serial.print("Player won game "); Serial.println(i); endGame(1); } } // Do the same for to check if the Arduino has won player = 2; winner = 0; for (int i = 0; i < 8; i++) { //Check game int winCheck = 0; for (int j = 0; j < 3; j++) { for (int k = 0; k < 3; k++) { if ((win[i][j][k] == 1) && (gamePlay[j][k] == player)) { winCheck += 1; } } } if (winCheck == 3) { winner = 1; Serial.print("Arduino won game "); Serial.println(i); endGame(2); } } if (squaresLeft == -1) { endGame(0); } }</p><p>void printGame() { // Prints the game to the serial monitor for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { Serial.print(gamePlay[i][j]); Serial.print(" "); } Serial.println(""); } Serial.print(squaresLeft); Serial.println(" squares left"); }</p><p>void endGame(int winner) { // Is called when a winner is found switch (winner) { case 0: Serial.println("It's a draw"); charlie.setLed(greenWin, true); charlie.setLed(redWin, true); break; case 1: Serial.println("Player wins"); charlie.setLed(greenWin, true); break; case 2: Serial.println("Arduino wins"); charlie.setLed(redWin, true); break; } while (digitalRead(resetButton) == LOW) { charlie.loop(); } initialise(); }</p>