本文为大家分享了C++五子棋的设计思路和设计实现,供大家参考,具体内容如下
成都创新互联从2013年成立,先为兴宁等服务建站,兴宁等地企业,进行企业商务咨询服务。为兴宁企业网站制作PC+手机+微官网三网同步一站式服务解决您的所有建站问题。算法思路:
在结束了对C++的学习之后,准备自己编制一些简单的练习程序。目前初步设想是编制一个人机对战的简易五子棋软件。 以下为个人设计思考的过程。
首先,进行问题分析与设计。计划实现的功能为,开局选择人机或双人对战,确定之后比赛开始。比赛结束后初始化棋盘,询问是否继续比赛或退出。后续可加入复盘、悔棋等功能。整个过程中,涉及到了棋子和棋盘两种对象,同时要加上人机对弈时的AI对象,即涉及到三个对象。
棋盘类的设计。
数据存储:五子棋棋盘为15*15的网格结构,即一共有225个节点,每个节点有横竖坐标各一,同时每个节点状态有3种,黑,白,或者为空。可考虑采用二维数组来存储。每个节点三种状态,适合采用枚举(enum)类型。
-* 实现功能*:1. 棋盘对象应负责实时更新棋盘状态并对外显示,因此需要接收棋子对象的输入,同时需要对外输出。而棋盘对象不需要对棋子对象发送信息,所以可以设计棋盘类中更新棋盘状态的函数接收棋子对象作为形参。2. 同时,在每次走棋之后,棋盘对象都要及时更新棋盘信息,即输出棋盘状态。3. 而且,每次走棋之后更新输出之前,应该对棋子走棋是否符合规则以及输赢进行判定。若将规则判定单独封装为一个对象,则不方便调用棋盘信息,故将规则判定设计为棋盘类的成员函数,接收两个形参,一个是棋盘当前的状态,一个是即将走的下一步棋,即一个棋子对象。
设计棋子对象。棋子对象应包含两种信息。一是棋子颜色,二是当前要走的棋子的位置坐标,并保留对外输出的接口。
接下来细化规则判定函数。
接下来设计下棋AI。设计为一个棋子类型的函数,即接收当前棋盘状态和对方最后一次落棋,返回棋子对象类型。
对弈算法设计。
接下来则是数据结构和对象设计及主函数调用实现:
类及类的实现
#define RENJU_H #include#include #include #define hor 7 #define ver 4 using namespace std; //用于记录坐标 struct position { int x; int y; position() { x = 0; y = 0; } position(int a,int b) { x = a; y = b; } }; //用于记录棋子颜色和节点状态 enum state { blank=0,black=1,white=2 }; //用于存储棋局分析信息:未完赛,犯规,平局,黑方胜,白方胜 enum result { go_on,error,draw,black_win,white_win }; // 设置光标 void setpos(COORD a) { HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleCursorPosition(out, a); } // 设置光标 void setpos(int i, int j) { COORD pos = { i, j }; setpos(pos); } //绘图函数,用于在指定坐标输出指定字符 inline void gps(int x,int y,char c) { setpos(y,x); cout< =10) cout< max) max = a[i]; } return max; } //检测是否符合胜利条件 //棋子类 class chess { public: inline chess(int x=0,int y=0,state c=blank) { point.x=x,point.y=y; color=c; }; inline chess(chess &ch) { point=ch.drop_point(); color=ch.get_color(); } ~chess(){}; struct position drop_point()const;//用于向外部提供棋子位置 inline state get_color() const { return color;}//提供棋子颜色信息 void set_point();//用于从外部获取棋子位置 void set_point(int x,int y){ point.x=x,point.y=y;} void set_point(position p){ point.x=p.x,point.y=p.y;} void set_color(state c){ color=c;}//设置棋子颜色 private: position point; enum state color; }; position chess::drop_point()const { return point; } void chess::set_point() { if(color==black) { setpos(110,1); cout<<"请黑方输入落子列数和行数,空格隔开:"; cin>>point.x>>point.y; while(point.x<1||point.x>15) { setpos(110,1); cout<<"列数输入超出范围,请重新输入1~15之间数字 "; cin>>point.x; } while(point.y<1||point.y>15) { setpos(110,2); cout<<"行数输入超出范围,请重新输入1~15之间数字 "; cin>>point.y; } } else if(color==white) { setpos(110,1); cout<<"请白方输入落子列数和行数,空格隔开:"; cin>>point.x>>point.y; while(point.x<1||point.x>15) { setpos(110,1); cout<<"列数输入超出范围,请重新输入1~15之间数字 "; cin>>point.x; } while(point.y<1||point.y>15) { setpos(110,2); cout<<"行数输入超出范围,请重新输入1~15之间数字 "; cin>>point.y; } } point.x--; point.y--; } //棋盘类 class chessboard { public: chessboard() { for(int i=0;i<15;i++) for(int j=0;j<15;j++) { square[i][j]=blank; } } chessboard(chessboard *cb) { for(int i=0;i<15;i++) for(int j=0;j<15;j++) { square[i][j]=cb->viewboard(i,j); } } inline state viewboard(position p_c) const;//接收坐标,返回该位置的状态 inline state viewboard(int x,int y) const;//接收整数坐标,返回该位置的状态 void update(chess ch);//接收新棋子,更新棋盘状态 void display()const;//向外输出棋盘状态 result judge(chess ch)const;//规则函数,判断走棋是否犯规和输赢 void clear()//清空棋盘 { for(int i=0;i<15;i++) for(int j=0;j<15;j++) { square[i][j]=blank; } } private: state square[15][15]; }; int check_five(chessboard bd,chess ch) { position ori=ch.drop_point(); int count=1;//计数器,统计同色个数 int sum[4]={0}; bool locked=0;//逻辑标记量,用来标记是否遇到了非同色节点 //水平方向检测 for(int i=0,locked=0;i<5&&((ori.x-i)>=0)&&(!locked);i++)//终止循环条件:同色超过4个或触碰到棋盘边界或遇到非同色节点 if(ch.get_color()==bd.viewboard(ori.x-i,ori.y)) count++; else if(i!=0) locked=1; //sum[0]=count-1; for(int i=0,locked=0;i<5&&((ori.x+i)<=14)&&(!locked);i++)//终止循环条件:同色超过4个或触碰到棋盘边界或遇到非同色节点 if(ch.get_color()==bd.viewboard(ori.x+i,ori.y)) count++; else if(i!=0) locked=1; //sum[1]=count-sum[0]-2; sum[0]=count; if(count>=5) return count; //竖直方向检测 count=1; for(int i=0,locked=0;i<5&&((ori.y-i)>=0)&&(!locked);i++)//终止循环条件:同色超过4个或触碰到棋盘边界或遇到非同色节点 if(ch.get_color()==bd.viewboard(ori.x,ori.y-i)) count++; else if(i!=0) locked=1; //sum[2]=count-1; for(int i=0,locked=0;i<5&&((ori.y+i)<=14)&&(!locked);i++)//终止循环条件:同色超过4个或触碰到棋盘边界或遇到非同色节点 if(ch.get_color()==bd.viewboard(ori.x,ori.y+i)) count++; else if(i!=0) locked=1; //sum[3]=count-sum[2]-2; sum[1]=count; if(count>=5) return count; //左上到右下斜向检测 count=1; for(int i=0,locked=0;i<5&&((ori.y-i)>=0)&&((ori.x-i)>=0)&&(!locked);i++)//终止循环条件:同色超过4个或触碰到棋盘边界或遇到非同色节点 if(ch.get_color()==bd.viewboard(ori.x-i,ori.y-i)) count++; else if(i!=0) locked=1; //sum[4]=count-1; for(int i=0,locked=0;i<5&&((ori.x+i)<=14)&&((ori.y+i)<=14)&&(!locked);i++)//终止循环条件:同色超过4个或触碰到棋盘边界或遇到非同色节点 if(ch.get_color()==bd.viewboard(ori.x+i,ori.y+i)) count++; else if(i!=0) locked=1; //sum[5]=count-sum[4]-2; sum[2]=count; if(count>=5) return count; //左下到右上斜向检测 count=1; for(int i=0,locked=0;i<5&&((ori.y+i)<=14)&&((ori.x-i)>=0)&&(!locked);i++)//终止循环条件:同色超过4个或触碰到棋盘边界或遇到非同色节点 if(ch.get_color()==bd.viewboard(ori.x-i,ori.y+i)) count++; else if(i!=0) locked=1; //sum[6]=count-1; for(int i=0,locked=0;i<5&&((ori.x+i)<=14)&&((ori.y-i)>=0)&&(!locked);i++)//终止循环条件:同色超过4个或触碰到棋盘边界或遇到非同色节点 if(ch.get_color()==bd.viewboard(ori.x+i,ori.y-i)) count++; else if(i!=0) locked=1; //sum[7]=count-sum[6]-2; sum[3]=count; if(count>=5) return count; return MAX(sum,4); } state chessboard::viewboard(position p_c) const { return square[p_c.x][p_c.y]; } state chessboard::viewboard(int x,int y) const { return square[x][y]; } void chessboard::update(chess ch) { position pos=ch.drop_point(); square[pos.x][pos.y]=ch.get_color(); } void chessboard::display()const { system("cls"); for(int i=0;i<15;i++)//打印列坐标说明 { gps(0,6+i*hor,i+1); } for(int i=0;i<15;i++)//打印列坐标说明 { gps(16*ver,6+i*hor,i+1); } for(int i=0;i<15;i++)//打印行坐标说明 { gps(3+i*ver,1,i+1); } for(int i=0;i<15;i++)//打印行坐标说明 { gps(3+i*ver,1+16*hor,i+1); } for(int i=0,j=0;i<15;i++) { for(j=0;j<15;j++) tab(1+i*ver,3+hor*j,square[j][i]); } cout< =5&&(set.get_color()==black)) return black_win; if(check_five(*this,set)>=5&&(set.get_color()==white)) return white_win; for(int i=0;i<15;i++) for(int j=0;j<15;j++) { if(square[i][j]==blank) full=0; } if(full==1) return draw; else return go_on; } #endif
另外有需要云服务器可以了解下创新互联建站www.cdcxhl.com,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。