【UVa】220 黑白棋

本文详细介绍了一种翻转棋游戏的AI算法实现过程,包括如何判断玩家在特定位置是否可以下子,如何列出所有合法的下子位置,以及如何执行玩家的下子操作并更新棋盘状态。通过具体的C语言代码示例,展示了算法的设计思路和实现细节。
摘要由CSDN通过智能技术生成
#include <stdio.h>
int Isok(char matrix[9][9], int x, int y, char player)
{//判断player能否在点(x,y)落子
    int x0 = x, y0 = y;
    while(y + 1 <= 8 && matrix[x][y+1] != '-' && matrix[x][y+1] != player)  y++;
    if(y > y0 && y+1<= 8 && matrix[x][y+1] == player)  return 1;  else y = y0;
    while(y+1 <= 8 && x+1 <= 8 && matrix[x+1][y+1] != '-' && matrix[x+1][y+1] != player) {x++; y++;}
    if(y > y0 && y+1<= 8 && x+1 <= 8 && matrix[x+1][y+1] == player)  return 1;  else {y = y0;  x = x0;}
    while(x + 1 <= 8 && matrix[x+1][y] != '-' && matrix[x+1][y] != player)  x++;
    if(x > x0 && x+1<= 8 && matrix[x+1][y] == player)  return 1;  else x = x0;
    while(y-1 >= 1 && x+1 <= 8 && matrix[x+1][y-1] != '-' && matrix[x+1][y-1] != player) {x++; y--;}
    if(y < y0 && y-1>= 1 && x+1 <= 8 && matrix[x+1][y-1] == player)  return 1;  else {y = y0;  x = x0;}
    while(y - 1 >= 1 && matrix[x][y-1] != '-' && matrix[x][y-1] != player)  y--;
    if(y < y0 && y-1 >= 1 && matrix[x][y-1] == player)  return 1;  else y = y0;
    while(y-1 >= 1 && x-1 >= 1 && matrix[x-1][y-1] != '-' && matrix[x-1][y-1] != player) {x--; y--;}
    if(y < y0 && y-1>= 1 && x-1 >= 1 && matrix[x-1][y-1] == player)  return 1;  else {y = y0;  x = x0;}
    while(x - 1 >= 1 && matrix[x-1][y] != '-' && matrix[x-1][y] != player)  x--;
    if(x < x0 && x-1 >= 1 && matrix[x-1][y] == player)  return 1;  else x = x0;
    while(y+1 <= 8 && x-1 >= 1 && matrix[x-1][y+1] != '-' && matrix[x-1][y+1] != player) {x--; y++;}
    if(y > y0 && y+1<= 8 && x-1 >= 1 && matrix[x-1][y+1] == player)  return 1;  else {y = y0;  x = x0;}
    return 0;
}

void List(char matrix[9][9], char player)
{//列出所有可落子的点
    int flag = 1, first = 1;
    for(int i = 1; i <= 8; i++)
    {
        for(int j = 1; j <= 8; j++)
        {
            if(matrix[i][j] == '-' && Isok(matrix, i, j, player) && first)  {printf("(%d,%d)", i, j); flag = first = 0;}
            else if(matrix[i][j] == '-' && Isok(matrix, i, j, player))  printf(" (%d,%d)", i, j);
        }
    }
    if(flag)  printf("No legal move.\n");
    else printf("\n");
}

