初学者的三子棋游戏

摘要:相信每个人都有一个设计游戏的梦想,都曾玩过王者农药,cf等许多游戏,对之充满好奇,好奇他是怎样做出来的呢。

目录

摘要:相信每个人都有一个设计游戏的梦想,都曾玩过王者农药,cf等许多游戏,对之充满好奇,好奇他是怎样做出来的呢。

一、设计游戏

1.游戏的基本流程

2.打印游戏菜单

3.规划

二、游戏划分

1.设计棋盘

2.打印棋盘

3.玩家下棋

4.电脑下棋

5.判断输赢

三、整个游戏代码

test.c

 game.c

 game.h


一、设计游戏

1.游戏的基本流程

首先一个代码的执行要现有main()函数

2.打印游戏菜单

可以通过函数的方法来使主函数变得简洁一些,写一个test()函数用来打印菜单,可以采用do—while循环来写,这样写可以先打印菜单,再判断玩家是否进行游戏。

创建一个整型变量,利用switch语句来判断是否进行下一步。

void test()
{
	int input = 0;
	do
	{
		//打印菜单
		printf("************n");
		printf("***1.开始***n");
		printf("***0.退出***n");
		printf("************n");
		//判断玩家的选择
		scanf("%d", &input);
		switch (input)
		{
		//选择1则执行游戏程序
		case 1:
				game();
				break;
		//选择0退出游戏
		case 0:
			break;
		//输入其他的数
		default:
			printf("请重新选择n");
		}
	} while (input);
}

3.规划

将每个部分分开

创建一个game.c文件将函数体部分放进game.c里。

创建一个game.h文件用来声明函数。

创建一个test.c文件写游戏的的主体部分

这样做可以合理规划,方便调试。

二、游戏划分

1.设计棋盘

要下棋得先有一个棋盘才能开始啊

首先棋盘3*3的大小

便采用#define来定义常量,也可以方便日后的棋盘大小的更改。

 棋盘的样子也想好了,那便定义一个二维数组用来当作棋盘。

接下就是初始化棋盘,并将其盘打印出来。

2.打印棋盘

要打印棋盘可以先将二维数组初始化为空格,编写一个函数    initialize_board(board, ROW, COL);

在game.c文件里编写函数体,进行二维数组的初始化。

//初始化棋盘
void initialize_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] = ' ';
		}
	}
}

当然要在game.h文件里声明该函数。

初始化后便可以将棋盘整体打印出来。

//打印棋盘
void printf_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)//这里来限制分割行的次数,重用打印2行---
		{
			for (j = 0; j < col; j++)//用来打印每列的---
			{
				printf("---");

				if (j < col - 1)//与上面一样,限制打印 | 的次数
					printf("|");
			}
			printf("n");
		}
	}
}

效果如下

我们来分析这一段代码,首先可以将棋盘分为三行三列,用 | 来隔离每个字符,分割行则利用 --- 来处理;

有2点需要注意:

第2列后不用打 | ,这时便需要限制他的打印次数,可以利用if语句的效果做到限制,编写出  if (j < col - 1)  用来限制打印 | 的次数。

第2行后不用打印 --- ,同样利用上面的if语句  if (i < row - 1)   来限制分割行的次数,只用打印2行分割行  ---   。

3.玩家下棋

棋盘已将打印出来,接下来便是游戏的开始了,这时就要往棋盘里下棋。

//玩家下棋
void play_game(char board[ROW][COL], int row, int col)
{
	//定义2个整型常量,来存放玩家输入的坐标位置
	int x = 0;
	int y = 0;
	printf("玩家下棋n");
	printf("请输入坐标n");
	
	while (1)
	{
		scanf("%d %d", &x, &y);
		//判断玩家输入的坐标是否在范围内
		if (x > 0 && x <= row && y > 0 && y <= col)
		{
			//判断坐标是否被占用
			if (board[x - 1][y - 1] == ' ')
			{
				board[x - 1][y - 1] = '*';
				break;
			}
			else
			{
				printf("坐标已被占用,请重新输入坐标。n");
			}
		}
		else
			printf("坐标非法n");
	}
}

