C语言实现五子棋小游戏(人VS人、人VS电脑分析+代码)


在这里插入图片描述

前言

之前写过三子棋游戏,现在在此基础上给大家分享下使用C语言实现五子棋游戏

游戏介绍

该游戏与三子棋类似,在一个棋盘上,谁先五子连成一线谁就赢,可以是横成一线,竖成一线,正三角斜线,反三角斜线。五子棋上手简单,而且很有趣,相信大家都玩过吧。
接下来为大家分析C语言编写五子棋游戏的过程。

一.设计思路

  • 首页要一个游戏主页菜单,可以选择玩家与玩家对战,玩家与电脑对战,以及退出游戏
  • 设计棋盘:初始化、打印棋盘,并且在每行头和每列头标注数字,方便玩家要落子的位置
  • 玩家1下棋和玩家2下棋或者玩家1与电脑下棋
  • 判断输赢,哪方落子先成一线就赢

游戏步骤:(玩家1vs玩家2与之相似)

void game1()
{
    
    
	char board[ROW][COL] = {
    
     0 };
	int k = 0;
	initboard(board, ROW, COL);//初始化棋盘
	displayboard(board, ROW, COL);//打印棋盘
	while (1)
	{
    
    
		player1move(board, ROW, COL);//玩家下棋
		displayboard(board, ROW, COL);//打印棋盘
		k = iswin(board, ROW, COL);//判断输赢
		if (k != 'c')
		{
    
    
			break;
		}
		computermove(board, ROW, COL);//电脑下棋
		displayboard(board, ROW, COL);//打印棋盘
		k = iswin(board, ROW, COL);//判断输赢
		if (k != 'c')
		{
    
    
			break;
		}
	}
	if (k == 'A')
	{
    
    
		printf("玩家赢\n");
	}
	else if (k == 'Z')
	{
    
    
		printf("电脑赢\n");
	}
	else
	{
    
    
		printf("平局\n");
	}
}

二.具体流程分析

1.主页设计

进入游戏界面,就显示菜单,用switch语句控制游戏要进入的入口,选择1玩家与电脑下棋,选择2玩家1与玩家2下棋,选择0退出游戏,输入其他的则输入有误,重新输入;使用do while()循环,这样可以玩完一局接着玩。

int main()//游戏主页
{
    
    
	int n = 0;
	srand((unsigned int)time(NULL));
	do
	{
    
    
		menu();
		printf("请选择是否进入游戏:");
		scanf("%d", &n);
		switch (n)
		{
    
    
		case 1:
			game1();//玩家1 VS 电脑
			break;
		case 2:
			game2();//玩家1 VS 玩家2
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("输入有误,请重新输入\n");
			break;
		}
	} while (n);
	return 0;
}

2.设计棋盘

使用二维数组board存储数据,ROW表示行,COL表示列,用#define来给行、列一个常量,这样后面方便修改棋盘的大小。调用initboard函数初始化棋盘,里面存放的是空格。

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

紧接着是打印棋盘,与三子棋不同,玩五子棋的棋盘较大,为了方便玩家要落子的位置,所以在行头和列头标注数字,相当于坐标。
先给每列头标注数字,再换行打印棋盘最上面的横线;外循环控制row行,内循环分别打印竖线和数据与竖线和横线,然后在行末增加竖线,这样棋盘更好看些。注意换行和空格。

void displayboard(char board[ROW][COL], int row, int col)
{
    
    
	printf("**·*·*·*·*·*·*·*·*·*·*·*·*·*·*·*·*·**\n");
	int i = 0;
	int j = 0;
	printf("  ");
	for (i = 0; i < row; i++)
	{
    
    
		printf(" %2d ", i + 1);//打印每列的坐标数字
	}
	printf("\n");
	printf("  ");
	for (j = 0; j < col; j++)
	{
    
    
		printf("----");//打印最上行横线
	}
	printf("\n");
	for (i = 0; i < row; i++)
	{
    
    
		printf("%2d", i + 1);//打印每行的坐标数字
		for (j = 0; j < col; j++)
		{
    
    
			
			printf("|");//先打印竖杆
			printf(" %c ", board[i][j]);//再打印空格和数据
			if (j == col - 1)//每行的最后一列补上竖杆
				printf("|");
		}
		printf("\n");
		printf("  ");
		for (j = 0; j < col; j++)
		{
    
    
			printf("|");//先打印竖杆
			printf("---");//再打印横线
			if (j == col - 1)//每行的最后一列补上竖杆
				printf("|");
		}
		printf("\n");
	}
	printf("**·*·*·*·*·*·*·*·*·*·*·*·*·*·*·*·*·**\n");
}

