UVa 220 Othello

 Othello 

Othello is a game played by two people on an 8 x 8 board, using disks that are white on one side and black on the other. One player places disks with the white side up and the other player places disks with the black side up. The players alternate placing one disk on an unoccupied space on the board. In placing a disk, the player must bracket at least one of the other color disks. Disks are bracketed if they are in a straight line horizontally, vertically, or diagonally, with a disk of the current player's color at each end of the line. When a move is made, all the disks that were bracketed are changed to the color of the player making the move. (It is possible that disks will be bracketed across more than one line in a single move.)

tex2html_wrap73 tex2html_wrap75

Write a program to read a series of Othello games. The first line of the input is the number of games to be processed. Each game consists of a board configuration followed by a list of commands. The board configuration consists of 9 lines. The first 8 specify the current state of the board. Each of these 8 lines contains 8 characters, and each of these characters will be one of the following:

 
		    `-' 		 indicating an unoccupied square

`B' indicating a square occupied by a black disk

`W' indicating a square occupied by a white disk

The ninth line is either a `B' or a `W' to indicate which is the current player. You may assume that the data is legally formatted.

The commands are to list all possible moves for the current player, make a move, or quit the current game. There is one command per line with no blanks in the input. Commands are formatted as follows:

List all possible moves for the current player.
The command is an ` L' in the first column of the line. The program should go through the board and print all legal moves for the current player in the format ( x, y) where  x represents the row of the legal move and  y represents its column. These moves should be printed in row major order which means:

1)
all legal moves in row number  i will be printed before any legal move in row number  j if  j is greater than  i
and 2)
if there is more than one legal move in row number  i, the moves will be printed in ascending order based on column number.

All legal moves should be put on one line. If there is no legal move because it is impossible for the current player to bracket any pieces, the program should print the message ``No legal move."

Make a move.
The command is an ` M' in the first column of the line, followed by 2 digits in the second and third column of the line. The digits are the row and the column of the space to place the piece of the current player's color,  unless the current player has no legal move. If the current player has no legal move, the current player is first changed to the other player and the move will be the move of the new current player. You may assume that the move is then legal. You should record the changes to the board, including adding the new piece and changing the color of all bracketed pieces. At the end of the move, print the number of pieces of each color on the board in the format `` Black - xx White - yy" where  xx is the number of black pieces on the board and  yy is the number of white pieces on the board. After a move, the current player will be changed to the player that did not move.