4.电脑下棋

玩家下完棋,就该电脑下了,那电脑该怎么下棋呢?

这是要利用到库函数   rand()函数;来生成一个随机数。

//电脑下棋
void computer_game(char board[ROW][COL], int row, int col)
{
	int x = 0;
	int y = 0;
	while (1)
	{
		x = rand() % row;//生成0~2的数字
		y = rand() % col;//生成0~2的数字
		if (board[x][y] == ' ')
		{
			board[x][y] = '#';
			break;
		}
	}
}

这里的x = rand() % row; 很重要,%row可以将生成的数字保持在0~2之间,y也是一样。

其中使用rand()是需先引用srand((unsigned int)time(NULL));    //随机产生一个数

5.判断输赢

双方都下过棋了,就需要判断谁赢谁输,还是平局。

可以采用函数的返回类型来进行判断,C——继续,Q——平局,*——玩家赢,#——电脑赢。

//判断输赢
char is_win(char board[ROW][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][1] != ' ')
		{
			return board[i][0];
		}
	}
	//判断三列
	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[0][0];
	}
	//判断副对角线
	if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')
	{
		return board[0][2];
	}

	//判断平局
	//以上4种情况都不满足时
	if (1 == board_full(board, row, col))
	{
		return 'Q';
	}
	//继续
	return 'C';
}

在判断出没有人赢时,在利用  board_full(board, row, col)  函数进行检测棋盘是否下满,下满则返回1,否之返回0;

//判断
int board_full(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;
			
		}
	}
	//棋盘以下满,返回1;
	return 1;
}

所以game.c里的函数体也就结束了,剩下的便是在test.c文件中来接受返回的字符。

		//判断
		if ('C' != is_win(board, ROW, COL))
		{
			if ('*' == is_win(board, ROW, COL))
			{
				printf("玩家赢n");
				break;
			}
			if ('#' == is_win(board, ROW, COL))
			{
				printf("电脑赢n");
				break;
			}
			if ('Q' == is_win(board, ROW, COL))
			{
				printf("平局n");
				break;
			}
		}

记得在判断谁赢了后加上break;来终止循环。

在test.c文件中的game()函数中调用的函数有以下这些,这样写的好处是代码简单明了。方便检查错误。有很大的便利。

void game()
{
	//定义一个二维数组
	char board[ROW][COL] = { 0 };

	//初始化棋盘
	initialize_board(board, ROW, COL);

	//打印棋盘
	printf_board(board, ROW, COL);
	
	while (1)
	{
		//玩家下棋
		play_game(board, ROW, COL);
		//打印棋盘
		printf_board(board, ROW, COL);
		//判断
		if ('C' != is_win(board, ROW, COL))
		{
			if ('*' == is_win(board, ROW, COL))
			{
				printf("玩家赢n");
				break;
			}
			if ('#' == is_win(board, ROW, COL))
			{
				printf("电脑赢n");
				break;
			}
			if ('Q' == is_win(board, ROW, COL))
			{
				printf("平局n");
				break;
			}
		}

		//电脑下棋
		computer_game(board, ROW, COL);
		//打印棋盘
		printf_board(board, ROW, COL);
		//判断
		if ('C' != is_win(board, ROW, COL))
		{
			if ('*' != is_win(board, ROW, COL))
				printf("玩家赢n");
			if ('#' != is_win(board, ROW, COL))
				printf("电脑赢n");
			if ('Q' != is_win(board, ROW, COL))
				printf("平局n");
		}

	}
}

至此,整个游戏也便可以运行了。

快去试试写出自己的三子棋游戏。

三、整个游戏代码

test.c

#include"game.h"

