C语言进阶之旅 番外篇(基础无AI算法三子棋)

代码码有大概的注释




三子棋的介绍

  • 其实就是井子棋
  • 各落子三次,连成一条线则赢(横、竖、对角)
  • 下满则为平局

在这里插入图片描述

思维导图

在这里插入图片描述

这个是要实现整个三子棋的基本思路

  1. 菜单
  2. 打印棋盘
  3. 玩家落子
  4. 电脑落子
  5. 判断输赢
  6. 游戏结束

ok那么开始吧

菜单环节

  1. 封装一个菜单函数menu()
  2. 选择(如果玩了一次,还想玩一次咋办?总不可能重新启动吧,那用户体验多差,这里我给用户极致的体验,只要他玩不腻,就死里玩)

**1:**交互界面

//作用就是给你看看,可以选择
void menu()
{
	printf("*******************************\n");
	printf("********      1.play      *****\n");
	printf("********      1.exit      *****\n");
	printf("*******************************\n");
}

**2:**选择

//是多次选择所以,的也能过switch
int input = 0;
     menu();
	scanf("%d", &input);
	switch (input)1
	{
	case 1:
		printf("开始游戏");
		break;
	case 0:
		printf("退出游戏");
		break;
	//这里提示吗,明明告诉告诉你0和1,你却瞎选,我忍,顾客是上帝
	default:
		printf("输入错误,请重新输入");
		break;
	}

2.5: 极致体验(防止不过过瘾)

int main()
{
	int input = 0;
	do
	{
		menu();
		printf("请输入:<");
		scanf("%d", &input);
		switch (input)//选择
		{
		case 1:
			printf("开始游戏");//后面改为game()函数
			break;
		case 0:
			printf("退出游戏");
			break;
		default:
			printf("输入错误,请重新输入");
			break;
		}
		return 0;
	} while (input);//这里根据你输入值判断是否要继续进行游戏
	
}

在这里插入图片描述


                                                         ok那么菜单环节到完成了

游戏

  • 创建一个三成三的数组

1 :缺点够灵活,不方便后期更改

void game()
{
	char board[3][3];

}

1.5 改进

void game()
{
	char board[ROW][COL];//把行列定义在头文件里需要更改,直接去改头文件改就可以了


创建一个头文件

用处:

  • 把需要改的值写里面,避免后期一个一个更改
  • 避免重复操作(定义的头文件,函数),只需要包含一下他,就不要在包别的头文件里,前提你在自定义头文件里已经包含过了
//包含自定义头文件
#include“ ”

打印棋盘

注:打印棋盘其实就是打印数组

1:初始化棋盘==初始化数组

  1. 封装一个函数初始化棋盘(InitBoard)
  2. 数组没初始化,里面都是随机值
  3. 初始化空格,后面就知道了特别妙
void InitBoard(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] = ' ';//把i行j列的元素变成空格
		}
	}
}

2:打印棋盘

  1. 封装一个打印棋盘函数(DisplayBoard)

这个就是棋盘的样子
在这里插入图片描述
在打印的时候先打印一个元素一个|在是元素在是|然后在是元素
然后一行分割- - -|- - -|- -
因此可以把它们看成一个整体
在这里插入图片描述

void DisplayBoard(char board[ROW][COL], int row, int col)
{
	int i = 0;
	for ( i = 0; i <row; i++)
	{
		printf(" %c | %c | %c \n",board[i][0],board[i][1],board[i][2]);
		if(i<row-1)//美化棋盘
		printf("---|---|---\n");
	}
}

第一次运行
在这里插入图片描述
第二次
在这里插入图片描述
这种写法其实不是特别好,不够灵活,以后要是想玩n子棋咋办

2.5:优化

void DisplayBoard(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++)
		{
			printf(" %c ", board[i][j]);//打印i行j列上的元素
			if ( j< col - 1)//美化棋盘
			{
				printf("|");
			}
		
		}
		printf("\n");
		if (i < row - 1)//分割线
		{
				int j = 0;
				for (j = 0; j < col; j++)
				{
					printf("---");
					if (j < col - 1)//美化棋盘
					{
						printf("|");
					}
				}
				
		}
		printf("\n");
	}
}

打印行
在这里插入图片描述
打印列
第一次
在这里插入图片描述

