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

原题链接:https://vjudge.net/problem/UVA-220
分类:递归、函数
备注:复杂模拟
前言:终于看到用了递归的题了…

代码如下:

#include
#include
const int dr[] = { -1,-1,-1,0,0,1,1,1 };//八连块
const int dc[] = { -1,0,1,-1,1,-1,0,1 };
char qp[10][10], op[10][10], cmd, cur, look;
char read()
{
	char ch = getchar();
	while (ch == ' ' || ch == '\n')ch = getchar();
	return ch;
}
int go(int tr, int tc, int row, int col, int type)//type=0表示list,type=1则为move
{
	int row2 = row + tr, col2 = col + tc;
	if (qp[row2][col2] == look)
		return go(tr, tc, row2, col2, type);
	if (!type && qp[row2][col2] == '-')
		return op[row2][col2] = 1;
	if (type && qp[row2][col2] == cur)
		return 1;
	return 0;
}
void List()
{
	memset(op, 0, sizeof(op));
	if (cur == 'W')look = 'B';
	else look = 'W';
	for (int i = 1; i <= 8; i++)
		for (int j = 1; j <= 8; j++)
			if (qp[i][j] == cur)
				for (int k = 0; k < 8; k++)
				{
					int row2 = i + dr[k], col2 = j + dc[k];
					if (qp[row2][col2] == look)
						go(dr[k], dc[k], row2, col2, 0);
				}
	int flag = 0;
	for(int i=1;i<=8;i++)
		for(int j=1;j<=8;j++)
			if (op[i][j])
			{
				if (flag)printf(" ");
				printf("(%d,%d)", i, j);
				flag = 1;
			}
	if (!flag)printf("No legal move.");
	printf("\n");
}
void draw(int tr,int tc,int row,int col)//翻转棋子
{
	if (qp[row][col] == cur)return;
	qp[row][col] = cur;
	draw(tr, tc, row + tr, col + tc);
}
void move()
{
	int row, col, flag = 0, w = 0, b = 0;
	row = read() - '0', col = read() - '0';
	if (cur == 'W')look = 'B';
	else look = 'W';
	for (int k = 0; k < 8; k++)
	{
		int row2 = row + dr[k], col2 = col + dc[k];
		if (qp[row2][col2] == look)
			if (go(dr[k], dc[k], row2, col2, 1))
			{
				draw(dr[k], dc[k], row2, col2);
				flag = 1;
			}
	}
	if (!flag)//如果目前下棋不合法则换人
	{
		char r = cur;
		cur = look;
		look = r;
		for (int k = 0; k < 8; k++)
		{
			int row2 = row + dr[k], col2 = col + dc[k];
			if (qp[row2][col2] == look)
				if (go(dr[k], dc[k], row2, col2, 1))
					draw(dr[k], dc[k], row2, col2);
		}
	}
	qp[row][col] = cur;
	cur = look;
	for (int i = 1; i <= 8; i++)
		for (int j = 1; j <= 8; j++)
			if (qp[i][j] == 'W')w++;
			else if (qp[i][j] == 'B')b++;
	printf("Black - %2d White - %2d\n", b, w);//注意格式
}
int main(void)
{
	int T;
	scanf("%d", &T);
	while(T--)
	{
		for (int i = 1; i <= 8; i++)
			for (int j = 1; j <= 8; j++)
				qp[i][j] = read();
		cur = read();
		while (1)
		{
			cmd = read();
			if (cmd == 'Q')
			{
				for (int i = 1; i <= 8; i++)
				{
					for (int j = 1; j <= 8; j++)
						printf("%c", qp[i][j]);
					printf("\n");
				}
				break;
			}
			if (cmd == 'L')List();
			if (cmd == 'M')move();
		}
		if(T)printf("\n");
	}
	return 0;
}

你可能感兴趣的:(《算法竞赛入门经典(第2版)》)