三子棋小游戏【C语言】

目录

前言

一、基本实现逻辑

二、实现步骤

1.实现进入游戏后的选择菜单——》这个实现起来较为容易,我们约定为:1是玩游戏, 0 是退出游戏!

2.要玩完了一局后接着玩,很容易想到要用循环。

3.采用多文件编程---》我们把实现游戏的相关代码放到game.c的文件里面,把所有头文件和函数的声明都放到game.h里面,谁用谁调用即可,把测试相关的代码都放到test.c里面。

4.创建棋盘

5.打印棋盘

6.玩家落子

7.电脑落子

8.胜负判断

三、全部游戏源码


前言

大家小时候,一定玩过三子棋也就是井字棋!它的玩法也很简单,让三个棋相连的时候就赢了!今天小编就用C语言来实现一下!如有不对的地方还请大正  小编先磕一个 Orz

一、基本实现逻辑

在实现前理清楚实现的顺序和逻辑,在实现中就能更好地实现,不至于一开始就一顿狂敲,到后面发现一堆bug这就得不偿失了!下面我们就来梳理一下实现该小游戏的逻辑:

1.我们希望进入游戏后可以有个菜单让我们选择

2.我们希望可以重复玩(一把玩完了还可以接着玩)

3.为了使每一个模块简洁,且调试起来方便我们采用多文件的形式

4.既然是下棋就得有个棋盘---》创建一个3*3的棋盘

5.打印棋盘

6.玩家落子(坐标形式)

7.电脑落子(随机)

8.判断胜负(玩家赢/电脑赢/平局)

二、实现步骤

1.实现进入游戏后的选择菜单——》这个实现起来较为容易,我们约定为:1是玩游戏, 0 是退出游戏!

代码演示:

#include

void menu()
{
	printf("************************\n");
	printf("********1. play ********\n");
	printf("********0. exit ********\n");
	printf("************************\n");
}

int main()
{
	int input = 0;
	menu();
	printf("请输入操作数:> ");
	scanf("%d", &input);
	return 0;
}

这里就用一个这样的简陋的菜单作为选择界面!(小编不会用Easyx等的图形库)菜单弹出来之后,你得选择玩还是退出!因此需要一个变量来存你要选择的值!

2.要玩完了一局后接着玩,很容易想到要用循环。

但三种循环选择哪一种呢?我们想一开始你也得给玩家弹出彩单让他选择,玩或者是退出!也就是说无论是否玩都得给玩家弹出彩单让他选择!到这里大家都能想到了。没错,用do...while循环!接上面说的选择1 玩游戏,0 退出。我们改怎么处理呢?答案是用选择结构中的switch case 语句较好(if else也可以)。下面小编就来实现一下:

代码演示:

#define _CRT_SECURE_NO_WARNINGS 1
#include

void menu()
{
	printf("************************\n");
	printf("********1. play ********\n");
	printf("********0. exit ********\n");
	printf("************************\n");
}

int main()
{
	int input = 0;
	do
	{
		menu();
		printf("请输入操作数:> ");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			printf("玩游戏!\n");
			break;
		case 0:
			printf("退出游戏!\n");
			break;
		default:
			printf("操作数非法,请重新输入!\n");
			break;
		}
	} while (input);
	return 0;
}

看效果:

三子棋小游戏【C语言】_第1张图片

3.采用多文件编程---》我们把实现游戏的相关代码放到game.c的文件里面,把所有头文件和函数的声明都放到game.h里面,谁用谁调用即可,把测试相关的代码都放到test.c里面。

看效果:

