UVA220黑白棋题目详解

题目直通车

UVA220

题目大意

黑白翻转棋游戏,棋子落子的位置必须是能和同色棋包住异色棋的位置,放好后被包住的异色棋要进行翻转,翻转成同色棋。需要对三种指令进行处理。

L:打印所有合法操作,按照从上到下,从左到右的顺序排列。
Mrc:放一枚棋子在(r,c)点,如果这个棋子放在这个位子不合法,就切换出棋方(输入的这个位子保证是合法的,不用担心切换后也不合法)。打印黑棋白棋的个数。
Q:退出游戏,打印棋盘

题目思路

找合法点:从上到下依次遍历所有点。是‘-’则继续判断。
对于L操作把合法点进行标记,对于M操作,把中间的棋子翻转。

注意

这个题的输出的坑很多,要注意输出的格式,比如合法操作的那几个点,最后一个合法点后面不允许有空格!还有要注意黑棋白棋总数的输出格式。

AC代码

代码有点长:其中输入输出的代码比较多,读者不必感到害怕。

#include<iostream>
#include<string>
#include<cstring>
using namespace std;
char board[10][10];//记录棋盘
char now;//走棋方
char rever;//被翻方

int dir[8][2] = { { -1, 0 }, { -1, 1 }, { 0, 1 }, { 1, 1 }, { 1, 0 }, { 1, -1 }, { 0, -1 }, { -1, -1 } };
int print[10][10];//输出的标志
int num = 0;

bool check(int i, int j, char type)
{
	int flag2 = 0;
	for (int d = 0; d<8; ++d)   //遍历8个方向
	{
		int x = i + dir[d][0];
		int y = j + dir[d][1];
		int flag = 0;//执行循环体的标志
		while (x >= 1 && x <= 8 && y >= 1 && y <= 8 && board[x][y] == rever)
		{
			flag = 1;
			x += dir[d][0];
			y += dir[d][1];
		}
		if (flag == 1)
		{
			if (x >= 1 && x <= 8 && y >= 1 && y <= 8 && board[x][y] == now)
			{
				flag2 = 1;
				if (type == 'L')
				{
					print[i][j] = 1;//可以的解
					num++;return true;
				}
				else if (type == 'M')
				{
					for (int xx = i, yy = j; xx!=x||yy!=y;)
					{
						board[xx][yy] = now;
						xx += dir[d][0];
						yy += dir[d][1];
					}
				}
			}
		}
	}
	if (flag2 == 0)
		return false;
	else
		return true;
}
void myL()
{
	memset(print,0,sizeof(print));
	num = 0;
	bool h = 0;
	for (int i = 1; i<9; ++i)
	{
		for (int j = 1; j<9; ++j)
		{
			if (board[i][j] != '-')
			{
				continue;//这个点肯定放不了
			}
			else     //有机会
			{
				if (check(i, j, 'L'))
					h = 1;
			}
		}
	}
	if (h == 0)
	{
		printf("No legal move.\n");
	}
	//输出
	else
	{
		for (int i = 1; i<9; ++i)
		{
			for (int j = 1; j<9; ++j)
			{
				if (print[i][j] == 1)
				{
					printf("(%d,%d)", i, j);//输出
					num--;
					if (num != 0)
						printf(" ");
				}
			}
		}
		printf("\n");
	}
}
void myM(int a, int b)
{

	if (check(a, b, 'M') == false)
	{
		char temp = rever;
		rever = now;
		now = temp;
		check(a, b, 'M');
	}
	int bn = 0, wn = 0;
	for (int i = 1; i<9; ++i)
	{
		for (int j = 1; j<9; ++j)
		{
			if (board[i][j] == 'W')wn++;
			else if (board[i][j] == 'B')bn++;
		}
	}
	printf("Black - %2d White - %2d\n",bn,wn);

}
int main()
{
//	freopen("in.txt","r",stdin);
//	freopen("out.txt","w",stdout);
	int n;
	cin >> n;
	while (n--)
	{
		for (int i = 1; i<9; ++i)
		{
			for (int j = 1; j<9; ++j)
			{
				cin >> board[i][j];
			}
		}
		cin >> now;
		if (now == 'W')
		{
			rever = 'B';
		}
		else
		{
			rever = 'W';
		}
		string cmd;
		while (cin >> cmd&&cmd[0] != 'Q')
		{
			if (cmd[0] == 'L')
			{
				myL();
			}
			else if (cmd[0] == 'M')
			{
				int x = cmd[1] - '0';
				int y = cmd[2] - '0';
				myM(x, y);
				char temp = rever;
				rever = now;
				now = temp;
			}
		}
		for (int i = 1; i<9; ++i)
		{
			for (int j = 1; j<9; ++j)
			{
				printf("%c", board[i][j]);
			}
			printf("\n");
		}
		if(n)printf("\n"); 
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值