这个简单的小游戏一定要会!使用C语言实现三子棋游戏

Posted ✯ SwaggerHYH

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了这个简单的小游戏一定要会!使用C语言实现三子棋游戏相关的知识,希望对你有一定的参考价值。

目录

一、游戏简介

二、游戏设计

2.1 棋盘设计

2.2 模型设计

三、游戏实现

3.1 SanZiQiMain.c

3.1.1 main(主模块)

3.1.2 choiceMenu(开始菜单)

3.2 Game.c

3.2.1 game(游戏执行)

3.2.2 boardInit(初始化数组)

3.2.3 displayBoard(显示棋盘)

3.2.4 playerMove(玩家下棋)

3.2.5 computerMove(电脑下棋)

3.2.6 isWin(判断赢棋)

四、游戏测试

五、游戏代码

3.1 Main.c

3.2 Game.c

3.3 Game.h


一、游戏简介

三子棋是黑白棋的一种。三子棋是一种民间传统游戏,又叫九宫棋、圈圈叉叉、一条龙、井字棋等。将正方形对角线连起来,相对两边依次摆上三个双方棋子,只要将自己的三个棋子走成一条线,对方就算输了。但是,有很多时候会出现和棋的情况。

二、游戏设计

2.1 棋盘设计

利用字符串,在屏幕上打印出一个‘#’号,作为游戏棋盘。(效果图如下)

2.2 模型设计

三、游戏实现

3.1 SanZiQiMain.c

3.1.1 main(主模块)

(1)模块功能及思路:本模块为程序的入口,通过此模块调入菜单,执行开始游戏或退出游戏的功能。同时也负责rand()函数的配置,rand()函数在之后生成随机数时需要调用,配置其的方法是在主模块中使用时间戳作为srand()函数的参数,这是编写本模块的要点,其它部分的编写思路较为简单,只需利用switch语句进行设计即可。

(2)模块代码:

int main()
{
	int flag = 0;

	do
	{
		srand((unsigned int)time(NULL));
		switch (flag = choiceMenu())
		{
		case 0:printf("退出游戏\\n"); break;
		case 1:game();break;
		default:printf("输入错误,请重新选择!\\n"); break;
		}
	} while (flag);

	return 0;
}

3.1.2 choiceMenu(开始菜单)

(1)模块功能及思路:该函数负责打印游戏开始菜单,同时需要返回玩家的选项值。

(2)模块代码:

int choiceMenu()
{
	int input = 0;

	printf("********************************\\n");
	printf("***********1. 开始游戏**********\\n");
	printf("***********0. 退出游戏**********\\n");
	printf("********************************\\n");
	printf("请选择>");
	scanf("%d", &input);

	return input;
}

3.2 Game.c

3.2.1 game(游戏执行)

(1)模块功能及思路:本模块负责游戏的执行。游戏执行的顺序为:显示棋盘——>玩家下棋——>显示棋盘——>判断是否赢棋——>电脑下棋——>显示棋盘——>判断是否赢棋……该过程在未区分出输赢之前应处在一个循环体之中。在此之前,我们还需要一个二维数组来存放每次下棋操作后的棋子信息,为了提高代码的复用性,数组的行与列采用宏定义的方式进行配置,同时这也是棋盘的行与列,之后将多次使用。为了方便管理,将其定义在Game.h文件下。

#define ROW 3
#define COL 3

由于显示棋盘时,需要打印二维数组中的内容,在第一次显示棋盘前,应当先对二维数组进行初始化,将其内部元素均置为‘ ’(空格)。

同时,在跳出循环体后,因根据赢棋判断函数打印出输赢信息,一轮游戏也就到此结束。

(2)模块代码:

void game()
{
	system("cls");
	char ret = 0;
	char board[ROW][COL];

	boardInit(board, ROW, COL);//初始化数组
	displayBoard(board, ROW, COL);//显示棋盘
	while (1)
	{
		playerMove(board, ROW, COL);//玩家下棋
		displayBoard(board, ROW, COL);//显示棋盘
		ret = isWin(board, ROW, COL);
		if (ret != 'C')
		{
			break;
		}//判断输赢
		computerMove(board, ROW, COL);//电脑下棋
		displayBoard(board, ROW, COL);//显示棋盘
		ret = isWin(board, ROW, COL);
		if (ret != 'C')
		{
			break;
		}//判断输赢
	}
	if (ret == '*')
	{
		printf("您赢了\\n");
	}
	else if (ret == '#')
	{
		printf("您输了\\n");
	}
	else
	{
		printf("平局\\n");
	}
}

