E05

  • Problem

    实现Tick Tac Toe小游戏。

  • Code
    #include <algorithm>
    #include <iostream>
    #include <string>
    using namespace std;
    class QP
    {
    public:
        void init() {
            for (int i = 0; i < 9; i++) {
                data[i] = EMPTY;
            }
            end = false;
            rs = "";
            count = 0;
            turn = PLAYER;
        }
        void show() {
            cout << endl;
            for (int i = 0; i < 9; i++) {
                cout << (data[i] == EMPTY ? '+' : (data[i] == PLAYER ? 'O' : 'X'))
                    << ((i + 1) % 3 ? '\0' : '\n');
            }
            cout << endl;
        }
        pair<int, int> get() {
            if (turn == COMPUTER) {
                auto t = next();
                cout << "computer put in: " << t.first << " " << t.second << endl;
                return t;
            }
            int x, y;
            cout << "input x and y: ";
            cin >> x >> y;
            return make_pair(x, y);
        }
        pair<int, int> next() {
            int *clone_data = new int[9];
            for (int i = 0; i < 9; i++) {
                clone_data[i] = data[i];
            }
            int index = -1;
            cout << search(clone_data, COMPUTER, -99999, 99999, index) << endl;
            delete clone_data;
            return make_pair(index / 3, index % 3);
        }
        bool set(pair<int, int> &put) {
            int index = put.first * 3 + put.second;
            if (data[index] != EMPTY) {
                return false;
            }
            count++;
            data[index] = turn;
            return true;
        }
        bool hasLine(int *t) {;
            return (t[0] != EMPTY && t[0] == t[1] && t[1] == t[2])
                || (t[3] != EMPTY && t[3] == t[4] && t[4] == t[5])
                || (t[6] != EMPTY && t[6] == t[7] && t[7] == t[8])
                || (t[0] != EMPTY && t[0] == t[3] && t[3] == t[6])
                || (t[1] != EMPTY && t[1] == t[4] && t[4] == t[7])
                || (t[2] != EMPTY && t[2] == t[5] && t[5] == t[8])
                || (t[0] != EMPTY && t[0] == t[4] && t[4] == t[8])
                || (t[2] != EMPTY && t[2] == t[4] && t[4] == t[6]);
        }
        void freshStateAfter(pair<int, int> &put) {
            bool line = hasLine(data);
            if (!line) {
                if (count == 9) {
                    rs = "draw...";
                    end = true;
                }
                return;
            }
            if (turn == PLAYER) {
                rs = "you win!";
            }
            else if (turn == COMPUTER) {
                rs = "you lose";
            }
            end = true;
        }
        void toggleTurn() {
            if (turn == PLAYER) {
                turn = COMPUTER;
            }
            else {
                turn = PLAYER;
            }
        }
        void start() {
            init();
            cout << "game start" << endl;
            while (!end) {
                show();
                auto put = get();
                if (set(put)) {
                    freshStateAfter(put);
                    toggleTurn();
                }
            }
            show();
            cout << rs << endl << endl;
        }
    private:
        int search(int *node, int whoseTurn, int alpha, int beta, int &pos) {    
            if (hasLine(node)) {
                return whoseTurn == COMPUTER ? -1 : 1;
            }
            else {
                bool isDraw = true;
                for (int i = 0; i < 9; i++) {
                    if (node[i] == EMPTY) {
                        isDraw = false;
                        break;
                    }
                }
                if (isDraw) {
                    return 0;
                }
            }
            int t, tpos;
            for (int i = 0; i < 9; i++) {
                if (node[i] == EMPTY) {
                    if (whoseTurn == COMPUTER) {
                        node[i] = COMPUTER;
                        t = search(node, PLAYER, alpha, beta, tpos);
                        node[i] = EMPTY;
                        if (t > alpha) {
                            alpha = t;
                            pos = i;
                        }
                        if (beta <= alpha) {
                            return alpha;
                        }    
                    }
                    else if (whoseTurn == PLAYER) {
                        node[i] = PLAYER;
                        t = search(node, COMPUTER, alpha, beta, tpos);
                        node[i] = EMPTY;
                        if (t < beta) {
                            beta = t;
                        }
                        if (beta <= alpha) {
                            return beta;
                        }
                    }
                }
            }
            return whoseTurn == COMPUTER ? alpha : beta;
        }
        string rs;
        int turn, count;
        bool end;
        int data[9];
        static int EMPTY, PLAYER, COMPUTER;
    };
    int QP::EMPTY = 0;
    int QP::PLAYER = 1;
    int QP::COMPUTER = -1;
    int main() {
        while (true) {
            QP q;
            q.start();
        }
    }
    
  • Result

    E05