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 = , sum = ;
for (int i = ; i < board.size(); ++i) {
for (int j = ; j < board[i].size(); ++j) {
int v = ;
if (board[i][j] == 'x') v = ;
else if (board[i][j] == 'o') v = ;
sum += v * factor;
factor *= ;
}
}
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 - - var][var];
}
return Piece::Empty;
} Piece getWinner(vector<vector<Piece>> board, int fixed_idx, Check check) {
Piece color = getIthColor(board, fixed_idx, , check);
if (color == Piece::Empty) {
return Piece::Empty;
}
for (int var = ; 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 = ; i < board.size(); ++i) {
if (board[i][] != Piece::Empty && board[i][] == board[i][] && board[i][] == board[i][]) {
return board[i][];
}
if (board[][i] != Piece::Empty && board[][i] == board[][i] && board[][i] == board[][i]) {
return board[][i];
}
}
if (board[][] != Piece::Empty && board[][] == board[][] && board[][] == board[][]) {
return board[][];
}
if (board[][] != Piece::Empty && board[][] == board[][] && board[][] == board[][]) {
return board[][];
}
return Piece::Empty;
} // N*N board
Piece hasWon2(vector<vector<Piece>> board) {
int N = board.size();
Piece winner = Piece::Empty;
for (int i = ; 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, -, Check::Diagonal);
if (winner != Piece::Empty) return winner;
winner = getWinner(board, -, 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 = , col = ;
for (row = ; row < N; ++row) {
if (board[row][] != Piece::Empty) {
for (col = ; col < N; ++col) {
if (board[row][col] != board[row][col - ]) {
break;
}
}
if (col == N) return board[row][];
}
}
for (col = ; col < N; ++col) {
if (board[][col] != Piece::Empty) {
for (row = ; row < N; ++row) {
if (board[row][col] != board[row - ][col]) {
break;
}
}
if (row == N) return board[][col];
}
}
if (board[][] != Piece::Empty) {
for (row = ; row < N; ++row) {
if (board[row][row] != board[row - ][row - ]) {
break;
}
}
if (row == N) return board[][];
}
if (board[N - ][] != Piece::Empty) {
for (row = ; row < N; ++row) {
if (board[N - row - ][row] != board[N - row][row - ]) {
break;
}
}
if (row == N) return board[N - ][];
}
return Piece::Empty;
} // N*N board
Piece hasWon4(vector<vector<Piece>> board) {
int N = board.size(), i = , j = ;
vector<Piece> pieces{Piece::Red, Piece::Blue};
for (Piece color : pieces) {
for (i = ; i < N; ++i) {
bool maybe_col = true, maybe_row = true;
for (j = ; 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 = ; i < N; ++i) {
if (board[i][i] != color) maybe_diag = false;
if (board[N - i - ][i] != color) maybe_revdiag = false;
}
if (maybe_diag || maybe_revdiag) return color;
}
return Piece::Empty;
} Piece convertIntToPiece(int i) {
if (i == ) {
return Piece::Blue;
} else if (i == ) {
return Piece::Red;
} else {
return Piece::Empty;
}
} void printVec(vector<vector<int>> v) {
for (int i = ; i < v.size(); ++i) {
for (int j = ; 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 = ; k < ; ++k) {
int N = ;
vector<vector<int>> v(N, vector<int>(N, ));
vector<vector<Piece>> board(N, vector<Piece>(N));
for (int i = ; i < N; ++i) {
for (int j = ; j < N; ++j) {
v[i][j] = rand() % ;
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 题目汇总

[CareerCup] 17.2 Tic Tac Toe 井字棋游戏的更多相关文章

  1. [LeetCode] Design Tic-Tac-Toe 设计井字棋游戏

    Design a Tic-tac-toe game that is played between two players on a n x n grid. You may assume the fol ...

  2. 井字棋游戏升级版 - TopTicTacToe项目 简介

    一.游戏简介 井字棋是一款世界闻名的游戏,不用我说,你一定知道它的游戏规则. 这款游戏简单易学,玩起来很有意思,不过已经证明出这款游戏如果两个玩家都足够聪明的话, 是很容易无法分出胜负的,即我们得到的 ...

  3. C++井字棋游戏,DOS界面版

    据说有一个能保证不败的算法.明天看看先再写个PVC版的. 正题.今天无聊写了个井字棋游戏,顺便逐渐让自己习惯良好的代码风格,放上来给新手学习学习. jzq2.cpp /* N字棋游戏PVP版,DOS版 ...

  4. JavaFX 井字棋游戏

    利用JavaFX设计一个井字棋游戏,其中包括了能够与玩家对战的AI.AI的实现相比五子棋来说要简单得多,可以保证AI在后手情况下绝对不会输,具体实现如下: /* * To change this li ...

  5. Java井字棋游戏

    试着写了一个井字棋游戏,希望各位能给予一些宝贵的建议. 一.棋盘类 package 井字棋游戏; public class ChessBoard { private int number; Perso ...

  6. [LeetCode] 348. Design Tic-Tac-Toe 设计井字棋游戏

    Design a Tic-tac-toe game that is played between two players on a n x n grid. You may assume the fol ...

  7. [C++] 井字棋游戏源码

    TicTac.h #define EX 1 //该点左鼠标 #define OH 2 //该点右鼠标 class CMyApp : public CWinApp { public: virtual B ...

  8. [Swift]LeetCode348. 设计井字棋游戏 $ Design Tic-Tac-Toe

    Design a Tic-tac-toe game that is played between two players on a n x n grid. You may assume the fol ...

  9. Raptor井字棋游戏

    作为大学第一个小作品,记录一下,也给那些想接触到Raptor游戏的人一个小小的参考QAQ至于Raptor的语法和使用,可以参考一下他的帮助手册,看不懂英文的话可以复制放到翻译上看. 以上是主函数 以下 ...

随机推荐

  1. html5实现银联海购商品分类列表

    银联海购官网请点击 http://haigou.unionpay.com/ 1.实现效果预览展示如下: 2.源码如下 <!DOCTYPE html> <html> <he ...

  2. jQuery AutoComplete 自动补全

    jQuery.AutoComplete是一个基于jQuery的自动补全插件.借助于jQuery优秀的跨浏览器特性,可以兼容Chrome/IE/Firefox/Opera/Safari等多种浏览器. 特 ...

  3. Linux学习心得之 Linux下ant安装与使用

    作者:枫雪庭 出处:http://www.cnblogs.com/FengXueTing-px/ 欢迎转载 Linux学习心得之 Linux下ant安装与使用 1. 前言2. ant安装3. 简单的a ...

  4. 理解java虚拟机内存分配堆,栈和方法区

    栈:存放局部变量 堆:存放new出来的对象 方法区:存放类的信息,static变量,常量池(字符串常量) 在堆中,可以说是堆的一部分   创建了一个student类,定义了name属性, id静态变量 ...

  5. Google C++单元测试框架GoogleTest---Extending Google Test by Handling Test Events

    Google TestExtending Google Test by Handling Test Events Google测试提供了一个事件侦听器API,让您接收有关测试程序进度和测试失败的通知. ...

  6. 我的Android第五章:通过Intent实现活动与活动之间的交互

    Intent在活动的操作 作用: Itent是Android程序中各个组件直接交换的一个重要方式可以指定当前组件要执行任务同时也可以给各个组件直接进行数据交互              同时Inten ...

  7. 了解HTML 元素分类

    HTML中包含大量的标签, 这些标签在我们使用中发现会有小小的差别, 有的标签用了之后不会有太大的布局变化, 只是语义化, 而有的标签却会重起一行, 相当于自己回车了一次, 这就是不同标签元素的分类不 ...

  8. yii2实战教程之第一个Yii程序

    之前考虑过要不要砍掉该章节,直接上手教你搭建简单的博客系统.出于实战基础加之自C语言的书籍出版以来,几乎所有的编程书籍都讲述了一个Hello World的例子作为开始.虽然我们仅仅是学习Yii2,但是 ...

  9. parawork功能使用说明

    项目整体估算 1.项目估算:依据项目属性,开发规模,参考行业平均生存率自动估算软件工作量.成本.工期 : 2.项目生产率分析:掌握研发生产率行业水平,方便项目管理 : 3.工期占比分析:了解项目关键节 ...

  10. SqlServer--查询案例

    use  MyDataBase1 -- * 表示显示所有列 -- 查询语句没有加where条件表示查询所有行 select *from TblStudent ---只查询表中的部分列 select t ...