三子棋-C语言入门级小游戏(保姆级教程)

目录

游戏规则

游戏创作思路

游戏设计

1.游戏菜单页面的设计     

2.棋盘初始化

3.棋盘打印

4.玩家下棋

5.电脑下棋

 6.胜负判断

“开始游戏” 


        作为初来道上的“大佬”们来说,学了一小段时间的初阶C语言,这不找个靶子试试手,这心也难以平静不是?今天小博主给大家推荐一个练手的——三子棋。说到这,我们的隔壁老王同学发言了,我不会写啊,咋办哩? 好家伙,这是个问题嘛?显然这算不上个问题,接下来小安带着大家一起来实现三子棋小游戏的编写。


 那么,老规矩,系好安全带,老司机准备发车啦~呜呜呜


游戏规则

        要编写一个游戏的前提是我们已经会玩这个游戏,那么为了防止有些同学呐没玩过不是,咱就先介绍一下游戏规则:

1.游戏一般采用3×3棋盘

2.游戏为双人轮流制下棋

3.双方依次轮流每次下一个棋子

4.获胜标准:玩家使自己的三颗棋子连成横,竖,斜其中一种情况即为获胜


游戏创作思路

首先我们打开编辑器,创建下面三个新建项

  1. test.c      ——   测试游戏
  2. game.h   ——  游戏函数的声明
  3. game.c   ——  游戏函数的实现

//此处声明以下游戏函数的声明和实现,名字可以不同,但是强烈建议一致,因为这样便于我们进行查找


游戏设计

1.游戏菜单页面的设计     

首先,在我们老司机开车进入游戏时,首先出现的就应该是我们的菜单界面。

这个时候呢,我们需要选择使用“菜单函数”(menu())来实现这一功能,这样做的目的可以使游戏多次重复,提高程序的可重复性,确保代码块的函数分块使用。

游戏菜单应该实现这几个功能:

  1. 开始游戏
  2. 退出游戏
  3.  非法输入的返回

 接下来是我们实现这一功能的代码块:

void menu()//打印菜单
{
	printf("************************************************\n");
	printf("****************   1.开始游戏   ****************\n");
	printf("****************   0.退出游戏   ****************\n");
	printf("************************************************\n");
}

以及选择模块的代码:

void test_game()//测试游戏面板
{
	int input = 0;
	srand((unsigned int)time(NULL));//随机数
	do
	{
		menu();
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("输入错误请重新输入\n");
			break;
		}
	} while (input);
}

那么这段代码经过我们老司机的神之一手操作以后会出现什么呢?

 


 

         这时候老王童靴发言了,很好又是老王同学。老王:师傅哩,那个光有车,没油,没领航员,没场地啊。    咳咳,急什么,这不就来啦

2.棋盘初始化

在游戏刚开始时,我们需要对棋盘进行初始化操作,对棋盘进行清空,以保证后续游戏的正常进行。在游戏刚开始时,我们需要对棋盘进行初始化操作,对棋盘进行清空,以保证后续游戏的正常进行。我们将使用“InitBoard()”函数” 将每一个棋盘格初始化为空格。

代码如下:

//初始化棋盘元素全部为0
	char board[ROW][COL] = { 0 };
	//将棋盘每一个元素变为空格
	InitBoard(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] = ' ';
		}
	}
}

3.棋盘打印

有了梦想以后,光在大脑里有怎么能行?这不得弄得看得见,摸得着。于是乎在完成棋盘的初始化操作后,我们就需要将初始化后的棋盘展现出来,。

在这里,老司机们就要使用“BoardDisplay()”这一函数来进行实现。

代码实现如下:

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

//优秀的老王童靴在这里又要发言了,他说如果我不想每次棋盘大小都是一样的怎么办呢?

在这里,我要告诉老王童靴,在这里我们要使用全局变量 ROW 和 COL 来进行操作,通过改变这两个全局变量的值就可以操作棋盘的大小格局。

代码运行如下:


 接下来,这场地是找到了,老王童靴又给我们说他不知道怎么飘了,这这这不得给他露一手?

 

