Advertisement
Hanaigi

Untitled

May 20th, 2024
54
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.23 KB | None | 0 0
  1. #include <SFML/Graphics.hpp>
  2. #include <iostream>
  3.  
  4. const int ROWS = 3;
  5. const int COLS = 3;
  6. const int CELL_SIZE = 300;
  7. const int SCREEN_WIDTH = COLS * CELL_SIZE;
  8. const int SCREEN_HEIGHT = ROWS * CELL_SIZE;
  9.  
  10. enum class Player { None, Cross, Nought };
  11.  
  12. struct GameState {
  13.     Player board[ROWS][COLS];
  14.     Player currentPlayer;
  15.     bool gameOver;
  16.     Player winner;
  17. };
  18.  
  19. void initialize(GameState& state) {
  20.     state.currentPlayer = Player::Cross;
  21.     state.gameOver = false;
  22.     state.winner = Player::None;
  23.     for (int i = 0; i < ROWS; ++i) {
  24.         for (int j = 0; j < COLS; ++j) {
  25.             state.board[i][j] = Player::None;
  26.         }
  27.     }
  28. }
  29.  
  30. bool checkWinner(const GameState& state, Player player) {
  31.     for (int i = 0; i < ROWS; ++i) {
  32.         if (state.board[i][0] == player && state.board[i][1] == player && state.board[i][2] == player) {
  33.             return true;
  34.         }
  35.     }
  36.     for (int j = 0; j < COLS; ++j) {
  37.         if (state.board[0][j] == player && state.board[1][j] == player && state.board[2][j] == player) {
  38.             return true;
  39.         }
  40.     }
  41.     if (state.board[0][0] == player && state.board[1][1] == player && state.board[2][2] == player) {
  42.         return true;
  43.     }
  44.     if (state.board[0][2] == player && state.board[1][1] == player && state.board[2][0] == player) {
  45.         return true;
  46.     }
  47.     return false;
  48. }
  49.  
  50. bool isBoardFull(const GameState& state) {
  51.     for (int i = 0; i < ROWS; ++i) {
  52.         for (int j = 0; j < COLS; ++j) {
  53.             if (state.board[i][j] == Player::None) {
  54.                 return false;
  55.             }
  56.         }
  57.     }
  58.     return true;
  59. }
  60.  
  61. bool isMoveValid(const GameState& state, int row, int col) {
  62.     return row >= 0 && row < ROWS && col >= 0 && col < COLS && state.board[row][col] == Player::None;
  63. }
  64.  
  65. void computerMove(GameState& state) {
  66.  
  67.     for (int i = 0; i < ROWS; ++i) {
  68.         for (int j = 0; j < COLS; ++j) {
  69.             if (state.board[i][j] == Player::None) {
  70.                 state.board[i][j] = Player::Nought;
  71.                 if (checkWinner(state, Player::Nought)) {
  72.                     return;
  73.                 }
  74.                 state.board[i][j] = Player::None;
  75.             }
  76.         }
  77.     }
  78.  
  79.     for (int i = 0; i < ROWS; ++i) {
  80.         for (int j = 0; j < COLS; ++j) {
  81.             if (state.board[i][j] == Player::None) {
  82.                 state.board[i][j] = Player::Cross;
  83.                 if (checkWinner(state, Player::Cross)) {
  84.                     state.board[i][j] = Player::Nought;
  85.                     return;
  86.                 }
  87.                 state.board[i][j] = Player::None;
  88.             }
  89.         }
  90.     }
  91.  
  92.  
  93.     if (state.board[1][1] == Player::None) {
  94.         state.board[1][1] = Player::Nought;
  95.         return;
  96.     }
  97.     if (state.board[0][0] == Player::None) {
  98.         state.board[0][0] = Player::Nought;
  99.         return;
  100.     }
  101.     if (state.board[0][2] == Player::None) {
  102.         state.board[0][2] = Player::Nought;
  103.         return;
  104.     }
  105.     if (state.board[2][0] == Player::None) {
  106.         state.board[2][0] = Player::Nought;
  107.         return;
  108.     }
  109.     if (state.board[2][2] == Player::None) {
  110.         state.board[2][2] = Player::Nought;
  111.         return;
  112.     }
  113.  
  114.     int row, col;
  115.     do {
  116.         row = rand() % ROWS;
  117.         col = rand() % COLS;
  118.     } while (state.board[row][col] != Player::None);
  119.     state.board[row][col] = Player::Nought;
  120. }
  121.  
  122. void drawBoard(sf::RenderWindow& window, const GameState& state) {
  123.     window.clear(sf::Color::White);
  124.     for (int i = 0; i < ROWS; ++i) {
  125.         for (int j = 0; j < COLS; ++j) {
  126.             sf::RectangleShape cell(sf::Vector2f(CELL_SIZE, CELL_SIZE));
  127.             cell.setPosition(j * CELL_SIZE, i * CELL_SIZE);
  128.             cell.setFillColor(sf::Color::Transparent);
  129.             cell.setOutlineThickness(2);
  130.             cell.setOutlineColor(sf::Color::Black);
  131.             window.draw(cell);
  132.  
  133.             if (state.board[i][j] == Player::Cross) {
  134.                 sf::Texture crossTexture;
  135.                 crossTexture.loadFromFile("cross.png");
  136.                 sf::Sprite crossSprite(crossTexture);
  137.                 crossSprite.setPosition(j * CELL_SIZE, i * CELL_SIZE);
  138.                 window.draw(crossSprite);
  139.             }
  140.             else if (state.board[i][j] == Player::Nought) {
  141.                 sf::Texture noughtTexture;
  142.                 noughtTexture.loadFromFile("nought.png");
  143.                 sf::Sprite noughtSprite(noughtTexture);
  144.                 noughtSprite.setPosition(j * CELL_SIZE, i * CELL_SIZE);
  145.                 window.draw(noughtSprite);
  146.             }
  147.         }
  148.     }
  149.  
  150.     if (state.gameOver) {
  151.         sf::Font font;
  152.         font.loadFromFile("arial.ttf");
  153.         sf::Text winnerText;
  154.         winnerText.setFont(font);
  155.         if (state.winner == Player::Nought)
  156.             winnerText.setString("Winner: Algorithm");
  157.         else
  158.             winnerText.setString("Draw!");
  159.         winnerText.setCharacterSize(50);
  160.         winnerText.setFillColor(sf::Color::Red);
  161.         winnerText.setPosition(300, SCREEN_HEIGHT / 2 - 50);
  162.         window.draw(winnerText);
  163.  
  164.         sf::RectangleShape restartButton(sf::Vector2f(200, 50));
  165.         restartButton.setFillColor(sf::Color::Green);
  166.         restartButton.setPosition(SCREEN_WIDTH / 2 - 100, SCREEN_HEIGHT / 2 + 50);
  167.         window.draw(restartButton);
  168.  
  169.         sf::Text buttonText;
  170.         buttonText.setFont(font);
  171.         buttonText.setString("Restart");
  172.         buttonText.setCharacterSize(30);
  173.         buttonText.setFillColor(sf::Color::White);
  174.         buttonText.setPosition(SCREEN_WIDTH / 2 - 60, SCREEN_HEIGHT / 2 + 55);
  175.         window.draw(buttonText);
  176.     }
  177.  
  178.     window.display();
  179. }
  180.  
  181. void handleInput(GameState& state, sf::RenderWindow& window) {
  182.     if (state.gameOver) {
  183.         sf::Event event;
  184.         while (window.pollEvent(event)) {
  185.             if (event.type == sf::Event::Closed)
  186.                 window.close();
  187.             else if (event.type == sf::Event::MouseButtonPressed) {
  188.                 sf::Vector2i mousePos = sf::Mouse::getPosition(window);
  189.                 if (mousePos.x >= SCREEN_WIDTH / 2 - 100 && mousePos.x <= SCREEN_WIDTH / 2 + 100 &&
  190.                     mousePos.y >= SCREEN_HEIGHT / 2 + 50 && mousePos.y <= SCREEN_HEIGHT / 2 + 100) {
  191.                     initialize(state);
  192.                     return;
  193.                 }
  194.             }
  195.         }
  196.     }
  197.     else {
  198.         if (state.currentPlayer == Player::Cross) {
  199.             sf::Event event;
  200.             while (window.pollEvent(event)) {
  201.                 if (event.type == sf::Event::Closed)
  202.                     window.close();
  203.  
  204.                 if (!state.gameOver && event.type == sf::Event::MouseButtonPressed) {
  205.                     sf::Vector2i mousePos = sf::Mouse::getPosition(window);
  206.                     int row = mousePos.y / CELL_SIZE;
  207.                     int col = mousePos.x / CELL_SIZE;
  208.                     if (isMoveValid(state, row, col)) {
  209.                         state.board[row][col] = Player::Cross;
  210.                         if (checkWinner(state, Player::Cross)) {
  211.                             state.gameOver = true;
  212.                             state.winner = Player::Cross;
  213.                         }
  214.                         else if (isBoardFull(state)) {
  215.                             state.gameOver = true;
  216.                         }
  217.                         else {
  218.                             state.currentPlayer = Player::Nought;
  219.                         }
  220.                     }
  221.                 }
  222.             }
  223.         }
  224.         else {
  225.             computerMove(state);
  226.             if (checkWinner(state, Player::Nought)) {
  227.                 state.gameOver = true;
  228.                 state.winner = Player::Nought;
  229.             }
  230.             else if (isBoardFull(state)) {
  231.                 state.gameOver = true;
  232.             }
  233.             else {
  234.                 state.currentPlayer = Player::Cross;
  235.             }
  236.         }
  237.     }
  238. }
  239.  
  240. int main() {
  241.     sf::RenderWindow window(sf::VideoMode(SCREEN_WIDTH, SCREEN_HEIGHT), "Tic Tac Toe");
  242.  
  243.     srand(static_cast<unsigned>(time(nullptr)));
  244.  
  245.     GameState gameState;
  246.     initialize(gameState);
  247.  
  248.     while (window.isOpen()) {
  249.         handleInput(gameState, window);
  250.         drawBoard(window, gameState);
  251.     }
  252.  
  253.     return 0;
  254. }
  255.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement