围棋/五子棋系统
来源:百度文库 编辑:神马文学网 时间:2024/06/03 03:47:36
//两天的成果#include
#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 for(short j=0;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< cout<<' ';
for(i=0;i {
cout< b++;
}
b='A';
for(i=0;i {
cout< cout< b++;
for(j=0;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< cout<<"弃权:*"< cout<<"投降:$"< 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 for(j=0;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 if(qp[x+1][y]==color)
{
cross.x++;
if(!gas(cross))
eat_L();
cross.x--;
}
del_L();
if(x 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 {
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--;
}
}
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 if(qp[sp.x+1][sp.y]==blank)
return true;
if(sp.x 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 for(j=0;j qp_w[i][j]=qp[i][j];
}
else
{
for(i=0;i for(j=0;j qp_b[i][j]=qp[i][j];
}
}void go::ret_qp()//恢复棋盘
{
short i,j;
if(w_play)
{
for(i=0;i for(j=0;j qp[i][j]=qp_b[i][j];
}
else
{
for(i=0;i for(j=0;j qp[i][j]=qp_w[i][j];
}
}bool go::cmp()
{
short i,j;
if(w_play)
{
for(i=0;i for(j=0;j if(qp_w[i][j]==qp[i][j])
return false;
}
else
{
for(i=0;i for(j=0;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 {
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<<"欢迎使用围棋/五子棋系统!"< cout<<"请选择棋的种类,0为五子棋,1为围棋"< cin>>x;
if(x==0)
p=new go;
else
p=new gobang;
p->play();
delete p;
getchar();
getchar();}
#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
}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<
for(i=0;i
cout< b++;
}
b='A';
for(i=0;i
cout<
for(j=0;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<
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
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
{
cross.x++;
if(!gas(cross))
eat_L();
cross.x--;
}
del_L();
if(x
{
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
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--;
}
}
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
return true;
if(sp.x
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
}
else
{
for(i=0;i
}
}void go::ret_qp()//恢复棋盘
{
short i,j;
if(w_play)
{
for(i=0;i
}
else
{
for(i=0;i
}
}bool go::cmp()
{
short i,j;
if(w_play)
{
for(i=0;i
return false;
}
else
{
for(i=0;i
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
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<<"欢迎使用围棋/五子棋系统!"<
if(x==0)
p=new go;
else
p=new gobang;
p->play();
delete p;
getchar();
getchar();}