轻松上手《三子棋》小游戏

今天呢,给小伙伴们分享一个比较容易上手的小游戏《三子棋》~

在创作这个小游戏之前呢,我们首先得分析一下这个游戏,让自己大脑有一个清晰的思路。先剖析游戏界面的布局,游戏实现,游戏输赢判断规则以及游戏玩法,再接着一步一步用代码的形式呈现出来。嘿嘿,那咱们就开始吧!(完整码源在最后)

一.概述

咱们先创建一个项目,然后再细分成源文件和头文件,这样方便咱们检查以及调用。

可以提前将需要的函数和库函数放入新创建的头文件,后续在源文件中需要使用时就可以直接引用新创建的头文件,这样比较方便和简洁。然后呢,咱们根据提前设定好的思路,一步一步将这些功能以代码形式实现。

#define ROW 3  //宏定义棋盘行数和列数
#define COL 3

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

//头文件中声明函数

//初始化棋盘
void init_board(char board[ROW][COL], int row, int col);

//打印棋盘
void print_board(char board[ROW][COL], int row, int col);

//玩家下棋
void player_move(char board[ROW][COL], int row, int col);

//电脑下棋
void computer_move(char board[ROW][COL], int row, int col);

//判断输赢的函数
char is_win(char board[ROW][COL], int row, int col);


二.游戏界面的实现

首先咱们可以创造一个简易的游戏开始界面,提醒玩家这是三子棋游戏,然后引导玩家进行游戏。

这里咱们可以用一个简单的函数来单独实现,方便后续的调整

void menu()  //不需要传入参数和返回值,所以用void形式就可以了
{
	printf("********** 三子棋 **********\n");
	printf("****************************\n");  
	printf("********* 1 - play *********\n");  //输入1即可开始游戏
	printf("********* 0 - exit *********\n");  //输入0 则退出游戏
	printf("****************************\n");


}

使用一个自定义的test函数来接受menu()函数,并且在里面实现是否游戏的功能。

void test()
{
	srand((unsigned int)time(NULL));
	again2:
	printf("是否继续游戏?\n");

	menu();
	int input = 0;
	again:
	printf("请选择是否游戏-> :  ");
	scanf("%d", &input);
	while (1)
   {
		if (input == 1)
		{
			game();
			goto again2;
		}
		else if (input == 0)
		{
			printf("退出游戏!\n");
			break;
		}
		else
		{
			printf("请重新选择!\n");
			goto again;
		}
	}
}

 紧接着就可以创作棋盘了。咱们可以用朴素的形式实现棋盘,通过 "___"

和“ | ”就可以了。这里用两个单独的函数以及循环语句来实现 。

void init_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 print_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)
		{
			for (j = 0; j < col; j++)
			{
				printf("___");
				if (j < col - 1)
					printf("|");
			}
			printf("\n");
		}
	}
}

这个就是棋盘实现效果

制作好棋盘后,就可以进行游戏实现了。

三.游戏实现

下棋其实就像填空一样,哪里有空位置,棋子就可以落在哪里。而位置就用坐标来代替。咱们可以通过二维数组的形式来实现,包括刚才制作棋盘,也使用了二维数组。这里呢,先穿插一下游戏玩法,可以人机对战和人人对战,咱们这里先用人机对战为例子,来介绍游戏实现的方法。

首先先从玩家的角度出发。作为游戏玩家,当看到游戏棋盘的时候,填入的坐标一般是大众化的形式以(1,1)开始,而二维数组是从(0,0)开始,所以咱们得提前设定好。咱们可以用一个单独的函数来实现玩家下棋的功能,通过代码咱们可以看到,玩家的棋子将会以“ * ”的形式出现在棋盘上。通过while 循环的方法将玩家输入的坐标呈现到棋盘上,如果玩家输入的坐标不在棋盘的范围内,系统将会提醒玩家重新输入!

void player_move(char board[ROW][COL], int row, int col)
{
	printf("玩家下棋\n");

	printf("请输入你想下棋的坐标\n");

	while (1)
	{
		int	x = 0;
		int y = 0;
		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");
	}

}

运行演示

接着就是电脑实现下棋。想让电脑实现下棋,也得给它一个具体的坐标,但是这个坐标需要它自动生成,并且是随机的,那怎么办呢?这里咱们可以发挥聪明的脑瓜,利用电脑上能产生随机数的功能。这个就是时间了,因为它每时每刻都在变化。C语言的函数库中有<time.h>和<stdlib.h>库函数,调用它们,然后再利用   srand((unsigned int)time(NULL))函数就可以生成随机值,在棋盘上以“ # ” 的形式作为棋子,直接看代码吧~

void computer_move(char board[ROW][COL], int row, int col)
{
	printf("电脑棋子为 # \n");
		while (1)
		{
			printf("电脑下棋\n");
			int x = rand() % row; // %: 使生成的值为 0,1,2
			int y = rand() % col;

			if (board[x][y] == ' ')
			{
				board[x][y] = '#';
				break;
			}
		
		}
}

运行演示

四.游戏输赢判断规则

三子棋的游戏规则就是看谁的棋子能够在横\竖\对角线的位置实现连接,不被打断。所以咱们可以根据这个逻辑,进行代码实现。但是也需要考虑棋下到最后,棋盘满了,谁都没能赢的情况,也就是平局。