第二次
在这里插入图片描述
最终效果
在这里插入图片描述



                                  到这里大致就完成了打印棋盘

玩家落子

  1. 封装一个函数(PlayMove)
  2. 判断下的位置是否落子
  3. 判断所下的坐标是否在棋盘内
void PlayMove(char board[ROW][COL], int row, int col)
{
	int x = 0;
	int y = 0;
	while (1)
	{
		printf("请落子:<");
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= row && y >= 1 && y <= col)//判断坐标是否正确
		{
			//程序员的坐标0,0普通人的坐标1,1
			if (board[x - 1][y - 1] == ' ')//如果x-1,y-1的坐标空格就落子
			{
				board[x - 1][y - 1] = 'O';
				break;//落子就跳出不需要在下,博弈,都是你一棋,它一棋
			}
			else//判成立,代表该位置已经落子
			{
				printf("改坐标被占用\n");
			}

		}
		else
		{
			printf("坐标违法,重新输入");
		}

	}
	
}

ok玩家下棋就完成了

电脑落子

  1. 封装一函数(ComputMove)
  2. 生成坐标(随机值%行,列)
  3. 判断所下位置是否落子
void ComputMove(char board[ROW][COL], int row, int col)
{
	int x = rand()%row;//控制坐是否正确
	int y = rand() % col;//控制坐标是否正确
	printf("电脑玩家落子\n");
	if (board[x][y] == ' ')//判断位置是否落子,无则落子
	{
		board[x][y] = 'X';
	}
}



                                          电脑的落子部分也完成了

判断输赢

返回O玩家赢
返回X电脑赢
返回P平局
返回C继续

  1. 封装一个函数(IsWin)
  2. 判断返回值

函数部分

//判断胜负
int IsFull(char board[ROW][COL],int row,int col)
{
	int i = 0;
	int j = 0;
	for ( i = 0; i < row; i++)
	{
		for ( i = 0; i < col; i++)
		{
			if (board[i][j] != ' ')
			{
				return 0;
			}
		}
	}
	return 1;
}
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][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[2][2] != ' ')
	{
		return board[1][1];
	}
	if (board[0][2] == board[1][1] && board[1][1] == board[2][1] && board[2][1] != ' ')
	{
		return board[1][1];
	}

	//判断是否平局
	//棋盘全满就是平局
	//全满就是没有空格
	//全满返回1
	int back = IsFull(board,row,col);//
	if (back == 1)
	{
		return'P';
	}
	else 
	{
		return 'C';
	}
	
}

判断部分

	while (1)
	{
		//玩家落
		PlayMove(board, ROW, COL);
		//打印棋盘
		DisplayBoard(board, ROW, COL);
		 ret = IsWin(board, ROW, COL);
			if (ret != 'C')//C是继续,不返回他那么就是赢输或者平
			{
				break;
			}
		//电脑落子
		ComputMove(board, ROW, COL);
		//打印棋盘
		DisplayBoard(board, ROW, COL);
		 ret = IsWin(board, ROW, COL);
		if (ret != 'C')//C是继续,不返回他那么就是赢输或者平
		{
			break;
		}

	}
	if (ret == 'O')
	{
		printf("恭喜你赢了\n");
	}
	if (ret == 'X')
	{
		printf("很遗憾电脑玩家胜利\n");
	}
	if (ret == 'P')
	{
		printf("你和电脑玩家不分伯仲\n");
	}
}

在这里插入图片描述

ok到这里整个三子棋游戏到此结束!!

三子棋的源代码

总结:

  • 这里所运用到知识点都是比较所学过的(循环,数组,函数,分支……)
  • 上面还要好多需要优化(AI高级算法)(判断输赢),后面慢慢改进
  • 不懂的地方自己慢慢调试,调试永远的神(写的时候好多错,调试好多次才写好),好吧其实调试键已经要被按烂了,都可以写一篇调试博客了哈哈
  • 写这个三子棋的过程中我收获挺多,会自己慢慢找错,耐心的写完了这个小游戏(耗时5个多小时),也发现自己好多的不足!!!我身上的坏毛病就和我写出大bug一样,需要慢慢改进!!!!

以上解析,代码若有错误请在评论区指出(或qq:1696912943),博主也很想知道,错了我会及时改正

持续更新中…………

  • 12
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值