C | 简易三子棋的实现

相信大家都玩过三子棋吧,在一个九宫格内,谁先实现三个棋子连线,谁就获得胜利!
C | 简易三子棋的实现_第1张图片

今天,我们就一起用C语言来实现简易版的三子棋。

首先,我们的思路大致如下:

1.程序开始时打印菜单,让玩家选择开始游戏还是退出游戏

2.玩家选择游戏后进入游戏

3.判断输赢后,重新回到菜单

为了更好的管理代码,我们建立三个文件,分别是:
game.c 用于游戏函数的实现
game.h 用于游戏函数的声明
test.c 用于测试相关的游戏函数

程序主体框架如下:

该框架放在test.c文件中,用于调用游戏函数

enum Choose
{
     
	EXIT,
	PLAY
};

int main()
{
     
	int input = 0;
	do
	{
     
		menu();
		scanf("%d", &input);

		switch (input)
		{
     
		case PLAY:
			game();//选择了玩游戏后,调用game函数来进行游戏
			break;
		case EXIT:
			printf("退出游戏\n");
			break;
		default:
			printf("选择有误,请重新选择\n");
			break;

		}

	} while (input);//当input为0时,推出循坏,结束程序


	return 0;
}

菜单函数的实现:

该函数实现放在game.c文件中,方便调用,方便管理

而该函数的声明,我们放在game.h中即可,我们只需要在test.c中引用game.h头文件就可以使用该函数了

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

游戏函数的实现:

我们为了日后维护的方便,同时为了能够将三子棋升级为五子棋甚至更大的棋盘

我们在定义棋盘的时候,不要把大小写死,可以通过define来定义大小

define定义放在game.h中

#define ROW 3
#define COL 3

接下来就是重中之重的game函数实现

game函数里面,包括了棋盘(二维数组)创建的函数,棋盘初始化的函数,打印棋盘的函数,玩家下棋的函数,电脑下棋的函数,判断棋盘是否已满的函数以及判断玩家或者电脑是否赢了的函数

由于函数众多,我们就不一一在game函数内部定义,统一再game函数外定义,通过game函数调用来完成游戏过程

void game()
{
     
	//该函数用于实现三子棋

	//创建棋盘数组
	char board[ROW][COL];

	//初始化棋盘数组
	Initboard(board,ROW,COL);

	//打印棋盘
	Printboard(board, ROW, COL);



	while (1)
	{
     

		int ret = 0;
		char tmp = 0;
		//玩家输入坐标来下棋
		Playermove(board, ROW, COL);
		Printboard(board, ROW, COL);

		//判断是否赢了
		tmp = Iswin(board, ROW, COL);
		if (tmp == '*')
		{
     
			printf("玩家赢了\n");
			break;
		}

		else if (tmp == '#')
		{
     
			printf("电脑赢了\n");
			break;
		}

		//判断棋盘是否已满
		ret = Isfull(board, ROW, COL);
		if (1 == ret)
			break;

		//电脑下棋
		Computermove(board, ROW, COL);
		Printboard(board, ROW, COL);

		//判断是否赢了
		tmp = Iswin(board, ROW, COL);
		if (tmp == '*')
		{
     
			printf("玩家赢了\n");
			break;
		}

		else if (tmp == '#')
		{
     
			printf("电脑赢了\n");
			break;
		}

		//判断棋盘是否已满
		ret = Isfull(board, ROW, COL);
		if (1 == ret)
			break;
	}


}

棋盘初始化的函数:

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 Printboard(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));
			if (j < col - 1)
			{
     
				printf("|");
			}
		}
		printf("\n");
		for (j = 0; j < col; j++)
		{
     
			if (i < row - 1)
				printf("--- ");
		}

		printf("\n");
	}
}

玩家下棋的函数:
玩家通过输入坐标来下棋,同时要注意判断玩家输入的坐标是否再棋盘大小范围之内,还要判断玩家输入的坐标对应的位置有没有放棋子。

void Playermove(char board[ROW][COL], int row, int col)
{
     
	int x = 0;
	int y = 0;
	while (1)
	{
     
		printf("请玩家输入:>\n");
		scanf("%d %d", &x, &y);
		//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] = '*';
				break;
			}
			else
				printf("该位置已被占用,请重新输入\n");
		}
		else
		{
     
			printf("输入有误,请重新输入\n");
		}

	}
}

电脑下棋的函数:
电脑下棋,在这里我们就用最简单的生成随机数来实现,就不设计更优(电脑能够主动赢,或者会堵玩家棋)的算法了(其实是我能力有限,想不到QAQ)

void Computermove(char (*board)[COL], int row, int col)
{
     
	printf("电脑走:>\n");

	while (1)
	{
     
		int x = (rand() % row);
		int y = (rand() % col);
		if (board[x][y] == ' ')
		{
     
			board[x][y] = '#';
			break;
		}
	}
}

判断棋盘是否已满的函数:
玩家和电脑每走一步,就应该调用该函数来判断棋盘是否已满,若已满,则需返回一个已满的条件,便于让循环终止

