Bootstrap

用C语言实现简单的五子棋游戏


前言

昨天和妹妹玩了五子棋,突发奇想能不能用所学的C语言知识写出来一个简单的给两个人玩的五子棋程序,那么各位小伙伴认真听讲,准备开始咯。

一、五子棋的整体思路

整体的思维导图:
在这里插入图片描述
首先我们创建三个文件,一个是test.c,用于整个游戏程序的实现,第二个是game.c,用于整个游戏函数的定义,第三个是game.h,用于整个游戏函数定义的声明及所有头文件的包括。

1、菜单

这个函数的作用是我可以在菜单上选择我是继续游戏,还是退出游戏。

2、棋盘

棋盘定义为一个二维数组,在二维数组中,首先初始化为空格,便于后续管理。而我们要下棋,最好是把棋盘打印出来看看,在这个地方就设计一个简易棋盘。后文会有详细介绍。

3、下棋

下棋可以是玩家1和玩家2下棋,同样可以是玩家和电脑下棋。当然前者就比较简单了,电脑下棋的核心是根据随机值来落子,随机值的取值和使用就比较难。

4、判断输赢

这个就比较简单了,首先应该是先判断每一行,每一列是否有相同的五个棋子,如果没有,再来判断棋盘是否下满了?如果还没有,那就继续下棋,如果满了,就返回平局。

二、代码实现

1、主函数代码的实现

主函数中主要是完成对整个代码的实现及函数的调用及输赢的判断

#include "fun.h"
#include<stdio.h>
void menu()
{
	printf("************************\n");
	printf("************************\n");
	printf("****1.play    0.exit****\n");
	printf("************************\n");
	printf("************************\n");
}
void game()
{
	char ret = 0;
	char board [ROW][COL] = { 0 };
	Init(board, ROW, COL);
	DisplayBoard(board, ROW, COL);
	//初始化数组
	while (1)
	{
		//棋盘
		PlayerChess(board, ROW, COL);
		DisplayBoard(board, ROW, COL);
		ComputerChess(board, ROW, COL);
		DisplayBoard(board, ROW, COL);
		ret = is_win(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:
		{
			game();
			break;
		}
		case 0:
		{
			printf("欢迎下次再来玩五子棋,退出程序\n");
			break;
		}
		default:
		{
			printf("输出非法,请重新输入\n");
			break;
		}
		}
	} while (input);
	return 0;
}

2、game.h头文件

#pragma once
#define ROW 5
#define COL 5
#include<stdlib.h>
#include<time.h>
#include<stdio.h>

void Init(char board[ROW][COL],int row , int col);
void DisplayBoard(char board[ROW][COL],int row , int col);
void PlayerChess(char board[ROW][COL], int row, int col);
void ComputerChess(char board[ROW][COL], int row, int col);

char is_win(char board[ROW][COL], int row, int col);

3、初始化棋盘(数组)函数的实现

首先是要求将棋盘全部置为空格,方便后续管理

void Init(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] = ' '; // 将数组里所有的元素都置为空格
		}
	}
}

4、打印棋盘

首先想要一个简单的棋盘,可以很好的放置棋子,那么首先应该想到的就是,需要打印两行,第一行,是打印棋子,第二行是打印棋盘,不然后面很难管理,如果混在一起的话,看以下代码

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]);
			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");
	}
	
}

5、玩家下棋

首先玩家输入一个坐标,有一个注意的点是我们平时看到的数组,例如第三行第二列就是在数组内部其实是第二行第一列,注意这一点,首先讲一个很重要的函数,是用来判断是否棋盘放满了的函数

int is_full(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++)
		{
			if (board[i][j] == ' ')
				return 1;
		}
	}
	return 0;
}

玩家下棋的实现代码

void PlayerChess(char board[ROW][COL], int row, int col)
{
	int x = 0;
	int y = 0;
	printf("玩家下棋,请输入下棋的坐标:>");
	while (1)
	{
		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");
				DisplayBoard(board, ROW, COL);
				printf("请输入下棋的坐标:>");
			}
		}
		else
		{
			printf("输入非法,请重新输入\n");
			DisplayBoard(board, ROW, COL);
			printf("请输入下棋的坐标:>");
		}
		if (is_full(board, row, col) == 0)
			break;
	}
}

