首页 > 其他分享 >数组应用实例1 —— 三子棋

数组应用实例1 —— 三子棋

时间:2024-03-29 12:33:45浏览次数:22  
标签:函数 int 三子 实例 board 数组 printf COL ROW

数组应用实例1 —— 三子棋

文章目录

本章目标

利用所学知识,编写一个简易的三子棋游戏。

本章内容

  1. 标识符常量的定义和头文件的包含

  2. 主函数 main()

  3. 测试游戏逻辑 test()

  4. 菜单界面 menu()

  5. 游戏实现 game()

  6. 初始化棋盘 InitBoard()

  7. 打印棋盘 DisplayBoard()

  8. 玩家下棋 PlayerMove()

  9. 电脑下棋 ComputerMove()

  10. 判断输赢 IsWin()

正文


一、标识符常量的定义和头文件的包含

库函数所需要的头文件的包含,标识符常量的定义。

//game.h

#include<stdio.h>//printf()、scanf()
#include<stdlib.h>//rand()、srand()、system()
#include<time.h>//time()
#include<windows.h>//Sleep()

#define ROW 3
#define COL 3


二、主函数 main()

主函数里调用测试游戏逻辑的函数,避免主函数的臃肿。

//test.c

int main()
{
	//数组应用实例-三子棋
    
	test();//测试游戏逻辑

	return 0;
}


三、测试游戏逻辑 test()

测试函数会调用菜单界面函数,提供进入游戏和退出游戏的选择。

//test.c

//测试游戏逻辑函数
void test()
{
	srand((unsigned int)time(NULL));//设置随机数种子

	int select = 0;
	do
	{
		menu();//菜单界面
		printf("请输入你的选择:>");
		scanf("%d", &select);

		switch (select)
		{
		case 1:
			game();//游戏逻辑
			break;
		case 0:
			printf("退出游戏!\n");
			break;
		default:
			printf("选择错误,请重新输入!\n");
			break;
		}
	} while (select);
}


四、菜单界面 menu()

提供游戏菜单界面的显示。

//test.c

//菜单界面函数
void menu()
{
	printf("**************************\n");
	printf("********  1.play  ********\n");
	printf("********  0.exit  ********\n");
	printf("**************************\n");
}


五、游戏实现 game()

包括创建棋盘数组、初始化棋盘、打印显示棋盘、回合制下棋(玩家下棋、电脑下棋)、判断输赢状态。

//test.c

//游戏逻辑函数
void game()
{
	char board[ROW][COL] = { 0 };//棋盘数组

	//初始化棋盘
	InitBoard(board, ROW, COL);
	//打印显示棋盘
	DisplayBoard(board, ROW, COL);

	//回合制下棋
	int ret = 0;
	while (1)
	{
		//玩家下棋
		PlayerMove(board, ROW, COL);
		DisplayBoard(board, ROW, COL);

		//每落一子就判断输赢
		ret = IsWin(board, ROW, COL);
		if (ret != 'C')
		{
			break;//如果返回值不是'C',就退出回合制下棋,判断输赢平局
		}

		//电脑下棋
		ComputerMove(board, ROW, COL);
		DisplayBoard(board, ROW, COL);

		//每落一子就判断输赢
		ret = IsWin(board, ROW, COL);
		if (ret != 'C')
		{
			break;//如果返回值不是'C',就退出回合制下棋,判断输赢平局
		}
	}

	//判断棋盘输赢状态
	if ('*' == ret)
		printf("玩家赢了!\n");
	else if ('#' == ret)
		printf("电脑赢了!\n");
	else
		printf("本场平局!\n");

	//本局棋盘最终情况
	printf("\n该局最终结果:>\n");
	DisplayBoard(board, ROW, COL);
	system("pause");//请按任意键继续
	system("cls");//清屏操作
}

//
//什么情况游戏结束?(返回值)
//玩家赢  --  '*'
//电脑赢  --  '#'
//平局    --  'D'
//继续    --  'C'
//


六、初始化棋盘 InitBoard()

将棋盘元素初始化为空格。

1 函数原型

//game.h

//初始化棋盘函数声明
void InitBoard(char board[ROW][COL], int row, int col);


2 函数实现

//game.c

//初始化棋盘函数实现
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] = ' ';//将棋盘初始化为空格
		}
	}
}


七、打印棋盘 DisplayBoard()

打印显示棋盘数据。

1 函数原型

//game.h

//打印显示棋盘函数声明
void DisplayBoard(char noard[ROW][COL], int row, int col);


2 函数实现

//game.c

//打印显示棋盘函数实现
//版本1
//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");
//	}
//	printf("\n");
//}
//版本2
void DisplayBoard(char board[ROW][COL], int row, int col)
{
	printf("\n");
	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("|");
		}
		printf("\n");

		if (i < row - 1)
		{
			for (j = 0; j < col; j++)
			{
				printf("---");//打印分隔横线
				if (j < col - 1)//打印分隔竖线
					printf("|");
			}
			printf("\n");
		}
	}
	printf("\n");
}


八、玩家下棋 PlayerMove()

玩家回合,玩家输入棋盘坐标进行下棋。

1 函数原型

//game.h

//玩家下棋函数声明
void PlayerMove(char board[ROW][COL], int row, int col);


2 函数实现

//game.c

//玩家下棋函数实现
void PlayerMove(char board[ROW][COL], int row, int col)
{
	int x = 0;//棋盘横坐标
	int y = 0;//棋盘纵坐标
	printf("玩家回合:>\n");

	while (1)
	{
		printf("请输入坐标(用空格分隔):>");
		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");
		}
	}
}


九、电脑下棋 ComputerMove()

电脑回合,电脑随机生成坐标下棋。

1 函数原型

//game.h

