三子棋(C 语言)

news2024/10/17 21:27:16

目录

  • 一、游戏设计的整体思路
  • 二、各个步骤的代码实现
    • 1. 菜单及循环选择的实现
    • 2. 棋盘的初始化和显示
    • 3. 轮流下棋及结果判断实现
    • 4. 结果判断实现
  • 三、所有代码
  • 四、总结

一、游戏设计的整体思路

(1)提供一个菜单让玩家选择人机对战、玩家对战或者退出游戏,且一局结束以后还可以继续选择直到退出。
(2)使用一个 3*3 二维数组来表示一个棋盘,存放双方的落子情况并进行显示。且显示时使用一些符号进行分隔让棋盘更加合理。
(3)初始棋盘应为空,然后提示先手方下棋,要对先手方落子位置进行判断(是否合法,是否该位置已经落子),最后先手方下棋完毕后应检查棋局状态(获胜、平局或继续);同理后手方下棋。
(4)若平局或者任意一方获胜则结束对局,显示结果。

本次代码使用多文件形式,一共有三个文件,一个头文件包含各种声明,一个 .c 文件进行测试,一个 .c 文件实现函数功能。
在这里插入图片描述

二、各个步骤的代码实现

1. 菜单及循环选择的实现

(1)主函数代码的实现

// 头文件
#include <stdio.h>
#include "Tic_tac_toe.h"

int main()
{
	// 所需变量
	int select = 0;
	// 选择
	do
	{
		// 菜单
		menu();
		// 选择
		scanf("%d", &select);
		// 判断
		switch (select)
		{
		case 1 :  // 人机对战
			PVE();
			break;
		case 2 :
			PVP();  // 玩家对战
			break;
		case 0 :
			printf("游戏结束!\n");
			break;
		}
	} while (select);

	return 0;
}

(2)头文件中的声明

// 菜单
void menu();

(3)函数实现

// 菜单
void menu()
{
	printf("**************************************\n");
	printf("**********      1. PVE      **********\n");
	printf("**********      2. PVP      **********\n");
	printf("**********      0. exit     **********\n");
	printf("**************************************\n");
}

(4)运行效果如下
在这里插入图片描述

2. 棋盘的初始化和显示

棋盘的初始化和显示分别设计为两个函数 —— InitBoard()、PrintBoard()。首先,需要在主函数创建棋盘,且大小使用符号常量,方便替换。然后把棋盘的信息传入人机对战和玩家对战函数中,并在头文件和实现文件中进行相应的声明和定义。

(1)主函数创建棋盘

int main()
{
	// 所需变量
	int select = 0;
	char board[ROW][COL] = { 0 };  // 创建棋盘
	//...
}

(2)头文件进行相应声明

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

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

// 人机对战模式
void PVE(char board[][COL], int row, int col);

// 玩家对战模式
void PVP(char board[][COL], int row, int col);

(3)实现文件进行定义

// 初始化棋盘
void InitBoard(char board[][COL], int row, int col)
{
	int i;
	for (i = 0; i < row; ++i)
	{
		int j;
		for (j = 0; j < col; ++j)
			board[i][j] = ' ';
	}
}

// 打印棋盘
void PrintBoard(char board[][COL], int row, int col)
{
	// 打印棋盘时,需要适当添加符号分隔
	int i;
	for (i = 0; i < row; ++i)
	{
		int j;
		for (j = 0; j < col; ++j)
			printf(" ---");
		// 下一行
		printf("\n");
		for (j = 0; j < col; ++j)
			printf("| %c ", board[i][j]);
		// 补齐改行分隔
		printf("|");
		// 下一行
		printf("\n");
	}
	// 补齐最后一行分隔
	for (i = 0; i < col; ++i)
		printf(" ---");
	
	printf("\n");
}

// 人机对战模式
void PVE(char board[][COL], int row, int col)
{
	printf("\n人机对战:\n");
	// 初始化棋盘
	InitBoard(board, row, col);
	// 显示棋盘
	PrintBoard(board, row, col);
}

// 玩家对战模式
void PVP(char board[][COL], int row, int col)
{
	printf("\n玩家对战:\n");
	// 初始化棋盘
	InitBoard(board, row, col);
	// 显示棋盘
	PrintBoard(board, row, col);
}

运行效果如下:
在这里插入图片描述

3. 轮流下棋及结果判断实现

