三字棋

三子棋是五子棋的简化版,原理和五子棋一样

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#define ROW 3
#define COL 3

//1.定义棋盘:二维数组
//2.初始化棋盘
//3.先打印一下棋盘
//4.用户下一步棋,顺便检查一下游戏是否结束
//5.电脑下一步棋,顺便检查一下游戏是否结束
//6.回到3

//游戏结束标志:(1)其中一个赢(2)平局,棋盘已满

void InitBoard(char board[ROW][COL])
{
	for (int row = 0; row < ROW; row++)
	{
		for (int col = 0; col < COL; col++)
		{
			board[row][col] = ' ';
		}
	}
}
void PrintBoard(char board[ROW][COL])
{
	for (int row = 0; row < ROW; row++)
	{
		printf("| %c | %c | %c |\n", board[row][0],board[row][1],board[row][2]);
		if (row < 2)
		{
			printf("|---|---|---|\n");
		}
	}
}

//x代表用户,o代表电脑
//
void UserMove(char board[ROW][COL])
{
	//
	//首先提示用户输入坐标,判断输入合法性
	//(1)若不合法
	    //a)数组的坐标越界:提示重新输入
		//b)当前位置已经有子:提示当前位置已有子,请重新输入
	//(2)若合法,把当前位置字符置为'x'
	//
	int row = 0;
	int col = 0;
	printf("请输入坐标:");
	while (1)
	{
		scanf("%d %d", &row, &col);
		//输入坐标超出范围
		if (!((row >= 0 && row < 3) && (col >= 0 && col<3)))
		{
			printf("输入坐标已超出范围,请重新输入:");
			continue;
		}
		//输入坐标未超出范围
		//1)当前位置已经有子:重新输入坐标
		//2)当前位置已经无子:置'x'
		else
		{
			if (board[row][col] != ' ')
			{
				printf("当前位置已经有子,请重新输入:");
				continue;
			}
			else
			{
				board[row][col] = 'x';
				break;
			}
		}	
	}	
}
void ComputerMove(char board[ROW][COL])
{
	//电脑产生两个随机数,分别代表其下子的横纵坐标
	//检测是否合法
	//a)若产生的数字不合法:(这里的不合法只有一种情况)当前位置已经有子
	//b)若产生的数字合法:置'o'
	while (1)
	{
		int row = rand() % ROW;
		int col = rand() % COL;
		if (board[row][col] != ' ')
		{
			continue;
		}
		else
		{
			board[row][col] = 'o';
			break;
		}
	}

}
//检查棋盘是否已满,满了返回1,不满返回0
int IsFull(char board[ROW][COL])
{
	for (int row = 0; row < ROW; row++)
	{
		for (int col = 0; col < COL; col++)
		{
			if (board[row][col] != ' ')
			{
				continue;
			}
			else
			{
				return 0;
			}
		}
	}
	return 1;

}
//此函数只检测出有无获胜者(或者说判定游戏有没有结束),不需要具体验证出具体获胜者是谁
char CheckWinner(char board[ROW][COL])
{
	
	//检查所有的行是否连在一起,有两种情况
	//a) 都是' ':
	//b)是x或o:
	//只需要返回位置字符即可,返回的字符可以判断游戏要不要结束
		   
	//检查所有的列是否连在一起,有两种情况
	//a) 都是' ':
	//b)是x或o:
	//只需要返回位置字符即可,返回的字符可以判断游戏要不要结束


	//检查两条对角线,同理也有上面两种情况
	//检查和棋
	///

	//检查行
	for (int row = 0; row < ROW; row++)
	{
		if (board[row][0] == board[row][1] && board[row][1] == board[row][2])
		{
			return board[row][0];
		}
	}
	//检查列
	for (int col = 0; col < COL; col++)
	{
		if (board[0][col] == board[1][col] && board[1][col] == board[2][col])
		{
			return board[0][col];
		}
	}
   //检查两条对角线
	if (board[0][0] == board[1][1] && board[1][1] == board[2][2]
		|| board[0][2] == board[1][1] && board[1][1] == board[2][0])
	{
		return board[1][1];
	}
	//检查和棋:和棋指的是棋盘已满,但是二者谁都未胜
	//棋盘已满有两种情况:
	//1)谁都未胜,x|x|o
	//	           o|o|x
	//			   x|o|x
	//2)刚满,有一方胜  o|x|o
	//                   x|x|x
	//				     o|x|o, 其中[1][1]的x是最后一步下的
	//但是由于程序的执行是按步骤从上到下的,所以出现2)情况时,
	//首先进入 CheckWinner函数会执行:检查行、列、对角线,然后就返回了,不会再执行到检查和棋
	if (IsFull(board))
	{
		return 1;
	}
	else
	{
		return 0;
	}
}
int main()
{
	char board[ROW][COL];
	InitBoard(board);
	char winner = ' ';
	while (1)
	{
		PrintBoard(board);
		//4.用户下一步棋,顺便检查一下游戏是否结束
		UserMove(board);

		//PrintBoard(board);

		winner = CheckWinner(board);
		if (winner != ' '&&winner!=0)//返回结果:x or o or 1 or 0
		{
			//游戏结束
			break;
		}
		//5.电脑下一步棋,顺便检查一下游戏是否结束
		ComputerMove(board);

		//PrintBoard(board);

		winner = CheckWinner(board);
		if (winner != ' '&&winner != 0)
		{
			//游戏结束
			break;
		}
	}
	//出了while循环,说明游戏结束
	PrintBoard(board);
	if (winner == 'x')
	{
		printf("用户赢\n");
	}
	else if (winner == 'o')
	{
		printf("电脑赢\n");
	}
	else if (winner == 1)
	{
		printf("和棋\n");
	}
	
	system("pause");
	return 0;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值