KÓŁKO i KRZYŻYK

Typ_projektu
Arduino
Zdjecie główne
Krótki opis projektu

Gra na arduino kółko i krzyżyk.

Niezbędne elementy

1. Płytka Arduino UNO

2. wyświetlacz lcd 128x64

3. płytka PCB

4. kabel usb do arduino

Opis projektu

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.

Zdjęcia
kod programu
#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
    }
}
Youtube
Tagi
kółko i krzyżyk arduino płytka pcb