UVA 220 Othello(模拟)

输入:
第一行游戏场次
接下来八行输入8*8的棋盘 :-空 B黑子 W白子
输入当前是谁的回合
L显示当前回合玩家能够下的位置M表示下子
Q结束当前游戏
输出:
L:当前能下点的坐标
M:黑子白子的个数
Q:输出最后的棋局
1.当前能下的位置:
先确定当前是谁的回合,然后
每个点扫描,检查是否符合条件,如果符合条件把这个点的坐标输出:
检查是否符合条件(x,y,假设当前回合是B){//这个位置能否下子
  当前位置是否是空白 如果不是直接返回false
  检查8个方向是否有W子,如果没有肯定不符合,
  如果有,沿着当前方向继续检查,直至遇到B,或者空白,或者出界:
  如果是B return true;
  else if(空白或者出界) return false;
  else 沿这个方向继续检查
}
2.下子:
先确定当前位置是否能够下子,如果不能直接返回false
否则,沿着8个方向检查,如果当前方向可行,先打上标记,
8个方向都检查结束,然后一起改变颜色(检查完一个方向就改变,可能其他方向的检查就会出问题)

如果当前用户没有地方能够下子:
直接切换成另个一人,并且变为他下子(假定下一次是可以下子的)

每个人下完子之后都要换人。
注意:
1.输出格式 黑白子个数占两位
2.如果当前用户没有一个能下的位置,换人,并且还在这个位置下子(题目保证换人之后能下),
下完之后换人
3.如果当前用户能下,下完之后换人
4.模拟

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
char g[9][9];//下标从1开始
int dir[8][2] = {{-1,0},{-1,1},{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1}};//8个探测的方向
int cur;//当前回合的玩家:0表示B 1表示W
void print(){
    for(int i=1;i<=8;i++){
        for(int j=1;j<=8;j++){
            cout<<g[i][j];
        }
        cout<<endl;
    }
}
bool isOut(int x,int y){//检查当前点是否出界
    return x<1||x>8||y<1||y>8;
}
bool check(int x,int y){//检查当前位置,对于当前玩家而言是否是合法的下子点
    if(g[x][y]!='-') return false;
    int i;
    for(i=0;i<8;i++){
        int nx = x+dir[i][0];
        int ny = y+dir[i][1];
        if(!isOut(nx,ny)&&(cur==0&&g[nx][ny]=='W'||cur==1&&g[nx][ny]=='B')){
            while(true){//沿着当前方向检查能否遇到下一个子完成封闭
                nx+=dir[i][0];
                ny+=dir[i][1];
                if(isOut(nx,ny)) break;//出界都没有遇到
                if(g[nx][ny]=='-') break;//第一个遇到的是空白位置
                if(cur==0&&g[nx][ny]=='W'||cur==1&&g[nx][ny]=='B') continue;//遇到的还是被封闭的子继续查找
                if(cur==0&&g[nx][ny]=='B'||cur==1&&g[nx][ny]=='W') return true;//完成封闭

            }
        }else{
            continue;
        }
    }
    return false;//8个方向没有一个可以构成封闭
}
bool noWay(){//检查当前玩家是否没有可下子的点
    bool Find = false;
    int i,j;
    for(i=1;i<=8;i++){
        for(j=1;j<=8;j++){
            //cout<<i<<" "<<j<<" "<<check(i,j)<<endl;
            if(check(i,j)){
                return false;
            }
        }
    }
    return true;
}
void ListAll(){//显示当前玩家所有可以下子的点
    int first = 1;
    bool Find = false;
    int i,j;
    for(i=1;i<=8;i++){
        for(j=1;j<=8;j++){
            //cout<<i<<" "<<j<<" "<<check(i,j)<<endl;
            if(check(i,j)){
                Find = true;
                if(first) first=0;
                else cout<<" ";
                cout<<"("<<i<<","<<j<<")";
            }
        }
    }
    if(!Find) cout<<"No legal move."<<endl;
    else cout<<endl;
}
void change(int x,int y){//假定当前位置是能够下子的位置,然后修改所有被封闭的点
    bool flag;
    int conv[9][9];
    memset(conv,0,sizeof(conv));
    int i,j;
    for(i=0;i<8;i++){
        int nx = x+dir[i][0];
        int ny = y+dir[i][1];
        if(!isOut(nx,ny)&&(cur==0&&g[nx][ny]=='W'||cur==1&&g[nx][ny]=='B')){
            flag = false;
            while(true){//沿着当前方向检查能否遇到下一个子完成封闭
                nx+=dir[i][0];
                ny+=dir[i][1];
                if(isOut(nx,ny)) break;//出界都没有遇到
                if(g[nx][ny]=='-') break;//第一个遇到的是空白位置
                if(cur==0&&g[nx][ny]=='W'||cur==1&&g[nx][ny]=='B') continue;//遇到的还是被封闭的子继续查找
                if(cur==0&&g[nx][ny]=='B'||cur==1&&g[nx][ny]=='W') {flag = true;break;}//完成封闭

            }
            if(flag){
                nx = x+dir[i][0];
                ny = y+dir[i][1];
                while(true){//添加修改标志
                    if(cur==0&&g[nx][ny]=='B'||cur==1&&g[nx][ny]=='W') break;//完成封闭
                    conv[nx][ny] = 1;
                    nx+=dir[i][0];
                    ny+=dir[i][1];
                }
            }
        }
    }
    for(i=1;i<=8;i++){
        for(j=1;j<=8;j++){
            if(conv[i][j]==1){
                if(cur==0){
                    g[i][j] = 'B';
                }else{
                    g[i][j] = 'W';
                }
            }
        }
    }
    g[x][y]=cur==0?'B':'W';//下子
}

int main()
{
    char c;
    int Case;
    char order[5];
    int i,j;
    int first = 1;
    cin>>Case;
    while(Case--){
        if(first) first=0;
        else cout<<endl;
        for(i=1;i<=8;i++){
            for(j=1;j<=8;j++){
                cin>>g[i][j];
            }
        }
        cin>>c;

        if(c=='B') cur = 0;
        else cur = 1;

        while(true){
            cin>>order;
            if(order[0]=='Q'){
                print();
                break;
            }else if(order[0]=='L'){
                ListAll();
            }else{
                int x = order[1]-48;
                int y = order[2]-48;
                if(noWay()){
                    cur = !cur;//如果没有地方可以下直接切换,变成另一个人在这个位置下子
                    change(x,y);
                    cur = !cur;
                }else{
                    if(check(x,y)){
                        change(x,y);
                        cur = !cur;
                    }else{//有可以下子的地方,但是当前下子的地方是不合法的。
                        ;
                    }
                }
                int bnum = 0;
                int wnum = 0;
                for(i=1;i<=8;i++){
                    for(j=1;j<=8;j++)
                        if(g[i][j]=='B') bnum++;
                        else if(g[i][j]=='W') wnum++;
                }
                printf("Black - %2d White - %2d\n",bnum,wnum);//输出格式 PE
                //cout<<"Black - "<<bnum<<" White - "<<wnum<<endl;
            }
        }

    }
    return 0;
}

 

posted @ 2019-06-14 20:03  fanyuheng  阅读(60)  评论(0)    收藏  举报