三子棋详解

经典小游戏——三子棋|C语言

每篇一句,与同行的你共勉:
不应该追求一切种类的快乐,而是应该追求高尚的快乐。

重温那些年草稿本上的勾勾叉叉的爱恨情仇。那年的夏天,那年同桌的你…

以下便是回忆的开始。

游戏构思

在这里插入图片描述

数据存储

这里我们主要是3字棋,棋盘都是以井字出现。棋盘落子得让别人知道,让别人输的明明白白,所以这里需要进行数据存储二维数组便最合适不过。

int ret=0;
	//棋盘需要存数据,使用数组
	//int arr[3][3];
	// 方便后期改变
	int arr[ROW][COL];
	//打印棋盘布局
	

数组安排后,这里为了后面方便改变数组大小就需要定义变量在头文件中;

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

棋盘布局

这里可以通过一张图进行了解到棋盘的布局。
在这里插入图片描述
这是在画图中可以这么丝滑,但在C语言中就必须用一些字符来表示,
在这里插入图片描述
下面便是棋盘的代码

//棋盘打印
void Display_board(int arr[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 ",arr[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");
			
		}
	}
}

以上可以得到一个框架,但是因为没有初始化,所以会存在一些随机值生成。这就需要下面步骤初始化棋盘

初始化棋盘

可能会想着使用0进行数组初始化,但是因为我们需要预留位置而棋盘看着就是一个框架,不需要显示任何值,所以这里直接使用字符空格进行初始化。

void Init(int arr[ROW][COL], int row, int col)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			arr[i][j] = ' ';
		}

	}
}

这里我们就可以得到一个3行3列的一个表格。下面就要开始进行棋艺的切磋。

玩家下棋

这里为了便于观察玩家落子为 ,后面电脑落子为#。这里进行落子是我们的棋子一定要在数组内所以需要进行判断数组坐标是否合法*、坐标是否被占这里需要注意进行条件判断时我们需要注意一些代码的书写。避免一些bug。

void Player_move(int arr[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 (arr[x-1][y-1]==' ')
			{
				arr[x-1][y-1] = '*';
				break;
			}
			else
			{
				printf("坐标占用\n");
			}
		}
		else
		{
			printf("输入坐标无效\n");
		}
		
		
	}
}

在书写坐标是否有效时,笔者便出现了一个bug一直显示坐标被占用,后面进行排查时发现条件判断时多了一个 == 前面多了一个空格。所以一直显示不对。

//坐标是否有效
			if (arr[x-1][y-1]==' ')
			{
				arr[x-1][y-1] = '*';
				break;
			}
			else
			{
				printf("坐标占用\n");
			}
		}

电脑下棋

经过上面代码书写,这和个代码书写便是大同小异。条件不同罢了。
代码放下;

//电脑下棋
void Computer_move(int arr[ROW][COL], int row, int col)
{
	int x = 0;
	int y = 0;
	printf("电脑下棋\n");
	while (1)
	{
		
		x = rand() % row;
		y = rand() % col;
		if ((x >= 1) && (x <= row) && (y >= 1) && (y <= col))
		{
			//坐标是否有效
			if (arr[x - 1][y - 1] != '*')
			{
				arr[x - 1][y - 1] = '#';
				break;
			}
		}
	}

}

输赢判断

既然是博弈,便会有高低。虽然这里对手有一点不给力(这里编程中电脑并没有达到Al智能程度)。输赢就只有行列三连,对角线三连。

//判断输赢
static int is_full(char arr[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 (' ' == arr[i][j])
			{
				return 0;
			}
		}
	}

	return 1;
}
int  who_win(int arr[ROW][COL], int row, int col)
{

		int i = 0;
		for (i = 0; i < row; i++)
		{
			if (arr[i][0] == arr[i][1] && arr[i][1] == arr[i][2] && arr[i][0] != ' ')
			{
				return arr[i][0];
			}
		}

		for (i = 0; i < col; i++)
		{
			if (arr[0][i] == arr[1][i] && arr[1][i] == arr[2][i] && arr[0][i] != ' ')
			{
				return arr[0][i];
			}
		}

		if (arr[0][0] == arr[1][1] && arr[1][1] == arr[2][2] && arr[1][1] != ' ')
		{
			return arr[1][1];
		}

		if (arr[0][2] == arr[1][1] && arr[1][1] == arr[2][0] && arr[1][1] != ' ')
		{
			return arr[1][1];
		}

		//判断平局
		if (is_full(arr, row, col) == 1)
		{
			return 'Q';
		}

		//继续
		return 'C';
	
}

以上便完成了所以模块代码书写。最后我们根据书写的代码片段以及对头文文件使用频率我们进行头文件书写。
在这里插入图片描述
有了前面准备好的代码最后进行代码块的布局调用

完成—测试

void game()
{
	int ret=0;
	//棋盘需要存数据,使用数组
	//int arr[3][3];
	// 方便后期改变
	int arr[ROW][COL];
	//打印棋盘布局
	Init(arr,ROW,COL);
	Display_board(arr, ROW, COL);

	while (1)
	{
		Player_move(arr, ROW, COL);
		//Display_board(arr, ROW, COL);
		


		ret = who_win(arr, ROW, COL);
		if (ret != 'C')
			break;

		Computer_move(arr, ROW, COL);
		Display_board(arr, ROW, COL);
		
		ret = who_win(arr, ROW, COL);
		if (ret != 'C')
			break;

	}
	printf("\n");
	if (ret == '*')
	{
		printf("玩家赢\n");
	}
	else if (ret == '#')
	{
		printf("电脑赢\n");
	}
	else if (ret == 'Q')
	{
		printf("平局\n");
	}
	Display_board(arr, ROW, COL);
}

//玩家赢 - '*'
//电脑赢 - '#'
//平局了 - 'Q'
//游戏继续 - 'C'
void menu()
{
	printf("######################\n");
	printf("### 1.play   0.exit ###\n");
	printf("######################\n");

}
int main()
{
	srand((unsigned int)time(NULL));
	int input = 0;
	do
	{
		menu();
		flag:
		printf("请选择是否游戏:");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 0:
			printf("退出游戏");
				break;
		default:
			printf("输入错误");
			goto flag;
			break;

		}
	
	} while (input);

	return 0;
}

以上便是三子棋实现全部过程。如有错误,请多指正。

评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小鱼君

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值