用C语言编写三子棋

使用C语言编写三子棋:

一、制作整个游戏的框架

首先我们要先编写出整个游戏的框架,也就是要先有游戏菜单并且要能够实现菜单的功能,代码如下:

#define _CRT_SECURE_NO_WARNINGS 1

#include<stdio.h>

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

int main()
{
	int input = 0;
	
	do
	{
		menu();
		printf("请选择:>");
		scanf("%d", &input);

		switch (input)
		{
		case 1:
			Playgame();
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("选择错误,请重新选择\n");
			break;
		}
	} while (input);

	return 0;
}

通过switch语句可以让用户选择菜单的功能若输入1,则会进入Playgame函数屏幕会打印出“三子棋”,而进入到循环的条件判断部分时,input为1,游戏可以重新开始;若输入0,则循环条件为假,”退出游戏“并且程序终止,若既不是1也不是0,循环条件同样为真,用户需要重新需要重新选择。

二、初始化并展现空棋盘

1.初始化棋盘

游戏的基本框架构建完成后,接下来就是完善Playgame函数,该函数也是游戏的核心。首先我们要给用户呈现一个3x3的棋盘,不难想到要使用二维数组,这里我们定义一个init_board()函数先初始化棋盘,


#define ROW 3
#define COL 3

void init_board(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 Playgame()
{
	char board[ROW][COL];
    //初始化棋盘
	init_board(board, ROW, COL);
}

注意:这里为方便观察代码,只展现代码的一部分

2.展现空棋盘

#define ROW 3 和 #define COL 3 是为了方便未来如果需要不是3x3棋盘时更改数据更方便。可以看出这里将棋盘全部初始化为空格,这里只是初始化棋盘,还要为用户展现出棋盘的模样,但如果值单纯的打印初始化后的棋盘,用户看到的只是一片空白,所以要定义一个display_board()函数来完善棋盘。代码如下:

void display_board(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++)
		{
			printf(" %c ", board[i][j]);
			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");
		}
	}
}

void Playgame()
{
	char board[ROW][COL];
	//初始化棋盘
	init_board(board, ROW, COL);
    //展现空棋盘
	display_board(board, ROW, COL);
}

至此,整个代码可以为用户呈现出整个棋盘,如图:

三、玩家下棋和电脑下棋

 棋盘完成后,当然就要开始下棋喽,这里我们分别定义Playermove() 和 Computermove() 两个函数来编表示玩家下棋和电脑下棋

1.玩家下棋

void Playermove(char board[ROW][COL], int row, int col)
{
	int i = 0;//玩家输入的行
	int j = 0;//玩家输入的列
	while (1)
	{
		printf("玩家下棋,请输入坐标:");
		scanf("%d %d", &i, &j);

		if (board[i - 1][j - 1] == ' ')
		{
			board[i - 1][j - 1] = '*';
			break;
		}
		else
		{
			printf("输入错误,请重新输入:\n");
		}
	}
void Playgame()
{
	char board[ROW][COL];
	//初始化棋盘
	init_board(board, ROW, COL);
	display_board(board, ROW, COL);

	Playermove(board, ROW, COL);
	display_board(board, ROW, COL);//玩家每下完一步棋,就展示依次下完后的棋盘
}

我们知道数组的下标是从0开始的,但我们总不能指望玩家都是程序员,所以我们要将玩家输入的坐标分别减1,如果玩家输入的坐标的位置是空格,则将该位置赋值为 *  并终止循环,若玩家输入坐标的位置不是空格,则循环继续,玩家需重新输入坐标。

2.电脑下棋

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] = '#';
			break;
		}
			
	}
}
void Playgame()
{
	char board[ROW][COL];
	//初始化棋盘
	init_board(board, ROW, COL);
	display_board(board, ROW, COL);

	Playermove(board, ROW, COL);
	display_board(board, ROW, COL);
		
	Computermove(board, ROW, COL);
	display_board(board, ROW, COL);//电脑每下完一步就展示一次棋盘
}

