习题4-3 黑白棋(Othello, ACM/ICPC World Finals 1992, UVa220)

代码转载自:https://blog.csdn.net/XieNaoban/article/details/52078533

你的任务是模拟黑白棋游戏的进程。黑白棋的规则为:黑白双方轮流放棋子,每次必须
让新放的棋子“夹住”至少一枚对方棋子,然后把所有被新放棋子“夹住”的对方棋子替换成己
方棋子。一段连续(横、竖或者斜向)的同色棋子被“夹住”的条件是两端都是对方棋子(不
能是空位)。如图4-6(a)所示,白棋有6个合法操作,分别为(2,3),(3,3),(3,5),  (6,2),(7,3),
(7,4)。选择在(7,3)放白棋后变成如图4-6(b)所示效果(注意有竖向和斜向的共两枚黑棋变
白)。注意(4,6)的黑色棋子虽然被夹住,但不是被新放的棋子夹住,因此不变白。

习题4-3 黑白棋(Othello, ACM/ICPC World Finals 1992, UVa220)_第1张图片
输入一个8*8的棋盘以及当前下一次操作的游戏者,处理3种指令:
L指令打印所有合法操作,按照从上到下,从左到右的顺序排列(没有合法操作时输出
No legal move)。
Mrc指令放一枚棋子在(r,c)。如果当前游戏者没有合法操作,则是先切换游戏者再操
作。输入保证这个操作是合法的。输出操作完毕后黑白方的棋子总数。
Q指令退出游戏,并打印当前棋盘(格式同输入)。

之前写了很长,将近两百行还没写完,烂的不能再烂了,于是翻了一下博客发现这个老哥写的非常好,代码重用性非常高,就分析一下他的代码:

其实下子的时候也是用到了L操作 需要判断 当前的颜色的棋子是否有地方放 所以用 is_print 控制是否输出结果 , 用Flag判断是否有地方可以放子。

void L(bool is_print)
{
    L_Refresh = 1, Flag = 0;
    for (int i = 0; i < 8; ++i)
        for (int j = 0; j < 8; ++j)
        {
            if (Board[i][j] != '-') continue;
            for (int l = 0; l < 8; ++l)
                if (judge(i, j, Rx[l], Ry[l], is_print))  break;
        }
    if (is_print) Flag ? printf("\n") : printf("No legal move.\n");
}

下子的话 那就比较简单了 直接用L()函数判断能否下子如果能的话分别判断八个方向是否能翻转棋子 如果能的话就翻转。

void M()
{
    char i = Command[1] - 49, j = Command[2] - 49;
    if (!L_Refresh) L(0);//判断是否可以下子 如果之前查询过是可以下子的话则跳过
    if (!Flag) Current = oppo();//没有地方可以下棋
    for (int l = 0; l < 8; ++l)
        if (judge(i, j, Rx[l], Ry[l], 0)) change(i, j, Rx[l], Ry[l]);
    Current == 'W' ? Num[0] += 1 : Num[1] += 1;
    Board[i][j] = Current;
    Current = oppo();
    L_Refresh = 0;
    printf("Black - %2d White - %2d\n", Num[1], Num[0]);
}

AC代码如下: 

#include
#include 
char Board[11][11], Current, Command[5];
bool Flag, L_Refresh;//flag用于空格的输出,同时可以判断出本局是不是当前颜色的棋子无路可走
int Times, Num[2];//Num:0白1黑
int Rx[] = { 0, 0, 1, -1, 1, -1, 1, -1 };
int Ry[] = { 1, -1, 0, 0, 1, -1, -1, 1 };
inline char oppo()
{
    return (Current == 'W' ? 'B' : 'W');
}

bool judge(int i, int j, int x, int y, bool is_print)
{
    int ii = i, jj = j + 1, flg = 0;
    while ((i += x) < 8 && (j += y) < 8 && i >= 0 && j >= 0)
    {
        if (Board[i][j] == '-') break;
        if (Board[i][j] == Current)
        {
            if (!flg) break;
            if (is_print)
            {
                if (Flag) printf(" ");
                printf("(%d,%d)", ii, jj);
            }
            if (!Flag) Flag = true;
            return true;
        }
        ++flg;
    }
    return false;
}

void change(int i, int j, int x, int y)
{
    int n = 0;
    while (Board[i += x][j += y] != Current)
    {
        Board[i][j] = Current, ++n;
    }
    Current == 'W' ? (Num[0] += n, Num[1] -= n) : (Num[0] -= n, Num[1] += n);
}

void L(bool is_print)
{
    L_Refresh = 1, Flag = 0;
    for (int i = 0; i < 8; ++i)
        for (int j = 0; j < 8; ++j)
        {
            if (Board[i][j] != '-') continue;
            for (int l = 0; l < 8; ++l)
                if (judge(i, j, Rx[l], Ry[l], is_print))  break;
        }
    if (is_print) Flag ? printf("\n") : printf("No legal move.\n");
}

void M()
{
    char i = Command[1] - 49, j = Command[2] - 49;
    if (!L_Refresh) L(0);//判断是否可以下子 如果之前查询过是可以下子的话则跳过
    if (!Flag) Current = oppo();//没有地方可以下棋
    for (int l = 0; l < 8; ++l)
        if (judge(i, j, Rx[l], Ry[l], 0)) change(i, j, Rx[l], Ry[l]);
    Current == 'W' ? Num[0] += 1 : Num[1] += 1;
    Board[i][j] = Current;
    Current = oppo();
    L_Refresh = 0;
    printf("Black - %2d White - %2d\n", Num[1], Num[0]);
}

void Q()
{
    for (int i = 0; i < 8; ++i) printf("%s\n", Board[i]);
}

int main()
{
    scanf("%d", & Times);
    while (Times--)
    {
        for (int i = 0; i < 8; ++i) scanf("%s", Board[i]);
        scanf("\n%c", & Current);
        L_Refresh = 0;
        Num[0] = Num[1] = 0;
        for (int i = 0; i < 8; ++i)
            for (int j = 0; j < 8; ++j)
            {
                if (Board[i][j] == 'W') ++Num[0];
                else if (Board[i][j] == 'B') ++Num[1];
            }
        while (scanf("%s", Command) && Command[0] != 'Q')
            Command[0] == 'L' ? L(1) : M();
        Q();
        if (Times) printf("\n");
    }
    return 0;
}

 

你可能感兴趣的:(刘汝佳紫书)