这里假设人机对战时,玩家使用符号 ‘#’,机器人使用符号 ‘*’;玩家对战时,一号玩家使用符号 ‘#’,二号玩家使用符号 ‘*’。玩家下棋和机器人下棋分别使用两个函数 —— PMove() 和 EMove()。PMove() 函数需要使用一个额外的变量判断是 1 号玩家下棋,还是 2 号玩家下棋。

判断结果函数 is_win() 需要判断每行是否相同、每列是否相同,倘若其中有一个实现,则有一方获胜,倘若没有则需要使用函数 is_full() 判断棋盘是否已满,若满则平局,否则继续。is_full() 函数也可以直接实现在 is_win() 函数内部。

(1)头文件函数声明

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

// 机器人下棋
void EMove(char board[][COL], int row, int col);

// 判断是否获胜
void is_win(char board[][COL], int row, int col);

(2)实现文件函数定义

// 玩家下棋
void PMove(char board[][COL], int row, int col, char who)
{
	// 所需变量
	int x, y;
	do
	{
		// 输入坐标
		printf("玩家下棋(输入坐标中间用空格隔开):\n");
		scanf("%d %d", &x, &y);
		// 判断合法性
		if ((x < 0 || x > row || y < 0 || y > col) || board[x - 1][y - 1] != ' ')
		{
			printf("坐标非法,请重新输入!\n");
		}
		else
		{
			board[x - 1][y - 1] = who;
			break;
		}

	} while (1);
}

// 机器人下棋
void EMove(char board[][COL], int row, int col)
{
	// 机器人是随机下棋的,这里就要获取随机数了
	// 需要包含头文件 stdlib.h 和 time.h 
	// 设置随机数种子
	srand((unsigned)time(0));
	printf("电脑下棋:\n");
	while (1)
	{
		int x = rand() % row;  // 0 - row - 1
		int y = rand() % col;  // 0 - col - 1
		if (board[x][y] == ' ')
		{
			board[x][y] = '*';
			break;
		}
	}
}

// 判断是否获胜
char is_win(char board[][COL], int row, int col)
{
	// 判断每行
	int r = 1;
	int i;
	for (i = 0; i < row; ++i)
	{
		// 重置判断符号
		r = 1;
		// 若首字符为空则下一行
		if (board[i][0] == ' ')
			continue;
		// 判断改行
		int j;
		for (j = 1; j < col; ++j)
		{
			r *= (board[i][j - 1] == board[i][j]);
			// 判断
			if (!r)
				break;
		}
		if (r)
			return board[i][0];
	}

	// 判断每列
	int c = 1;
	int j;
	for (j = 0; j < col; ++j)
	{
		// 重置判断符号
		c = 1;
		// 首字符为空则下一列
		if (board[0][j] == ' ')
			continue;
		// 判断该列
		int i;
		for (i = 1; i < row; ++i)
		{
			c *= (board[i - 1][j] == board[i][j]);
			// 判断
			if (!c)
				break;
		}
		if (c)
			return board[0][j];
	}

	// 判断对角线
	int d = 1;
	if (board[0][0] != ' ')
	{
		for (i = 1; i < row; ++i)
		{
			d *= (board[i - 1][i - 1] == board[i][i]);
			// 判断
			if (!d)
				break;
		}
		if (d)
			return board[0][0];
	}

	if (board[0][col] != ' ')
	{
		d = 1;
		for (i = 1; i < row; ++i)
		{
			d *= (board[i - 1][col - i + 1] == board[i][col - i]);
			// 判断
			if (!d)
				break;
		}
		if (d)
			return board[0][col];
	}

	// 判断棋盘是否已满
	int full = 1;
	for (i = 0; i < row; ++i)
	{
		for (j = 0; j < col; ++j)
		{
			if (board[i][j] == ' ')
			{
				// 未满
				return 'C';
			}
		}
	}
	// 已满
	return 'D';

}

上述代码中 is_win() 函数中所使用的是通用判断方法,即使改变了符号常量 ROW 和 COL 的值也可以是判断。(如果实在理解不了,可以只当 3*3 的特殊情况来实现判断,当然,也可能是我的代码写的不好)。

(3)程序运行结果:
这里值展示人机对战的三种结果:

玩家获胜:
在这里插入图片描述

电脑获胜:
在这里插入图片描述

平均:
在这里插入图片描述

4. 结果判断实现

该代码直接放在了函数 PMove() 和函数 EMove() 中,也可以单独写一个函数。

(1)实现文件函数定义