效果图:

在这里插入图片描述

3.玩家(1或2)下棋和电脑下棋

玩家下棋:设置两个变量x,y分别为表示输入的行坐标和列坐标,x和y必须在棋盘的范围内,超出坐标范围则不打印,又因为数组下标是从0开始的,所以当某个坐标为空时,方括号应写成x-1和y-1,落子成功则跳出循环。

void player2move(char board[ROW][COL], int row, int col)
{
    
    
	int x = 0;
	int y = 0;
	while (1)
	{
    
    
		printf("玩家2下棋:>\n");
		printf("请输入要下的坐标(12行/12列):");
		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] = 'D';
				break;
			}
			else
			{
    
    
				printf("该坐标已被占用,请重新输入!\n");
			}
		}
		else
		{
    
    
			printf("坐标不在棋盘范围内,请重新输入!\n");
		}
	}
}

电脑下棋:设置随机数,为空则打印,然后跳出循环,否则继续

void computermove(char board[ROW][COL], int row, int col)
{
    
    
	int x = 0;
	int y = 0;
	while (1)
	{
    
    
		printf("电脑下棋:>\n");
		x = rand() % row;
		y = rand() % col;
		if (board[x][y] == ' ')
		{
    
    
			board[x][y] = 'Z';
			break;
		}
	}
}

4.判断输赢

返回’A’,玩家1赢;返回’D’,玩家2赢;返回’Z’,电脑赢;返回 ‘c’ 继续;返回其他平局
赢的方式:
1.行成五子
2.列成五子
3.正三角斜线成五子
4.反三角斜线成五子

int isfull(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 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++)
	{
    
    
		for (j = 0; j < col - 4; j++)
		{
    
    
			if (board[i][j] == board[i][j + 1] && board[i][j + 1] == board[i][j + 2] && board[i][j + 2] ==
				board[i][j + 3] && board[i][j + 3] == board[i][j + 4] && board[i][j] != ' ')
			{
    
    
				return board[i][j];
			}
		}
	}
	//列成五子
	for (j = 0; j < col; j++)
	{
    
    
		for (i = 0; i < row - 4; i++)
		{
    
    
			if (board[i][j] == board[i + 1][j] && board[i + 1][j] == board[i + 2][j] && board[i + 2][j] ==
				board[i + 3][j] && board[i + 3][j] == board[i + 4][j] && board[i][j] != ' ')
			{
    
    
				return board[i][j];
			}
		}
	}
	//正斜成五子
	for (i = 0; i < row; i++)
	{
    
    
		for (j = 0; j < col; j++)
		{
    
    
			if (board[i][j] == board[i + 1][j + 1] && board[i + 1][j + 1] == board[i + 2][j + 2] &&
				board[i + 2][j + 2] == board[i + 3][j + 3] && board[i + 3][j + 3] == board[i + 4][j + 4] &&
				board[i][j] != ' ')
			{
    
    
				return board[i][j];
			}
		}
	}
	//反斜成五子
	for (i = 0; i < row; i++)
	{
    
    
		for (j = 0; j < col; j++)
		{
    
    
			if (board[i][j] == board[i - 1][j + 1] && board[i - 1][j + 1] == board[i - 2][j + 2] &&
				board[i - 2][j + 2] == board[i - 3][j + 3] && board[i - 3][j + 3] == board[i - 4][j + 4] &&
				board[i][j] != ' ')
			{
    
    
				return board[i][j];
			}
		}
	}
	//棋盘满了平局,否则继续
	if (isfull(board, ROW, COL) == 1)
	{
    
    
		return 'q';
	}
	return 'c';
}

