zoukankan      html  css  js  c++  java
  • [CareerCup] 17.2 Tic Tac Toe 井字棋游戏

    17.2 Design an algorithm to figure out if someone has won a game oftic-tac-toe. 

    这道题让我们判断玩家是否能赢井字棋游戏,有下面几点需要考虑:

    1. 判断是否能赢hasWon函数是调用一次还是多次,如果是多次,我们可能为了优化而需要加入一些预处理。

    2. 井字棋游戏通常是3x3的大小,我们是否想要实现NxN的大小?

    3. 我们需要在代码紧凑,执行速度和代码清晰之间做出选择。

    #include <iostream>
    #include <string>
    #include <vector>
    #include <ctime>
    
    using namespace std;
    
    int convertBoardToInt(vector<string> board) {
        int factor = 1, sum = 0;
        for (int i = 0; i < board.size(); ++i) {
            for (int j = 0; j < board[i].size(); ++j) {
                int v = 0;
                if (board[i][j] == 'x') v = 1;
                else if (board[i][j] == 'o') v = 2;
                sum += v * factor;
                factor *= 3;
            }
        }
        return sum;
    }
    
    enum class Piece {Empty, Red, Blue};
    
    enum class Check {Row, Column, Diagonal, ReverseDiagonal};
    
    Piece getIthColor(vector<vector<Piece>> board, int idx, int var, Check check) {
        int N = board.size();
        if (check == Check::Row) {
            return board[idx][var];
        } else if (check == Check::Column) {
            return board[var][idx];
        } else if (check == Check::Diagonal) {
            return board[var][var];
        } else if (check == Check::ReverseDiagonal) {
            return board[N - 1 - var][var];
        }
        return Piece::Empty;
    }
    
    Piece getWinner(vector<vector<Piece>> board, int fixed_idx, Check check) {
        Piece color = getIthColor(board, fixed_idx, 0, check);
        if (color == Piece::Empty) {
            return Piece::Empty;
        }
        for (int var = 1; var < board.size(); ++var) {
            if (color != getIthColor(board, fixed_idx, var, check)) {
                return Piece::Empty;
            }
        }
        return color;
    }
    
    // work for 3*3 board
    Piece hasWon1(vector<vector<Piece>> board) {
        for (int i = 0; i < board.size(); ++i) {
            if (board[i][0] != Piece::Empty && board[i][0] == board[i][1] && board[i][0] == board[i][2]) {
                return board[i][0];
            }
            if (board[0][i] != Piece::Empty && board[0][i] == board[1][i] && board[0][i] == board[2][i]) {
                return board[0][i];
            }
        }
        if (board[0][0] != Piece::Empty && board[0][0] == board[1][1] && board[0][0] == board[2][2]) {
            return board[0][0];
        }
        if (board[2][0] != Piece::Empty && board[2][0] == board[1][1] && board[2][0] == board[0][2]) {
            return board[2][0];
        }
        return Piece::Empty;
    }
    
    // N*N board
    Piece hasWon2(vector<vector<Piece>> board) {
        int N = board.size();
        Piece winner = Piece::Empty;
        for (int i = 0; i < N; ++i) {
            winner = getWinner(board, i, Check::Row);
            if (winner != Piece::Empty) return winner;
            winner = getWinner(board, i, Check::Column);
            if (winner != Piece::Empty) return winner;
        }
        winner = getWinner(board, -1, Check::Diagonal);
        if (winner != Piece::Empty) return winner;
        winner = getWinner(board, -1, Check::ReverseDiagonal);
        if (winner != Piece::Empty) return winner;
        return Piece::Empty;
    }
    
    // N*N board
    Piece hasWon3(vector<vector<Piece>> board) {
        int N = board.size(), row = 0, col = 0;
        for (row = 0; row < N; ++row) {
            if (board[row][0] != Piece::Empty) {
                for (col = 1; col < N; ++col) {
                    if (board[row][col] != board[row][col - 1]) {
                        break;
                    }
                }
                if (col == N) return board[row][0];
            }
        }
        for (col = 0; col < N; ++col) {
            if (board[0][col] != Piece::Empty) {
                for (row = 1; row < N; ++row) {
                    if (board[row][col] != board[row - 1][col]) {
                        break;
                    }
                }
                if (row == N) return board[0][col];
            }
        }
        if (board[0][0] != Piece::Empty) {
            for (row = 1; row < N; ++row) {
                if (board[row][row] != board[row - 1][row - 1]) {
                    break;
                }
            }
            if (row == N) return board[0][0];
        }
        if (board[N - 1][0] != Piece::Empty) {
            for (row = 1; row < N; ++row) {
                if (board[N - row - 1][row] != board[N - row][row - 1]) {
                    break;
                }
            }
            if (row == N) return board[N - 1][0];
        }
        return Piece::Empty;
    }
    
    // N*N board
    Piece hasWon4(vector<vector<Piece>> board) {
        int N = board.size(), i = 0, j = 0;
        vector<Piece> pieces{Piece::Red, Piece::Blue};
        for (Piece color : pieces) {
            for (i = 0; i < N; ++i) {
                bool maybe_col = true, maybe_row = true;
                for (j = 0; j < N; ++j) {
                    if (board[i][j] != color) maybe_row = false;
                    if (board[j][i] != color) maybe_col = false;
                }
                if (maybe_col || maybe_row) return color;
            }
            bool maybe_diag = true, maybe_revdiag = true;
            for (i = 0; i < N; ++i) {
                if (board[i][i] != color) maybe_diag = false;
                if (board[N - i - 1][i] != color) maybe_revdiag = false;
            }
            if (maybe_diag || maybe_revdiag) return color;
        }
        return Piece::Empty;
    }
    
    Piece convertIntToPiece(int i) {
        if (i == 1) {
            return Piece::Blue;
        } else if (i == 2) {
            return Piece::Red;
        } else {
            return Piece::Empty;
        }
    }
    
    void printVec(vector<vector<int>> v) {
        for (int i = 0; i < v.size(); ++i) {
            for (int j = 0; j < v[i].size(); ++j) {
                cout << v[i][j] << " ";
            }
            cout << endl;
        }
        cout << endl;
    }
    
    void printPiece(Piece p) {
        if (p == Piece::Empty) cout << "Empty" << endl;
        else if (p == Piece::Red) cout << "Red" << endl;
        else if (p == Piece::Blue) cout << "Blue" << endl;
    }
    
    int main() {
        srand(time(NULL));
        for (int k = 0; k < 10; ++k) {
            int N = 3;
            vector<vector<int>> v(N, vector<int>(N, 0));
            vector<vector<Piece>> board(N, vector<Piece>(N));
            for (int i = 0; i < N; ++i) {
                for (int j = 0; j < N; ++j) {
                    v[i][j] = rand() % 3;
                    board[i][j] = convertIntToPiece(v[i][j]);
                }
            }
            Piece p1 = hasWon1(board);
            Piece p2 = hasWon2(board);
            Piece p3 = hasWon3(board);
            Piece p4 = hasWon4(board);
            if (p1 != p2 || p2 != p3 || p3 != p4) {
                printPiece(p1);
                printPiece(p2);
                printPiece(p3);
                printPiece(p4);
                printVec(v);
            }
            cout << endl;
        }
    }

    CareerCup All in One 题目汇总

  • 相关阅读:
    爬取网页图片
    python 猜数字游戏
    位移运算
    生成随机的名字
    不截半个汉字
    一致性hash的实现
    安装前端脚手架
    什么是快速排序?
    HTML5有趣的标签
    stopPropagation / stopImmediatePropagation
  • 原文地址:https://www.cnblogs.com/grandyang/p/5407377.html
Copyright © 2011-2022 走看看