int  Isfull(char(*board)[COL], int row, int col)
{
     
	int i = 0;
	for (i = 0; i < row; i++)
	{
     
		int j = 0;
		for (j = 0; j < col; j++)
		{
     
			if (board[i][j] == ' ')
			{
     
				return 0;
			}
		}
	}
	if (ROW == i)
	{
     
		printf("棋盘已满,退出游戏\n");
		return 1;
	}
}

判断输赢的函数:
玩家和电脑每走一步,就应该调用该函数,用于判断输赢,若已经分出胜负,则需要返回一个能够判断输赢的条件,便于让循环终止

char Iswin(char(*board)[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[0][i] != ' ')
		{
     
			return board[0][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];
}

以上就是各个函数的定义了

我们只需要把思路整理一下,把每一个函数的定义放在game函数之前,并且把以上的函数都放在game.c文件即可,至于上述函数的声明,我们放在game.h中,我们只需要再test.c和game.c中各自引用game.h就可以啦

最后的汇总:

test.c

#include"game.h";
//三子棋的测试

enum Choose
{
     
	EXIT,
	PLAY
};


int main()
{
     
	int input = 0;
	do
	{
     
		menu();
		srand((unsigned int)time(NULL));
		scanf("%d", &input);

		switch (input)
		{
     
		case EXIT:
			printf("退出游戏\n");
			break;
		case PLAY:
			game();
			break;
		default:
			printf("输入有误,请重新选择\n");
			break;
		}

	} while (input);
	return 0;
}

game.c

//游戏相关函数的实现
#include"game.h"


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

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 Printboard(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));
			if (j < col - 1)
			{
     
				printf("|");
			}
		}
		printf("\n");
		for (j = 0; j < col; j++)
		{
     
			if (i < row - 1)
				printf("--- ");
		}

		printf("\n");
	}
}

void Playermove(char board[ROW][COL], int row, int col)
{
     
	int x = 0;
	int y = 0;
	while (1)
	{
     
		printf("请玩家输入:>\n");
		scanf("%d %d", &x, &y);
		//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] = '*';
				break;
			}
			else
				printf("该位置已被占用,请重新输入\n");
		}
		else
		{
     
			printf("输入有误,请重新输入\n");
		}

	}
}

//char board[ROW][COL]
void Computermove(char (*board)[COL], int row, int col)
{
     
	printf("电脑走:>\n");

	while (1)
	{
     
		int x = (rand() % row);
		int y = (rand() % col);
		if (board[x][y] == ' ')
		{
     
			board[x][y] = '#';
			break;
		}
	}
}

int  Isfull(char(*board)[COL], int row, int col)
{
     
	int i = 0;
	for (i = 0; i < row; i++)
	{
     
		int j = 0;
		for (j = 0; j < col; j++)
		{
     
			if (board[i][j] == ' ')
			{
     
				return 0;
			}
		}
	}
	if (ROW == i)
	{
     
		printf("棋盘已满,退出游戏\n");
		return 1;
	}
}


char Iswin(char(*board)[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[0][i] != ' ')
		{
     
			return board[0][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];
}

void game()
{
     
	//该函数用于实现三子棋

	//创建棋盘数组
	char board[ROW][COL];

	//初始化棋盘数组
	Initboard(board,ROW,COL);

	//打印棋盘
	Printboard(board, ROW, COL);



	while (1)
	{
     

		int ret = 0;
		char tmp = 0;
		//玩家输入坐标来下棋
		Playermove(board, ROW, COL);
		Printboard(board, ROW, COL);

		//判断是否赢了
		tmp = Iswin(board, ROW, COL);
		if (tmp == '*')
		{
     
			printf("玩家赢了\n");
			break;
		}

		else if (tmp == '#')
		{
     
			printf("电脑赢了\n");
			break;
		}

		//判断棋盘是否已满
		ret = Isfull(board, ROW, COL);
		if (1 == ret)
			break;

		//电脑下棋
		Computermove(board, ROW, COL);
		Printboard(board, ROW, COL);

		//判断是否赢了
		tmp = Iswin(board, ROW, COL);
		if (tmp == '*')
		{
     
			printf("玩家赢了\n");
			break;
		}

		else if (tmp == '#')
		{
     
			printf("电脑赢了\n");
			break;
		}

		//判断棋盘是否已满
		ret = Isfull(board, ROW, COL);
		if (1 == ret)
			break;
	}


}

game.h

//游戏函数的声明
//棋盘大小的定义

#include
#include
#include
#include
#define ROW 3
#define COL 3

void menu();
void game();

好啦,三子棋游戏的实现到这里就结束啦


结语:
创作不易,希望大家可以点赞、评论、转发、关注一条龙哦!

你们的支持是我创作最大的动力!!

由于本人能力有限,若有错误,希望指正!!

如果有更好的方法或者想法,也欢迎再评论区留言哦~

C | 简易三子棋的实现_第2张图片

你可能感兴趣的:(c语言,数据结构)