据说有一个能保证不败的算法。明天看看先再写个PVC版的。

正题。今天无聊写了个井字棋游戏,顺便逐渐让自己习惯良好的代码风格,放上来给新手学习学习。

jzq2.cpp

/*
N字棋游戏PVP版,DOS版
本棋盘可扩充,仅仅需调整检測条件就可以,其它接口不需改变。
非人机对战型。PVP类型;
@author:天下无双
@date:2014-5-25
@version:1.0
*/
#include <iostream>
#include <string>
#define INVALIDINDEX -1
#define FULL -2
#define OK 0
#define WIN 1
#define ISIN -3
using namespace std;
struct box{ //用box代表棋盘上每个格子
int chess;//用一种颜色代表棋子,black和white
int status;//0代表该格子没有棋子,1代表已经有了棋子
};
enum COLOR{black,white};
class chessBoard
{
private: static const int MAXROW=10;
static const int MAXCOLUMN=10;
int row;
int column;
int blackBox;//剩余棋盘格子数,就可以落棋点
box arr[MAXROW][MAXCOLUMN];
void setRow(int r){row=r;};
void setCol(int c){column=c;};
int GetRow()const{return row;};
int GetCol()const{return column;};
public:
chessBoard(int r,int col){
if(r>MAXROW||col>MAXCOLUMN){
cerr<<"棋盘大小超出范围"<<endl;
setRow(MAXROW);
setCol(MAXCOLUMN);
}else{
setRow(r);
setCol(col);
//int rr=GetRow();
//int cc=GetCol();
//blackBox=r*col;//初始化可落棋点//无法在这里设置blackBox,这是什么情况?
}
initialize();
creat();
}
void initialize()
{
int r=chessBoard::GetRow();
int col=chessBoard::GetCol();
blackBox=r*col;
for(int i=0;i<r;i++)
for(int j=0;j<col;j++)
{
arr[i][j].chess=-1;
arr[i][j].status=0;
} } //超出范围。返回 INVALIDINDEX -1
//已经赢了,返回 WIN 1
//棋盘满了,返回 FULL -2
//正常落棋 返回 OK 0
//该点存在棋子 返回 ISIN -3
int insertChess(int i,int j,COLOR c)//落棋 //仅提供落棋接口
{
int r=chessBoard::GetRow();
int col=chessBoard::GetCol();
if(i<0||j<0||i>=r||j>=col)
return INVALIDINDEX;
//if(c!=black&&c!=white)
//return INVALIDINDEX;
if(arr[i][j].status==0){//将棋子落入棋盘
arr[i][j].chess=c;
arr[i][j].status=1;//标识此格
flush();//刷新
blackBox--;
if(isGameOver())
return WIN;
if(isFull())
return FULL;
return OK;
}
return ISIN;
} protected:
void creat(){//初始化棋盘
int r=chessBoard::GetRow();
int col=chessBoard::GetCol();
for(int i=0;i<r;i++){
for(int j=0;j<col-1;j++){
cout<<" |";
}
cout<<endl;
}
}; void flush(){//重绘棋盘 system("cls");
int r=chessBoard::GetRow();
int col=chessBoard::GetCol();
for(int i=0;i<r;i++){
for(int j=0;j<col;j++){
if(white==arr[i][j].chess)
cout<<"0";
else if(black==arr[i][j].chess)
cout<<"*";
else
cout<<" ";
if(j!=col-1)
cout<<"|";
}
cout<<endl;
}
} bool isFull()const{//推断棋盘是否已经落满棋子
return blackBox==0;
}; bool isEmpty()const{;//推断棋盘是否为空
return blackBox==GetRow()*GetCol();
};
//由棋盘自己检測是否已经满了。 //或者游戏是否结束
bool isFinish()const{//检測棋盘是否已满
return isFull();//若棋盘满了。则游戏结束
}; bool isGameOver()const{
int r=chessBoard::GetRow();
int col=chessBoard::GetCol();
int color=-1;
for(int i=0;i<r;i++){//检測每一行。是否连成一排。
if(arr[i][0].chess==black||arr[i][0].chess==white)
color=arr[i][0].chess;//假设每行的第一个box有内容且为black||white
else
continue;//检測下一行
for(int j=1;j<col;j++){
if(color==arr[i][j].chess)//假设后面的跟第一个颜色同样
if(col==j+1){//假设到了比較最后一个且相等时
string colors;
if(color==1)
colors="white";
else
colors="black";
//cout<<endl<<colors<<" is winner!"<<endl;
cout<<endl<<"恭喜"<<colors<<"赢得了本次游戏! "<<endl;
return true;
}
else //假设不是最后一个。继续比較
continue;
else //假设颜色不同
break;
}
}
//检測每一列
for(int i=0;i<col;i++){//检測每一列,是否连成一排,
if(arr[0][i].chess==black||arr[0][i].chess==white)
color=arr[0][i].chess;//假设每列的第一个box有内容且为black||white
else
continue;//检測下一列
for(int j=1;j<r;j++){
if(color==arr[j][i].chess)//假设后面的跟第一个颜色同样
if(r==j+1){//假设到了比較最后一个且相等时
string colors;
if(color==1)
colors="white";
else
colors="black";
//cout<<endl<<colors<<" is winner!"<<endl;
cout<<endl<<"恭喜"<<colors<<"赢得了本次游戏。"<<endl;
return true;
}
else //假设不是最后一个,继续比較
continue;
else //假设颜色不同
break;
}
}
//检測正对角线
color=arr[0][0].chess;
bool falg=false;
if(color==black||color==white)//第一格是否有棋子
falg=true;
if(falg) //假设有棋子
for(int i=1,j=1;i<r&&j<col;i++,j++){
if(arr[i][j].chess==color)
if(i==r-1){
string colors;
if(color==1)
colors="white";
else
colors="black";
//cout<<endl<<colors<<" is winner!"<<endl;
cout<<endl<<"恭喜"<<colors<<"赢得了本次游戏! "<<endl;
return true;
}
else
continue;
else
break;
}
//检測側对角线 X
color=arr[r-1][0].chess;
falg=false;
if(color==black||color==white)//第一格是否有棋子
falg=true;
if(falg) //假设有棋子
for(int i=r-2,j=1;i>=0&&j<col;i--,j++){
if(arr[i][j].chess==color)
if(i==0){
string colors;
if(color==1)
colors="white";
else
colors="black";
//cout<<endl<<colors<<" is winner!"<<endl;
cout<<endl<<"恭喜"<<colors<<"赢得了本次游戏! "<<endl;
return true;
}
else
continue;
else
break;
}
return false;//假设都不满足,说明游戏还没有结束
};
};

