#include <SFML/Graphics.hpp>
#include <iostream>
#include <vector>

enum class Cell { Empty, X, O };

class TicTacToe {
public:
    TicTacToe() : window(sf::VideoMode(600, 600), "Tic Tac Toe"), board(9, Cell::Empty), currentPlayer(Cell::X) {}

    void run() {
        while (window.isOpen()) {
            handleInput();
            update();
            render();
        }
    }

private:
    void handleInput() {
        sf::Event event;
        while (window.pollEvent(event)) {
            if (event.type == sf::Event::Closed) {
                window.close();
            }
            if (event.type == sf::Event::MouseButtonPressed && event.mouseButton.button == sf::Mouse::Left) {
                int cellX = event.mouseButton.x / (600 / 3);
                int cellY = event.mouseButton.y / (600 / 3);
                int cellIndex = cellY * 3 + cellX;

                if (cellIndex >= 0 && cellIndex < 9 && board[cellIndex] == Cell::Empty) {
                    board[cellIndex] = currentPlayer;
                    if (checkWin(currentPlayer)) {
                        std::cout << (currentPlayer == Cell::X ? "X wins!" : "O wins!") << std::endl;
                        resetGame();
                    } else if (checkDraw()) {
                        std::cout << "Draw!" << std::endl;
                        resetGame();
                    } else {
                        currentPlayer = (currentPlayer == Cell::X) ? Cell::O : Cell::X;
                    }
                }
            }
        }
    }

    void update() {}

    void render() {
        window.clear(sf::Color::White);
        drawBoard();
        drawMarks();
        window.display();
    }

    void drawBoard() {
        for (int i = 1; i < 3; ++i) {
            sf::Vertex lineV[] = {
                sf::Vertex(sf::Vector2f(0, i * 600 / 3), sf::Color::Black),
                sf Frontier(sf::Vector2f(600, i * 600 / 3), sf::Color::Black)
            };
             sf::Vertex lineH[] = {
                sf::Vertex(sf::Vector2f(i * 600 / 3, 0), sf::Color::Black),
                sf::Vertex(sf::Vector2f(i * 600 / 3, 600), sf::Color::Black)
            };
            window.draw(lineV, 2, sf::Lines);
            window.draw(lineH, 2, sf::Lines);
        }
    }

    void drawMarks() {
        for (int i = 0; i < 9; ++i) {
            int cellX = (i % 3) * 600 / 3;
            int cellY = (i / 3) * 600 / 3;

            if (board[i] == Cell::X) {
                sf::Font font;
                if (!font.loadFromFile("arial.ttf")) {
                    return;
                }
                sf::Text text("X", font, 80);
                text.setFillColor(sf::Color::Black);
                text.setPosition(cellX + 600 / 6 - text.getLocalBounds().width / 2, cellY + 600 / 6 - text.getLocalBounds().height / 2);
                window.draw(text);
            } else if (board[i] == Cell::O) {
                sf::Font font;
                if (!font.loadFromFile("arial.ttf")) {
                    return;
                }
                sf::Text text("O", font, 80);
                 text.setFillColor(sf::Color::Black);
                text.setPosition(cellX + 600 / 6 - text.getLocalBounds().width / 2, cellY + 600 / 6 - text.getLocalBounds().height / 2);
                window.draw(text);
            }
        }
    }

    bool checkWin(Cell player) {
        // Check rows
        for (int i = 0; i < 3; ++i) {
            if (board[i * 3] == player && board[i * 3 + 1] == player && board[i * 3 + 2] == player) {
                return true;
            }
        }
        // Check columns
        for (int i = 0; i < 3; ++i) {
            if (board[i] == player && board[i + 3] == player && board[i + 6] == player) {
                return true;
            }
        }
        // Check diagonals
        if (board[0] == player && board[4] == player && board[8] == player) {
            return true;
        }
        if (board[2] == player && board[4] == player && board[6] == player) {
            return true;
        }
        return false;
    }

    bool checkDraw() {
        for (int i = 0; i < 9; ++i) {
            if (board[i] == Cell::Empty) {
                return false;
            }
        }
        return true;
    }

    void resetGame() {
        for (int i = 0; i < 9; ++i) {
            board[i] = Cell::Empty;
        }
        currentPlayer = Cell::X;
    }

    sf::RenderWindow window;
    std::vector<Cell> board;
    Cell currentPlayer;
};

int main() {
    TicTacToe game;
    game.run();
    return 0;
}