4.玩家下棋

接下来我们来实现老司机们下棋这一功能。

完成这一功能,我们需要注意以下几点: 

接收——接受玩家所输入的地址位置(我们所判断的数组元素应该是玩家输入值-1,因为数组元素下标起始位置为0嘛

判断——判断玩家所输入的地址所在是否已有落子

存储——将玩家的棋子落入对应地

代码实现:

//玩家开始下棋
		player_move(board, ROW, COL);
		DisplayBoard(board, ROW, COL);
		win = IsWin(board, ROW, COL);
		if (win != 'C')
			break;
void player_move(char board[ROW][COL], int row, int col)
{
	printf("玩家下棋,请输入坐标->\n");
	int x = 0;
	int y = 0;
	while (1)
	{
		scanf("%d %d", &x, &y);
		if (x >= 1 && y >= 1 && x <= row && y <= col)
		{
			if (board[x - 1][y - 1] == ' ')
			{
				board[x - 1][y - 1] = '*';
				break;
			}
			else
			{
				printf("该坐标已有棋子,请重新上一步操作\n");
			}
		}
		else
		{
			printf("该坐标不存在,请重新上一步操作\n");
		}
	}
}

运行结果:


5.电脑下棋

电脑下棋呢,那肯定让他随机下的啦,所谓无招胜有招嘛

要实现电脑随机下棋,就需要我们设置一个随机数

x = rand() % row;
y = rand() %  col;     来进行创建坐标的随机数

当然,电脑下棋与玩家下棋相一致也要遵守规则,(接受、判断、存储)

代码实现:

//电脑开始下棋
		computer_move(board, ROW, COL);
		DisplayBoard(board, ROW, COL);
		win = IsWin(board, ROW, COL);
void computer_move(char board[ROW][COL], int row, int col)
{
	printf("电脑下棋->\n");
	int x = 0;
	int y = 0;
	while (1)
	{
		x = rand() % row;//x属于0到2
		y = rand() % col;//y属于0到2
		if (board[x - 1][y - 1] == ' ')
		{
			board[x - 1][y - 1] = '#';
			break;
		}
	}

代码运行结果:


老王童靴又说了,没错,又是他,很优秀嘛!

老王:这我们也不知道谁最后是车神啊!

你看看,你看看,还没开始呢,这胜负欲就出来了,很好,那就来吧

 6.胜负判断

在这里,我们使用Iswin()函数来判断胜负。

在这一函数中,我们需要实现以下几个逻辑:

要返回四种不同的状态

玩家赢     -->  返回'*'

电脑赢     -->  返回'#'

平局         -->  返回'C'

游戏继续  -->  返回'E'

判断输赢,返回为*玩家胜,#电脑胜,'C'继续,'E'平局

代码如下:

	//判断输赢,返回为*玩家胜,#电脑胜,'C'继续,'E'平局
		//char win = IsWin(board, ROW, COL);
if (win == '#')
		printf("我的天呐,你竟然连人工智障都不如\n");
	else if (win == '*')
		printf("哇偶,恭喜您获得胜利\n");
	else
		printf("很遗憾,您和电脑五五开\n");

在实现Iswin()这一函数时,老司机们需要注意以下几点:

判断行

判断列

判断对角线

判断棋盘是否已经放满   -- >  确认游戏是否继续(需要一个Is_full()函数来实现这一功能)

char IsWin(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][1] != ' ')
		{
			return board[i][1];
		}
	}
	//判断列
	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))
	{
		return 'E';
	}
	else
		return 'C';
}
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;//没找到空格返回1,平局
}

“开始游戏” 

终于,家人们,亲爱的老司机们,我们期待的这一刻来临了!!!

我宣布,比赛开始:

 哇偶,让我们以最热烈的掌声恭喜老王童靴!!!

 


test.c:

#define _CRT_SECURE_NO_WARNINGS 1

#include "szq.h"