//电脑下棋函数声明
void ComputerMove(char board[ROW][COL], int row, int col);


2 函数实现

//game.c

//电脑下棋函数实现
void ComputerMove(char board[ROW][COL], int row, int col)
{
	int x = 0;
	int y = 0;
	printf("电脑回合:>\n");

	while (1)
	{
		//电脑随机生成坐标
		x = rand() % row;//0 ~ row-1
		y = rand() % col;//0 ~ col-1

		//检查坐标是否被未占用
		if (board[x][y] == ' ')
		{
			board[x][y] = '#';//电脑落子:#
			break;
		}
	}
}


十、判断输赢 IsWin()

通过检验行是否相等、列是否相等或者对角线是否相等且是否是非空格字符判断输赢;以及通过棋盘是否已满判断本局游戏是否继续还是最终平局。

1 函数原型

//game.h

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


2 IsFull() 函数实现

判断棋盘坐标是否已满。

//game.c

//判断棋盘是否已满函数实现
//使用static限定函数只在本文件中使用
static int IsFull(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++)
		{
			if (board[i][j] == ' ')
				return 0;//没满,棋盘还有空格未填满
		}
	}
	return 1;//满了,棋盘已被填满
}


3 IsWin() 函数实现

//game.c

//判断输赢函数实现
int 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][1];//返回坐标信息
		}
	}

	//判断列
	for (i = 0; i < col; i++)
	{
		if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[1][i] != ' ')
		{
			return board[1][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 (IsFull(board, ROW, COL) == 1)
	{
		return 'D';//平局(draw)
	}
	else
	{
		return 'C';//继续(continue)
	}
}


总结:

  本节给出了数组应用实例——三子棋的简单实现,分文件编写了函数声明、函数定义和游戏实现。


感谢您的阅读,如有任何错误,欢迎您的批评指正!

标签:函数,int,三子,实例,board,数组,printf,COL,ROW
From: https://blog.csdn.net/qq_43108974/article/details/137140511

相关文章

  • 除自身以外数组的乘积 - LeetCode 热题 16
    大家好!我是曾续缘......
  • [幻灯片]软件需求设计方法学全程实例剖析-03-业务用例图和业务序列图
    DDD领域驱动设计批评文集做强化自测题获得“软件方法建模师”称号《软件方法》各章合集pdf已上传至本号的CSDN资源,或到以下地址下载:http://umlchina.com/training/umlchina_03_bm.pdf......
  • java实现字节数组转int(采用IEEE 754标准)
    /***字节数组转int*采用IEEE754标准**@parambytes*@returnfloat*/publicintbytesToInt(byte[]bytes){//获取字节数组转化成的2进制字符串StringbinaryStr=bytesToBinaryStr(bytes);//符号位......
  • 20240328,位运算,可变数组,链表(我是真的没有听懂)
    位运算一,按位运算按位运算,把整数当作2进制的数字进行运算?&按位与,|按位或,~按位取反,^按位的异或,<<左移, >>右移1.1&按位与·如果(x)i==1并且(y)i==1,那么(x&y)=1否则的话(x&y)i=0按位与常用于两种应用:·让某一位或某些位为0:  x&0xFE·取一个数中的一段: x&......
  • Java抽象类详解:定义、特性与实例化限制(day12)
    抽象类总结一下今天老师上课的内容,前面几节课听得是有点懵,在讲到内存问题,也就是代码在栈、堆、以及方法区是怎么执行的,听得不是很懂,今天讲到抽象类以及重写的机制,似乎开始慢慢懂得了java的底层原理。父类:子类:上面的Cat类重写父类的eat()方法。Test:如果我们将父类的......
  • 重生前端之我在javascript敲代码(03-数组)
    一.数组(重点)思考:如何保存一个班级的所有学生的姓名?回答:一种方法利用前面学习过的知识,则每一条信息都需要一个变量去保存,缺点是这样做很麻烦,而且容易出错,又不合理;另一种方法就是利用数组。概念:数组是存储一系列值的变量集合,可以存储多个值。1.1语法数组构成:数组由一个或......
  • 差分数组
    定义对于数组A[n],它的差分数组为:\[diff[i]=\begin{cases}A[i],&i==0\\A[i]-A[i-1],&0<i<n\end{cases}\]显然,通过差分数组diff[n],可以求得A[n]中的某一具体元素:\[A[i]=\begin{cases}diff[i],&i==0\\diff[i]+A[i-1],&0<i<n\end{cases}\]应用数组A[n]......
  • 关于《完全手册Excel VBA典型实例大全——通过368个例子掌握》随书样例的下载
    按照早先下载的电子教程查看和编写vba,有些例子使用运行错误,想着看看原始文件。容易看到,网上有提供的doc或者pdf文档,都不完整,可能是{完全手册Excel_VBA典型实例大全:通过368个例子掌握}.{doc,pdf}这样命名的,139页或者134页的样子。搜索发现很多一些链接要么失效,要么是需要相应的积......
  • 补|(52/60)最长递增子序列、最长连续递增序列、最长重复子数组
    子序列问题最长递增子序列leetcode:300.最长递增子序列动态规划代码实现/*以nums[i]结尾的(含)递增子序列最长为dp[i]dp[i]由dp[0~i-1]的最大值推出if(nums[i]>nums[j])dp[i]=max(dp[i],dp[j]+1);//如果严格递增dp[0]=1;其余为0正序遍历*/classSol......
  • QT串口通信原理加实例
    串口通信原理:一、串口通信的基本原理串口的本质功能是作为CPU和串行设备间的编码转换器。当数据从CPU经过串行端口发送出去时,字节数据转换为串行的位(bit);在接收数据时,串行的位被转换为字节数据。应用程序要使用串口进行通信,必须在使用之前向操作系统提出资源申请要求(打开......