소감

2005/03/13 Accepted 0:00.010 64
깔끔하게 짜려고 했는데 의외로 지저분해졌다.
처음엔 모든 말의 위치를 기준으로 검사를 하려고 했는데 굳이 그럴필요 없이 왕의 위치를 기준으로 검사를 하면 더 간단할것 같아 그렇게 짰다.
toupper를 쓰려면 ctype.h를 include해야한다.
나중에 리팩토링을 해봐야겠다.

소스

~cpp 
#include <iostream>
using namespace std;
#include <ctype.h>

const int EMPTY = 0;
const int BLACK = 1;
const int WHITE = 2;

char board[8][8];

int whereSide(int y, int x)
{
	if (board[y][x] >= 'a' && board[y][x] <= 'z')
		return BLACK;
	else if (board[y][x] >= 'A' && board[y][x] <= 'Z')
		return WHITE;
	else
		return EMPTY;
}

bool isInBoard(int y, int x)
{
	if (y >= 0 && y < 8 && x >= 0 && x < 8)
		return true;
	return false;
}

bool PawnCheck(int y, int x, int side)
{
	if (side == WHITE)
	{
		if (isInBoard(y - 1, x - 1) && board[y - 1][x - 1] == 'p')
			return true;
		else if (isInBoard(y - 1, x + 1) && board[y - 1][x + 1] == 'p')
			return true;
	}
	else
	{
		if (isInBoard(y + 1, x - 1) && board[y + 1][x - 1] == 'P')
			return true;
		else if (isInBoard(y + 1, x - 1) && board[y + 1][x + 1] == 'P')
			return true;
	}
	return false;
}

bool RookCheck(int y, int x, int side)
{
	int move[4][2] = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}};
	int i, k;
	for (k = 0; k < 4; k++)
	{
		for (i = 1; i <= 7 && isInBoard(y + i * move[k][0], x + i * move[k][1]); i++)
		{
			if (board[y + i * move[k][0]][x + i * move[k][1]] == EMPTY)
				continue;
			else if (whereSide(y + i * move[k][0], x + i * move[k][1]) == side)
				break;
			else
			{
				if (toupper(board[y + i * move[k][0]][x + i * move[k][1]]) == 'R')
					return true;
				else
					break;
			}
		}
	}
	return false;
}

bool BishopCheck(int y, int x, int side)
{
	int move[4][2] = {{-1, 1}, {1, 1}, {1, -1}, {-1, -1}};
	int i, k;
	for (k = 0; k < 4; k++)
	{
		for (i = 1; i <= 7 && isInBoard(y + i * move[k][0], x + i * move[k][1]); i++)
		{
			if (board[y + i * move[k][0]][x + i * move[k][1]] == EMPTY)
				continue;
			else if (whereSide(y + i * move[k][0], x + i * move[k][1]) == side)
				break;
			else
			{
				if (toupper(board[y + i * move[k][0]][x + i * move[k][1]]) == 'B')
					return true;
				else
					break;
			}
		}
	}
	return false;

}

bool QueenCheck(int y, int x, int side)
{
	int move[8][2] = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}, {-1, 1}, {1, 1}, {1, -1}, {-1, -1}};
	int i, k;
	for (k = 0; k < 8; k++)
	{
		for (i = 1; i <= 7 && isInBoard(y + i * move[k][0], x + i * move[k][1]); i++)
		{
			if (board[y + i * move[k][0]][x + i * move[k][1]] == EMPTY)
				continue;
			else if (whereSide(y + i * move[k][0], x + i * move[k][1]) == side)
				break;
			else
			{
				if (toupper(board[y + i * move[k][0]][x + i * move[k][1]]) == 'Q')
					return true;
				else
					break;
			}
		}
	}
	return false;
}

bool KingCheck(int y, int x, int side)
{
	int move[8][2] = {{-1, 0}, {-1, 1}, {0, 1}, {1, 1}, {1, 0}, {1, -1}, {0, -1}, {-1, -1}};
	int k;
	for (k = 0; k < 8; k++)
	{
		if (isInBoard(y + move[k][0], x + move[k][1]))
		{
			if (whereSide(y + move[k][0], x + move[k][1]) != side && toupper(board[y + move[k][0]][x + move[k][1]]) == 'K')
					return true;
		}
	}
	return false;

}
bool KnightCheck(int y, int x, int side)
{
	int move[8][2] = {{-2, 1}, {-1, 2}, {1, 2}, {2, 1}, {2, -1}, {1, -2}, {-1, -2}, {-2, -1}};
	int k;
	for (k = 0; k < 8; k++)
	{
		if (isInBoard(y + move[k][0], x + move[k][1]))
		{
			if (whereSide(y + move[k][0], x + move[k][1]) != side && toupper(board[y + move[k][0]][x + move[k][1]]) == 'N')
					return true;
		}
	}
	return false;
}



bool isInCheck(int y, int x, int side)
{
        if (PawnCheck(y, x, side))
			return true;
		if (RookCheck(y, x, side))
			return true;
		if (BishopCheck(y, x, side))
			return true;
		if (QueenCheck(y, x, side))
			return true;
		if (KingCheck(y, x, side))
			return true;
		if (KnightCheck(y, x, side))
			return true;
		return false;
}

int main()
{
        int i, j;
        bool isEmpty;
        int gameCnt = 0;

        while (true)
        {
            gameCnt++;
			isEmpty = true;
            for (i = 0; i < 8; i++)
				cin >> board[i];

            for (i = 0; i < 8; i++)
                for (j = 0; j < 8; j++)
				{
					if (board[i][j] == '.')
						board[i][j] = EMPTY;
                    if (whereSide(i, j) != EMPTY)
                    {
                            isEmpty = false;
                    }
				}

            if (isEmpty)
                    break;
            for (i = 0; i < 8; i++)
                for (j = 0; j < 8; j++)
				{
					if ((board[i][j] == 'K' || board[i][j] == 'k') && isInCheck(i, j, whereSide(i, j)))
					{
					
						if (whereSide(i, j) == WHITE)
						{
							cout << "Game #" << gameCnt << ": white king is in check." << endl;
							i = 8;
							break;;
						}
						else
						{
							cout << "Game #" << gameCnt << ": black king is in check." << endl;
							i = 8;
							break;;
						}
					}
				}
			if (i == 8)
				cout << "Game #" << gameCnt << ": no king is in check." << endl;
        }
        return 0;
}

댓글

Retrieved from http://wiki.zeropage.org/wiki.php/CheckTheCheck/곽세환
last modified 2021-02-07 05:22:51