Tic-Tac-Toe

Description

In the game of tic-tac-toe, two players take turns marking squares of an initially empty 3 × 3 grid with either X’s or O’s. The first player always marks squares using X’s, whereas the second player always marks squares using O’s. If at any point during the game either player manages to mark three consecutive squares in a row, column, or diagonal with his/her symbol, the game terminates.

Given a board configuration, your goal is to determine whether the board configuration represents the possible final state of a valid tic-tac-toe game.

Input

The input test file will contain multiple cases. Each test case consists of a single line containing 9 characters, which represent the 9 squares of a tic-tac-toe grid, given one row at a time. Each character on the line will either be ‘X’, ‘O’ (the letter O), or ‘.’ (indicating an unfilled square). The end-of-file is marked by a single line containing the word “end”.

Output

For each input test case, write a single line containing either the word “valid” or “invalid” indicating whether the given board configuration is the final state of some possible tic-tac-toe game.

Sample Input
XXXOO.XXX
XOXOXOXOX
OXOXOXOXO
XXOOOXXOX
XO.OX...X
.XXX.XOOO
X.OO..X..
OOXXXOOXO
end
Sample Output
invalid
valid
invalid
valid
valid
invalid
invalid
invalid

#include<iostream>
using namespace std;
char map[4][4];
int i, j;
bool vict(char c)//讨论获胜的四种情况,行、列、对角线(两种)
{
	for (int i = 0; i < 3; i++)
	{
		if (map[i][0] == c && map[i][1] == c && map[i][2] == c)//一行三个为相同的子
		{
			return 1;
		}
	}
	for (int i = 0; i < 3; i++)//一列三个为相同的子
	{
		if (map[0][i] == c && map[1][i] == c && map[2][i] == c)
		{
			return 1;
		}
	}
	if (map[0][0] == c && map[1][1] == c && map[2][2] == c)//对角线,下同
	{
		return 1;
	}
	if (map[2][0] == c && map[1][1] == c && map[0][2] == c)
	{
		return 1;

	}
	return 0;
}

bool check()
{
	int no, nx, nf;//x是先手,o是后手
	no = nx = nf = 0;
	for (i = 0; i<3; i++)
		for (j = 0; j<3; j++)
			if (map[i][j] == 'O') no++;//统计o的个数
			else if (map[i][j] == 'X') nx++;//统计x的个数
			else nf++;//统计空格的个数
			if (nx<no || nx>no + 1) return 0;//如果先手的子数小于后手或者先手比后手多了一个以上,则判为不合法
			if (vict('O') && nx>no) return 0;//如果后手赢了并且先手大于后手,也为不合法(如果后手胜,先手和后手的子数应该一样多的)
			if (!nf || vict('O') || vict('X'))//除去上面两种不合法的情况,如果棋盘下满了或者后手胜或者先手胜,则是合法的
				return 1;
			return 0;
}
int main()
{
	while (cin >> map[0][0] && map[0][0] != 'e')//一个字符一个字符的读入,如果读入到e(end),停止读入
	{
		cin >> map[0][1] >> map[0][2];//读完3*3中第一行剩下的
		for (i = 1; i<3; i++)
			for (j = 0; j<3; j++)
				cin >> map[i][j];
		if (!check()) cout << "in";
		cout << "valid\n";
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值