分享

围棋/五子棋系统

 上善若水teamo 2010-04-22
//两天的成果
#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();
}

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多