// 人机对战模式
void PVE(char board[][COL], int row, int col)
{
	printf("\n人机对战:\n");
	// 初始化棋盘
	InitBoard(board, row, col);
	// 显示棋盘
	PrintBoard(board, row, col);
	// 开始下棋
	int ret = 0;
	do
	{
		// 玩家下棋
		PMove(board, row, col, '#');
		// 显示棋盘
		PrintBoard(board, row, col);
		// 判断
		ret = is_win(board, row, col);
		if (ret != 'C')
			break;
		// 机器人下棋
		EMove(board, row, col);
		// 显示棋盘
		PrintBoard(board, row, col);
		// 判断
		ret = is_win(board, row, col);
		if (ret != 'C')
			break;
	} while (1);
	// 判断最终结果
	if (ret == '#')
		printf("玩家获胜!\n");
	else if (ret == '*')
		printf("电脑获胜!\n");
	else
		printf("平局!\n");
}

// 玩家对战模式
void PVP(char board[][COL], int row, int col)
{
	printf("\n玩家对战:\n");
	// 初始化棋盘
	InitBoard(board, row, col);
	// 显示棋盘
	PrintBoard(board, row, col);
	// 开始下棋
	int ret = 0;
	do
	{
		// 玩家 1 号下棋
		PMove(board, row, col, '#');
		// 显示棋盘
		PrintBoard(board, col, row);
		// 判断
		ret = is_win(board, row, col);
		if (ret != 'C')
			break;
		// 玩家 2 号下棋
		PMove(board, row, col, '*');
		// 显示棋盘
		PrintBoard(board, col, row);
		// 判断
		ret = is_win(board, row, col);
		if (ret != 'C')
			break;
	} while (1);
	// 判断最终结果
	if (ret == '#')
		printf("玩家 1 号获胜!\n");
	else if (ret == '*')
		printf("玩家 2 号获胜!\n");
	else
		printf("平局!\n");
}

(2)演示结果
在上一次演示结果中已经体现。

三、所有代码

分三个文件,分别是头文件 Tic_tac_toe.h,测试文件 test.c,和函数实现文件 Tic_tac_toe.c。

(1)Tic_tac_toe.h

// 常量声明
#define ROW 3
#define COL 3

// 函数声明

// 菜单
void menu();

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

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

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

// 机器人下棋
void EMove(char board[][COL], int row, int col);

// 判断是否获胜
char is_win(char board[][COL], int row, int col);

// 人机对战模式
void PVE(char board[][COL], int row, int col);

// 玩家对战模式
void PVP(char board[][COL], int row, int col);

(2)test.c

// 头文件
#include <stdio.h>
#include "Tic_tac_toe.h"

int main()
{
	// 所需变量
	int select = 0;
	char board[ROW][COL] = { 0 };
	// 选择
	do
	{
		// 菜单
		menu();
		// 选择
		scanf("%d", &select);
		// 判断
		switch (select)
		{
		case 1 :  // 人机对战
			PVE(board, ROW, COL);
			break;
		case 2 :
			PVP(board, ROW, COL);  // 玩家对战
			break;
		case 0 :
			printf("游戏结束!\n");
			break;
		default :
			printf("选择错误请重新选择!\n");
			break;
		}
	} while (select);

	return 0;
}

(3)Tic_tac_toe.c

// 头文件
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "Tic_tac_toe.h"

// 函数定义

// 菜单
void menu()
{
	printf("**************************************\n");
	printf("**********      1. PVE      **********\n");
	printf("**********      2. PVP      **********\n");
	printf("**********      0. exit     **********\n");
	printf("**************************************\n");
}

// 初始化棋盘
void InitBoard(char board[][COL], int row, int col)
{
	int i;
	for (i = 0; i < row; ++i)
	{
		int j;
		for (j = 0; j < col; ++j)
			board[i][j] = ' ';
	}
}

// 打印棋盘
void PrintBoard(char board[][COL], int row, int col)
{
	// 打印棋盘时,需要适当添加符号分隔
	int i;
	for (i = 0; i < row; ++i)
	{
		int j;
		for (j = 0; j < col; ++j)
			printf(" ---");
		// 下一行
		printf("\n");
		for (j = 0; j < col; ++j)
			printf("| %c ", board[i][j]);
		// 补齐改行分隔
		printf("|");
		// 下一行
		printf("\n");
	}
	// 补齐最后一行分隔
	for (i = 0; i < col; ++i)
		printf(" ---");
	
	printf("\n");
}

