详解!C语言编程实现小游戏“三子棋”

今天我们来编程实现一个充满童趣的小游戏“三子棋”
先来说一下三子棋的规则:

三子棋又叫九宫棋、圈圈叉叉、一条龙等。
将正方形对角线连起来,或相对两边依次摆上三个双方棋子,
总之只要将自己的三个棋子走成一条线,
对方就算输了。

图示
不用再过多解释了,相信大家一定都玩过!

那么,该如何用编程的方式实现它呢?
首先,我们创建项目后,要建立三个文件
在这里插入图片描述
分别是头文件game.h,用来声明库函数,存储我们在编程中所自定义函数的函数名,以及宏定义棋盘的宽高。
源文件game.c文件用于储存我们所编写的游戏中所要用到的自定义的函数体。
test.c中包含的是整个游戏程序的大框架和游戏菜单程序。

我们先在test.c文件中定义菜单函数,并在主函数中调用

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
void menu()
{
	printf("***********************************\n");
	printf("************   1.play  ************\n");
	printf("************   0.exit  ************\n");
	printf("***********************************\n");
}
int main()
{
	int input = 0;
	printf("欢迎启动三子棋!\n");
	do
	{
		menu();
		printf("请选择:");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("输入错误,请重新输入!\n");
			break;
		}
	} 
	while (input);
	return 0;
}

调试成功后是这样子的:
在这里插入图片描述
接下来就是最重要的game()程序体了
首先要展出棋盘,
我们知道三子棋的棋盘是一个3x3的正方形格子,即九宫格。
在程序执行后可以是这样子
在这里插入图片描述
我们在game.h文件中定义宽高

#define ROW 3
#define COL 3

接下来再game.c中写出初始化数组的程序,在游戏一开始时将数组中的所有元素初始为“ ”(空格)

void InitBoard(char board[ROW][COL], int row, int col)
{
	memset(&board[0][0], ' ', row*col*sizeof(board[0][0]));
}

这里我们使用memset函数,记得加上声明

#include <string.h>

接着写出展出棋盘的函数

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]);//这里是 空格+%c+空格 //
			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");
		}
	}
}

这样就可以实现上图的效果,
棋盘的展出与初始化完成

接下来我们定义让玩家先走,于是写出玩家走棋的函数
玩家走的棋用’X’来表示

void PlayerMove(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)//判断玩家所输入的坐标是否在棋盘内//
		{
			if (board[x - 1][y - 1] == ' ')//判断所输入的坐标是否已被占用//
			{
				board[x - 1][y - 1] = 'X';
				break;
			}
			else
			{
				printf("抱歉,坐标已经被占用,请重新输入!\n");
			}
		}
		else
		{
			printf("输入的坐标有误,请重新输入!\n");
		}
	}
}

接着写出电脑走棋的函数
电脑走的棋用’O’来表示

void ComputerMove(char board[ROW][COL], int row, int col)
{
	int x = 0;
	int y = 0;
	printf("电脑走:\n");    
	while (1)
	{
		x = rand() % row;
		y = rand() % col;
		if (board[x][y] == ' ')
		{
			board[x][y] = 'O';
			break;
		}
	}
}

这里我们用到了rand函数,令电脑在没占用的位置随机走一步棋
需要进行声明

#include <stdlib.h>

并且需要在主函数下调用srand函数
同时声明

#include <time.h>

最后,需要定义一个函数来判断输赢或平局
我们在构成获胜条件时让函数的返回值为棋子所用的字符
在函数的末尾我们还需要一个用于判断棋盘是否被占满的函数IsFull(在下方说明),
占满时返回’Q’否则返回‘ ’
当返回值为‘ ’时未出现获胜方,则应继续游戏
当返回‘Q’时意味着没有一方获胜,而棋盘已被占满,即为平局

char IsWin(char board[ROW][COL], int row, int col)
{
	int i = 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];
		}
	}
	for (i = 0; i<col; i++)
	{
		if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[1][i] != ' ')
		{
			return board[1][i];
		}
	}
	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 (IsFull(board, row, col) == 1)
	{
		return 'Q';
	}
	return ' ';
}

IsFull函数用于判断棋盘是否被占满,未被占满返回值为0,占满时返回1

int IsFull(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;
}

(以上函数均写在文件game.c中)

这时我们就可以写出game函数了
每当完成一步棋后都需要调用IsWin函数来进行一次判断

void game()
{
	char board[ROW][COL] = { 0 };
	char ret = 0;
	InitBoard(board, ROW, COL);
	DisplayBoard(board, ROW, COL);
	while (1)
	{
		PlayerMove(board, ROW, COL);
		ret = IsWin(board, ROW, COL);
		if (ret != ' ')
			break;
		DisplayBoard(board, ROW, COL);
		ComputerMove(board, ROW, COL);
		ret = IsWin(board, ROW, COL);
		if (ret != ' ')
			break;
		DisplayBoard(board, ROW, COL);
	}
	if (ret == 'X')
		printf("玩家赢!\n");
	else if (ret == 'O')
		printf("电脑赢!\n");
	else if (ret == 'Q')
		printf("平局\n");
	DisplayBoard(board, ROW, COL);
}

三子棋函数完成!
你是否找回了童趣呢?

完整代码:https://github.com/Yubao-wss/Game/tree/master/Sanzi Chess/Sanzi Chess

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值