//判断棋盘是否还有空位置,如果没有,且没决出胜负,则为平局
int is_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;
		}

	}
	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][0] != ' ')
		{
			return board[i][0];
		}
	}
	//判断三列
	for (i = 0; i < col; i++)
	{
		if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ')
		{
			return board[0][i];
		}
	}
	//对角线
	if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')
	{
		return board[1][1];
	}
	if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')
	{
		return board[1][1];
	}

	//平局?
	if (is_full(board, row, col) == 1)
	{
		return 'Q';
	}

	//继续
	//没有玩家或者电脑赢,也没有平局,游戏继续
	return 'C';
}

最后呢,咱们可以将这些函数功能,通过调用,都实现在咱们自己定义的game()函数中

void game()
{
	char board[ROW][COL];
	char ret = 0; //接受判断函数返回值
	 init_board(board, ROW, COL); //制作棋盘功能
     print_board(board, ROW, COL);
	 while (1)
 {	 
	 player_move(board, ROW, COL); //玩家下棋功能
	 print_board(board, ROW, COL);
	 //判断输赢
	 ret = is_win(board, ROW, COL);
	 if (ret != 'C')
	 {
		 break;
	 }
	 computer_move(board, ROW, COL);
	 print_board(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");
		
	 }
	
}

运行演示

五.玩法扩展

如果想和身边小伙伴一起玩的话,可以将电脑下棋的函数替换成玩家2的函数,具体操作就是在咱们自定义的头文件中,加入玩家2函数,然后玩家2下棋规则以及判断输赢规则都一样,这里小伙伴们可以自己动手来实现这一功能。


//玩家2函数

void player2_move(char board[ROW][COL], int row, int col)
{
	printf("玩家2下棋\n");

	printf("请输入你想下棋的坐标\n");

	while (1)
	{
		int	x = 0;
		int y = 0;
		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");
	}
}

六.小小提醒

在写代码过程中,咱们一定得先理清思路,这样才能有条不紊的实现代码功能,不然容易半路卡壳,还有就是函数的使用,要考虑好是否需要返回值以及其类型,传入参数,函数内部逻辑。在使用循环和选择语句时,这个 “ {} ”的使用一定要清晰,不然代码很容易就不按你的思路运行了。

最后,看懂代码和会写是完全不一样的,所以实践很重要!

祝小伙伴们早日成为技术大牛@


                               ///自定义头文件

#define ROW 3 
#define COL 3

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

//头文件中声明函数

//初始化棋盘
void init_board(char board[ROW][COL], int row, int col);

//打印棋盘
void print_board(char board[ROW][COL], int row, int col);

//玩家下棋
void player_move(char board[ROW][COL], int row, int col);

//电脑下棋
void computer_move(char board[ROW][COL], int row, int col);

//判断输赢的函数
char is_win(char board[ROW][COL], int row, int col);







                               ///游戏实现源文件

#include "game.h"

void menu()  //不需要传入参数和返回值,所以用void形式就可以了
{
	printf("********** 三子棋 **********\n");
	printf("****************************\n");
	printf("********* 1 - play *********\n");
	printf("********* 0 - exit *********\n");
	printf("****************************\n");


}


void game()
{
	char board[ROW][COL];
	char ret = 0;
	 init_board(board, ROW, COL);
     print_board(board, ROW, COL);
	 while (1)
 {	 
	 player_move(board, ROW, COL);
	 print_board(board, ROW, COL);
	 //判断输赢
	 ret = is_win(board, ROW, COL);
	 if (ret != 'C')
	 {
		 break;
	 }
	 computer_move(board, ROW, COL);
	 print_board(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");
		
	 }
	
}


void test()
{
	srand((unsigned int)time(NULL));
	again2:
	printf("是否继续游戏?\n");

	menu();
	int input = 0;
	again:
	printf("请选择是否游戏-> :  ");
	scanf("%d", &input);
	while (1)
   {
		if (input == 1)
		{
			game();
			goto again2;
		}
		else if (input == 0)
		{
			printf("退出游戏!\n");
			break;
		}
		else
		{
			printf("请重新选择!\n");
			goto again;
		}
	}
}


int main()
{

	test();
	return 0;
}



                               ///游戏内部源文件

#include "game.h"

void init_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 print_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)
		{
			for (j = 0; j < col; j++)
			{
				printf("___");
				if (j < col - 1)
					printf("|");
			}
			printf("\n");
		}
	}

}
//玩家下棋
void player_move(char board[ROW][COL], int row, int col)
{
	printf("玩家下棋\n");

	printf("请输入你想下棋的坐标\n");

	while (1)
	{
		int	x = 0;
		int y = 0;
		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_move(char board[ROW][COL], int row, int col)
{
	printf("电脑棋子为 # \n");
		while (1)
		{
			printf("电脑下棋\n");
			int x = rand() % row; // %: 使生成的值为 0,1,2
			int y = rand() % col;

			if (board[x][y] == ' ')
			{
				board[x][y] = '#';
				break;
			}
		
		}
}

//判断棋盘是否还有空位置,如果没有,且没决出胜负,则为平局
int is_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;
		}

	}
	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][0] != ' ')
		{
			return board[i][0];
		}
	}
	//判断三列
	for (i = 0; i < col; i++)
	{
		if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ')
		{
			return board[0][i];
		}
	}
	//对角线
	if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')
	{
		return board[1][1];
	}
	if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')
	{
		return board[1][1];
	}

	//平局?
	if (is_full(board, row, col) == 1)
	{
		return 'Q';
	}

	//继续
	//没有玩家或者电脑赢,也没有平局,游戏继续
	return 'C';
}


  • 27
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值