您的位置:首页 > 其它

[CareerCup] 17.2 Tic Tac Toe 井字棋游戏

2016-04-19 11:07 295 查看
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 题目汇总
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: