UVA 10196 - Check The Check (将军)

/*
* 题目的链接地址  http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=29&page=show_problem&problem=1137 
*
* 作者 仪冰
* QQ   974817955
*
* 题目描述
* 模拟棋盘。黑棋在棋盘的上半部分,用小写字母表示;白棋在下半部分,用大写字母表示。
* 一共有六种棋子。
* p ——> 只能走斜前方。即白棋只能走↖(左上),↗(右上);黑棋只能走↙(左下),↘(右下)
* r ——> 可以走垂直方向和水平方向上走,可以走任意格。
* b ——> 可以走对角线方向上走,可以走任意格。
* q ——> 可以走垂直方向、水平方向、对角线方向,可以走任意格。
* k ——> 可以走垂直方向、水平方向、对角线方向,只能走一格。
* n ——> 和中国象棋马的走法一样,走日字。(没有蹩马腿这个规则)
*
* 需要注意的是:
* 对于r、b、q这三种棋子,如果在他们的行走的方向上有其他的棋子,则不能继续走了。
*
* 输入样例
..k.....
ppp.pppp
........
.R...B..
........
........
PPPPPPPP
K.......

rnbqkbnr
pppppppp
........
........
........
........
PPPPPPPP
RNBQKBNR

rnbqk.nr
ppp..ppp
....p...
...p....
.bPP....
.....N..
PP..PPPP
RNBQKB.R

........
........
........
........
........
........
........
........
* 输出样例
Game #1: black king is in check.
Game #2: no king is in check.
Game #3: white king is in check.

* 自己的输入样例
R.pkp..R
..ppp...
.....B..
B..Q..Q.
........
...R....
........
........

R.pkp..R
.NpppN..
..N..B..
B..Q..Q.
........
...R....
.....P..
....K...
* 自己的输出样例
Game #1: no king is in check.
Game #2: black king is in check.
*/

#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

const int SIZEX = 9;   //棋盘行数
const int SIZEY = 9;   //棋盘列数

//这是Knight的边界数组, 在很多题目中都有用到边界数组
int coordinate[8][2] = {-1,-2, -2,-1, -2,1, -1,2, 1,2, 2,1, 2,-1, 1,-2};

/* 函数声明 */
bool blackChessPawn(char chess[SIZEX][SIZEY], int x, int y, char ch); //黑棋的pawn
bool whiteChessPawn(char chess[SIZEX][SIZEY], int x, int y, char ch); //白棋的pawn
bool Rook(char chess[SIZEX][SIZEY], int x, int y, char ch);           //黑白棋的Rook
bool Bishop(char chess[SIZEX][SIZEY], int x, int y, char ch);         //黑白棋的Bishop
bool Queen(char chess[SIZEX][SIZEY], int x, int y, char ch);          //黑白棋的Queen
bool Knight(char chess[SIZEX][SIZEY], int x, int y, char ch);         //黑白棋的Knight

int main()
{
    char chessBoard[SIZEX][SIZEY]; //棋盘
    int number = 0;                //计数器,判断是否结束程序
    bool boolean = false;          //判断是否将军
    int gameCount = 1;             //数据的组数

    while (true)
    {
        for (int i=1; i<9; i++)
        {
            for (int j=1; j<9; j++)
            {
                scanf("%c", &chessBoard[i][j]);
                if (chessBoard[i][j] == '.')
                {
                    number++;
                }
            }
            scanf("%*c");
        }

        //判断程序是否结束
        if (number == 64)
        {
            break;
        }
        number = 0;

        scanf("%*c");  //吸收一个换行

        for (int i=1; i<9; i++)
        {
            for (int j=1; j<9; j++)
            {
                switch (chessBoard[i][j])
                {
                    case 'p':
                         boolean = blackChessPawn(chessBoard, i, j, 'K');
                         if (boolean)
                         {
                             cout << "Game #" << gameCount
                                  << ": white king is in check." << endl;
                         }
                         break;
                    case 'P':
                         boolean = whiteChessPawn(chessBoard, i, j, 'k');
                         if (boolean)
                         {
                             cout << "Game #" << gameCount
                                  << ": black king is in check." << endl;
                         }
                         break;
                    case 'r':
                         boolean = Rook(chessBoard, i, j, 'K');
                         if (boolean)
                         {
                             cout << "Game #" << gameCount
                                  << ": white king is in check." << endl;
                         }
                         break;
                    case 'R':
                         boolean = Rook(chessBoard, i, j, 'k');
                         if (boolean)
                         {
                             cout << "Game #" << gameCount
                                  << ": black king is in check." << endl;
                         }
                         break;
                    case 'b':
                         boolean = Bishop(chessBoard, i, j, 'K');
                         if (boolean)
                         {
                             cout << "Game #" << gameCount
                                  << ": white king is in check." << endl;
                         }
                         break;
                    case 'B':
                         boolean = Bishop(chessBoard, i, j, 'k');
                         if (boolean)
                         {
                             cout << "Game #" << gameCount
                                  << ": black king is in check." << endl;
                         }
                         break;
                    case 'q':
                         boolean = Queen(chessBoard, i, j, 'K');
                         if (boolean)
                         {
                             cout << "Game #" << gameCount
                                  << ": white king is in check." << endl;
                         }
                         break;
                    case 'Q':
                         boolean = Queen(chessBoard, i, j, 'k');
                         if (boolean)
                         {
                             cout << "Game #" << gameCount
                                  << ": black king is in check." << endl;
                         }
                         break;
                    case 'n':
                         boolean = Knight(chessBoard, i, j, 'K');
                         if (boolean)
                         {
                             cout << "Game #" << gameCount
                                  << ": white king is in check." << endl;
                         }
                         break;
                    case 'N':
                         boolean = Knight(chessBoard, i, j, 'k');
                         if (boolean)
                         {
                             cout << "Game #" << gameCount
                                  << ": black king is in check." << endl;
                         }
                         break;
                    default : break;
                }

                if (boolean)
                {
                    break;
                }
            }

            if (boolean)
            {
                break;
            }
        }

        if (!boolean)
        {
            cout<< "Game #" << gameCount << ": no king is in check." << endl;
        }
        else
        {
            boolean = false;
        }

        gameCount++;
    }
    return 0;
}