void menu()//打印菜单
{
	printf("************************************************\n");
	printf("****************   1.开始游戏   ****************\n");
	printf("****************   0.退出游戏   ****************\n");
	printf("************************************************\n");
}
void game()
{
	//初始化棋盘元素全部为0
	char board[ROW][COL] = { 0 };
	//将棋盘每一个元素变为空格
	InitBoard(board, ROW, COL);
	//打印棋盘
	DisplayBoard(board, ROW, COL);
	char win = 0;
	while (1)
	{
		//玩家开始下棋
		player_move(board, ROW, COL);
		DisplayBoard(board, ROW, COL);
		win = IsWin(board, ROW, COL);
		if (win != 'C')
			break;
		//电脑开始下棋
		computer_move(board, ROW, COL);
		DisplayBoard(board, ROW, COL);
		win = IsWin(board, ROW, COL);
		if (win != 'C')
			break;
		//判断输赢,返回为*玩家胜,#电脑胜,'C'继续,'E'平局
		//char win = IsWin(board, ROW, COL);
	}
	if (win == '#')
		printf("我的天呐,你竟然连人工智障都不如\n");
	else if (win == '*')
		printf("哇偶,恭喜您获得胜利\n");
	else
		printf("很遗憾,您和电脑五五开\n");
}
void test_game()//测试游戏面板
{
	int input = 0;
	srand((unsigned int)time(NULL));//随机数
	do
	{
		menu();
		printf("亲爱的老司机童靴请输入:>");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("输入错误请重新输入\n");
			break;
		}
	} while (input);
}
int main()
{
	test_game();
	return 0;
}

saq.c:

#define _CRT_SECURE_NO_WARNINGS 1

#include "szq.h"

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] = ' ';
		}
	}
}
void DisplayBoard(char board[ROW][COL], int row, int col)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < row; i++)
	{
		if (i < row)//打印分隔行
		{
			for (j = 0; j < row; j++)
			{
				printf("---");
				if (j < col - 1)
					printf("+");
			}
		}
		printf("\n");  //换行
		for (j = 0; j < col; j++)
		{
			printf(" %c ", board[i][j]);
			if (j < col - 1)
				printf("|");//打印棋格之间的间隔
		}
		printf("\n");//换行
	}
	for (j = 0; j < row; j++)
	{
		printf("---");
		if (j < col - 1)
			printf("+");
	}
	printf("\n");
}
void player_move(char board[ROW][COL], int row, int col)
{
	printf("玩家下棋,请输入坐标->\n");
	int x = 0;
	int y = 0;
	while (1)
	{
		scanf("%d %d", &x, &y);
		if (x >= 1 && y >= 1 && x <= row && y <= col)
		{
			if (board[x - 1][y - 1] == ' ')
			{
				board[x - 1][y - 1] = '*';
				break;
			}
			else
			{
				printf("该坐标已有棋子,请重新上一步操作\n");
			}
		}
		else
		{
			printf("该坐标不存在,请重新上一步操作\n");
		}
	}
}
void computer_move(char board[ROW][COL], int row, int col)
{
	printf("电脑下棋->\n");
	int x = 0;
	int y = 0;
	while (1)
	{
		x = rand() % row;//x属于0到2
		y = rand() % col;//y属于0到2
		if (board[x - 1][y - 1] == ' ')
		{
			board[x - 1][y - 1] = '#';
			break;
		}
	}
}
char IsWin(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][1] != ' ')
		{
			return board[i][1];
		}
	}
	//判断列
	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))
	{
		return 'E';
	}
	else
		return 'C';
}
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;//没找到空格返回1,平局
}

saq.h:

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

void InitBoard(char board[ROW][COL], int row, int col);
void DisplayBoard(char board[ROW][COL], int row, int col);
void player_move(char board[ROW][COL], int row, int col);
void computer_move(char board[ROW][COL], int row, int col);
char IsWin(char board[ROW][COL], int row, int col);

感谢各位同志耐心的看完,再次表示由衷感谢,希望对同学们的学习起到一定帮助,如果觉得不错的话,可以给小安点个关注,下次有好东西了咱第一个看到不是,谢谢大家的支持!!!

 

 

 

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小赛毛

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值