C语言编写小游戏:Tic Tac Toe(三子棋)

    三子棋:在3*3的棋盘中,谁先用自己的棋走出一条直线(横着三个/竖着三个/对角线三个),谁就算赢!下面我们就来一起编写一下这个小游戏吧!!!

    首先我们先生成一个游戏菜单:

void menu()
{
	printf("*****三子棋*****\n");
	printf("*****1:play*****\n");
	printf("*****0:exit*****\n");
	printf("Please select:");
}

    下面我们写一下主函数:

int main()
{
	int a = 0;
	do
	{
		menu();//先调游戏菜单
		scanf("%d",&a);//接受玩家输入的数字
		switch(a)//判断玩家输入的数字
		{
		case 1:
			game();//如果玩家输入1,表示玩游戏,直接进入game()!
			break;
		case 0:
			exit(0);//如果玩家输入0,表示退出游戏,直接退出!
		default://表示玩家输入了其他数字,出错,提示重新输入!
			printf("Error!Please try again!\n");
			break;
		}
	}while(1);
	system("pause");
	return 0;
}

    因为我们后面要用到一个3*3的二维数组,所以我们先宏定义两个变量,以便后面使用:

#define ROW 3
#define COL 3

    main函数写完了,就到了我们的游戏逻辑部分game():

void game()
{
	char a;
	char arr[ROW][COL];//定义一个3*3的数组
	memset(arr,' ',ROW*COL);//将数组arr的内容全部赋值为空格
	do
	{      
		print_board(arr,ROW);//因为玩家要玩游戏,所以我们要在屏幕上打印出来一个棋盘
		player_move(arr,ROW);//打印出棋盘之后,玩家开始下棋
		a = is_win(arr,ROW);//玩家下完棋后,开始判断游戏结果
		if(a!=' ') //  ‘ ’:没人赢
		{
			break;//如果已经分出胜负,跳出循环
		}		
		computer_move(arr,ROW);//如果没有分出胜负,电脑下棋
		a = is_win(arr,ROW);//下完之后判断游戏结果
	}while(a == ' ');
	if(a == 'x')//判断玩家是否获胜:‘x’代表玩家获胜
		printf("Congratulations,you win!\n");
	else if(a == 'o')//判断玩家是否获胜:‘o’代表电脑获胜
		printf("It's too bad,you lose!\n");
	else //判断是否是平局
		printf("Draw!\n");

} 

    好了,游戏主逻辑已经编好,我们开始写所用到的函数,我们先来写打印棋盘的函数:

    棋盘样式看个人喜好,下面写了一种简单的

void print_board(char arr[][COL],int row)
{
	int i = 0;
	for(;i<ROW;i++)
	{	printf    (" %c | %c | %c \n",arr[i][0],arr[i][1],arr[i][2]);
		if(i!=ROW-1)
			printf("---|---|---\n");
	}
}

    展示一下打印出来的样式:

    打印出棋盘之后,就轮到我们下棋了,下面先编写玩家下棋的函数:

void player_move(char arr[][COL],int row)
{
	int x,y;//先定义两个变量,以便接收玩家下棋的坐标
	do
	{
		printf("Please input your coordinate:(x,y)!");//提示玩家下棋
		scanf("%d%d",&x,&y);//接收玩家所下的位置
		if(x>=1 && x<=3 && y>=1 && y<=3)//判断玩家输入坐标是否有误
			if(arr[x-1][y-1]==' ')//判断玩家输入的位置是否已经被占
			{	arr[x-1][y-1]= 'x';//将玩家输入的位置用‘x’占用
				break;
			}	
			else//玩家输入位置被占,提示玩家重新输入位置
				printf("Error!This place was be used!\n");
		else//玩家输入坐标有误,直接提示玩家error
			printf("Error!");
	}while(1);
}
    下面再来编写电脑下棋的函数:
void computer_move(char arr[][COL],int row)
{
	srand((unsigned long)time(NULL));//利用函数生成随机数
	do
	{
		int x = rand() % row;//控制随机数小于3并把结果赋给横坐标
		int y = rand() % COL;//控制随机数小于3并把结果赋给纵坐标
                if(arr[x][y] == ' ')//判断电脑选择的位置是否被占
		{	arr[x][y] = 'o';//将电脑下棋的位置用‘o’占用
			break;
		}
	}while(1);
}
    下完棋之后,我们要判断是产生了游戏结果,所以我们写判断游戏结果的函数:
char is_win(char arr[][COL],int row)
{
	int i = 0;
	for(;i<3;i++)//判断第i行是否全都相同
	{
		if(arr[i][0]==arr[i][1]&&arr[i][1]==arr[i][2]&&arr[i][0]!=' ')
			return arr[i][0];//将第i行的内容返回
	}
	for(i = 0;i<3;i++)//判断第i列是否全都相同
	{
		if(arr[0][i]==arr[1][i]&&arr[1][i]==arr[2][i]&&arr[0][i]!=' ')
			return arr[0][i];//将第i列的内容返回
	}
	if(arr[0][0]==arr[1][1]&&arr[1][1]==arr[2][2]&&arr[0][0]!=' ')//判断捺对角线(\)的内容是否全都相同
		return arr[0][0];
	else if(arr[0][2]==arr[1][1]&&arr[1][1]==arr[2][0]&&arr[0][2]!=' ')//判断撇对角线(/)的内容是否全都相同
		return arr[0][2];
	else if(is_full(arr,ROW))//判断是否是平局,如果是平局返回‘q’
		return 'q';
	else //判断是否还未产生游戏结果,如果还未产生游戏结果返回‘ ’
		return ' ';
}
    上面在判断是否是平局时调用了函数is_full(),用来判断棋盘是否下满。下面我们来编写这个函数:
int is_full(char arr[][COL],int row)
{//思路是这样:我们来判断数组当中每一个元素是否有空格,如果有空格,说明没有满,返回0;否则返回1。
	int i,j;
	for(i=0;i<row;i++)
	{
		for(j=0;j<COL;j++)
			if(arr[i][j]==' ')//判断是否有空格
				return 0;//有空格返回0。
	}
	return 1;//没有空格返回1。
}

    至此,我们就把所有的工作都完成了,下面我们来玩一下吧!


    总结一下吧:首先说一下,这是我第一次写小游戏,也是第一次写这么长的代码,在写之前觉得这个逻辑过程什么的都是非常easy的,可是不写不知道,一写吓一跳。第一次写完之后出现了好多的错误和警告,然后慢慢改慢慢改,最终还是完成了这个小游戏。总之,光用脑袋想是没用的,还得自己动手实践。在今后,我会加强自己对代码的编写和练习,努力提升自己。



猜你喜欢

转载自blog.csdn.net/weixin_41890097/article/details/80011621
今日推荐