/* 函数实现 */
bool blackChessPawn(char chess[SIZEX][SIZEY], int x, int y, char ch) //黑棋的pawn
{
    int xx, yy;
    xx = x+1;
    yy = y-1;
    if ((xx>=1) && (xx<=8) && (yy>=1) && (yy<=8) && (chess[xx][yy] == ch))
    {
        return true;
    }

    yy = y+1;
    if ((xx>=1) && (xx<=8) && (yy>=1) && (yy<=8) && (chess[xx][yy] == ch))
    {
        return true;
    }

    return false;   //没有构成将军
}

bool whiteChessPawn(char chess[SIZEX][SIZEY], int x, int y, char ch) //白棋的pawn
{
    int xx, yy;
    xx = x-1;
    yy = y-1;
    if ((xx>=1) && (xx<=8) && (yy>=1) && (yy<=8) && (chess[xx][yy] == ch))
    {
        return true;
    }

    yy = y+1;
    if ((xx>=1) && (xx<=8) && (yy>=1) && (yy<=8) && (chess[xx][yy] == ch))
    {
        return true;
    }

    return false;      //没有构成将军
}

bool Rook(char chess[SIZEX][SIZEY], int x, int y, char ch)           //黑白棋的Rook
{
    int i;

    //判断垂直方向上半段
    for (i=x-1; i>=1; i--)
    {
        if (chess[i][y] == ch)
        {
            return true;
        }

        if (chess[i][y] != '.')  //如果有阻碍物
        {
            break;
        }
    }

    //判断垂直方向下半段
    for (i=x+1; i<=8; i++)
    {
        if (chess[i][y] == ch)
        {
            return true;
        }

        if (chess[i][y] != '.')  //如果有阻碍物
        {
            break;
        }
    }

    //判断水平方向左半段
    for (i=y-1; i>=1; i--)
    {
        if (chess[x][i] == ch)
        {
            return true;
        }

        if (chess[x][i] != '.')  //如果有阻碍物
        {
            break;
        }
    }

    //判断水平方向右半段
    for (i=y+1; i<=8; i++)
    {
        if (chess[x][i] == ch)
        {
            return true;
        }

        if (chess[x][i] != '.')  //如果有阻碍物
        {
            break;
        }
    }

    return false;     //没有构成将军
}

bool Bishop(char chess[SIZEX][SIZEY], int x, int y, char ch)         //黑白棋的Bishop
{
    int xx;     //行数
    int yy;     //列数
    int Min;    //最小值。8*8的图中,行数和列数相同
    int startX; //开始行
    //int startY; //开始列
    int i, j;

    //判断左上角
    xx = x-1;
    yy = y-1;
    if (xx < yy)
    {
        Min = xx;
    }
    else
    {
        Min = yy;
    }
    startX = x-Min;
    //startY = y-Min;
    //for (i=startX, j=startY; i<x; i++, j++)
    for (i=x-1, j=y-1; i>=startX; i--, j--)
    {
        if (chess[i][j] == ch)
        {
            return true;
        }

        if (chess[i][j] != '.')    //如果有障碍物
        {
            break;
        }
    }

    //判断右上角
    xx = x-1;
    yy = 8-y;
    if (xx < yy)
    {
        Min = xx;
    }
    else
    {
        Min = yy;
    }
    startX = x-Min;
    //startY = y+Min;
    //for (i=startX, j=startY; i<x; i++, j--)
    for (i=x-1, j=y+1; i>=startX; i--, j++)
    {
        if (chess[i][j] == ch)
        {
            return true;
        }

        if (chess[i][j] != '.')   //如果有障碍物
        {
            break;
        }
    }

    //判断左下角
    xx = 8-x;
    yy = y-1;
    if (xx < yy)
    {
        Min = xx;
    }
    else
    {
        Min = yy;
    }
    startX = x+Min;
    //startY = y-Min;
    //for (i=startX, j=startY; j<y; i--, j++)
    for (i=x+1, j=y-1; i<=startX; i++, j--)
    {
        if (chess[i][j] == ch)
        {
            return true;
        }

        if (chess[i][j] != '.')      //如果有障碍物
        {
            break;
        }
    }

    //判断右下角
    xx = 8-x;
    yy = 8-y;
    if (xx < yy)
    {
        Min = xx;
    }
    else
    {
        Min = yy;
    }
    startX = x+Min;
    //startY = y+Min;
    //for (i=startX, j=startY; i>x; i--, j--)
    for (i=x+1, j=y+1; i<=startX; i++, j++)
    {
        if (chess[i][j] == ch)
        {
            return true;
        }

        if (chess[i][j] != '.')    //如果有障碍物
        {
            break;
        }
    }

    return false;  //不构成将军
}

