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

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

代码如下:

#include<stdio.h>
#include<string.h>
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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JILIN.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值