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;
}