首页 > 代码库 > C++井字棋游戏,DOS界面版

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

据说有一个能保证不败的算法,明天看看先再写个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......

好了,睡了,各位晚安。