// 玩家下棋
void PMove(char board[][COL], int row, int col, char who)
{
	// 所需变量
	int x, y;
	do
	{
		// 输入坐标
		printf("玩家下棋(输入坐标中间用空格隔开):\n");
		scanf("%d %d", &x, &y);
		// 判断合法性
		if ((x < 0 || x > row || y < 0 || y > col) || board[x - 1][y - 1] != ' ')
		{
			printf("坐标非法,请重新输入!\n");
		}
		else
		{
			board[x - 1][y - 1] = who;
			break;
		}

	} while (1);
}

// 机器人下棋
void EMove(char board[][COL], int row, int col)
{
	// 机器人是随机下棋的,这里就要获取随机数了
	// 需要包含头文件 stdlib.h 和 time.h 
	// 设置随机数种子
	srand((unsigned)time(0));
	printf("电脑下棋:\n");
	while (1)
	{
		int x = rand() % row;  // 0 - row - 1
		int y = rand() % col;  // 0 - col - 1
		if (board[x][y] == ' ')
		{
			board[x][y] = '*';
			break;
		}
	}
}

// 判断是否获胜
char is_win(char board[][COL], int row, int col)
{
	// 判断每行
	int r = 1;
	int i;
	for (i = 0; i < row; ++i)
	{
		// 重置判断符号
		r = 1;
		// 若首字符为空则下一行
		if (board[i][0] == ' ')
			continue;
		// 判断改行
		int j;
		for (j = 1; j < col; ++j)
		{
			r *= (board[i][j - 1] == board[i][j]);
			// 判断
			if (!r)
				break;
		}
		if (r)
			return board[i][0];
	}

	// 判断每列
	int c = 1;
	int j;
	for (j = 0; j < col; ++j)
	{
		// 重置判断符号
		c = 1;
		// 首字符为空则下一列
		if (board[0][j] == ' ')
			continue;
		// 判断该列
		int i;
		for (i = 1; i < row; ++i)
		{
			c *= (board[i - 1][j] == board[i][j]);
			// 判断
			if (!c)
				break;
		}
		if (c)
			return board[0][j];
	}

	// 判断对角线
	int d = 1;
	if (board[0][0] != ' ')
	{
		for (i = 1; i < row; ++i)
		{
			d *= (board[i - 1][i - 1] == board[i][i]);
			// 判断
			if (!d)
				break;
		}
		if (d)
			return board[0][0];
	}

	if (board[0][col] != ' ')
	{
		d = 1;
		for (i = 1; i < row; ++i)
		{
			d *= (board[i - 1][col - i + 1] == board[i][col - i]);
			// 判断
			if (!d)
				break;
		}
		if (d)
			return board[0][col];
	}

	// 判断棋盘是否已满
	int full = 1;
	for (i = 0; i < row; ++i)
	{
		for (j = 0; j < col; ++j)
		{
			if (board[i][j] == ' ')
			{
				// 未满
				return 'C';
			}
		}
	}
	// 已满
	return 'D';

}


// 人机对战模式
void PVE(char board[][COL], int row, int col)
{
	printf("\n人机对战:\n");
	// 初始化棋盘
	InitBoard(board, row, col);
	// 显示棋盘
	PrintBoard(board, row, col);
	// 开始下棋
	int ret = 0;
	do
	{
		// 玩家下棋
		PMove(board, row, col, '#');
		// 显示棋盘
		PrintBoard(board, row, col);
		// 判断
		ret = is_win(board, row, col);
		if (ret != 'C')
			break;
		// 机器人下棋
		EMove(board, row, col);
		// 显示棋盘
		PrintBoard(board, row, col);
		// 判断
		ret = is_win(board, row, col);
		if (ret != 'C')
			break;
	} while (1);
	// 判断最终结果
	if (ret == '#')
		printf("玩家获胜!\n");
	else if (ret == '*')
		printf("电脑获胜!\n");
	else
		printf("平局!\n");
}

// 玩家对战模式
void PVP(char board[][COL], int row, int col)
{
	printf("\n玩家对战:\n");
	// 初始化棋盘
	InitBoard(board, row, col);
	// 显示棋盘
	PrintBoard(board, row, col);
	// 开始下棋
	int ret = 0;
	do
	{
		// 玩家 1 号下棋
		PMove(board, row, col, '#');
		// 显示棋盘
		PrintBoard(board, col, row);
		// 判断
		ret = is_win(board, row, col);
		if (ret != 'C')
			break;
		// 玩家 2 号下棋
		PMove(board, row, col, '*');
		// 显示棋盘
		PrintBoard(board, col, row);
		// 判断
		ret = is_win(board, row, col);
		if (ret != 'C')
			break;
	} while (1);
	// 判断最终结果
	if (ret == '#')
		printf("玩家 1 号获胜!\n");
	else if (ret == '*')
		printf("玩家 2 号获胜!\n");
	else
		printf("平局!\n");
}

