//两天的成果
#include<iostream.h>
#define lsh 13 enum crossing{white,black,blank}; enum result{normal,illegal,giveup,victory,surrender}; struct point { short x; short y; }; class go_gobang { protected: enum crossing qp[lsh][lsh]; // enum result{normal,illegal,giveup,victory,surrender}; struct point cross; bool w_play; void note();//记录到数组 enum result tail(char *p);// 特殊字符判断 virtual bool verd(char *p);//合法性判断 void show(); public: go_gobang(); virtual void play()=0; }; go_gobang::go_gobang() { w_play=false; for(short i=0;i<lsh;i++) for(short j=0;j<lsh;j++) qp[i][j]=blank; } void go_gobang::note()
{ if(w_play) qp[cross.x][cross.y]=white; else qp[cross.x][cross.y]=black; } enum result go_gobang::tail(char *p)
{ if(p[0]=='*') { w_play=!w_play; return giveup; } else if(p[0]=='$') { if(w_play) cout<<"黑方获胜!"; else cout<<"白方获胜!"; return surrender; }
return normal; } bool go_gobang::verd(char *p) { short x,y; if(p[0]<'A'||p[0]>='a'+lsh || p[0]>='A'+lsh && p[0]<'a') return false; if(p[1]<'A'||p[1]>='a'+lsh || p[1]>='A'+lsh && p[1]<'a') return false; if(p[0]>='a') x=p[0]-'a'; else x=p[0]-'A'; if(p[1]>='a') y=p[1]-'a'; else y=p[1]-'A'; if(qp[x][y]!=blank) //判断是否有子 return false; cross.x=x; cross.y=y; return true; }
void go_gobang::show() { short i,j; char b='a'; cout<<endl; cout<<' '; for(i=0;i<lsh;i++) { cout<<b<<' '; b++; } b='A'; for(i=0;i<lsh;i++) { cout<<endl; cout<<b; b++; for(j=0;j<lsh;j++) { switch(qp[i][j]) { case white: cout<<"●"; break; case black: cout<<"○"; break; case blank: if(i==0) { if(j==0) cout<<"┏"; else if(j==lsh-1) cout<<"┓"; else cout<<"┯"; } else if(i==lsh-1) { if(j==0) cout<<"┗"; else if(j==lsh-1) cout<<"┛"; else cout<<"┷"; } else { if(j==0) cout<<"┠"; else if(j==lsh-1) cout<<"┨"; else cout<<"┼"; } break; } } } cout<<endl; cout<<"弃权:*"<<endl;//显示弃权、投降的提示信息 cout<<"投降:$"<<endl; if(w_play) cout<<"●";//显示当前的走棋方为白方 else cout<<"○";//显示当前的走棋方为黑方 } class gobang:public go_gobang //五子棋
{ private: bool five();//五子判断 virtual bool verd(char *p); public: virtual void play(); }; struct L_go { struct point pv; L_go *pn; }; class go:public go_gobang //围棋 { public: go(); virtual void play(); private: struct L_go *pt; //链表头 enum crossing qp_w[lsh][lsh]; enum crossing qp_b[lsh][lsh]; bool gas(struct point x);//查气 bool empty(struct point x); void del_L(); //删除链表 bool find_L(struct point sp); void in_L(struct point sp);//插入到链表中 void eat_L(); //吃子 void note_qp(); void ret_qp(); bool cmp();//是否是非法 virtual bool verd(char *sp);//合法性判断 }; go::go() { short i,j; for(i=0;i<lsh;i++) for(j=0;j<lsh;j++) { qp_w[i][j]=blank; qp_b[i][j]=blank; } } void go::play()
{ char key[3]; enum result z; while(true) { show(); cin>>key; z=tail(key); if(z==normal) { if(verd(key)) { note_qp();//备份 w_play=!w_play;//换方 } else { ret_qp(); cout<<"非法输入!"; } } else if(z==surrender) return; } } bool go::verd(char *p)//围棋合法性判断
{ enum crossing color;//判断周围棋子是否有气,color 异色 short x,y; if(!go_gobang::verd(p)) //调用基类判断合法性 return false; note();//记录到棋盘 if(w_play) color=black; else color=white; x=cross.x; y=cross.y; del_L();//清链表 if(x>0)//判断当前落子点是否大于0 if(qp[x-1][y]==color)//上 { cross.x--; if(!gas(cross)) eat_L(); cross.x++; } del_L(); if(y>0)//判断当前落子点不是最左边 if(qp[x][y-1]==color)//左 { cross.y--; if(!gas(cross)) eat_L(); cross.y++; } del_L(); if(x<lsh-1) //下 if(qp[x+1][y]==color) { cross.x++; if(!gas(cross)) eat_L(); cross.x--; } del_L(); if(x<lsh-1) //右 if(qp[x][y+1]==color) { cross.y++; if(!gas(cross)) eat_L(); cross.y--; //当前下棋点 } del_L(); if(!gas(cross)) return false; if(cmp()) //和上次比较 return false; return true; } bool go::gas(struct point sp)//查气
{ if(empty(sp))//自查 return true;//有气返回真 in_L(sp); if(sp.x>0) { if(qp[sp.x-1][sp.y]==qp[sp.x][sp.y])//是不是同色 { sp.x--; if(find_L(sp)) //没有找到 if(gas(sp)) return true; sp.x++;//恢复 }
} if(sp.y) { if(qp[sp.x][sp.y-1]==qp[sp.x][sp.y]) { sp.y--; if(find_L(sp)) if(gas(sp)) return true; sp.y++; } } if(sp.x<lsh-1) { if(qp[sp.x+1][sp.y]==qp[sp.x][sp.y]) { sp.x--; if(find_L(sp)) if(gas(sp)) return true; sp.x--; } } if(sp.y<lsh-1)//右 { if(qp[sp.x][sp.y+1]==qp[sp.x][sp.y]) { sp.y++; if(find_L(sp)) if(gas(sp)) return true; sp.y--; } } return false; }
bool go::empty(struct point sp)
{ if(sp.x>0)//上 if(qp[sp.x-1][sp.y]==blank) return true; if(sp.y>0) //左 if(qp[sp.x][sp.y-1]==blank) return true; if(sp.x<lsh-1)//下 if(qp[sp.x+1][sp.y]==blank) return true; if(sp.x<lsh-1)//右 if(qp[sp.x][sp.y+1]==blank) return true; return false; } void go::del_L()//删除链表
{ struct L_go *p0,*p1; p0=pt; while(p0!=NULL) { p1=p0; p0=p0->pn; delete p1;//删除一个单元格 } pt=NULL; } bool go::find_L(struct point sp)//找到链表中是否有值
{ struct L_go *p0; p0=pt; while(p0!=NULL) { if(sp.x==p0->pv.x && sp.y==p0->pv.y) return false; p0=p0->pn; }
return true; } void go::in_L(struct point sp) //插入到链表
{ struct L_go *p0; p0=new L_go; p0->pv.x=sp.x; p0->pv.y=sp.y; p0->pn=pt; pt=p0; } void go::eat_L() //吃子
{ struct L_go *p0; p0=pt; while(p0!=NULL) { qp[p0->pv.x][p0->pv.y]=blank; p0=p0->pn; } } void go::note_qp() //备份棋盘
{ short i,j; if(w_play) { for(i=0;i<lsh;i++) for(j=0;j<lsh;j++) qp_w[i][j]=qp[i][j]; } else { for(i=0;i<lsh;i++) for(j=0;j<lsh;j++) qp_b[i][j]=qp[i][j]; } } void go::ret_qp()//恢复棋盘
{ short i,j; if(w_play) { for(i=0;i<lsh;i++) for(j=0;j<lsh;j++) qp[i][j]=qp_b[i][j]; } else { for(i=0;i<lsh;i++) for(j=0;j<lsh;j++) qp[i][j]=qp_w[i][j]; } } bool go::cmp()
{ short i,j; if(w_play) { for(i=0;i<lsh;i++) for(j=0;j<lsh;j++) if(qp_w[i][j]==qp[i][j]) return false; } else { for(i=0;i<lsh;i++) for(j=0;j<lsh;j++) if(qp_b[i][j]!=qp[i][j]) return false; } return true; } bool gobang::five() { short n,i,j,x=cross.x,y=cross.y; enum crossing z=qp[x][y]; n=0; j=y; while(j>0) { if(qp[x][j-1]==z) j--; else break; }
while(qp[x][j]==z) { if(j++==lsh) break; if(++n==5) return true; } n=0; j=y; while(i>0) { if(qp[i-1][y]==z) i--; else break; } while(qp[i][y]==z) { if(i++==lsh) break; if(++n==5) return true; } n=0; i=x; j=y; while(i>0 && j>0) { if(qp[i][j]==z) { i--; j--; } else break; } while(qp[i][j]==z) { if(i++==lsh) break; if(j++==lsh) break; if(++n==5) return true; } n=0; i=x; j=y; while(i>0 && j<lsh-1) { if(qp[i][j]==z) { i--; j++; } else break; } while(qp[i][j]==z) { if(i++==lsh) break; if(j--==-1) break; if(++n==5) return true; } return false; } bool gobang::verd(char *p)
{ if(!go_gobang::verd(p)) return false; //可添加黑棋进入点判断 note(); return true; } void gobang::play()
{ char key[3]; enum result x; while(true) { show(); cin>>key; x=tail(key); if(x==normal) { if(!verd(key)) cout<<"非法输入!"; else { if(five()) { if(w_play) cout<<"白方胜利!"; else cout<<"黑方胜利!"; return; } else w_play=!w_play; } }
else if(x==surrender) return; } } void main()
{int x; go_gobang *p; cout<<"欢迎使用围棋/五子棋系统!"<<endl; cout<<"请选择棋的种类,0为五子棋,1为围棋"<<endl; cin>>x; if(x==0) p=new go; else p=new gobang; p->play(); delete p; getchar(); getchar(); }
|
|