[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
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】