四、总结

本次三子棋的代码编写总体来说还可以,基本上都实现了上述功能,其中的某些代码本人均是根据符号常量来编写的,也就是即使符号常量改变,本代码依旧可以实现。当然,本人水平有限,有的地方看不懂可能是本人代码写的太烂,这里先道个歉。

当然代码还有很多可以提升的地方,比如优化棋盘,可以使用鼠标来下棋,提升电脑的水平等。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2216009.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

企业电子印章主要通过以下几种方式进行防伪

企业电子印章主要通过以下几种方式进行防伪&#xff1a; 一、数字证书和加密技术 数字证书认证 企业电子印章依托数字证书&#xff0c;数字证书由权威的第三方数字认证机构颁发&#xff0c;确保了印章使用者的身份真实性。 数字证书如同企业在数字世界的身份证&#xff0c;包…

Python 工具库每日推荐 【sqlparse】

文章目录 引言SQL解析工具的重要性今日推荐:sqlparse工具库主要功能:使用场景:安装与配置快速上手示例代码代码解释实际应用案例案例:SQL查询分析器案例分析高级特性自定义格式化处理多个语句扩展阅读与资源优缺点分析优点:缺点:总结【 已更新完 Python工具库每日推荐 专…

SpringCloud-持久层框架MyBatis Plus的使用与原理详解

在现代微服务架构中&#xff0c;SpringCloud 是一个非常流行的解决方案。而在数据库操作层面&#xff0c;MyBatis Plus 作为 MyBatis 的增强工具&#xff0c;能够简化开发&#xff0c;提升效率&#xff0c;特别是在开发企业级应用和分布式系统时尤为有用。本文将详细介绍 MyBat…

我们是不是有点神话了OPENAI和CHATGPT?OPENAI真的Open?

网上很多人大力推荐和神化OPENAI的CHATGPT等产品&#xff0c;好像这神器无所不能!也不知道是VPN代理商为了给自己做广告&#xff1f;还是CHATGPT注册代理推销产品?或者有可能是国外宣传CHATGPT文章直接翻译过来的?不可否认CHATGPT确实是一款伟大的产品&#xff0c;但有些情况…

HarmonyOS的DevEcoStudio安装以及初步认识

目录 1.DevEco下载 2.DevEco安装 3. 未开启Hyper-V 1--开启Hyper-v流程 4.编译错误 5.目录结构 1&#xff09;AppScope 2&#xff09;entry: 3&#xff09;build 4&#xff09;entry->src 5&#xff09;entry->src->main->etc 6&#xff09;entry->src->main…

Shell编程-if和else

作者介绍&#xff1a;简历上没有一个精通的运维工程师。希望大家多多关注作者&#xff0c;下面的思维导图也是预计更新的内容和当前进度(不定时更新)。 我们前面学习了那么多命令&#xff0c;以及涉及到部分逻辑判断的问题。从简单来说&#xff0c;他就是Shell编程&#xff0c;…

一键快捷回复软件助力客服高效沟通

双十一临近&#xff0c;电商大战一触即发&#xff01;在这个购物狂欢的热潮中&#xff0c;客服团队的效率至关重要。今天我要和大家分享一个非常实用的快捷回复软件&#xff0c;特别是为电商客服小伙伴们准备的。这款软件能够极大地提高你的工作效率&#xff0c;让你在处理客户…

小程序开发设计-模板与配置:WXML模板语法⑨

上一篇文章导航&#xff1a; 小程序开发设计-协同工作和发布&#xff1a;协同工作⑧-CSDN博客https://blog.csdn.net/qq_60872637/article/details/142455703?spm1001.2014.3001.5501 注&#xff1a;不同版本选项有所不同&#xff0c;并无大碍。 目录 上一篇文章导航&…

OpenAI 公布了其新 o1 模型家族的元提示(meta-prompt)

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

开发板资源介绍【STM32MP157 学习笔记】

引言 FS-MP1A 开发板是基于 ST&#xff08;意法半导体&#xff09;公司的 STM32MP1 系列微处理器设计的先进开发板。该系列处理器集成了 Arm Cortex-A7 和 Cortex-M4 两种内核的异构架构&#xff0c;在高性能和灵活性的基础上&#xff0c;保证了低功耗、实时控制和高度集成化。…