main.cpp

#include <iostream>
#include "jzq2.cpp"
using namespace std;
int main()
{
//3,3代表棋盘为3*3,而且是指三个一排即为胜利
//相同的。5,5代表5字棋。可是棋盘大小也是5*5
//扩展棋盘将在下一版本号推出
chessBoard cb(3,3);
int status;
COLOR c=black;//记录下一步轮到谁走
int x,y;
bool falg=false;//用于记录是否成功落棋
bool isExit=false;//用于记录游戏是否结束
while(!isExit)
{
cout<<"\n\"0\"代表white,\"*\"代表black"<<endl;
cout<<"请输入落棋点:如(1,1)则输入:1 1"<<endl;
string colors;
if(c==black)
colors="black";
else
colors="white";
cout<<"如今轮到"<<colors<<"走下一步棋:";
cin>>x>>y;
/*
if(falg)
c=c==black?white:black;//换人走
*/
status=cb.insertChess(x,y,c);
switch(status){
//超出范围。返回 INVALIDINDEX -1
//已经赢了。返回 WIN 1
//棋盘满了,返回 FULL -2
//正常落棋 返回 OK 0
case 0:falg=true;
c=c==black? white:black;//假设成功落棋,换人走下一步棋
break;
case -1:cout<<"\n\n输入坐标不正确。超出范围"<<endl;
falg=false;
break;
case 1:cout<<"\n\n游戏结束。"<<endl;
falg=false;
isExit=true;
break;
case -2:cout<<"\n\n棋盘已满! "<<endl;
cout<<"\n\n游戏即将结束。"<<endl;
falg=false;
isExit=true;
break;
case -3:cout<<"\n\n该点已有棋子"<<endl;
falg=false;
break;
}
}
cin.get();
cin.get();
};