void game()
{
	//定义一个二维数组
	char board[ROW][COL] = { 0 };

	//初始化棋盘
	initialize_board(board, ROW, COL);

	//打印棋盘
	printf_board(board, ROW, COL);
	
	while (1)
	{
		//玩家下棋
		play_game(board, ROW, COL);
		//打印棋盘
		printf_board(board, ROW, COL);
		//判断
		if ('C' != is_win(board, ROW, COL))
		{
			if ('*' == is_win(board, ROW, COL))
			{
				printf("玩家赢n");
				break;
			}
			if ('#' == is_win(board, ROW, COL))
			{
				printf("电脑赢n");
				break;
			}
			if ('Q' == is_win(board, ROW, COL))
			{
				printf("平局n");
				break;
			}
		}

		//电脑下棋
		computer_game(board, ROW, COL);
		//打印棋盘
		printf_board(board, ROW, COL);
		//判断
		if ('C' != is_win(board, ROW, COL))
		{
			if ('*' != is_win(board, ROW, COL))
				printf("玩家赢n");
			if ('#' != is_win(board, ROW, COL))
				printf("电脑赢n");
			if ('Q' != is_win(board, ROW, COL))
				printf("平局n");
		}

	}
}
void meau()
{
	//打印菜单
	printf("************n");
	printf("***1.开始***n");
	printf("***0.退出***n");
	printf("************n");
}
void test()
{
	int input = 0;
	srand((unsigned int)time(NULL));//随机产生一个数
	do
	{
		meau();
		printf("请选择n");
		//判断玩家的选择
		scanf("%d", &input);
		switch (input)
		{
			//选择1则执行游戏程序
		case 1:
			game();
			break;
			//选择0退出游戏
		case 0:
			break;
			//输入其他的数
		default:
			printf("请重新选择n");
			break;
		}
	} while (input);
}
int main()
{
	test();
	return 0;
}

 game.c

#include"game.h"

//初始化棋盘
void initialize_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 printf_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)//这里来限制分割行的次数,只用打印2行---
		{
			for (j = 0; j < col; j++)//用来打印每列的---
			{
				printf("---");

				if (j < col - 1)//与上面一样,限制打印 | 的次数
					printf("|");
			}
			printf("n");
		}
	}
}

//玩家下棋
void play_game(char board[ROW][COL], int row, int col)
{
	//定义2个整型常量,来存放玩家输入的坐标位置
	int x = 0;
	int y = 0;
	printf("玩家下棋n");
	printf("请输入坐标n");
	
	while (1)
	{
		scanf("%d %d", &x, &y);
		//判断玩家输入的坐标是否在范围内
		if (x > 0 && x <= row && y > 0 && y <= col)
		{
			//判断坐标是否被占用
			if (board[x - 1][y - 1] == ' ')
			{
				board[x - 1][y - 1] = '*';
				break;
			}
			else
			{
				printf("坐标已被占用,请重新输入坐标。n");
			}
		}
		else
			printf("坐标非法n");
	}
}

//电脑下棋
void computer_game(char board[ROW][COL], int row, int col)
{
	printf("电脑下棋n");
	int x = 0;
	int y = 0;
	while (1)
	{
		x = rand() % row;//生成0~2的数字
		y = rand() % col;//生成0~2的数字
		if (board[x][y] == ' ')
		{
			board[x][y] = '#';
			break;
		}
	}
}

//判断
int board_full(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;
			
		}
	}
	//棋盘以下满,返回1;
	return 1;
}

//判断输赢
char is_win(char board[ROW][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][1] != ' ')
		{
			return board[i][0];
		}
	}
	//判断三列
	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[0][0];
	}
	//判断副对角线
	if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')
	{
		return board[0][2];
	}

	//判断平局
	//以上4种情况都不满足时
	if (1 == board_full(board, row, col))
	{
		return 'Q';
	}
	//继续
	return 'C';
}

 game.h

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

#define ROW 3     //行
#define COL 3     //列

//初始化棋盘
void initialize_board(char board[ROW][COL], int row, int col);
//打印棋盘
void printf_board(char board[ROW][COL], int row, int col);
//玩家下棋
void play_game(char board[ROW][COL], int row, int col);
//电脑下棋
void computer_game(char board[ROW][COL], int row, int col);
//判断
char is_win(char board[ROW][COL], int row, int col);

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇

)">
下一篇>>