【C语言初阶】6 三子棋小游戏思路与代码实现

gitee仓库代码提交https://gitee.com/hacha/practice.git
三子棋小游戏思路
通过人机对战的形式,用坐标来确定落子的位置,三子相连判断输赢
模块可分为:1.初始化数组中的元素,全部初始化为空格,能让棋盘打印的规整
2.打印棋盘,在控制台显示出棋盘
3.玩家下棋 4.电脑下棋(循环)
5.判断输赢,退出循环
在这里插入图片描述
代码模块化,更好的厘清思路,test.c 实现测试游戏进行,game.c 三子棋游戏的实现 game.h 函数声明

1. test部分

1.1打印菜单判断是否进入游戏

#include <stdio.h>
void menu()
{
	printf("*************************************\n");
	printf("*********  1.play 0.exit  ***********\n");
	printf("*************************************\n");

}
int main()
{
	int input = 0;	
	// 1次不够再来1次  循环
	// 要先进来一次,判断玩家玩不玩,所以采用do  while的形式
	do
	{
		//菜单
		menu();
		printf("请选择:>");
		scanf("%d", &input);
		switch (input)
		{
			// 进入游戏
		case 1:
			printf("三子棋\n");
			break;
			// 退出游戏
		case 0:
			printf("游戏结束\n");
			break;
			// 输入错误
		default:
			printf("输入错误,请重新输入\n");
			break;
		}
	} while (input);
	return 0;
}

在这里插入图片描述

2.game部分

2.1 初始化棋盘InitBoard

要初始化棋盘就要先有棋盘,在test中创建棋盘
用33的二维数组作为棋盘,但是如果以后要更改,33太固定了,所以通过#define 定义行列
在这里插入图片描述

// 二维数组传参,直接拿一个二维数组接收
void InitBoard(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] = ' ';
		}
	}
}

2.2 打印棋盘DisplayBoard

下棋首先要看到棋盘,通过分割线划分坐标
上面只是初始化了棋盘当中的元素,并未打印
所以,打印棋盘包括元素与分割线

void DisplayBoard(char board[ROW][COL], int row, int col)
{
	//将1行元素和1行分割线看做一组,通过i控制组数
	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("|");
			}
		}
		// 打印完1行 换行  
		printf("\n");
		// --- 线在最后1行也不能显示
		if (i < row - 1)
		{
			for (j = 0; j < col; j++)
			{
				printf("---");
				// 同理
				if (j < col - 1)
				{
					printf("|");
				}
			}
			printf("\n");
		}
	}
}

在这里插入图片描述
棋盘打印完成

2.3 玩家下棋PlayerMove

void PlayerMove(char board[ROW][COL], int row, int col)
{
	printf("玩家下棋\n");
	printf("请选择坐标:>");
	int x = 0, y = 0;	
	while (1)
	{
		scanf("%d %d", &x, &y);
		// 先判断坐标的合法性
		if (x >= 1 && x <= 3 && y >= 1 && y <= 3)
		{
			//  这里的坐标并不代表下标,所以x-1,y-1
			if (board[x - 1][y - 1] == ' ')
			{
				// 玩家落子设置为*
				board[x - 1][y - 1] = '*';
				break;
			}
			// 坐标被占用的情况
			else
			{
				printf("输入坐标被占用,请重新输入\n");
			}
		}
		else
		{
			printf("输入坐标不合法,请重新输入");
		}
	}
}

在这里插入图片描述
玩家下棋完成

2.4 电脑下棋ComputerMove

电脑生成随机数,对行列取模生成范围内的随机数
要使用到库函数rand生成随机数
在调用rand之前要先调用srand(在整个项目当中只需要设置1次即可,所以设置在test函数当中)

void ComputerMove(char board[ROW][COL], int row, int col)
{
	printf("电脑下棋\n");
	while (1)
	{
		// 这里的x,y是生成的随机数取模,所以x,y的取值为0,1,2 就是下标
		int x = rand() % row;
		int y = rand() % col;
		if (board[x][y] == ' ')
		{
			//电脑落子为#
			board[x][y] = '#';
			break;
		}
	}
}

在这里插入图片描述
人机互动完成,接下来就是判断输赢

2.5.1判断输赢IsWin

// 用字符类型接收
char IsWin(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][2] != ' ')
		{
			// 此时数组当中存放的就是赢的一方,直接return
			return board[i][0];
		}
	}
	int j = 0;
	for (j = 0; j < col; j++)
	{
		// 某一列相等
		if (board[0][j] == board[1][j] && board[1][j] == board[2][j] && board[0][j] != ' ')
		{
			return board[0][j];
		}
	}
	// 对角线相等
	if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[0][0] != ' ')
	{
		return board[0][0];
	}
	if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')
	{
		return board[0][0];
	}
	// 当以上条件都未进入就说明棋局:
	// 要么继续   --'C '  Continue
	// 要么就是棋盘满了平局--'Q' quit
	// 如果继续返回C   如果平局 返回Q
	//拿ret接收IsFull的字符
	int ret = IsFull(board, ROW, COL);
	return ret;
}

2.5.2 棋盘是否放满IsFull

//棋局是否满了
char IsFull(char board[ROW][COL], int row, int col)
{
	int i = 0, j = 0;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			if (board[i][j] == ' ')
			{
				return 'C';
			}
		}
	}
	// 到这里就是棋盘满了的情况
	return 'Q';
}

3. main循环判断是否还要继续

do
	{
		//菜单
		menu();
		printf("请选择:>");
		scanf("%d", &input);
		switch (input)
		{
		// 进入游戏
		case 1:
			//初始化棋盘
			InitBoard(board, ROW, COL);
			//打印棋盘
			DisplayBoard(board, ROW, COL);
			// 循环下棋
			//接收IsWin的返回值
			char num = 0;
			while (1)
			{
				// 玩家下棋
				PlayerMove(board, ROW, COL);
				num = IsWin(board, ROW, COL);
				// 只要不是'C' 就说明判断出胜负或者是平局
				if (num != 'C')
				{
					break;
				}
				DisplayBoard(board, ROW, COL);
				ComputerMove(board, ROW, COL);
				num = IsWin(board, ROW, COL);
				if (num != 'C')
				{
					break;
				}
				DisplayBoard(board, ROW, COL);
			}
			if (num == '*')
			{
				printf("玩家赢\n");
			}
			else if (num == '#')
			{
				printf("电脑赢\n");
			}
			else
			{
				printf("平局\n");
			}
			// 判断完棋局输赢再打印1次棋盘
			DisplayBoard(board, ROW, COL);
			break;
		// 退出游戏
		case 0:
			printf("游戏结束\n");
			break;
		// 输入错误
		default:
			printf("输入错误,请重新输入\n");
			break;
		}
	} while (input);

在这里插入图片描述在这里插入图片描述
到这里,代码就实现完成喽!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值