网易游戏2016实习生招聘笔试题目--井字棋

题目描述

解题思路

使用一个3维数组input[][3][3],保存输入的棋局的状态。再使用一个一维数组result[],保存每个棋局的胜负情况,用数字表示胜负。3表示o胜,12表示x胜,0表示棋盘下满平局,-1表示不存在的棋盘状态。
对于每一个棋局,输入3*3的状态之后,就对其胜负情况进行判定。分别判断每一行,每一列,对角线及反对角线的状态,并将最终判定结果值存入到result数组中。

实现代码


    #include<iostream>

    #define SBOUNDARY 2000
    #define BOARDSIZE 3

    using namespace std;

    int status[8]; // 记录3行3列及两个对角线的和的情况
    int input[SBOUNDARY][3][3]; // 每一个输入都单独进行处理,且后续没有对棋盘进行遍历,因此只需要使用一个[3][3]矩阵即可
    int result[SBOUNDARY];

    int main(){
        char c;
        int S = 0;
        int x_count = 0;
        int o_count = 0;
        cin>>S;
        for(int s=0;s<S;s++){
            x_count = 0;
            o_count = 0;
            for(int i=0;i<8;i++){
                status[i] = 0;
            }
            // 输入棋局
            for(int i=0;i<BOARDSIZE;i++){
                for(int j=0;j<BOARDSIZE;j++){
                    cin>>c;
                    // 对输入进行统计,以判定棋盘状态
                    if(c == 'X'){
                        input[s][i][j] = 1;
                        x_count++;
                    }else if(c == 'O'){
                        input[s][i][j] = 4;
                        o_count++;
                    }else if(c == '_'){
                        input[s][i][j] = 0;
                    }
                    if(i==0){ // 第一行
                        status[0]+=input[s][i][j];
                    }else if(i==1){ // 第二行
                        status[1]+=input[s][i][j];
                    }else if(i==2){ // 第三行
                        status[2]+=input[s][i][j];
                    }
                    if(j==0){ // 第一列
                        status[3]+=input[s][i][j];
                    }else if(j==1){
                        status[4]+=input[s][i][j];
                    }else if(j==2){
                        status[5]+=input[s][i][j];
                    }
                    if(i == j){ // 对角线
                        status[6]+=input[s][i][j];
                    }
                    if(i+j == 2){ // 反对角线
                        status[7]+=input[s][i][j];
                    }
                }
            }
            // 对当前输入的棋局进行判断
            if(x_count < o_count ){ // 非法状态
                result[s] = -1;
            }else{
                int i=0;
                for(;i<8;i++){
                    if(status[i] == 3){
                        result[s] = 3; // x胜;使用3标记为x获胜--代表存在3个连续的1
                        break;
                    }else if(status[i] == 12){
                        result[s] = 12; // o胜;使用12标记o获胜--代表存在3个连续的4
                        break;
                    }else if(status[i] == 2 && x_count == o_count){ // 出现两个连续的x且下一步该x走
                        result[s] = 4; // next x胜
                        break;
                    }else if(status[i] == 8 && x_count == (o_count+1)){ // 出现两个连续的o且下一步该o走
                        result[s] = 13; // next o胜
                        break;
                    }
                }
                if(i == 8 && (x_count+o_count) == 9){ // 如果未出现上述胜负情况,那么判断是否平局
                    result[s] = 1; // 棋盘下满,平局;平局不能将值设为result[]的初始默认值0
                }
            }
        }
        // 根据结果数组中数字值输出各个棋局的胜负情况
        for(int i=0;i<S;i++){
            if(result[i] == -1){
                cout<<"Invalid"<<endl;
            }else if(result[i] == 3){
                cout<<"X win"<<endl;
            }else if(result[i] == 12){
                cout<<"O win"<<endl;
            }else if(result[i] == 4 || result[i] == 13){
                cout<<"Next win"<<endl;
            }else if(result[i] == 1){
                cout<<"Draw"<<endl;
            }else {
                cout<<"Next cannot win"<<endl;
            }
        }

        return 0;
    }

测试用例及输出

输出结果:

第一个例子,因为X先下,所以该局面不可能出现

第二个例子,为结束局面,X取胜

第三个例子,全部格子下完,双方均无法取胜,平局

第四个例子,局面未分胜负,下一个下的是X,可以取胜

第五个例子,局面未分胜负,下一个下的是O,无论下到哪一个格子均无法取胜