3.2.2 boardInit(初始化数组)

(1)模块功能及思路:本模块要执行的是对数组的初始化。思路也非常简单,只需要利用循环对二维数组进行遍历即可。

(2)模块代码:

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

3.2.3 displayBoard(显示棋盘)

(1)模块功能及思路:在编写代码之前,已经设计好了棋盘。本函数只需按照固定格式打印出棋盘即可。难点在于根据行与列的值找到找到打印循环的规律。列入3x3时,每行打印的数据为3个,只需循环col次,而每行的分割线‘|’只需打印2次,所以只需要循环col-1次。打印行分割线时同理,最后一行的数据下面不需要分割线,因此在打印前判断i是否小于row-1即可。

(2)模块代码:

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

3.2.4 playerMove(玩家下棋)

(1)模块功能及思路:本模块执行的功能为玩家下棋,只需调整二维数组中的数据即可。需要注意的是判断输入数据是否合法(不超出行与列)判断所下位置是否已被占用

同时,为了取得更好的游玩效果,可以在适当的时候调用system("cls")进行清屏幕,使得游玩时显示的效果就是像在固定的棋盘上放下棋子,而不是刷新整个棋盘。

(2)模块代码:

void playerMove(char board[ROW][COL], int row, int col)
{
	int x = 0;
	int y = 0;

	printf("玩家走:\\n");
	while (1)
	{
		printf("请输入坐标>");
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
			if (board[x - 1][y - 1] != ' ')
			{
				printf("坐标已占用,请重新输入\\n");
			}
			else
			{
				board[x - 1][y - 1] = '*';
				system("cls");
				break;
			}
		}
		else
		{
			printf("坐标输入错误,请重新输入\\n");
		}
	}
}

3.2.5 computerMove(电脑下棋)

(1)模块功能及思路:基本思路与玩家下棋相似,重点在与如何使得计算机的到落子的坐标。这里就要运用到之前提到的rand()函数了,经过配置后,每次调用rand()函数会获取到一个随机值,而本模块所需要的随机值在0~2之间,所以只需利用%运算符即可。同理为了取得更好的游戏效果,添加了清屏代码延时代码Sleep(1000)(用于模拟电脑思考时间)

(2)模块代码:

void computerMove(char board[ROW][COL], int row, int col)
{
	printf("电脑走:\\n");
	Sleep(1000);
	while (1)
	{
		int x = rand() % 3;
		int y = rand() % 3;
		if (board[x][y] == ' ')
		{
			board[x][y] = '#';
			system("cls");
			break;
		}
	}
}

3.2.6 isWin(判断赢棋)

(1)模块功能及思路:本模块的返回值有四个方向:1.玩家赢;2.电脑赢;3.平局;4.游戏继续。

若在一次落子后,一方取得了胜利,则情况必为三横行、三竖行、两斜行中的一种,只需利用判断语句进行判断即可。同时若玩家获胜则返回*,电脑获胜则返回#(便于代码书写)。

若没有赢棋,则判断是否平局,只需要遍历数组判断其值是否均不为空格即可。

其它情况则游戏继续。

(2)模块代码:

char isWin(char board[ROW][COL], int row, int col)
{
	int i = 0;
	int flag = 1;

	for (i = 0; i < row; i++) 
	{
		if (board[i][0] != ' ' && board[i][0] == board[i][1] && board[i][0] == board[i][2])
		{
			return board[i][0];
		}
	}
	for (i = 0; i < col; i++) 
	{
		if (board[0][i] != ' ' && board[0][i] == board[1][i] && board[0][i] == board[2][i])
		{
			return board[0][i];
		}
	}
	if (board[0][0] != ' ' && board[0][0] == board[1][1] && board[0][0] == board[2][2])
	{
		return board[0][0];
	}
	if (board[2][0] != ' ' && board[2][0] == board[1][1] && board[2][0] == board[0][2])
	{
		return board[2][0];
	}
	for (i = 0; i < row; i++)
	{
		int j = 0;
		for (j = 0; j < col; j++)
		{
			if (board[i][j] == ' ')
			{
				flag = 0;
				break;
			}
		}
	}
	if (flag) 
	{
		return 'P';
	}
	return 'C';

	//1. 判断输赢*/#
	//2. 判断平局P
	//3. 游戏继续C
}

