3C(#游戏)

题目链接

题目大意:

当然,大家都熟悉井字棋游戏。 这些规则确实很简单。 两个玩家A、B轮流在3x3的方格的单元格中画符号(玩家A总是画“X”,玩家B总是画“0”)。 首先在水平、垂直或对角线上出现3个相同的符号的玩家获胜,比赛结束。 玩家A总是为先手。 如果3x3的方格被填满,但是在所有水平、垂直或对角线上均未出现3个相同的符号,宣布平局。

给你一个3*3的方格,每个单元格是“.”(空白),“X”或“0”。 你必须输出以下内容之一:

玩家A走棋(输出“first”)——如果出现给定的状态后,下一步为玩家A走棋。

玩家B走棋(输出“second”)——如果出现给定的状态后,下一步为玩家B走棋。

非法(输出“illegal”)——如果给定的状态无法在正常游戏过程中出现。

玩家A胜利(输出“the first player won”)——如果给定的状态中玩家A胜利。

玩家B胜利(输出“the second player won”)——如果给定的状态中玩家B胜利。

平局(输出“draw”)——如果给定的状态是平局。

思路:

这道题目确实没有用到什么算法,直接朴树判断即可。那为什么要记录他呢?应为这道题的可扩张性极高。

这道题目的难点是判断"illegal",即非法输入。

他有很多种情况,而且很容易被忽略:(a先手,b后手)

  1. 如果b下的步数大于a的步数,不合法
  2. 如果a比b的步数大于1,不合法
  3. 如果a, b步数都大于等于3,并且a, b都赢,不合法
  4. a的步数大于b的步数,b赢了,不合法
  5. a,b步数相同,但a赢了,不合法好像跟3重合了啊。(哈哈)

AC代码:

#include <bits/stdc++.h>
using namespace std;
 
char s[4][4];
 
bool as()
{
	for (int i = 1; i <= 3; i ++ )
	{
		int cnt = 0;
		for (int j = 1; j <= 3; j ++ )
		{
			if(s[i][j] == 'X') cnt ++;
		}
		if (cnt == 3) return 1;
	}
 
	for (int i = 1; i <= 3; i ++ )
	{
		int cnt = 0;
		for (int j = 1; j <= 3; j ++ )
		{
			if(s[j][i] == 'X') cnt ++;
		}
		if (cnt == 3) return 1;
	}
 
	int cnt = 0;
	for (int i = 1; i <= 3; i ++ )
	{
		if (s[i][i] == 'X') cnt ++ ;
	}
	if (cnt == 3) return 1;
 
	cnt = 0;
	for (int i = 1; i <= 3; i ++ )
	{
		if (s[i][4 - i] == 'X') cnt ++;
	}
	if (cnt == 3) return 1;
 
	return 0;
}
 
bool bs()
{
	for (int i = 1; i <= 3; i ++ )
	{
		int cnt = 0;
		for (int j = 1; j <= 3; j ++ )
		{
			if(s[i][j] == '0') cnt ++;
		}
		if (cnt == 3) return 1;
	}
 
	for (int i = 1; i <= 3; i ++ )
	{
		int cnt = 0;
		for (int j = 1; j <= 3; j ++ )
		{
			if(s[j][i] == '0') cnt ++;
		}
		if (cnt == 3) return 1;
	}
 
	int cnt = 0;
	for (int i = 1; i <= 3; i ++ )
	{
		if (s[i][i] == '0') cnt ++ ;
	}
	if (cnt == 3) return 1;
 
	cnt = 0;
	for (int i = 1; i <= 3; i ++ )
	{
		if (s[i][4 - i] == '0') cnt ++;
	}
	if (cnt == 3) return 1;
 
	return 0;
}
 
bool af()
{
	int a = 0, b = 0;
	for (int i = 1; i <= 3; i ++ )
	{
		for (int j = 1; j <= 3; j ++ )
		{
			if (s[i][j] == 'X') a ++ ;
			if (s[i][j] == '0') b ++;
		}
	}
 
	if (b == a) return 1;
	return 0;
}
 
bool bf()
{
	int a = 0, b = 0;
	for (int i = 1; i <= 3; i ++ )
	{
		for (int j = 1; j <= 3; j ++ )
		{
			if (s[i][j] == 'X') a ++ ;
			if (s[i][j] == '0') b ++;
		}
	}
 
	if (a > b) return 1;
	return 0;
}
 
bool check()
{
	int a = 0, b = 0;
	for (int i = 1; i <= 3; i ++ )
	{
		for (int j = 1; j <= 3; j ++ )
		{
			if (s[i][j] == 'X') a ++ ;
			if (s[i][j] == '0') b ++;
		}
	}
	
	if (b > a || abs(a - b) > 1 || ((a >= 3 && b >= 3) && (as() && bs())) || (a > b && bs()) || (a == b && as())) return 1;
	return 0;
}
 
bool other()
{
	int a = 0, b = 0;
	for (int i = 1; i <= 3; i ++ )
	{
		for (int j = 1; j <= 3; j ++ )
		{
			if (s[i][j] == 'X') a ++ ;
			if (s[i][j] == '0') b ++;
		}
	}
 
	if (a == 5 && b == 4 && !(as()) && !bs()) return 1;
	return 0;
}
 
void solved()
{
	for (int i = 1; i <= 3; i ++ )
	{
		cin >> (s[i] + 1);
	}
	if (check())
	{
		puts("illegal");
		return ;
	}
	if(other())
	{
		puts("draw");
		return ;
	}
	if (as())
	{
		puts("the first player won");
		return ;
	}
	if(bs())
	{
		puts("the second player won");
		return ;
	}
	if(af())
	{
		puts("first");
		return ;
	}
	if(bf())
	{
		puts("second");
		return ;
	}
 
	
}
 
int main()
{
	solved();
 
 
	return 0;
}

 

posted @ 2022-11-18 12:03  Luli&  阅读(113)  评论(0编辑  收藏  举报