由于题目只是一个3*3的简单棋盘,所以没有对其进行扩展,但是思路都是一样的。
另外,还有就是对于棋盘的输入状态也是不必要存储的,只需要一个3*3数组即可,不需要一个3维数组。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用C++实现井字棋游戏的α-β剪枝算法的示例代码: ```c++ #include <iostream> #include <vector> #include <algorithm> using namespace std; const int BOARD_SIZE = 3; const int MAX_DEPTH = 9; enum class Player { None, Human, Computer }; struct Move { int row; int col; }; struct Board { vector<vector<Player>> cells; Board() { cells.resize(BOARD_SIZE, vector<Player>(BOARD_SIZE, Player::None)); } bool is_full() const { for (int row = 0; row < BOARD_SIZE; ++row) { for (int col = 0; col < BOARD_SIZE; ++col) { if (cells[row][col] == Player::None) { return false; } } } return true; } bool is_winner(Player player) const { // Check rows for (int row = 0; row < BOARD_SIZE; ++row) { bool win = true; for (int col = 0; col < BOARD_SIZE; ++col) { if (cells[row][col] != player) { win = false; break; } } if (win) { return true; } } // Check columns for (int col = 0; col < BOARD_SIZE; ++col) { bool win = true; for (int row = 0; row < BOARD_SIZE; ++row) { if (cells[row][col] != player) { win = false; break; } } if (win) { return true; } } // Check diagonals bool win = true; for (int i = 0; i < BOARD_SIZE; ++i) { if (cells[i][i] != player) { win = false; break; } } if (win) { return true; } win = true; for (int i = 0; i < BOARD_SIZE; ++i) { if (cells[i][BOARD_SIZE - i - 1] != player) { win = false; break; } } if (win) { return true; } return false; } vector<Move> get_moves() const { vector<Move> moves; for (int row = 0; row < BOARD_SIZE; ++row) { for (int col = 0; col < BOARD_SIZE; ++col) { if (cells[row][col] == Player::None) { moves.push_back({row, col}); } } } return moves; } void make_move(const Move& move, Player player) { cells[move.row][move.col] = player; } void undo_move(const Move& move) { cells[move.row][move.col] = Player::None; } void print() const { for (int row = 0; row < BOARD_SIZE; ++row) { for (int col = 0; col < BOARD_SIZE; ++col) { switch (cells[row][col]) { case Player::None: cout << "-"; break; case Player::Human: cout << "X"; break; case Player::Computer: cout << "O"; break; } if (col < BOARD_SIZE - 1) { cout << "|"; } } cout << endl; if (row < BOARD_SIZE - 1) { cout << "-----" << endl; } } } }; int evaluate(const Board& board) { if (board.is_winner(Player::Computer)) { return 1; } else if (board.is_winner(Player::Human)) { return -1; } else { return 0; } } int alpha_beta_pruning(Board& board, int depth, int alpha, int beta, bool maximizing_player) { if (depth == MAX_DEPTH || board.is_full()) { return evaluate(board); } if (maximizing_player) { int max_eval = -1000; for (const auto& move : board.get_moves()) { board.make_move(move, Player::Computer); int eval = alpha_beta_pruning(board, depth + 1, alpha, beta, false); board.undo_move(move); max_eval = max(max_eval, eval); alpha = max(alpha, eval); if (beta <= alpha) { break; } } return max_eval; } else { int min_eval = 1000; for (const auto& move : board.get_moves()) { board.make_move(move, Player::Human); int eval = alpha_beta_pruning(board, depth + 1, alpha, beta, true); board.undo_move(move); min_eval = min(min_eval, eval); beta = min(beta, eval); if (beta <= alpha) { break; } } return min_eval; } } Move get_best_move(const Board& board) { int max_eval = -1000; Move best_move; for (const auto& move : board.get_moves()) { Board new_board = board; new_board.make_move(move, Player::Computer); int eval = alpha_beta_pruning(new_board, 0, -1000, 1000, false); if (eval > max_eval) { max_eval = eval; best_move = move; } } return best_move; } int main() { Board board; Player current_player = Player::Human; // Randomly select first player if (rand() % 2 == 0) { current_player = Player::Computer; Move move = {rand() % BOARD_SIZE, rand() % BOARD_SIZE}; board.make_move(move, current_player); board.print(); } while (!board.is_full() && !board.is_winner(Player::Human) && !board.is_winner(Player::Computer)) { if (current_player == Player::Human) { int row, col; cout << "Enter row and column (0-indexed): "; cin >> row >> col; Move move = {row, col}; if (board.cells[row][col] == Player::None) { board.make_move(move, current_player); current_player = Player::Computer; } else { cout << "Invalid move!" << endl; } } else { Move move = get_best_move(board); board.make_move(move, current_player); current_player = Player::Human; cout << "Computer's move:" << endl; } board.print(); } if (board.is_winner(Player::Human)) { cout << "You win!" << endl; } else if (board.is_winner(Player::Computer)) { cout << "Computer wins!" << endl; } else { cout << "Tie!" << endl; } return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值