110107 Check The Check


#include <stdio.h>
#include <vector>

using namespace std;

#define DIM_SIZE (8 + 2 + 2)
#define LINE_SIZE 8
#define DELTA ((DIM_SIZE - LINE_SIZE) / 2)

enum ChessType_t
{
	BLACK = 0,
	WHITE
};

class Chess
{
public:
	typedef Chess* ChessPtr;
	typedef ChessPtr ChessCol[DIM_SIZE][DIM_SIZE];

	Chess(int row, int col, ChessType_t type) : m_Row(row), m_Col(col), m_type(type)
	{
	}

	virtual ~Chess()
	{
	}

	virtual bool Check(ChessCol& chessCol) = 0;
	ChessType_t GetType() { return m_type; }

protected:
	virtual bool IsKing() { return false; }

	bool DoCheck(ChessCol& chessCol, int row, int col, bool& blocked)
	{
		blocked = false;
		ChessPtr& pChess = chessCol[row][col];
		if (!pChess)
			return false;

		blocked = true;
		if ((pChess->m_type != m_type) && (pChess->IsKing()))
			return true;
		return false;
	}

protected:
	int m_Row, m_Col;
	ChessType_t m_type;
};

class P : public Chess // Soldier
{
public:
	P(int row, int col, ChessType_t type) : Chess(row, col, type)
	{
	}
	virtual bool Check(ChessCol& chessCol)
	{
		bool dummy;
		if (BLACK == m_type)
			return (DoCheck(chessCol, m_Row + 1, m_Col - 1, dummy) || DoCheck(chessCol, m_Row + 1, m_Col + 1, dummy));
		return (DoCheck(chessCol, m_Row - 1, m_Col - 1, dummy) || DoCheck(chessCol, m_Row - 1, m_Col + 1, dummy));
	}
};

class N : public Chess // Horse
{
public:
	N(int row, int col, ChessType_t type) : Chess(row, col, type)
	{
	}
	virtual bool Check(ChessCol& chessCol)
	{
		bool dummy;
		return (DoCheck(chessCol, m_Row - 1, m_Col - 2, dummy) || 
			DoCheck(chessCol, m_Row - 1, m_Col + 2, dummy) ||
			DoCheck(chessCol, m_Row - 2, m_Col - 1, dummy) ||
			DoCheck(chessCol, m_Row - 2, m_Col + 1, dummy) ||
			DoCheck(chessCol, m_Row + 1, m_Col - 2, dummy) ||
			DoCheck(chessCol, m_Row + 1, m_Col + 2, dummy) ||
			DoCheck(chessCol, m_Row + 2, m_Col - 1, dummy) ||
			DoCheck(chessCol, m_Row + 2, m_Col + 1, dummy));
	}
};

class B : virtual public Chess // Elephant
{
public:
	B(int row, int col, ChessType_t type) : Chess(row, col, type)
	{
	}
	virtual bool Check(ChessCol& chessCol)
	{
		// Left Upper
		bool blocked = false;
		int curRow = m_Row - 1, curCol = m_Col - 1;
		while(!blocked) 
		{
			if ((curRow < DELTA) || (curCol < DELTA))
				break;

			if (DoCheck(chessCol, curRow, curCol, blocked))
				return true;
			--curRow;
			--curCol;
		}

		// Right Upper
		blocked = false;
		curRow = m_Row - 1;
		curCol = m_Col + 1;
		while(!blocked) 
		{
			if ((curRow < DELTA) || (curCol >= (DELTA + LINE_SIZE)))
				break;

			if (DoCheck(chessCol, curRow, curCol, blocked))
				return true;
			--curRow;
			++curCol;
		}

		// Left Below
		blocked = false;
		curRow = m_Row + 1;
		curCol = m_Col - 1;
		while(!blocked) 
		{
			if ((curRow >= (DELTA + LINE_SIZE)) || (curCol < DELTA))
				break;

			if (DoCheck(chessCol, curRow, curCol, blocked))
				return true;
			++curRow;
			--curCol;
		}

		// Right Below
		blocked = false;
		curRow = m_Row + 1;
		curCol = m_Col + 1;
		while(!blocked) 
		{
			if ((curRow >= (DELTA + LINE_SIZE)) || (curCol >= (DELTA + LINE_SIZE)))
				break;

			if (DoCheck(chessCol, curRow, curCol, blocked))
				return true;
			++curRow;
			++curCol;
		}

		return false;
	}
};

class R : virtual public Chess // Car
{
public:
	R(int row, int col, ChessType_t type) : Chess(row, col, type)
	{
	}
	virtual bool Check(ChessCol& chessCol)
	{
		// Left
		bool blocked = false;
		int curCol = m_Col - 1;
		while(!blocked) 
		{
			if (curCol < DELTA)
				break;

			if (DoCheck(chessCol, m_Row, curCol, blocked))
				return true;
			--curCol;
		}

		// Right
		blocked = false;
		curCol = m_Col + 1;
		while(!blocked) 
		{
			if (curCol >= (DELTA + LINE_SIZE))
				break;

			if (DoCheck(chessCol, m_Row, curCol, blocked))
				return true;
			++curCol;
		}

		// Upper
		blocked = false;
		int curRow = m_Row - 1;
		while(!blocked) 
		{
			if (curRow < DELTA)
				break;

			if (DoCheck(chessCol, curRow, m_Col, blocked))
				return true;
			--curRow;
		}

		// Below
		blocked = false;
		curRow = m_Row + 1;
		while(!blocked) 
		{
			if (curRow >= (DELTA + LINE_SIZE))
				break;

			if (DoCheck(chessCol, curRow, m_Col, blocked))
				return true;
			++curRow;
		}

		return false;
	}
};