已经測试过了3*3的无BUG。当然前提是你输入的是数字。你要是输入字母的话,果断崩!

先放到PVP的来玩玩,哈哈哈。

今天跑去多益网络机试。回来的途中竟然想起来最后一道题少写了一个推断。郁闷。

另一道回来的途中才大概想了出来。

郁闷ing......

好了,睡了,各位晚安。

C++井字棋游戏,DOS界面版的更多相关文章

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

    17.2 Design an algorithm to figure out if someone has won a game oftic-tac-toe. 这道题让我们判断玩家是否能赢井字棋游戏, ...

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

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

  3. JavaFX 井字棋游戏

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

  4. Java井字棋游戏

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

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

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

  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. [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 ...

  8. Raptor井字棋游戏

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

  9. [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 ...

随机推荐

  1. python的递归算法学习(3):汉诺塔递归算法

    汉诺塔问题是递归函数的经典应用,它来自一个古老传说:在世界刚被创建的时候有一座钻石宝塔A,其上有64个金蝶.所有碟子按从大到小的次序从塔底堆放至塔顶.紧挨着这座塔有另外两个钻石宝塔B和C.从世界创始之 ...

  2. 开发框架 springBoot

    1.多个环境的配置文件 在application.yml 中配置需要调用的配置文件 spring: profiles: active: dev 运行方式的,先运行application.yml 再根据 ...

  3. PHP中利用PHPMailer使用QQ邮箱实现邮件发送

    /** * 下订单发送邮件 * @to 收件人 @title 标题 @content 内容 */ function sendMail($to,$title,$content){ //引入PHPMail ...

  4. (12)C#枚举,结构

    枚举 枚举类型是类似自定义的一个类,类里放着你自己定义的常量,关键字enum. enum Season{spring,summer,fall,winter} 想用这里的常量的话,首先把变量定义成 Se ...

  5. 51nod 算法马拉松 34 Problem D 区间求和2 (FFT加速卷积)

    题目链接  51nod 算法马拉松 34  Problem D 在这个题中$2$这个质数比较特殊,所以我们先特判$2$的情况,然后仅考虑大于等于$3$的奇数即可. 首先考虑任意一个点对$(i, j)$ ...

  6. Job的使用

    1.Job完成状态监听: job.addJobChangeListener(new JobChangeAdapter() {            @Override            publi ...

  7. 又是一年NOIP然鹅我考的是高数(虽然我没打并且内容与NOIP无关)(手动滑稽)

    好长时间没有写过总结了.也是高三结束,自招结束.成功的由国宝变为四害,整个人也是完全放松的,或者说是放肆的. 整个暑假都是游戏睡觉,游戏睡觉,也没有干什么有意义的事.有人说别人都在学习大一课程的时候我 ...

  8. [POI2014]Ant colony

    题目大意: 给定一棵$n(n\le10^6)$个结点的树.在每个叶子结点,有$g$群蚂蚁要从外面进来,其中第$i$群有$m_i$只蚂蚁.这些蚂蚁依次爬树(一群蚂蚁爬完后才会爬另一群),若当前经过结点度 ...

  9. (转)Unity3D研究院之游戏架构脚本该如何来写(三十九)

     这篇文章MOMO主要想大家说明一下我在Unity3D游戏开发中是如何写游戏脚本的,对于Unity3D这套游戏引擎来说入门极快,可是要想做好却非常的难.这篇文章的目的是让哪些已经上手Unity3D游戏 ...

  10. Hadoop 2.2.0 Job源代码阅读笔记

    本文所有涉及的内容均为2.2.0版本中呈现. 概述: Job在创建Job并且提交的人的眼中,可以在创建的时候通过配置Job的内容,控制Job的执行,以及查询Job的运行状态.一旦Job提交以后,将不能 ...