Gra na arduino kółko i krzyżyk.
1. Płytka Arduino UNO
2. wyświetlacz lcd 128x64
3. płytka PCB
4. kabel usb do arduino
Gra kółko i krzyżyk to jedna z najprostszych gier w której występuje rywalizacja. W naszym projekcie wykorzystaliśmy 2 tryby singleplayer oraz multiplayer. W trybie singleplayer gramy przeciwko algorytmowi , który działa na zasadzie losowania początkowego położenia, następnie algorytm analizuje każdy koljeny nasz ruch i stawia swoje pole. Niemal niemożliwe jest wygrać z algorytmem jeśli się nie zaczyna. Drugi tryb to rozgrywka między dwoma przweciwnikami, możemy grać też ze sobą po każdym ruchu zmienia się gracz. W projekcie wykorzystujemy mikrokontroler Arduino wyświetlacz lcd 128x64, oraz autorską płytkę PCB. Kod wykorzystywany w projekcie został współtworzony przez Sztuczną inteligencje.
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define BUTTON_MOVE 5
#define BUTTON_OK 4
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET 7 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(128, 64, &Wire, OLED_RESET);
int gameStatus = 0;
int currentPlayer = 0; // 0 = Player 1, 1 = Player 2
int winner = -1; // -1 = Playing, 0 = Draw, 1 = Player 1, 2 = Player 2
int board[] = {0, 0, 0,
0, 0, 0,
0, 0, 0}; // 0 = blank, 1 = Player 1 (circle), 2 = Player 2 (cross)
//--------------------------------------------------------------------------------------------------------
void playMove() {
int playerMove = 0;
bool stayInLoop = true;
bool showDot = false;
long timerPos = millis() - 1000;
while (stayInLoop) {
while (board[playerMove] != 0) {
playerMove++;
if (playerMove > 8) playerMove = 0;
}
// Flashing "?" at the current position
if (timerPos + 200 < millis()) {
timerPos = millis();
showDot = !showDot;
playMove_showPos(playerMove, showDot); // Update display
}
if (digitalRead(BUTTON_MOVE) == LOW) {
playMove_showPos(playerMove, false); // Hide "?" at the current position
do {
playerMove = (playerMove + 1) % 9; // Move to the next position and loop back if necessary
} while (board[playerMove] != 0); // Skip over already filled positions
showDot = true; // Ensure "?" will be shown at the new position
timerPos = millis(); // Reset timer to flash "?" immediately at the new position
}
if (digitalRead(BUTTON_OK) == LOW) stayInLoop = false;
delay(100);
}
playMove_showPos(playerMove, false); // Hide "?" before updating the board
board[playerMove] = currentPlayer + 1; // Assign the chosen cell to the current player.
}
//--------------------------------------------------------------------------------------------------------
void playMove_showPos(int playerMove, bool showDot) {
display.setTextSize(2);
// Set cursor position based on playerMove
int x = (playerMove % 3) * 20 + 5;
int y = (playerMove / 3) * 20 + 5;
display.setCursor(x, y);
if (showDot) display.setTextColor(WHITE); else display.setTextColor(BLACK);
display.print("?");
display.display();
}
//--------------------------------------------------------------------------------------------------------
void checkWinner() {
// Check horizontal, vertical, and diagonal lines for a win
for (int i = 0; i < 3; i++) {
if (board[i * 3] != 0 && board[i * 3] == board[i * 3 + 1] && board[i * 3 + 1] == board[i * 3 + 2]) {
winner = board[i * 3];
}
if (board[i] != 0 && board[i] == board[i + 3] && board[i + 3] == board[i + 6]) {
winner = board[i];
}
}
if ((board[0] != 0 && board[0] == board[4] && board[4] == board[8]) ||
(board[2] != 0 && board[2] == board[4] && board[4] == board[6])) {
winner = board[4];
}
if (winner == -1) {
bool isDraw = true;
for (int i = 0; i < 9; i++) {
if (board[i] == 0) {
isDraw = false;
break;
}
}
if (isDraw) winner = 0;
}
}
//--------------------------------------------------------------------------------------------------------
void resetGame() {
for (int i = 0; i < 9; i++) board[i] = 0;
winner = -1;
gameStatus = 0;
currentPlayer = 0; // Start with Player 1
}
//--------------------------------------------------------------------------------------------------------
void boardDrawing() {
display.clearDisplay();
display.setTextColor(WHITE);
// Draw grid lines
display.drawFastHLine(0, 21, 64, WHITE);
display.drawFastHLine(0, 42, 64, WHITE);
display.drawFastVLine(21, 0, 64, WHITE);
display.drawFastVLine(42, 0, 64, WHITE);
// Draw cell contents
display.setTextSize(2);
for (int i = 0; i < 9; i++) {
int x = (i % 3) * 20 + 5;
int y = (i / 3) * 20 + 5;
display.setCursor(x, y);
if (board[i] == 1) display.print("o");
else if (board[i] == 2) display.print("x");
else display.print(" ");
}
display.display();
delay(200);
}
//--------------------------------------------------------------------------------------------------------
void setup() {
pinMode(BUTTON_MOVE, INPUT_PULLUP);
pinMode(BUTTON_OK, INPUT_PULLUP);
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
delay(500);
display.clearDisplay();
display.setTextColor(WHITE);
display.display();
}
//--------------------------------------------------------------------------------------------------------
void loop() {
if (gameStatus == 0) {
resetGame();
boardDrawing();
gameStatus = 1;
}
if (gameStatus == 1) {
while (winner == -1) {
playMove();
boardDrawing();
checkWinner();
currentPlayer = (currentPlayer + 1) % 2; // Switch players
}
// Show winner or draw message
display.setTextSize(2);
display.setCursor(68, 25);
if (winner == 0) {
display.print("Draw");
} else {
display.clearDisplay();
display.setCursor(20, 32);
display.print("P");
display.print(winner);
display.print(" Wins");
}
display.display();
delay(2000);
// Wait for both buttons to be released
while (digitalRead(BUTTON_MOVE) == LOW || digitalRead(BUTTON_OK) == LOW);
gameStatus = 0; // Reset for a new game
}
}