这里还要在主函数的一开始加上这行代码    srand((unsigned int)time(NULL));这行代码是用来初始化随机数生成器的。srand函数需要传入一个unsigned int类型的参数作为种子,一般使用当前时间作为种子,可以保证每次运行程序时生成的随机数序列都是不同的。time(NULL)函数返回的是当前系统时间的秒数,因为时间在不断地变化,所以不同的时戳会对应不同的随机数序列。而    x = rand() % row; y = rand() % col; 是用来生成一个介于0到2之间的随机数的。rand()函数会生成一个大于等于0且小于等于RAND_MAX的随机整数,RAND_MAX是C语言标准库中的常量,表示由rand()函数生成的随机数的最大值,而%3的操作会将这个随机整数对3取模,得到的结果就是0、1、2之中的一个,因此x和y的值就是随机的0、1、2之中的一个。当x和y确定后,Computermove函数中如果坐标(x,y)处为空,则将其赋值为#。

四、判断结果

一盘棋的结果有,玩家获胜、电脑获胜、平局和继续下棋,所以我们定义一个isWin(),

int isFair(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;
}
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[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];
	}
	//判断是否平局
	if (isFair(board, row, col))
	{
		return 'Q';
	}

    //以上结果都不是则棋局继续
	return 'C';
}

无论是玩家赢还是电脑赢,在某一横线、竖线和斜线上肯定都是*或#,则我们将其返回至Playgame函数中若为平局,则返回Q,以上结果都不是则返回C,利用这些返回值,我们要在Play game函数中做文章。

void Playgame()
{
	char ret = 0;
	char board[ROW][COL];
	//初始化棋盘
	init_board(board, ROW, COL);
	display_board(board, ROW, COL);

	while (1)
	{
		Playermove(board, ROW, COL);
		display_board(board, ROW, COL);
		ret = isWin(board, ROW, COL);
		if (ret != 'C')
		{
			break;
		}
		Computermove(board, ROW, COL);
		display_board(board, ROW, COL);
		ret = isWin(board, ROW, COL);
		if (ret != 'C')
		{
			break;
		}

	}
	if (ret == '*')
	{
		printf("玩家获胜!\n");
	}
	else if (ret == '#')
	{
		printf("电脑获胜!\n");
	}
	else if (ret == 'Q')
	{
		printf("平局!\n");
	}
}

因为整盘棋中,玩家和电脑不可能只下一步棋,所以要在Playgeme函数中加一个while循环直到分出胜负,或平局循环终止。isWin()的返回值有ret接收,当ret不是C时循环终止,然后根据ret是什么来判断结果是什么。

五、完整代码展现

#define _CRT_SECURE_NO_WARNINGS 1

#include<stdio.h>
#include<string.h>
#include<time.h>

#define ROW 3
#define COL 3

void init_board(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 display_board(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++)
		{
			printf(" %c ", board[i][j]);
			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");
		}
	}
}

void Playermove(char board[ROW][COL], int row, int col)
{
	int i = 0;
	int j = 0;
	while (1)
	{
		printf("玩家下棋,请输入坐标:");
		scanf("%d %d", &i, &j);

		if (board[i - 1][j - 1] == ' ')
		{
			board[i - 1][j - 1] = '*';
			break;
		}
		else
		{
			printf("输入错误,请重新输入:\n");
		}
	}
}

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] = '#';
			break;
		}
			
	}
}

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

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[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];
	}
	
	if (isFair(board, row, col))
	{
		return 'Q';
	}
	return 'C';
}



void menu()
{
	printf("*************************\n");
	printf("*****   1. play    ******\n");
	printf("*****   0. exit    ******\n");
	printf("*************************\n");
}
void Playgame()
{
	char ret = 0;
	char board[ROW][COL];
	//初始化棋盘
	init_board(board, ROW, COL);
	display_board(board, ROW, COL);

	while (1)
	{
		Playermove(board, ROW, COL);
		display_board(board, ROW, COL);
		ret = isWin(board, ROW, COL);
		if (ret != 'C')
		{
			break;
		}
		Computermove(board, ROW, COL);
		display_board(board, ROW, COL);
		ret = isWin(board, ROW, COL);
		if (ret != 'C')
		{
			break;
		}

	}
	if (ret == '*')
	{
		printf("玩家获胜!\n");
	}
	else if (ret == '#')
	{
		printf("电脑获胜!\n");
	}
	else if (ret == 'Q')
	{
		printf("平局!\n");
	}

}

int main()
{
	int input = 0;
	srand((unsigned int)time(NULL));

	do
	{
		menu();
		printf("请选择:>");
		scanf("%d", &input);

		switch (input)
		{
		case 1:
			Playgame();
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("选择错误,请重新选择\n");
			break;
		}
	} while (input);



	return 0;

}

具体的运行,大家可以自行去尝试,那么谢谢大家阅读!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值