阿里 C++面试,算法题没做出来,,,

我本人是非科班学 C 后端和嵌入式的。在我面试的过程中&#xff0c;竟然得到了阿里​ C 研发工程师的面试机会。因为&#xff0c;阿里主要是用 Java 比较多&#xff0c;C 的岗位比较少​&#xff0c;所以感觉这个机会还是挺难得的。 阿里 C 研发工程师面试考了我一道类似于快速…

深度学习-22-基于keras的十大经典算法之深度神经网络DNN

文章目录 1 深度神经网络(DNN)1.1 DNN简介1.2 DNN基本结构2 模拟应用2.1 构建模型2.2 训练模型2.3 模型预测3 鸢尾花数据集3.1 加载数据3.2 构建模型3.3 训练模型3.4 模型预测4 问题及解决5 参考附录1 深度神经网络(DNN) 1.1 DNN简介 背景:深度神经网络(DNN)也叫多层感…

歌曲怎么去掉原唱只留伴奏?创作无界,轻松获取伴奏音轨

在音乐制作、翻唱或是卡拉OK等场合&#xff0c;我们经常需要歌曲的伴奏版本&#xff0c;即去掉原唱声音&#xff0c;只保留背景音乐的部分。然而&#xff0c;并非每首歌曲都会官方发布伴奏版本&#xff0c;这时我们就需要借助一些技术手段来实现这一目标。本文将介绍几种常见的…

linux线程 | 同步与互斥(上)

前言&#xff1a;本节内容主要是线程的同步与互斥。 本篇文章的主要内容都在讲解互斥的相关以及周边的知识。大体的讲解思路是通过数据不一致问题引出锁。 然后谈锁的使用以及申请锁释放锁的原子性问题。 那么&#xff0c; 废话不多说&#xff0c; 现在开始我们的学习吧&#x…

使用OpenCV实现基于EigenFaces的人脸识别

引言 人脸识别技术近年来得到了飞速的发展&#xff0c;它被广泛应用于安全监控、门禁系统、智能设备等领域。其中&#xff0c;基于特征脸&#xff08;EigenFaces&#xff09;的方法是最早期且较为经典的人脸识别算法之一。本文将介绍如何使用Python和OpenCV库实现一个简单的人…

【LeetCode】每日一题 2024_10_15 三角形的最大高度(枚举、模拟)

前言 每天和你一起刷 LeetCode 每日一题~ LeetCode 启动&#xff01; 题目&#xff1a;三角形的最大高度 代码与解题思路 久违的简单题 这道题读完题目其实不难想到有两条路可以走&#xff1a; 1、题目很明显只有两种情况&#xff0c;枚举是第一个球是红球还是蓝球这两种情…

导数的概念及在模型算法中的应用

一. 导数概念与计算 1. 导数的物理意义&#xff1a; 瞬时速率。一般的&#xff0c;函数yf(x)在x处的瞬时变化率是 2. 导数的几何意义&#xff1a; 曲线的切线&#xff0c;当点趋近于P时&#xff0c;直线 PT 与曲线相切。容易知道&#xff0c;割线的斜率是当点趋近于 P 时&…

UE5学习笔记25-游戏中时间同步

一、原因 1.由于网络问题会导致服务器上的时间和客户端上获得的时间不一致 二、解决方法 在程序启动时向服务器请求服务器的时间返回给客户端并获得客户端发送消息的往返的时间&#xff0c;在获得客户端上的时间&#xff0c;用服务器上获得的时间加上往返时间减去客户端上的时…

稳字诀! 洞见 强者的社交格局:从不恋战——早读(逆天打工人爬取热门微信文章解读)

都是文字 引言Python 代码第一篇 洞见 强者的社交格局&#xff1a;从不恋战第二篇 稳字诀结尾 引言 今天很奇怪 一直都挺烦造的 好像有很多事情忙 但是就是忙着找不定 不能定下心来 主要还是在股市 其他方面应该没啥 计划表还是不够给力 没办法把心在约定住 稳字诀 勤燃香,奋…

深入 IDEA 字节码世界:如何轻松查看 .class 文件?

前言&#xff1a; 作为一名 Java 开发者&#xff0c;理解字节码对于优化程序性能、调试错误以及深入了解 JVM 运行机制非常重要。IntelliJ IDEA 作为最流行的开发工具之一&#xff0c;为开发者提供了查看 .class 文件字节码的功能。在本文中&#xff0c;我将带你一步步探索如何…