满满的童年——C语言之井字棋(三子棋)

一.游戏介绍及规则

相信很多小伙伴在学生时代都玩过井字棋(三子棋),在课余时间在自己的草稿纸上画着井字图,然后找同学一起玩,今天,博主就用C语言带大家回忆童年的乐趣。

游戏规则:在这里插入图片描述
如图,在井字图中,横行、竖行或者对角线三子相同则游戏胜利,若棋盘下满时仍未分出胜负则平局。

注:先介绍程序实现的主要功能,后文会有完整代码

二.游戏步骤

  1. 程序开始执行时玩家需要选择是否开始游戏,输入1则游戏开始,输入0则退出游戏。
    在这里插入图片描述
  2. 当玩家选择开始游戏时,将会进入模式选择,输入1则为人机模式——玩家与电脑对战,输入2则为人人模式,玩家可以于自己的朋友开始游戏。
    在这里插入图片描述
  3. 玩家选择完游戏模式之后,将会打印出井字图,玩家通过输入坐标位置选择下棋的位置,电脑则自动下棋。
    在这里插入图片描述
  4. 当出现三子相连时,游戏结束,此时三子相连方胜利,若无三子相连且棋盘已满则为平局。
    在这里插入图片描述

三.游戏功能

1. 初始化数组

创建二维数组board[ROW][COL],初始化为空,以便打印井字图时为空白。

//初始化数组
void InitBoard(char board[ROW][COL], int row, int col)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < ROW; i++)
	{
		for (j = 0; j < COL; j++)
		{
			board[i][j] = ' ';
		}
	}
}

2. 打印井字图

井字图中用符号‘|’作为列的分隔符,符号‘—’作为行的分隔符,每一个小格子中左右分别一个空格,中间为二维数组board的元素。

//打印棋盘
void DisplayBoard(char board[ROW][COL], int row, int col)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < ROW; i++)
	{
		for (j = 0; j < COL; j++)
		{
			printf(" %c ", board[i][j]);
			if (j < COL - 1)
				printf("|");
		}
		//每一行换行
		printf("\n");
		//打印行分隔符
		if (i < ROW - 1)
		{
			for (j = 0; j < COL; j++)
			{
				printf("---");
				if (j < COL - 1)
					printf("|");
			}
		}
		printf("\n");
	}
}

3. 玩家下棋

玩家通过输入具体位置的坐标进行下棋,若输入坐标小于等于零或者大于数组board的行号或列号,则坐标不合法;若此时想下棋位置原先已有棋则需要重新选择下棋的位置。

void Player1(char board[ROW][COL], int row, int col)
{
	int i = 0;
	int j = 0;
	while (1)
	{
		printf("玩家1请输入下棋的位置:>\n");
		scanf("%d%d", &i, &j);
		//判断坐标是否合法
		if (i > 0 && i <= row && j > 0 && j <= col)
		{
		    //判断所选位置是否已有棋子
			if (board[i - 1][j - 1] == ' ')
			{
				board[i - 1][j - 1] = '*';
				break;
			}
			else
				printf("该位置被占用,请重新选择\n");
		}
		else
			printf("输入的坐标不合法重新输入\n");
	}
}

4. 电脑下棋

通过生成随机数来确定下棋的位置

void Computer(char board[ROW][COL], int row, int col)
{
	int i = 0;
	int j = 0;
	printf("电脑下棋:>\n");
	while (1)
	{
	    //生成随机数
		i = rand() % row;
		j = rand() % col;
		if (board[i][j] == ' ')
		{
			board[i][j] = '#';
			break;
		}
	}
}

5. 判断棋盘是否已满

棋盘未满则返回0,已满则返回1

int is_full(char board[ROW][COL], int row, int col)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			if (board[i][j] == ' ')
				return 0;
		}
	}
	return 1;//棋盘满了
}

6. 判断输赢

当出现某个字符三个相连时就返回该字符,棋盘满了返回字符‘Q’,若以上情况都未出现,则返回字符‘C’。

//判断输赢
char is_win(char board[ROW][COL], int row, int col)
{
	int i = 0;
	int j = 0;
	//判断行赢
	for (i = 0; i < row; i++)
	{
		if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][0] != ' ')
		{
			return board[i][0];
			break;
		}
	}
	//判断列赢
	for (j = 0; j < row;j++)
	{
		if (board[0][j] == board[1][j] && board[1][j] == board[2][j] && board[0][j] != ' ')
		{
			return board[0][j];
			break;
		}
	}
	//判断对角线赢
	if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[0][0] != ' ')
		return board[0][0];
	if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[2][0] != ' ')
		return board[0][2];
	if (is_full(board, ROW, COL) == 1)
		return 'Q';
	return 'C';
}

7.实现人机模式

//人机对抗
void Play_Computer(char board[ROW][COL], int row, int col)
{
	char ret = 0;
	while (1)
	{
		Player1(board, ROW, COL);
		//每下一步棋则打印棋盘
		DisplayBoard(board, ROW, COL);
		ret = is_win(board, ROW, COL);
		//若棋盘已满则跳出循环
		if (ret != 'C')
		{
			break;
		}
		Computer(board, ROW, COL);
		DisplayBoard(board, ROW, COL);
		ret = is_win(board, ROW, COL);
		if (ret != 'C')
		{
			break;
		}
	}
	if (ret == '#')
		printf("电脑赢\n");
	else if (ret == '*')
		printf("玩家赢\n");
	else
		printf("平局\n");
}

8.人人对抗模式

void Play_Play(char board[ROW][COL], int row, int col)
{
	char ret = 0;
	while (1)
	{
		Player1(board, ROW, COL);
		DisplayBoard(board, ROW, COL);
		ret = is_win(board, ROW, COL);
		if (ret != 'C')
		{
			break;
		}
		Player2(board, ROW, COL);
		DisplayBoard(board, ROW, COL);
		ret = is_win(board, ROW, COL);
		if (ret != 'C')
		{
			break;
		}
	}
	if (ret == '+')
		printf("玩家2赢\n");
	else if (ret == '*')
		printf("玩家1赢\n");
	else
		printf("平局\n");
}

最后,附上代码链接:三子棋,有需要的小伙伴可以去我的gittee仓库查看,谢谢各位大佬。

各位大佬有何看法和意见,欢迎评论区讨论。

  • 61
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 32
    评论
评论 32
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值