bool Queen(char chess[SIZEX][SIZEY], int x, int y, char ch)          //黑白棋的Queen
{
    int xx;     //行数
    int yy;     //列数
    int Min;    //最小值。8*8的图中,行数和列数相同
    int startX; //开始行
    //int startY; //开始列
    int i, j;

    //判断左上角
    xx = x-1;
    yy = y-1;
    if (xx < yy)
    {
        Min = xx;
    }
    else
    {
        Min = yy;
    }
    startX = x-Min;
    //startY = y-Min;
    //for (i=startX, j=startY; i<x; i++, j++)
    for (i=x-1, j=y-1; i>=startX; i--, j--)
    {
        if (chess[i][j] == ch)
        {
            return true;
        }

        if (chess[i][j] != '.')    //如果有障碍物
        {
            break;
        }
    }

    //判断右上角
    xx = x-1;
    yy = 8-y;
    if (xx < yy)
    {
        Min = xx;
    }
    else
    {
        Min = yy;
    }
    startX = x-Min;
    //startY = y+Min;
    //for (i=startX, j=startY; i<x; i++, j--)
    for (i=x-1, j=y+1; i>=startX; i--, j++)
    {
        if (chess[i][j] == ch)
        {
            return true;
        }

        if (chess[i][j] != '.')   //如果有障碍物
        {
            break;
        }
    }

    //判断左下角
    xx = 8-x;
    yy = y-1;
    if (xx < yy)
    {
        Min = xx;
    }
    else
    {
        Min = yy;
    }
    startX = x+Min;
    //startY = y-Min;
    //for (i=startX, j=startY; j<y; i--, j++)
    for (i=x+1, j=y-1; i<=startX; i++, j--)
    {
        if (chess[i][j] == ch)
        {
            return true;
        }

        if (chess[i][j] != '.')      //如果有障碍物
        {
            break;
        }
    }

    //判断右下角
    xx = 8-x;
    yy = 8-y;
    if (xx < yy)
    {
        Min = xx;
    }
    else
    {
        Min = yy;
    }
    startX = x+Min;
    //startY = y+Min;
    //for (i=startX, j=startY; i>x; i--, j--)
    for (i=x+1, j=y+1; i<=startX; i++, j++)
    {
        if (chess[i][j] == ch)
        {
            return true;
        }

        if (chess[i][j] != '.')    //如果有障碍物
        {
            break;
        }
    }

    //判断垂直方向上半段
    for (i=x-1; i>=1; i--)
    {
        if (chess[i][y] == ch)
        {
            return true;
        }

        if (chess[i][y] != '.')  //如果有阻碍物
        {
            break;
        }
    }

    //判断垂直方向下半段
    for (i=x+1; i<=8; i++)
    {
        if (chess[i][y] == ch)
        {
            return true;
        }

        if (chess[i][y] != '.')  //如果有阻碍物
        {
            break;
        }
    }

    //判断水平方向左半段
    for (i=y-1; i>=1; i--)
    {
        if (chess[x][i] == ch)
        {
            return true;
        }

        if (chess[x][i] != '.')  //如果有阻碍物
        {
            break;
        }
    }

    //判断水平方向右半段
    for (i=y+1; i<=8; i++)
    {
        if (chess[x][i] == ch)
        {
            return true;
        }

        if (chess[x][i] != '.')  //如果有阻碍物
        {
            break;
        }
    }

    return false;   //没有构成将军
}

bool Knight(char chess[SIZEX][SIZEY], int x, int y, char ch)         //黑白棋的Knight
{
    int i;
    int xx, yy;
    for (i=0; i<8; i++)
    {
        xx = x+coordinate[i][0];
        yy = y+coordinate[i][1];

        if (chess[xx][yy] == ch)
        {
            return true;
        }
    }

    return false;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值