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. Effective c++读书笔记

    1.视C++为一个语言联邦     C.object-oriented C++.template C++.STL 2.尽可能使用const:     1)关键字const出现的星号左边,表示被指物事常 ...

  2. 高性能javascript学习笔记系列(6) -ajax

    参考 高性能javascript javascript高级程序设计 ajax基础  ajax技术的核心是XMLHttpRequest对象(XHR),通过XHR我们就可以实现无需刷新页面就能从服务器端读 ...

  3. 自定义AlertDialog控件的使用(AndroidStudio)

    AlertDialog 第一种:可随意自定义控件 第一步:自定义弹出的页面 ,新建一个XML页面 如下图  不需要Activity 第二步:在主页面设置一个按钮弹出上图页面  (下面是主要代码  调用 ...

  4. Nginx中文详解、配置部署及高并发优化

      一.Nginx常用命令: 1. 启动 Nginx          /usr/local/nginx/sbin/nginxpoechant@ubuntu:sudo ./sbin/nginx2. 停 ...

  5. Android入门开发时注意的两个问题

    android开发中的问题: . 开发应用时要访问网络往往会忘记添加网络权限 <uses-permission android:name="android.permission.INT ...

  6. iOS tableViewCell自适应高度 第三发类库

    在github中有许多大牛封装好的第三发类库,其中有个自适应cell高度的类库 下载地址:https://github.com/gsdios/SDAutoLayout model类 commentsM ...

  7. databtables 设置(显示)行号

    var table = $('#priceStrategtyTable').DataTable({         "rowCallback": function( row, da ...

  8. WebBrowser的Cookie操作之流量刷新机

    最近一直在思考着如何通过代码去伪装或实现人工自然浏览网页的效果,起初能想到的是用WebBrowser实现这一效果,需要达到的功能预想有以下几点: 1.自动刷新 2.模拟人工下拉滚动条并停留一段时间: ...

  9. 使用 Fiddler 上传微信公众账号 自定义菜单

    0.你必须有微信公众账号的服务号.成为开发者之后.... 1.得到你的 appid (xxxxxxoooo)和 secret (oooooooxxxxxxx) 2.用这个链接得到你的 access_t ...

  10. JVM内存模型

    原文地址:http://www.cnblogs.com/dingyingsi/p/3760447.html 1.程序计数器 程序计数器(Program Counter Register)是一块较小的内 ...