三子棋小游戏【C语言】_第2张图片

 这里要注意的是:一般引库里面的头文件我们用<>(例如:#include),而引用自己的头文件时用""。

4.创建棋盘

我们要下棋首先得有一个棋盘,我们想三子棋的棋盘实际上就是一个3*3的字符数组(该数组应该里面放的都是空格),在里面放上(覆盖空格)不同的字符而进行下棋的;那我们先创建一个3*3的字符数组,为了让我们看到先赋值为0,达到效果后改为' ';

代码演示:

三子棋小游戏【C语言】_第3张图片

三子棋小游戏【C语言】_第4张图片 看效果:

三子棋小游戏【C语言】_第5张图片  

这时候效果已经出来了,但有一个缺陷就是,这里的行和列已经写死了!如果后期有变动就改的东西很多!有没有更好地办法呢?答案是有的,我们前面初识C语言的时候说过一个东西叫#define定义的自符常量!用这个就可以!

void game()
{
	//创建棋盘
	char board[R][C] = { 0 };
	//初始化棋盘
	InitBoard(board, R, C);
	//打印棋盘
	DisplayBoard(board, R, C);
}

5.打印棋盘

上面已经创建弄好了棋盘,但还没有实现真正棋盘的打印,先来看看我们期盼的棋盘,

三子棋小游戏【C语言】_第6张图片

下来我们就来打印一下和他差不多的一个吧!

void DisplayBoard(char board[R][C], int r, int c)
{
	for (int i = 0; i < r; i++)
	{
		for (int j = 0; j < c; j++)
		{
			printf(" %c ", board[i][j]);
			if(j < c - 1)
				printf("|");
		}
		printf("\n");

		if (i < r - 1)
		{
			for (int j = 0; j < c; j++)
			{
				printf("---");
				if (j < c - 1)
					printf("|");
			}
			printf("\n");
		}

	}
}

看效果:

三子棋小游戏【C语言】_第7张图片

这样就基本模拟出来了一个棋盘!

6.玩家落子

由于小编也还是刚刚还没入门的小菜鸡,不会高端的技术,所以我们就采用简单的,玩家下棋我们就采用坐标,玩家输入要落子的位置(行、列都是1---3),这里我猜您有疑问,数组不是下标从0开始的吗,这里怎么是1开始的,我们要理解玩家,不可能每个玩家都是程序员吧!实现思路:遍历数组,当玩家的落子位置没有被占用(是空格),用 * 号覆盖空格,如果落子位置已经被占用了,提醒玩家重新落子!

代码演示:

void PlayerMove(char board[R][C], int r, int c)
{
	int x = 0; 
	int y = 0;
	printf("玩家下棋: \n");
	while (1)
	{
		printf("请输入落子坐标:> ");
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= r && y >= 1 && y <= c)
		{
			if (board[x - 1][y - 1] == ' ')
			{
				board[x - 1][y - 1] = '*';
				break;
			}
			else
			{
				printf("此处已经被占用,请重新落子!\n");
			}
		}
		else
		{
			printf("落子坐标非法,请重新落子!\n");
		}
	}
}

当落子完之后给玩家反馈一下棋盘即落子后打印一遍棋盘!看效果:

三子棋小游戏【C语言】_第8张图片

OK玩家落子已解决!下面让我们来看看电脑落子吧!

7.电脑落子

电脑落子我们采用的是随机落子(在x,y都属于0---2),这里就不用x,y1--3了,因为是电脑,你让他怎样执行他就怎样执行!如何随机落子呢?我们想起来我们前面的猜数字游戏产生随机数的方法,上次是1--100,这次我们只要0-- 2即可!同样和上面玩家落子一样,得是 '  ' 时,才让落子。

代码演示:

void ComputerMove(char board[R][C], int r, int c)
{
	int x = 0;
	int y = 0;
	printf("电脑下棋: \n");
	while (1)
	{
		x = rand() % r;
		y = rand() % c;
		if (x >= 0 && x <= R && y >= 0 && y <= C)
		{
			if (board[x][y] == ' ')
			{
				board[x][y] = '#';
				break;
			}
		}
	}
}

ok!看效果:

三子棋小游戏【C语言】_第9张图片

经测试无问题!但现在面临的一个问题是他会无限制的落子找到棋盘满了,即使三个相同的相连了还不会停止,要解决这个问题,就要判断输赢! 

8.胜负判断

我们知道,三子棋当有三个相同的连起来时就结束了(某一方赢了),当棋盘满了还没有三个相同的相连时,就说明既不是玩家赢也不是电脑赢即平局了!如果棋盘没满就代表着还没有结束,继续下棋!

代码实现:

int IsFull(char board[R][C], int r, int c)
{
	for (int i = 0; i < r; i++)
	{
		for (int j = 0; j < c; j++)
		{
			if (board[i][j] == ' ')
			{
				return 0;
			}
		}
	}

	return 1;
}

//玩家赢返回'*' 电脑赢返回'#' 继续返回 'C' 平局返回'Q'
char IsWin(char board[R][C], int r, int c)
{
	//行
	for (int i = 0; i < r; i++)
	{
		if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][0] != ' ')
			return board[i][0];
	}

	//列
	for (int i = 0; i < c; i++)
	{
		if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ')
			return board[0][i];
	}

	//对角线
	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[2][0];

	//判断是否继续
	if (IsFull(board, r, c) == 1)
	{
		return 'Q';
	}
	
	return 'C';
}

我们来玩几把试一试:

三子棋小游戏【C语言】_第10张图片

三子棋小游戏【C语言】_第11张图片

三子棋小游戏【C语言】_第12张图片