在这里插入图片描述
在这里插入图片描述

全部代码:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define ROW 12
#define COL 12
//初始化棋盘
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 displayboard(char board[ROW][COL], int row, int col)
{
    
    
	printf("**·*·*·*·*·*·*·*·*·*·*·*·*·*·*·*·*·**\n");
	int i = 0;
	int j = 0;
	printf("  ");
	for (i = 0; i < row; i++)
	{
    
    
		printf(" %2d ", i + 1);//打印每列的坐标数字
	}
	printf("\n");
	printf("  ");
	for (j = 0; j < col; j++)
	{
    
    
		printf("----");//打印最上行横线
	}
	printf("\n");
	for (i = 0; i < row; i++)
	{
    
    
		printf("%2d", i + 1);//打印每行的坐标数字
		for (j = 0; j < col; j++)
		{
    
    
			
			printf("|");//先打印竖杆
			printf(" %c ", board[i][j]);//再打印空格和数据
			if (j == col - 1)//每行的最后一列补上竖杆
				printf("|");
		}
		printf("\n");
		printf("  ");
		for (j = 0; j < col; j++)
		{
    
    
			printf("|");//先打印竖杆
			printf("---");//再打印横线
			if (j == col - 1)//每行的最后一列补上竖杆
				printf("|");
		}
		printf("\n");
	}
	printf("**·*·*·*·*·*·*·*·*·*·*·*·*·*·*·*·*·**\n");
}
//玩家1下棋
void player1move(char board[ROW][COL], int row, int col)
{
    
    
	int x = 0;
	int y = 0;
	while (1)
	{
    
    
		printf("玩家1下棋:>\n");
		printf("请输入要下的坐标(12行/12列):");
		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] = 'A';
				break;
			}
			else
			{
    
    
				printf("该坐标已被占用,请重新输入!\n");
			}
		}
		else
		{
    
    
			printf("坐标不在棋盘范围内,请重新输入!\n");
		}
	}
}
//玩家2下棋
void player2move(char board[ROW][COL], int row, int col)
{
    
    
	int x = 0;
	int y = 0;
	while (1)
	{
    
    
		printf("玩家2下棋:>\n");
		printf("请输入要下的坐标(12行/12列):");
		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] = 'D';
				break;
			}
			else
			{
    
    
				printf("该坐标已被占用,请重新输入!\n");
			}
		}
		else
		{
    
    
			printf("坐标不在棋盘范围内,请重新输入!\n");
		}
	}
}
//电脑下棋
void computermove(char board[ROW][COL], int row, int col)
{
    
    
	int x = 0;
	int y = 0;
	while (1)
	{
    
    
		printf("电脑下棋:>\n");
		x = rand() % row;
		y = rand() % col;
		if (board[x][y] == ' ')
		{
    
    
			board[x][y] = 'Z';
			break;
		}
	}
}
//判断输赢
int isfull(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 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++)
	{
    
    
		for (j = 0; j < col - 4; j++)
		{
    
    
			if (board[i][j] == board[i][j + 1] && board[i][j + 1] == board[i][j + 2] && board[i][j + 2] ==
				board[i][j + 3] && board[i][j + 3] == board[i][j + 4] && board[i][j] != ' ')
			{
    
    
				return board[i][j];
			}
		}
	}
	//列成五子
	for (j = 0; j < col; j++)
	{
    
    
		for (i = 0; i < row - 4; i++)
		{
    
    
			if (board[i][j] == board[i + 1][j] && board[i + 1][j] == board[i + 2][j] && board[i + 2][j] ==
				board[i + 3][j] && board[i + 3][j] == board[i + 4][j] && board[i][j] != ' ')
			{
    
    
				return board[i][j];
			}
		}
	}
	//正斜成五子
	for (i = 0; i < row; i++)
	{
    
    
		for (j = 0; j < col; j++)
		{
    
    
			if (board[i][j] == board[i + 1][j + 1] && board[i + 1][j + 1] == board[i + 2][j + 2] &&
				board[i + 2][j + 2] == board[i + 3][j + 3] && board[i + 3][j + 3] == board[i + 4][j + 4] &&
				board[i][j] != ' ')
			{
    
    
				return board[i][j];
			}
		}
	}
	//反斜成五子
	for (i = 0; i < row; i++)
	{
    
    
		for (j = 0; j < col; j++)
		{
    
    
			if (board[i][j] == board[i - 1][j + 1] && board[i - 1][j + 1] == board[i - 2][j + 2] &&
				board[i - 2][j + 2] == board[i - 3][j + 3] && board[i - 3][j + 3] == board[i - 4][j + 4] &&
				board[i][j] != ' ')
			{
    
    
				return board[i][j];
			}
		}
	}
	//棋盘满了平局,否则继续
	if (isfull(board, ROW, COL) == 1)
	{
    
    
		return 'q';
	}
	return 'c';
}
//玩家1 VS 电脑
void game1()
{
    
    
	char board[ROW][COL] = {
    
     0 };
	int k = 0;
	initboard(board, ROW, COL);//初始化棋盘
	displayboard(board, ROW, COL);//打印棋盘
	while (1)
	{
    
    
		player1move(board, ROW, COL);//玩家下棋
		displayboard(board, ROW, COL);//打印棋盘
		k = iswin(board, ROW, COL);//判断输赢
		if (k != 'c')
		{
    
    
			break;
		}
		computermove(board, ROW, COL);//电脑下棋
		displayboard(board, ROW, COL);//打印棋盘
		k = iswin(board, ROW, COL);//判断输赢
		if (k != 'c')
		{
    
    
			break;
		}
	}
	if (k == 'A')
	{
    
    
		printf("玩家赢\n");
	}
	else if (k == 'Z')
	{
    
    
		printf("电脑赢\n");
	}
	else
	{
    
    
		printf("平局\n");
	}
}
//玩家1 VS 玩家2
void game2()
{
    
    
	char board[ROW][COL] = {
    
     0 };
	int k = 0;
	initboard(board, ROW, COL);//初始化棋盘
	displayboard(board, ROW, COL);//打印棋盘
	while (1)
	{
    
    
		player1move(board, ROW, COL);//玩家1下棋
		displayboard(board, ROW, COL);//打印棋盘
		k = iswin(board, ROW, COL);//判断输赢
		if (k != 'c')
		{
    
    
			break;
		}
		player2move(board, ROW, COL);//玩家2下棋
		displayboard(board, ROW, COL);//打印棋盘
		k = iswin(board, ROW, COL);//判断输赢
		if (k != 'c')
		{
    
    
			break;
		}
	}
	if (k == 'A')
	{
    
    
		printf("玩家1赢\n");
	}
	else if (k == 'D')
	{
    
    
		printf("玩家2赢\n");
	}
	else
	{
    
    
		printf("平局\n");
	}
}
void menu()//打印菜单
{
    
    
	printf("----------------------------------\n");
	printf("---------* 五子棋小游戏 *---------\n");
	printf("--------* 1.玩家1 VS 电脑 *-------\n");
	printf("--------* 2.玩家1 VS 玩家2 *------\n");
	printf("-----------* 0.退出游戏 *---------\n");
	printf("----------------------------------\n");
}
int main()//游戏主页
{
    
    
	int n = 0;
	srand((unsigned int)time(NULL));
	do
	{
    
    
		menu();
		printf("请选择是否进入游戏:");
		scanf("%d", &n);
		switch (n)
		{
    
    
		case 1:
			game1();//玩家1 VS 电脑
			break;
		case 2:
			game2();//玩家1 VS 玩家2
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("输入有误,请重新输入\n");
			break;
		}
	} while (n);
	return 0;
}

好了,分享到此结束。如果喜欢,可以邀请你的小伙伴一起玩哦~

猜你喜欢

转载自blog.csdn.net/2301_77459845/article/details/131500895