Quit the current game.
The command will be a ` Q' in the first column of the line. At this point, print the final board configuration using the same format as was used in the input. This terminates input for the current game.

You may assume that the commands will be syntactically correct. Put one blank line between output from separate games and no blank lines anywhere else in the output.

Sample Input

2
--------
--------
--------
---WB---
---BW---
--------
--------
--------
W
L
M35
L
Q
WWWWB---
WWWB----
WWB-----
WB------
--------
--------
--------
--------
B
L
M25
L
Q

Sample Output

(3,5) (4,6) (5,3) (6,4)
Black -  1 White -  4
(3,4) (3,6) (5,6)
--------
--------
----W---
---WW---
---BW---
--------
--------
--------

No legal move.
Black -  3 White - 12
(3,5)
WWWWB---
WWWWW---
WWB-----
WB------
--------
--------
--------
--------
 
#include "stdio.h"
#include "string.h"

char chess[10][10];

int legal_move(int x, int y);
void change_chess(int x, int y);
char now_turn;
char ver_turn;

int main()
{
	int n;
	int count = 0;
	scanf("%d", &n);
	while(count < n)
	{
		count++;
		if(count != 1)
			printf("\n");
		// 先记录初始棋盘
		memset(chess, 0, sizeof(chess));
		int i;
		char str[10];
		for(i = 1; i <= 8; i++)
		{		
			memset(str, 0, sizeof(str));
			scanf("%s", str);
			for(int j = 0; j < 8; j++)
				chess[i][j+1] = str[j];
		}
		memset(str, 0, sizeof(str));
		scanf("%s", str);
		// 记录现在的走方
		now_turn = str[0];
		// 记录现在不走的一方
		if(now_turn == 'B')
			ver_turn = 'W';
		else
			ver_turn = 'B';
		while(1)
		{
			memset(str, 0, sizeof(str));
			scanf("%s", str);
			// 如果是查看可走的地方
			if(str[0] == 'L')
			{
				int l_count = 0;
				for(int i = 1; i <= 8; i++)
				{
					for(int j = 1; j <= 8; j++)
					{
						if(legal_move(i, j))
						{
							l_count++;
							if(l_count == 1)
								printf("(%d,%d)", i, j);
							else
								printf(" (%d,%d)", i, j);
						}
					}
				}
				if(l_count == 0)
					printf("No legal move.");
				printf("\n");
			}	
			// 如果是走棋
			else if(str[0] == 'M')
			{
				int x = str[1] - '0';
				int y = str[2] - '0';
				//如果该步棋合法,就走,并且改变棋盘
				if(legal_move(x, y))
				{
					change_chess(x, y);	
				}	
				// 如果不合法,就让对手走这步棋,并改变棋盘
				else
				{
					char tmp = now_turn;
					now_turn = ver_turn;
					ver_turn = tmp;
					change_chess(x, y);
				}
			
				// 统计棋盘上的黑白子数
				int b_count = 0;	
				int w_count = 0;
				for(int a = 1; a <= 8; a++)	
				{
					for(int b = 1; b <= 8; b++)
					{
						if(chess[a][b] == 'B')
							b_count++;
						else if(chess[a][b] == 'W')
							w_count++;
					}
				}
				printf("Black - %2d White - %2d\n", b_count, w_count);

				// 改变对手
				char tmp = now_turn;
                              	now_turn = ver_turn;
                              	ver_turn = tmp;
			}
			// 如果退出
                        else if(str[0] == 'Q')
                        {	
				// 打印棋盘
				for(int a = 1; a <= 8; a++)
				{
					for(int b = 1; b <= 8; b++)
						printf("%c", chess[a][b]);
					printf("\n");
				}
				break;
			}
		}
		
		
	}	
}


// 用该步棋改变棋盘
void change_chess(int x, int y)
{
	// 改变该地方的棋
	chess[x][y] = now_turn;

	// 八个方向,检查是否可以走
	// 1.检查正上方
	int end = 0;
	int i = x - 1;
	while(i >= 1 && chess[i][y] == ver_turn)
	{
		i--;
		end++;
	}
	// 改变棋盘
	if(end > 0 && x-end-1 >= 1 && chess[x-end-1][y] == now_turn)
	{
		for(int k = x-1; k >= x-end; k--)
			chess[k][y] = now_turn;
	}

	// 2.检查正下方
	end = 0;
	i = x + 1;
	while(i <= 8 && chess[i][y] == ver_turn)
        {
                i++;
                end++;
        }
        if(end > 0 && x+end+1 <= 8 && chess[x+end+1][y] == now_turn)
	{
                for(int k = x+1; k <= x+end; k++)
                        chess[k][y] = now_turn;
        }

	// 3.检查正左方
	end = 0;
	i = y - 1;
	while(i >= 1 && chess[x][i] == ver_turn)
	{
		i--;
		end++;
	}	
	if(end > 0 && y-end-1 >= 1 && chess[x][y-end-1] == now_turn)
	{
                for(int k = y-1; k >= y-end; k--)
                        chess[x][k] = now_turn;
        }
	
	// 4.检查正右方
	end = 0;
	i = y + 1;
	while(i <= 8 && chess[x][i] == ver_turn)
        {
                i++;
                end++;
        }
        if(end > 0 && y+end+1 <= 8 && chess[x][y+end+1] == now_turn)
        {
                for(int k = y+1; k <= y+end; k++)
                        chess[x][k] = now_turn;
        }

	// 5.检查斜上左方
	end = 0;
	i = x - 1;
	int j = y - 1;
	while(i >= 1 && j >= 1 && chess[i][j] == ver_turn)
	{
		i--;
		j--;
		end++;
	}	
	if(end > 0 && x-end-1 >= 1 && y-end-1 >= 1 && chess[x-end-1][y-end-1] == now_turn)
	{
                for(int k = x-1, m = y-1; k >= x-end && m >= y-end; k--,m--)
                        chess[k][m] = now_turn;
        }

	// 6.检查斜下右方
	end = 0;
	i = x + 1;
	j = y + 1;
	while(i <= 8 && j <= 8 && chess[i][j] == ver_turn)
        {
                i++;
                j++;
                end++;
        }
        if(end > 0 && x+end+1 <= 8 && y+end+1 <= 8 && chess[x+end+1][y+end+1] == now_turn)
	{
                for(int k = x+1, m = y+1; k <= x+end && m <= y+end; k++,m++)
                        chess[k][m] = now_turn;
        }

	// 7.检查斜上右方
	end = 0;
	i = x - 1;
        j = y + 1;
        while(i >= 1 && j <= 8 && chess[i][j] == ver_turn)
        {
                i--;
                j++;
                end++;
        }
        if(end > 0 && x-end-1 >= 1 && y+end+1 <= 8 && chess[x-end-1][y+end+1] == now_turn)
        {
                for(int k = x-1, m = y+1; k >= x-end && m <= y+end; k--,m++)
                        chess[k][m] = now_turn;
        }

	// 8.检查斜下左方
        end = 0;
        i = x + 1;
        j = y - 1;
        while(i <= 8 && j >= 1 && chess[i][j] == ver_turn)
        {
                i++;
                j--;
                end++;
        }
        if(end > 0 && x+end+1 <= 8 && y-end-1 >= 1 && chess[x+end+1][y-end-1] == now_turn)
        {
                for(int k = x+1, m = y-1; k <= x+end && m >= y-end; k++,m--)
                        chess[k][m] = now_turn;
        }
}


// 检查现在的这个位置是不是可走的步
// 可走,返回1
// 不可走,返回0
int legal_move(int x, int y)
{
	if(chess[x][y] != '-')
		return 0;
	
	// 八个方向,检查是否可以走
	// 1.检查正上方
	int end = 0;
	int i = x - 1;
	while(i >= 1 && chess[i][y] == ver_turn)
	{
		i--;
		end++;
	}
	if(end > 0 && x-end-1 >= 1 && chess[x-end-1][y] == now_turn)
		return 1;

	// 2.检查正下方
	end = 0;
	i = x + 1;
	while(i <= 8 && chess[i][y] == ver_turn)
        {
                i++;
                end++;
        }
        if(end > 0 && x+end+1 <= 8 && chess[x+end+1][y] == now_turn)
                return 1;	

	// 3.检查正左方
	end = 0;
	i = y - 1;
	while(i >= 1 && chess[x][i] == ver_turn)
	{
		i--;
		end++;
	}	
	if(end > 0 && y-end-1 >= 1 && chess[x][y-end-1] == now_turn)
		return 1;
	
	// 4.检查正右方
	end = 0;
	i = y + 1;
	while(i <= 8 && chess[x][i] == ver_turn)
        {
                i++;
                end++;
        }
        if(end > 0 && y+end+1 <= 8 && chess[x][y+end+1] == now_turn)
                return 1;

	// 5.检查斜上左方
	end = 0;
	i = x - 1;
	int j = y - 1;
	while(i >= 1 && j >= 1 && chess[i][j] == ver_turn)
	{
		i--;
		j--;
		end++;
	}	
	if(end > 0 && x-end-1 >= 1 && y-end-1 >= 1 && chess[x-end-1][y-end-1] == now_turn)
		return 1;

	// 6.检查斜下右方
	end = 0;
	i = x + 1;
	j = y + 1;
	while(i <= 8 && j <= 8 && chess[i][j] == ver_turn)
        {
                i++;
                j++;
                end++;
        }
        if(end > 0 && x+end+1 <= 8 && y+end+1 <= 8 && chess[x+end+1][y+end+1] == now_turn)
                return 1;	

	// 7.检查斜上右方
	end = 0;
	i = x - 1;
        j = y + 1;
        while(i >= 1 && j <= 8 && chess[i][j] == ver_turn)
        {
                i--;
                j++;
                end++;
        }
        if(end > 0 && x-end-1 >= 1 && y+end+1 <= 8 && chess[x-end-1][y+end+1] == now_turn)
                return 1;

	// 8.检查斜下左方
        end = 0;
        i = x + 1;
        j = y - 1;
        while(i <= 8 && j >= 1 && chess[i][j] == ver_turn)
        {
                i++;
                j--;
                end++;
        }
        if(end > 0 && x+end+1 <= 8 && y-end-1 >= 1 && chess[x+end+1][y-end-1] == now_turn)
                return 1;

	// 如果都没有走的地方,返回不能走
	return 0;
}

题目本身没啥意思,主要是printf输出时 %2d 代表输出整数占两位,如果只有一位,前面补空格
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值