【C语言】如何创建一个简单的三子棋游戏

1. 前言

今天我们来玩 一个游戏:三子棋。它结合了我们最近学过的数组和函数,同时又会用到猜数字游戏时的一些思路,可以很好地帮助我们巩固知识,并且认识一些新的思路和方法。博客可能有点长,但很详细。

2. 准备

我们首先要创建一个项目,然后创建一个test.c源文件作为测试模块,创建game模块来实现函数,其中game.h用来声明函数,game.c用来实现函数。

3.要求

  • 这个游戏可以重复玩
  • 有必要的提醒,如下棋,输赢等
  • 有棋盘(二维数组)和棋子(玩家的棋子是*,电脑的棋子是#)
  • 尽量不要把代码写得太死了(可移植性)

4.思路

4.1菜单

老样子,我们得为玩家提供一个菜单,但既然我们学习函数了,我们的一些操作和功能实现就交给函数去完成。所以我们调用一个test函数来实现三子棋的基本功能。在这里插入图片描述

现在我们在game.h中声明,在game.c中实现,并且只要在两个.c文件中引用头文件game.h就可以实现这个函数。
在这里插入图片描述

与猜数字游戏类似,不同的选择不同的结果。

  1. input为循环的判断条件,当它恰好为0时,循环停止。
  2. 在game函数中实现三子棋的功能。

4.3打印棋盘

4.3.1创建二维数组

在这里插入图片描述
我们要玩三子棋,我们可以创建一个33的棋盘,但如果我们要玩1010的棋盘,我们是不是就得在函数中寻找这个数组,然后改变它的行和列?这未免太麻烦了。
所以我们就可以在头文件中定义两个常量,然后当我们要扩大或缩小棋盘时,就可以在头文件中改变这两个值。同时我们在game.h中包含头文件,这样我们在源文件就不用包含头文件在这里插入图片描述在这里插入图片描述

4.3.2初始化二维数组

我们可以把数组初始化为空格,当我们下棋时就直接覆盖这些空格即可。在这里插入图片描述

4.3.3打印二维数组在这里插入图片描述

不是简单地打印二维数组,因为全是空格,打印出来也看不出来,所以得加一些标志,比如加一些|和-。如图在这里插入图片描述
这种就很好地给玩家呈现一个棋盘。那我们该如何制作一个棋盘?同时如果我们想要玩10*10的棋盘我们该怎么制作来提高棋盘的可移植性。

在这里插入图片描述

  1. 我们要打印这个二维数组,首先得先确定打印行和列,我们可以看出每行打印完后都都打印一列—|—|—,除了最后一行数组元素打印后没有这列。因此把一行数组和一行—|—|—看成一个整体来打印,最后根据判断不打印—|—|—。
    在这里插入图片描述

  2. 当我们打印一行时,我们发现每次我们打印完空格后就再打印一个|,每行的最后一个空格后面没有跟着|。因此我们把一个空格和一个|看成一个整体进行打印,最后判断决定只打印空格,不打印|。在这里插入图片描述
    代码实现

void print_board(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");
	}
}

这个代码既可以打印33的棋盘,也可以打印1010的棋盘。在这里插入图片描述
在这里插入图片描述

4.4 玩家下棋

同样,我们写一个函数来进行玩家的下棋功能。
在这里插入图片描述
在这里插入图片描述

  1. 首先提醒玩家下棋,让他们输入下棋的坐标。因为玩家可能不是程序员,所以他们一般认为第一行和第一列的下标是1,所以我们对数组进行赋值时只需减一即可。在这里插入图片描述
  2. 判断玩家的下标是否符合要求?在棋盘内?同时给予提醒。在这里插入图片描述
    如果玩家输入错误,给予玩家机会,直到玩家输对为止,这时我们就得用到循环,当满足下棋的条件时,就用break跳出循环。
  3. 当棋子在棋盘上时,我们还要判断我们要下棋的坐标是否已经被占用。如果被占用,提醒玩家重新下棋。

在这里插入图片描述

4.5 电脑下棋

同样,我们写一个函数来实现电脑下棋的功能。在这里插入图片描述
在这里插入图片描述

  1. 我们希望电脑得到两个随机的坐标,这时我们就得用到猜数字游戏学到的三个函数:rand(),srand()和time()。在这里插入图片描述
    在这里插入图片描述
    注意
    (1) 这三个函数我在猜数字游戏中有详细讲到,这里就不一一讲解了。
    (2)我们得到随机值后,要把他们限制在棋盘的范围内,这时,我们可以把随机值%数组的行和列。比如棋盘的范围是3*3,我们将得到的随机值%3得到的是0、1、2,这恰好满足数组行和列的下标。

  2. 我们还要判断这个坐标是否已被占用。如果被占用,让电脑通过循环得到没被占用的坐标,这时不用提醒电脑。当满足下棋的要求时,就用break跳出循环。

在这里插入图片描述

4.6 比较输赢

  1. 我们在每次玩家和电脑下完棋后就打印棋盘,让玩家了解情况。在这里插入图片描述

在这里插入图片描述

  1. 一次不能决出胜负,因此我们得用循环。在这里插入图片描述
  2. 每次下完棋后,都要判断谁赢谁输。因此我们写一个函数,通过其返回值判断。一共有四种情况,如图。在这里插入图片描述
    在这里插入图片描述

至于为什么要返回这些符号,后面会讲到。

  1. 通过is_win函数的返回值,我们可以判断谁输谁赢。

在这里插入图片描述
在这里插入图片描述

  1. 现在我们就要实现is_win函数
    例子以n*n棋盘为例
    已知在一行中连下三个棋子就获胜,在一列中连下三个棋子就获胜,在两条对角线中连下三个棋子就获胜
    (1).首先先在一行中判断是否有连续的三个棋子。在这里插入图片描述
    在这里插入图片描述
    由图可以看出当j满足j<=col-3时,且在这行中有连续的三个相同的棋子,那就可以获胜。在这里插入图片描述

在这里就体现出返回符号的好处,如果玩家赢了返回*,*恰好就是玩家的棋子,这样就不用花费心思去想其他返回值。

(2).判断每列是否有连续相同的三个棋子。在这里插入图片描述
当满足i满足i<=row-3且在这列中连续三个都是相同的棋子,就能获胜。在这里插入图片描述

(3).判断在正对角线是否有连续三个相同的棋子。在这里插入图片描述
正对角线:当i满足i>=row-3,j满足j>=col-3并且有连续三个相同的棋子时就能获胜。在这里插入图片描述
(4).判断在副对角线上是否有连续三个相同的棋子
在这里插入图片描述
当i满足i>=row-3,j满足j>=2,并且在副对角线上有连续相同的三个棋子就能获胜。在这里插入图片描述

  1. 写is_full函数来判断棋盘已满(平局)在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

5. 测试在这里插入图片描述

在这里插入图片描述

6.总结

今天学习了三子棋,如果大家发现有什么更优的解法可以放在评论区,大家一起探讨。感谢!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值