温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

C语言怎么实现三子棋

发布时间:2022-04-14 09:14:13 来源:亿速云 阅读:152 作者:iii 栏目:开发技术

这篇文章主要介绍了C语言怎么实现三子棋的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇C语言怎么实现三子棋文章都会有所收获,下面我们一起来看看吧。

    1、三子棋是什么?

    1.1 百度百科

    三子棋是黑白棋的一种。三子棋是一种民间传统游戏,又叫九宫棋、圈圈叉叉、一条龙、井字棋等。将正方形对角线连起来,相对两边依次摆上三个双方棋子,只要将自己的三个棋子走成一条线,对方就算输了。但是,有很多时候会出现和棋的情况。

    C语言怎么实现三子棋

    1.2 游戏编程准备工作

    通过观察上图,三子棋是下在一个井字形或者九宫格的棋盘内的。因此,我们可以先从打印一个棋盘入手开始编写程序。为了方便起见,我们规定输出下面这样的九宫格棋盘。

    C语言怎么实现三子棋

    参照三子棋的下棋规则,制定初步的编程思路:

    1、在玩游戏开始前输出一些符号和文字,让界面更加有仪式感,例如:

    	printf("*********************\n");
    	printf("*****1. 开始游戏*****\n");
    	printf("*****0. 退出游戏*****\n");
    	printf("*********************\n");

    2、提示玩家选择:

    • 输入1代表玩游戏

    • 输入0代表退出游戏

    • 输入其他,提示输入错误,需要玩家重新输入

    3、下棋开始前先初始化棋盘,在打印出棋盘

    4、玩家下棋后,再次打印出棋盘

    5、电脑下棋后,再次打印出棋盘

    6,如此循环往复几步后,判断赢家是谁,下棋结束

    7、玩家可选择继续玩还是退出程序

    2. 程序实现

    2.1 搭建程序框架

    我们首先搭建程序框架,让程序能够跑起来,再接着修改程序,实现基本功能。

    因为游戏是多次进行的,选择do-while循环结构,编写程序主题结构。

    void menu()
    {//输出提示字符
    	printf("*********************\n");
    	printf("*****1. 开始游戏*****\n");
    	printf("*****0. 退出游戏*****\n");
    	printf("*********************\n");
    }
    void play()
    {//玩游戏的代码
    	printf("玩家选择玩游戏!\n");
    }
    
    int main()
    {//利用do-while循环,写成主体结构
    	int input = 0;
    	do
    	{
    		menu();//输出提示信息
    		printf("请选择1或者0==> ");//1代表玩,0代表退出游戏
    		scanf("%d", &input);//玩家输入
    		switch (input)
    		{//通过分支结构,决定输入是什么
    			case 1://玩游戏
    				play();//调用玩游戏的函数
    				break;
    			case 0://退出游戏
    				printf("退出游戏!\n");
    				break;
    			default://重新输入
    				printf("输入错误,请重新输入1或0 \n");
    				break;
    		}//先进入循环输出提示信息,当输入1时,满足循环条件,接着执行循环里面的程序,也就是玩游戏
    		//当输入0时,不满足循环条件,也就是退出游戏
    		//使用do-while循环符合逻辑
    	} while (input);
    	return 0;
    }

    运行程序,分别输入1 2 0,输出结果如下所示,达到了预期的界面效果:

    • 输入1代表玩游戏

    • 输入其他,提示输入错误,需要玩家重新输入

    • 输入0代表退出游戏

    C语言怎么实现三子棋

    2.2 模块化编程

    上面一小节的代码搭建了程序的框架,能实现程序的基础功能,我们接着进一步play函数中添加代码,完善玩游戏的功能

    由于代码较多,将采用模块化编程,这一使代码可读性更高一点。将不同功能的函数实现放在不同的源文件中。

    2.2.1 源文件test.c

    将函数main 、test、menu、play放入源文件test.c中,这里只是初步规划,代码会随着实现功能慢慢增加。

    //后续将会逐步添加,不表明只有这些
    #include "play.h"//头文件必须添加,printf等函数正常工作
    
    void menu()
    {//输出提示字符
    	printf("*********************\n");
    	printf("*****1. 开始游戏*****\n");
    	printf("*****0. 退出游戏*****\n");
    	printf("*********************\n");
    }
    void play()
    {//玩游戏的具体实现代码
    	printf("玩家选择玩游戏!\n");
    	//存放下棋的数据
    	char board[ROW][COL] = { 0 };
    	//初始化棋盘为全空格
    	InitBoard(board, ROW, COL);
    }
    void test()
    {//游戏界面代码
    	int input = 0;
    	do
    	{
    		menu();
    		printf("请选择1或者0==> ");
    		scanf("%d", &input);
    		switch (input)
    		{
    		case 1:
    			play();
    			break;
    		case 0:
    			printf("退出游戏!\n");
    			break;
    		default:
    			printf("输入错误,请重新输入1或0 \n");
    			break;
    		}
    	} while (input);
    }
    int main()
    {
    	test();
    	return 0;
    }
    2.2.2 源文件play.c

    将函数初始化棋盘、打印棋盘、玩家下棋,等等放入源文件play.c,这里只是初步规划,代码会随着实现功能慢慢增加。

    //后续将会逐步添加,不表明只有这些
    #include "play.h"//头文件必须添加,包含stdio.h,使printf等函数正常工作
    //初始化棋盘
    void InitBoard(char board[ROW][COL], int row, int col)
    {
    }
    //打印棋盘
    void DisplayBoard(char board[ROW][COL], int row, int col)
    {
    }
    //玩家下棋
    void PlayMover(char board[ROW][COL], int row, int col)
    {
    }
    //电脑下棋
    void ComputerMove(char board[ROW][COL], int row, int col)
    {
    }
    2.2.3 头文件play.h

    将宏定义,函数声明放在这个头文件件play.h,这里只是初步规划,代码会随着实现功能慢慢增加。

    //后续将会逐步添加,不表明只有这些
    #include<stdio.h>//添加头文件
    
    #define ROW 3//棋盘行数
    #define COL 3//棋盘列数
    
    void play();
    //初始化棋盘
    void InitBoard(char board[ROW][COL], int row, int col);
    //打印棋盘
    void DisplayBoard(char board[ROW][COL], int row, int col);
    //玩家下棋
    void PlayMover(char board[ROW][COL], int row, int col);
    //电脑下棋
    void ComputerMove(char board[ROW][COL], int row, int col);

    2.3 程序实现&mdash;拓展play函数

    2.3.1 棋盘初始化与打印函数

    在玩家下棋前,需要完成两件事情

    • 使用函数 InitBoard: 初始化棋盘,用空格初始化

    • 使用函数 DisplayBoard: 将棋盘打印出来。

    //test.c
    void play()
    {
    	printf("玩家选择玩游戏!\n");
    	//存放下棋的数据 ROW代表棋盘行数,COL代表棋盘列数
    	char board[ROW][COL] = { 0 };
    	//初始化棋盘为全空格
    	InitBoard(board, ROW, COL);
    	//展示棋盘,打印
    	DisplayBoard(board, ROW, COL);
    }
    //play.c
    void InitBoard(char board[ROW][COL], int row, int col)
    {
    	int i = 0;
    	for (i = 0; i < row; i++)
    	{
    		int j = 0;
    		for (j = 0; j < col; j++)
    		{
    			board[i][j] = ' ';//赋值空格,进行格式化
    		}
    	}
    }
    //第一稿
    void DisplayBoard(char board[ROW][COL], int row, int col)
    {
    	int i = 0;
    	for (i = 0; i < row; i++)
    	{
    		int j = 0;
    		for (j = 0; j < col; j++)
    		{//此时数组里都是空格
    			printf("%c", board[i][j]);//都是空格看不见
    		}
    		printf("\n");
    	}
    }

    运行结果显示,函数InitBoard使用空格完成初始化,但是空格直接打印都是空白,看不见,因此需要修改打印函数DisplayBoard

    C语言怎么实现三子棋

    • 2.3.1.1 打印函数DisplayBoard&mdash;&mdash;修改1

    //第二稿
    void DisplayBoard(char board[ROW][COL], int row, int col)
    {
    	int i = 0;
    	for (i = 0; i < row; i++)
    	{
    		printf(" %c | %c | %c \n", board[i][0], board[i][1], board[i][2]);
    		//打印分隔符
    		printf("---|---|---\n");
    	}ruxiat
    }

    C语言怎么实现三子棋

    打印结果如上图,基本上是一个九宫格棋盘了。但是第三行的字符是多余的,需要再次修改。

    • 2.3.1.2 打印函数DisplayBoard&mdash;&mdash;修改2

    //第三稿
    void DisplayBoard(char board[ROW][COL], int row, int col)
    {
    	int i = 0;
    	for (i = 0; i < row; i++)
    	{//但是这里有问题,每行的输出是固定的3个,当行列改变时,这里就不能用了
    		printf(" %c | %c | %c \n", board[i][0], board[i][1], board[i][2]);
    		//打印分隔符
    		if(i<ROW-1)//第三行不打印
    			printf("---|---|---\n");
    	}
    }

    C语言怎么实现三子棋

    运行结果如上所示。但是上面的代码也存在问题,每行字符输出是固定的3个,当行列改变时,这里就会出问题。

    printf(" %c | %c | %c \n", board[i][0], board[i][1], board[i][2]);

    将棋盘的行数、列数改为10 ,运行结果如下:

    C语言怎么实现三子棋

    因此,这行代码需要修改。

    • 2.3.1.3 打印函数DisplayBoard&mdash;&mdash;修改3

    //第四稿
    void DisplayBoard(char board[ROW][COL], int row, int col)
    {
    	int i = 0;
    	for (i = 0; i < row; i++)
    	{
    		for (int  j = 0; j < col; j++)
    		{//将这里改为自动化输出
    			printf(" %c ", board[i][j]);
    			printf("|");
    		}
    		printf("\n");
    		//打印分隔符
    		if (i < row - 1)//第三行不打印
    			printf("---|---|---\n");
    	}
    }

    C语言怎么实现三子棋

    上图为显示结果,第三列有问题,对代码进行修改。

    • 2.3.1.4 打印函数DisplayBoard&mdash;&mdash;修改4

    //第五稿
    void DisplayBoard(char board[ROW][COL], int row, int col)
    {
    	int i = 0;
    	for (i = 0; i < row; i++)
    	{
    		for (int j = 0; j < col; j++)
    		{
    			printf(" %c ", board[i][j]);
    			if(j<col-1)第三列不打印
    				printf("|");
    		}
    		printf("\n");
    		//打印分隔符
    		if (i < row - 1)//第三行不打印
    			printf("---|---|---\n");//这里也有问题,写成固定的
    	}
    }

    C语言怎么实现三子棋

    上面是运行结果,**程序代码也存在问题,同前面一样,输出的字符是固定的,**因此再次修改代码。

    	printf("---|---|---\n");//这里也有问题,写成固定的
    • 2.3.1.5 打印函数DisplayBoard&mdash;&mdash;修改5

    //第六稿,至此改完
    void DisplayBoard(char board[ROW][COL], int row, int col)
    {
    	int i = 0;
    	for (i = 0; i < row; i++)
    	{
    		for (int j = 0; j < col; j++)
    		{
    			printf(" %c ", board[i][j]);
    			if (j < col - 1)第三列不打印
    				printf("|");
    		}
    		printf("\n");//每一行打完就换行
    		//打印分隔符
    		if (i < row - 1)//第三行不打印
    		{
    			for (int j = 0; j < col; j++)
    			{//此时可以测试10行10列了
    				printf("---");//纯粹的符号打印,没有输入的字符
    				if (j < col - 1)//第三列不打印
    					printf("|");
    			}
    			printf("\n");//每一行打完就换行
    		}
    	}
    }

    C语言怎么实现三子棋

    运行结果如上图。将棋盘行数、列数改为10,再次运行,结果见下图,由此,打印函数DisplayBoard修改结束,符合使用要求了。

    C语言怎么实现三子棋

    2.3.2 玩家下棋函数 PlayMover

    在初始化并打印棋盘后,接着就要邀请玩家下棋了,下完后也要打印出棋盘。在函数 paly 里添加 PlayMover 和 DisplayBoard。

    void play()
    {
    	printf("玩家选择玩游戏!\n");
    	//存放下棋的数据
    	char board[ROW][COL] = { 0 };
    	//初始化棋盘为全空格
    	InitBoard(board, ROW, COL);
    	//展示棋盘,打印
    	DisplayBoard(board, ROW, COL);
    	//玩家下棋
    	PlayMover(board, ROW, COL);
    	//展示棋盘,打印
    	DisplayBoard(board, ROW, COL);
    }

    玩家下棋函数 PlayMover,根据玩家输入的坐标信息,在对应的位置输入*,代表落下棋子。

    void PlayMover(char board[ROW][COL], int row, int col)
    {
    	int x = 0;
    	int y = 0;
    	printf("游戏已开始,请玩家下棋\n");
    	while (1)
    	{
    		printf("请输入落棋子位置 ==> ");
    		scanf("%d %d", &x, &y);
    		if (x >= 1 && x <= row && y >= 1 && y <= col)
    		{//玩家的角度,行列都是1开始的
    			//下棋
    			if (board[x - 1][y - 1] == ' ')//数组角度,代码要减1
    			{//落棋位置,就是前面打印棋盘 %c 的位置
    				board[x - 1][y - 1] = '*';//输入字符,代表落下棋子
    				break;
    			}
    			else
    			{
    				printf("该位置已有棋子,请重新选择落子位置\n");
    			}
    		}
    		else
    		{
    			printf("坐标非法,请重新输入\n");
    		}
    	}
    }

    输入坐标1 1,结果显示:在对应位置输出*,代表落下棋子。由此表明,玩家下棋函数 PlayMover符合预期效果。

    C语言怎么实现三子棋

    2.3.3 电脑下棋函数 ComputerMove

    玩家下棋后,打印出棋盘,紧接着就轮到电脑下棋了,同样打印出棋盘。在函数 paly 里添加 ComputerMove 和 DisplayBoard。

    void play()
    {
    	printf("玩家选择玩游戏!\n");
    	//存放下棋的数据
    	char board[ROW][COL] = { 0 };
    	//初始化棋盘为全空格
    	InitBoard(board, ROW, COL);
    	//展示棋盘,打印
    	DisplayBoard(board, ROW, COL);
    	//玩家下棋
    	PlayMover(board, ROW, COL);
    	//展示棋盘,打印
    	DisplayBoard(board, ROW, COL);
    	//电脑下棋
    	ComputerMove(board, ROW, COL);
    	//展示棋盘,打印
    	DisplayBoard(board, ROW, COL);
    }

    电脑是自己随机下棋的,电脑的行数、列数先随机产生一个0-2的坐标位置,再判断这个位置是否为空:

    • 为空,输入字符#,代表电脑在此落下棋子

    • 否则,会循环再次产生随机数,直到为空

    下面将在源文件 play.c 中添加函数 ComputerMove 的实现代码,并在头文件 play.h 中添加函数声明。

    //头文件 play.h中
    void ComputerMove(char board[ROW][COL], int row, int col);
    
    //源文件 play.c中
    void ComputerMove(char board[ROW][COL], int row, int col)
    {
    	int x = 0;
    	int y = 0;
    	printf("电脑下棋 ==> \n");
    	while (1)
    	{//电脑下棋是随机的
    		x = rand() % row;//输出0-2之间的随机数 0 1 2
    		y = rand() % col;//输出0-2之间的随机数 0 1 2
    		if (board[x][y]==' ')//先判断对应坐标是否为空格
    		{//空格代表没有棋子,则电脑将落下棋子 
    			board[x][y] = '#';//#代表电脑下棋
    			break;//下完就跳出循环
    		}
    	}
    }

    由于坐标位置随机产生的,要在 头文件 play.h 中添加两个头文件

    #include <stdlib.h>//库函数
    #include <time.h>//与系统时间有关的

    在源文件 test.c 中的函数test中,添加函数srand,放在do-while循环之前,这样电脑下棋的位置将是真正的随机产生。

    srand((unsigned int)time(NULL));

    C语言怎么实现三子棋

    运行结果见上图,由于下棋是双方轮流下棋的,所以玩家下棋和电脑下棋是一个循环的动作。在此在函数play 添加while循环:

    void play()
    {
    	printf("玩家选择玩游戏!\n");
    	//存放下棋的数据
    	char board[ROW][COL] = { 0 };
    	//初始化棋盘为全空格
    	InitBoard(board, ROW, COL);
    	//展示棋盘,打印
    	DisplayBoard(board, ROW, COL);
    	while (1)
    	{
    		//玩家下棋
    		PlayMover(board, ROW, COL);
    		//展示棋盘,打印
    		DisplayBoard(board, ROW, COL);
    		//电脑下棋
    		ComputerMove(board, ROW, COL);
    		//展示棋盘,打印
    		DisplayBoard(board, ROW, COL);
    	}
    }

    C语言怎么实现三子棋

    运行结果见上图。到此,代码已经实现了正常的下棋功能并显示出来。

    2.2.4 判断赢家函数 WhoIsWin

    三子棋棋盘一共只能下9个棋子,因此经过双方几轮下棋后,势必会分出胜负,结果分为三种:

    • 玩家赢,约定返回 *

    • 电脑赢,约定返回 #

    • 平局,约定返回 q,此时棋盘已满是棋子,不分胜负

    • 其他情况,约定返回 c,继续下棋

    当然,以上结果是不包括掀了棋盘的。

    C语言怎么实现三子棋

    基于前面的代码基础上,在函数 paly 里添加判断赢家的函数WhoIsWin ,修改后的函数 play逻辑是:

    • 在while循环中,玩家先下棋

    • 函数 WhoIsWin 会判断棋盘的结果,并以字符的方式返回,赋值给result

    • if判断result的值

    (1)若返回的字符是c,则程序往下运行,轮到电脑下棋

    (2)若返回的字符不是c,说明下棋出结果了,break直接跳出while循环,进行剩下的3个if判断

    (3)返回 *,代表玩家赢; 返回 #,代表电脑赢;返回 c,代表平局;

    void play()
    {
    	printf("玩家选择玩游戏!\n");
    	char result = 0;//棋盘最终结果根据result判断
    	//存放下棋的数据
    	char board[ROW][COL] = { 0 };
    	//初始化棋盘为全空格
    	InitBoard(board, ROW, COL);
    	//展示棋盘,打印
    	DisplayBoard(board, ROW, COL);
    	while (1)
    	{
    		//玩家下棋
    		PlayMover(board, ROW, COL);
    		//展示棋盘,打印
    		DisplayBoard(board, ROW, COL);
    		result = WhoIsWin(board, ROW, COL);//函数判断下棋结果后,返回对应的字符
    		if (result !='c')//玩家下棋后进行一次判断
    		{//不继续下棋,说明已经分出胜负了
    			break;
    		}
    		//电脑下棋
    		ComputerMove(board, ROW, COL);
    		//展示棋盘,打印
    		DisplayBoard(board, ROW, COL);
    		result = WhoIsWin(board, ROW, COL);//函数判断下棋结果后,返回对应的字符
    		if (result != 'c')//电脑下棋后进行一次判断
    		{//不继续下棋,说明已经分出胜负了
    			break;
    		}
    	}
    	//根据函数WhoIsWin返回的字符,输出下棋结果
    	if (result == '*')
    	{
    		printf("玩家赢了\n");
    	}
    	else if (result == '#')
    	{
    		printf("电脑赢了\n");
    	}
    	else
    	{
    		printf("平局\n");
    	}
    }

    在源文件 play.c 添加 WhoIsWin 的代码,并在**头文件 play.h **添加函数声明:

    //头文件 play.h中
    char WhoIsWin(char board[ROW][COL], int row, int col);
    int IfFull(char board[ROW][COL], int row, int col);

    函数 WhoIsWin 的逻辑:

    • 判断每一行、每一列、对角线上,三个棋子相同吗?相同且不是空格,直接返回代表棋子的字符, *为玩家,#为电脑

    • 棋盘棋子都是满的,则代表平局,返回字符 q

    • 其他情况,代表继续下棋,还没分出胜负,返回字符 c

    //源文件 play.c中
    //判断棋盘是否满了? 此函数包含在 WhoIsWin 中
    int IfFull(char board[ROW][COL], int row, int col)
    {
    	for (int  i = 0; i < row; i++)
    	{
    		for (int j = 0; j < col; j++)
    		{
    			if (board[i][j] == ' ')
    			{
    				return 0;//存在空格棋盘没有满
    			}
    		}
    	}
    }
    //判断赢家
    char WhoIsWin(char board[ROW][COL], int row, int col)
    {
    	//判断行,每一行连续三个棋子相同
    	for (int  i = 0; i < row; i++)
    	{
    		if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][1] != ' ')
    		{//只要连续三个棋子相同,就直接返回这个棋子,这里不用区分* 还是#
    			return board[i][1];
    		}
    	}
    	//判断列,每一列连续三个棋子相同
    	for (int j = 0; j < row; j++)
    	{
    		if (board[0][j] == board[1][j] && board[1][j] == board[2][j] && board[1][j] != ' ')
    		{
    			return board[1][j];
    		}
    	}
    	//对角线,连续三个棋子相同
    	if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')
    	{//主对角线
    		return board[1][1];
    	}
    	if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')
    	{//副对角线
    		return board[1][1];
    	}
    	//判断平局,棋盘满了,不分胜负
    	if (IfFull(board, row, col) == 1)
    	{
    		return 'q';//quit表示平局
    	}
    	//没有赢家,棋盘也没满,继续下棋
    	return 'c';//continue,表示继续
    }

    运行结果见下图,基本上一个完整的三子棋游戏代码已经实现了。

    但是上述代码还有一个小问题,在判断每一行、每一列、对角线上,三个棋子是否相同时,代码直接写固定的3个,如果将棋盘改成5行5列的五子棋时,这里就会出现问题了。这里留到以后在修改成能适应五子棋的游戏。三子棋的代码实现就告一段落了。

    C语言怎么实现三子棋

    关于“C语言怎么实现三子棋”这篇文章的内容就介绍到这里,感谢各位的阅读!相信大家对“C语言怎么实现三子棋”知识都有一定的了解,大家如果还想学习更多知识,欢迎关注亿速云行业资讯频道。

    向AI问一下细节

    免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

    AI