void Move(char matrix[9][9], char *player, int x, int y)
{
    int flag = 0;
    if(matrix[x][y] == '-' && Isok(matrix, x, y, *player))  flag = 1; //判断可不可以落子
    if(!flag)
    {
        if(*player == 'B')  *player = 'W';  else  *player = 'B';
    }
    //无论怎样,已经可以落子,一定有别的子被吃掉
    matrix[x][y] = *player;
    int x0 = x, y0 = y;
    char against;
    if(*player == 'B')  against = 'W';   else against = 'B';
    //把夹住的敌方棋子吃掉
    //判断这条线是不是可以吃掉对方棋子的线
    while(y + 1 <= 8 && matrix[x][y+1] == against)  y++;  //一定是一直遇到against才会++,否则就退出
    if(y > y0 && y+1<= 8 && matrix[x][y+1] == *player)  //y > y0说明 退出之前一直都是黑子 y+1<=8 说明下一个位置有可能可以落子,是player就开始通吃
        for(int i=y0+1; i<=y; i++)
            matrix[x][i] = *player;
    y = y0;
    while(y+1 <= 8 && x+1 <= 8 && matrix[x+1][y+1] == against) {x++; y++;}
    if(y > y0 && y+1<= 8 && x+1 <= 8 && matrix[x+1][y+1] == *player)
        for(int i=x0+1, j=y0+1; i<=x; i++, j++)
            matrix[i][j] = *player;
    y = y0;  x = x0;
    while(x + 1 <= 8 && matrix[x+1][y] == against)  x++;
    if(x > x0 && x+1<= 8 && matrix[x+1][y] == *player)
        for(int i=x0+1; i <= x; i++)
            matrix[i][y] = *player;
    x = x0;
    while(y-1 >= 1 && x+1 <= 8 && matrix[x+1][y-1] == against) {x++; y--;}
    if(y < y0 && y-1>= 1 && x+1 <= 8 && matrix[x+1][y-1] == *player)
        for(int i = x0+1, j = y0-1; i <= x; i++, j--)
            matrix[i][j] = *player;
    y = y0;  x = x0;
    while(y - 1 >= 1 && matrix[x][y-1] == against)  y--;
    if(y < y0 && y-1 >= 1 && matrix[x][y-1] == *player)
        for(int j = y0-1; j >= y; j--)
            matrix[x][j] = *player;
    y = y0;
    while(y-1 >= 1 && x-1 >= 1 && matrix[x-1][y-1] == against) {x--; y--;}
    if(y < y0 && y-1>= 1 && x-1 >= 1 && matrix[x-1][y-1] == *player)
        for(int i = x0-1, j = y0-1; i >= x; i--, j--)
            matrix[i][j] = *player;
    y = y0;  x = x0;
    while(x - 1 >= 1 && matrix[x-1][y] == against)  x--;
    if(x < x0 && x-1 >= 1 && matrix[x-1][y] == *player)
        for(int i = x0-1; i >= x; i--)
            matrix[i][y] = *player;
    x = x0;
    while(y+1 <= 8 && x-1 >= 1 && matrix[x-1][y+1] == against) {x--; y++;}
    if(y > y0 && y+1<= 8 && x-1 >= 1 && matrix[x-1][y+1] == *player)
        for(int i = x0-1, j = y0+1; i >= x; i--, j++)
            matrix[i][j] = *player;

    int black = 0, white = 0;  //记得赋初值
    for(int i = 1; i <= 8; i++)
        for(int j = 1; j <= 8; j++)
        {
            if(matrix[i][j] == 'B')  black++;
            else if(matrix[i][j] == 'W')  white++;
        }
    printf("Black -%3d White -%3d\n", black, white);
    *player = against;
}

void Quit(char matrix[9][9])
{
    for(int i = 1; i <= 8; i++)
    {
        for(int j = 1; j <= 8; j++)
        {
            printf("%c", matrix[i][j]);
        }
        printf("\n");
    }
}

int main()
{
    int T, start = 0;
    scanf("%d", &T);
    getchar();
    while(T--)
    {
        char matrix[9][9], player, command[105][3];
        for(int i = 1; i <= 8; i++)
        {
            for(int j = 1; j <= 8; j++)
            {
                matrix[i][j] = getchar();
            }
            getchar();
        }
        player = getchar();
        getchar();
        int count = 1;
        command[0][0] = 'A';
        for(; command[count-1][0] != 'Q'; count++)
        {
            scanf("%s", command[count]);
            getchar();
        }
        for(int i = 1; i < count; i++)
        {
            if(command[i][0] == 'L')   {if(start) {start = 0; printf("\n");} List(matrix, player);  continue;}
            else if(command[i][0] == 'M')  {if(start) {start = 0; printf("\n");} Move(matrix, &player, command[i][1]-'0', command[i][2]-'0');  continue;}
            else if(command[i][0] == 'Q') {Quit(matrix);  start = 1;}
        }

    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值