class Q : public B, public R // Queen
{
public:
	Q(int row, int col, ChessType_t type) : Chess(row, col,  type), B(row, col,  type), R(row, col,  type)
	{
	}
	virtual bool Check(ChessCol& chessCol)
	{
		return (B::Check(chessCol) || R::Check(chessCol));
	}
};

class K : public Chess
{
public:
	K(int row, int col, ChessType_t type) : Chess(row, col, type)
	{
	}
	virtual bool Check(ChessCol& chessCol)
	{
		bool dummy;
		for (int i = m_Col - 1; i <= m_Col + 1; ++i)
		{
			if (DoCheck(chessCol, m_Row - 1, i, dummy)) // Upper
				return true;
			if (DoCheck(chessCol, m_Row + 1, i, dummy)) // Below
				return true;
		}

		// Left & Right
		return (DoCheck(chessCol, m_Row, m_Col - 1, dummy) ||
			DoCheck(chessCol, m_Row, m_Col + 1, dummy));
	}

	virtual bool IsKing() { return true; }
};

class ChessPanel
{
public:
	ChessPanel(int index) : m_ValidChessCnt(0), m_Index(index)
	{
		for(int i = 0; i < DIM_SIZE; ++i)
		{
			for(int j = 0; j < DIM_SIZE; ++j)
			{
				m_ChessCol[i][j] = NULL;
			}
		}
	}

	~ChessPanel()
	{
		for(int i = 0; i < DIM_SIZE; ++i)
		{
			for(int j = 0; j < DIM_SIZE; ++j)
			{
				if (m_ChessCol[i][j])
					delete m_ChessCol[i][j];
			}
		}
	}

	void Input(char* pLine, int lineNo)
	{
		int cnt = 0;
		for (int i = 0; i < LINE_SIZE; ++i)
		{
			int row = DELTA + lineNo, col = DELTA + i;
			Chess::ChessPtr& pChess = m_ChessCol[row][col];
			switch(pLine[i])
			{
			case 'p':
				pChess = new P(row, col, BLACK);
				++cnt;
				break;
			case 'P':
				pChess = new P(row, col, WHITE);
				++cnt;
				break;

			case 'n':
				pChess = new N(row, col, BLACK);
				++cnt;
				break;
			case 'N':
				pChess = new N(row, col, WHITE);
				++cnt;
				break;

			case 'b':
				pChess = new B(row, col, BLACK);
				++cnt;
				break;
			case 'B':
				pChess = new B(row, col, WHITE);
				++cnt;
				break;

			case 'r':
				pChess = new R(row, col, BLACK);
				++cnt;
				break;
			case 'R':
				pChess = new R(row, col, WHITE);
				++cnt;
				break;

			case 'q':
				pChess = new Q(row, col, BLACK);
				++cnt;
				break;
			case 'Q':
				pChess = new Q(row, col, WHITE);
				++cnt;
				break;

			case 'k':
				pChess = new K(row, col, BLACK);
				++cnt;
				break;
			case 'K':
				pChess = new K(row, col, WHITE);
				++cnt;
				break;

			default:
				pChess = NULL;
				break;
			}
		}
		m_ValidChessCnt += cnt;
	}

	bool IsValid()
	{
		return (m_ValidChessCnt > 0);
	}

	void Check()
	{
		for (int i = DELTA; i < (DELTA + LINE_SIZE); ++i)
		{
			for (int j = DELTA; j < (DELTA + LINE_SIZE); ++j)
			{
				if (!m_ChessCol[i][j])
					continue;
				if (!m_ChessCol[i][j]->Check(m_ChessCol))
					continue;

				if (BLACK == m_ChessCol[i][j]->GetType())
				{
					printf("Game #%d: white king is in check.\n", m_Index);
					return;
				}

				printf("Game #%d: black king is in check.\n", m_Index);
				return;
			}
		}

		printf("Game #%d: no king is in check.\n", m_Index);
	}

private:
	Chess::ChessCol m_ChessCol;
	int m_ValidChessCnt;
	int m_Index;
};

void Input(vector<ChessPanel*>& chessPanelCol)
{
	char buf[DIM_SIZE];
	int index = 1;
	while(true)
	{
		ChessPanel* pPanel = new ChessPanel(index);
		for (int i = 0; i < LINE_SIZE; ++i)
		{
			fgets(buf, DIM_SIZE, stdin);
			pPanel->Input(buf, i);
		}

		if (pPanel->IsValid())
		{
			fgets(buf, DIM_SIZE, stdin); // Consume the empty line.
			++index;
			chessPanelCol.push_back(pPanel);
			continue;
		}

		delete pPanel;
		return;
	}
}

void Check(vector<ChessPanel*>& chessPanelCol)
{
	for (size_t i = 0; i < chessPanelCol.size(); ++i)
	{
		chessPanelCol[i]->Check();
	}
}

void Clear(vector<ChessPanel*>& chessPanelCol)
{
	for (size_t i = 0; i < chessPanelCol.size(); ++i)
	{
		delete chessPanelCol[i];
	}

	chessPanelCol.clear();
}

int main(int argc, char* argv[])
{
	vector<ChessPanel*> chessPanelCol;
	Input(chessPanelCol);
	Check(chessPanelCol);
	Clear(chessPanelCol);
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值