四、游戏测试

 

五、游戏代码

3.1 SanZiQiMain.c

#define _CRT_SECURE_NO_WARNINGS 1

#include "Game.h"

int choiceMenu()
{
	int input = 0;

	printf("********************************\\n");
	printf("***********1. 开始游戏**********\\n");
	printf("***********0. 退出游戏**********\\n");
	printf("********************************\\n");
	printf("请选择>");
	scanf("%d", &input);

	return input;
}

int main()
{
	int flag = 0;

	do
	{
		srand((unsigned int)time(NULL));
		switch (flag = choiceMenu())
		{
		case 0:printf("退出游戏\\n"); break;
		case 1:game();break;
		default:printf("输入错误,请重新选择!\\n"); break;
		}
	} while (flag);

	return 0;
}

3.2 Game.c

#define _CRT_SECURE_NO_WARNINGS 1

#include "Game.h"

void boardInit(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");
	}
}

void playerMove(char board[ROW][COL], int row, int col)
{
	int x = 0;
	int y = 0;

	printf("玩家走:\\n");
	while (1)
	{
		printf("请输入坐标>");
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
			if (board[x - 1][y - 1] != ' ')
			{
				printf("坐标已占用,请重新输入\\n");
			}
			else
			{
				board[x - 1][y - 1] = '*';
				system("cls");
				break;
			}
		}
		else
		{
			printf("坐标输入错误,请重新输入\\n");
		}
	}
}

void computerMove(char board[ROW][COL], int row, int col)
{
	printf("电脑走:\\n");
	Sleep(1000);
	while (1)
	{
		int x = rand() % 3;
		int y = rand() % 3;
		if (board[x][y] == ' ')
		{
			board[x][y] = '#';
			system("cls");
			break;
		}
	}
}

char isWin(char board[ROW][COL], int row, int col)
{
	int i = 0;
	int flag = 1;

	for (i = 0; i < row; i++) 
	{
		if (board[i][0] != ' ' && board[i][0] == board[i][1] && board[i][0] == board[i][2])
		{
			return board[i][0];
		}
	}
	for (i = 0; i < col; i++) 
	{
		if (board[0][i] != ' ' && board[0][i] == board[1][i] && board[0][i] == board[2][i])
		{
			return board[0][i];
		}
	}
	if (board[0][0] != ' ' && board[0][0] == board[1][1] && board[0][0] == board[2][2])
	{
		return board[0][0];
	}
	if (board[2][0] != ' ' && board[2][0] == board[1][1] && board[2][0] == board[0][2])
	{
		return board[2][0];
	}
	for (i = 0; i < row; i++)
	{
		int j = 0;
		for (j = 0; j < col; j++)
		{
			if (board[i][j] == ' ')
			{
				flag = 0;
				break;
			}
		}
	}
	if (flag) 
	{
		return 'P';
	}
	return 'C';

	//1. 判断输赢*/#
	//2. 判断平局P
	//3. 游戏继续C
}

void game()
{
	system("cls");
	char ret = 0;
	char board[ROW][COL];

	boardInit(board, ROW, COL);//初始化数组
	displayBoard(board, ROW, COL);//显示棋盘
	while (1)
	{
		playerMove(board, ROW, COL);//玩家下棋
		displayBoard(board, ROW, COL);//显示棋盘
		ret = isWin(board, ROW, COL);
		if (ret != 'C')
		{
			break;
		}//判断输赢
		computerMove(board, ROW, COL);//电脑下棋
		displayBoard(board, ROW, COL);//显示棋盘
		ret = isWin(board, ROW, COL);
		if (ret != 'C')
		{
			break;
		}//判断输赢
	}
	if (ret == '*')
	{
		printf("您赢了\\n");
	}
	else if (ret == '#')
	{
		printf("您输了\\n");
	}
	else
	{
		printf("平局\\n");
	}
}

3.3 Game.h

#pragma once

#include <stdlib.h>
#include <time.h>
#include <stdio.h>
#include <windows.h>
#define ROW 3
#define COL 3

void game();

以上是关于这个简单的小游戏一定要会!使用C语言实现三子棋游戏的主要内容,如果未能解决你的问题,请参考以下文章

C语言游戏跟电脑battle三子棋

C语言实现三子棋游戏

C语言—实现三子棋小游戏

用c语言写三子棋游戏

C语言实现游戏三子棋

用C语言实现三子棋游戏