6、电脑下棋

首先我们要处理随机值的问题,一般使用rand()这个函数,使用rand之前,需要使用 srand 函数为伪随机数生成器提供种子
srand一般适合time函数连用,固定用法如下:
srand((unsigned int)time(NULL)),一般只在开头使用一次,那么在主函数中有声明

void ComputerChess(char board[ROW][COL], int row, int col)
{
	
	printf("电脑下棋\n");
	while (1)
	{
		int x = rand() % row+1; 
		int y = rand() % col+1;
		if (board[x - 1][y - 1] == ' ')
		{
			board[x - 1][y - 1] = '#';
			break;
		}
		if (is_full(board, row, col) == 0)
			break;
	}
}

7、判断输赢

平局:棋盘下满了还没分出胜负 返回Q字符
玩家胜利:返回值为 * 字符
电脑胜利:返回值为 # 字符
继续下棋:返回值为C字符
看实现代码:

char is_win(char board[ROW][COL], int row, int col)
{
	
	int i = 0;
	for (int i = 0; i < row; i++)
	{
		if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][2] == board[i][3] && board[i][3] == board[i][4] && board[i][0] != ' ')
			return board[i][0];
	}
	for (int i = 0; i < col; i++)
	{
		if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[2][i] == board[3][i] && board[3][i] == board[4][i] && board[0][i] != ' ')
			return board[0][i];
	}
	if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[2][2] == board[3][3] && board[3][3] == board[4][4] && board[2][2] != ' ')
		return board[0][0];
	if (board[0][4] == board[1][3] && board[1][3] == board[2][2] && board[2][2] == board[3][1] && board[3][1] == board[4][0] && board[2][2] != ' ')
		return board[0][4];

	if (is_full(board, row, col) == 0)
		return 'Q';
	return 'C';
}

三、总体代码实现及输出结果

test.c 函数和game.h函数上文均有说明,game.c函数如下,其实就是前面每个函数讲解的综合

#define  _CRT_SECURE_NO_WARNINGS 1
#include "fun.h"
void Init(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 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]);
			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");
	}
	
}
int is_full(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++)
		{
			if (board[i][j] == ' ')
				return 1;
		}
	}
	return 0;
}

void PlayerChess(char board[ROW][COL], int row, int col)
{
	int x = 0;
	int y = 0;
	printf("玩家下棋,请输入下棋的坐标:>");
	while (1)
	{
		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");
				DisplayBoard(board, ROW, COL);
				printf("请输入下棋的坐标:>");
			}
		}
		else
		{
			printf("输入非法,请重新输入\n");
			DisplayBoard(board, ROW, COL);
			printf("请输入下棋的坐标:>");
		}
		if (is_full(board, row, col) == 0)
			break;
	}
}
void ComputerChess(char board[ROW][COL], int row, int col)
{
	
	printf("电脑下棋\n");
	while (1)
	{
		int x = rand() % row+1; 
		int y = rand() % col+1;
		if (board[x - 1][y - 1] == ' ')
		{
			board[x - 1][y - 1] = '#';
			break;
		}
		if (is_full(board, row, col) == 0)
			break;
	}
}
char is_win(char board[ROW][COL], int row, int col)
{
	
	int i = 0;
	for (int i = 0; i < row; i++)
	{
		if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][2] == board[i][3] && board[i][3] == board[i][4] && board[i][0] != ' ')
			return board[i][0];
	}
	for (int i = 0; i < col; i++)
	{
		if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[2][i] == board[3][i] && board[3][i] == board[4][i] && board[0][i] != ' ')
			return board[0][i];
	}
	if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[2][2] == board[3][3] && board[3][3] == board[4][4] && board[2][2] != ' ')
		return board[0][0];
	if (board[0][4] == board[1][3] && board[1][3] == board[2][2] && board[2][2] == board[3][1] && board[3][1] == board[4][0] && board[2][2] != ' ')
		return board[0][4];

	if (is_full(board, row, col) == 0)
		return 'Q';
	return 'C';
}

玩家获胜:
在这里插入图片描述
电脑获胜:
在这里插入图片描述
平局:
在这里插入图片描述

总结

本文讲解了五子棋的实现方法,如果你觉得本文不错,还请给博主点个关注,后续会给大家带来更精彩的博文。

;