// ===== CodeLab: C++ 小游戏②:井字棋(带 AI) =====
// 来源: https://aoerliang.dpdns.org/articles/game-cpp-tictactoe
// 以下代码片段按文章出现顺序拼接, 共 6 段

// ----- 片段 1 (cpp) -----
#include <iostream>
#include <vector>

using Board = std::vector<std::vector<char>>;

Board makeBoard() {
    return Board(3, std::vector<char>(3, ' '));
}

// ----- 片段 2 (cpp) -----
void draw(const Board& b) {
    for (int r = 0; r < 3; ++r) {
        std::cout << " " << b[r][0] << " | " << b[r][1] << " | " << b[r][2] << "\n";
        if (r < 2) std::cout << "---+---+---\n";
    }
}

// ----- 片段 3 (cpp) -----
bool win(const Board& b, char p) {
    for (int i = 0; i < 3; ++i) {
        if (b[i][0] == p && b[i][1] == p && b[i][2] == p) return true;
        if (b[0][i] == p && b[1][i] == p && b[2][i] == p) return true;
    }
    return (b[0][0] == p && b[1][1] == p && b[2][2] == p) ||
           (b[0][2] == p && b[1][1] == p && b[2][0] == p);
}

bool full(const Board& b) {
    for (const auto& row : b)
        for (char c : row)
            if (c == ' ') return false;
    return true;
}

// ----- 片段 4 (cpp) -----
bool moveAI(Board& b) {
    // 1 能赢就赢
    for (int r = 0; r < 3; ++r)
        for (int c = 0; c < 3; ++c)
            if (b[r][c] == ' ') {
                b[r][c] = 'O';
                if (win(b, 'O')) return true;
                b[r][c] = ' ';   // 撤销试探
            }
    // 2 玩家要赢就堵
    for (int r = 0; r < 3; ++r)
        for (int c = 0; c < 3; ++c)
            if (b[r][c] == ' ') {
                b[r][c] = 'X';
                if (win(b, 'X')) { b[r][c] = 'O'; return true; }
                b[r][c] = ' ';
            }
    // 3 占中心,否则找空位
    if (b[1][1] == ' ') { b[1][1] = 'O'; return true; }
    for (int r = 0; r < 3; ++r)
        for (int c = 0; c < 3; ++c)
            if (b[r][c] == ' ') { b[r][c] = 'O'; return true; }
    return false;   // 棋盘满了
}

// ----- 片段 5 (cpp) -----
int main() {
    Board b = makeBoard();
    std::cout << "井字棋!你执 X,AI 执 O。输入行列(1~3),如 2 2\n";
    while (true) {
        draw(b);
        int r, c;
        std::cout << "你的回合(行 列): ";
        std::cin >> r >> c;
        --r; --c;
        if (r < 0 || r > 2 || c < 0 || c > 2 || b[r][c] != ' ') {
            std::cout << "无效位置,重新输入!\n";
            continue;
        }
        b[r][c] = 'X';
        if (win(b, 'X')) { draw(b); std::cout << "你赢了!\n"; break; }
        if (full(b))     { draw(b); std::cout << "平局。\n"; break; }
        moveAI(b);
        if (win(b, 'O')) { draw(b); std::cout << "AI 赢了!\n"; break; }
        if (full(b))     { draw(b); std::cout << "平局。\n"; break; }
    }
    return 0;
}

// ----- 片段 6 (bash) -----
g++ -std=c++17 -o tictactoe tictactoe.cpp
./tictactoe