三、全部游戏源码

game.h

#define _CRT_SECURE_NO_WARNINGS 1
#include
#include
#include
#define R 3
#define C 3

//初始化棋盘
void InitBoard(char board[R][C], int r, int c);
//打印棋盘
void DisplayBoard(char board[R][C], int r, int c);
//玩家下棋
void PlayerMove(char board[R][C], int r, int c);
//电脑下棋
void ComputerMove(char board[R][C], int r, int c);
//判断输赢
//玩家赢返回'*'  电脑赢返回'#'  继续返回 'C'  平局返回'Q'
char IsWin(char board[R][C], int r, int c);

game.c

#include"game.h"

void InitBoard(char board[R][C], int r, int c)
{
	for (int i = 0; i < r; i++)
	{
		for (int j = 0; j < c; j++)
		{
			board[i][j] = ' ';
		}
	}
}

void DisplayBoard(char board[R][C], int r, int c)
{
	for (int i = 0; i < r; i++)
	{
		for (int j = 0; j < c; j++)
		{
			printf(" %c ", board[i][j]);
			if(j < c - 1)
				printf("|");
		}
		printf("\n");

		if (i < r - 1)
		{
			for (int j = 0; j < c; j++)
			{
				printf("---");
				if (j < c - 1)
					printf("|");
			}
			printf("\n");
		}

	}
}


void PlayerMove(char board[R][C], int r, int c)
{
	int x = 0; 
	int y = 0;
	printf("玩家下棋: \n");
	while (1)
	{
		printf("请输入落子坐标:> ");
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= r && y >= 1 && y <= c)
		{
			if (board[x - 1][y - 1] == ' ')
			{
				board[x - 1][y - 1] = '*';
				break;
			}
			else
			{
				printf("此处已经被占用,请重新落子!\n");
			}
		}
		else
		{
			printf("落子坐标非法,请重新落子!\n");
		}
	}
}	


void ComputerMove(char board[R][C], int r, int c)
{
	int x = 0;
	int y = 0;
	printf("电脑下棋: \n");
	while (1)
	{
		x = rand() % r;
		y = rand() % c;
		if (x >= 0 && x <= R && y >= 0 && y <= C)
		{
			if (board[x][y] == ' ')
			{
				board[x][y] = '#';
				break;
			}
		}
	}
}


int IsFull(char board[R][C], int r, int c)
{
	for (int i = 0; i < r; i++)
	{
		for (int j = 0; j < c; j++)
		{
			if (board[i][j] == ' ')
			{
				return 0;
			}
		}
	}

	return 1;
}

//玩家赢返回'*' 电脑赢返回'#' 继续返回 'C' 平局返回'Q'
char IsWin(char board[R][C], int r, int c)
{
	//行
	for (int i = 0; i < r; i++)
	{
		if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][0] != ' ')
			return board[i][0];
	}

	//列
	for (int i = 0; i < c; i++)
	{
		if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ')
			return board[0][i];
	}

	//对角线
	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[2][0];

	//判断是否继续
	if (IsFull(board, r, c) == 1)
	{
		return 'Q';
	}
	
	return 'C';
}

test.c

#include"game.h"

void menu()
{
	printf("************************\n");
	printf("********1. play ********\n");
	printf("********0. exit ********\n");
	printf("************************\n");
}

void game()
{
	//创建棋盘
	char board[R][C] = { 0 };
	//初始化棋盘
	InitBoard(board, R, C);
	//打印棋盘
	DisplayBoard(board, R, C);
	char ret = 0;
	while (1)
	{
		//玩家下棋
		PlayerMove(board, R, C);
		DisplayBoard(board, R, C);
		//判断输赢
		ret = IsWin(board, R, C);
		if (ret != 'C')
			break;
		//电脑下棋
		ComputerMove(board, R, C);
		DisplayBoard(board, R, C);
		//判断输赢
		ret = IsWin(board, R, C);
		if (ret != 'C')
			break;
	}

	if (ret == '*')
		printf("玩家赢!\n");
	else if (ret == '#')
		printf("电脑赢!\n");
	else
		printf("平局!\n");

}

int main()
{
	srand((unsigned int)time(NULL));
	int input = 0;
	do
	{
		menu();
		printf("请输入操作数:> ");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();
			//printf("玩游戏!\n");
			break;
		case 0:
			printf("退出游戏!\n");
			break;
		default:
			printf("操作数非法,请重新输入!\n");
			break;
		}
	} while (input);

	return 0;
}

OK!好兄弟我们下期再见!

你可能感兴趣的:(c语言,开发语言)