当前位置: 首页 > news >正文

YOLOv11-ultralytics-8.3.67部分代码阅读笔记-patches.py

patches.py

ultralytics\utils\patches.py

目录

patches.py

1.所需的库和模块

2.def imread(filename: str, flags: int = cv2.IMREAD_COLOR): 

3.def imwrite(filename: str, img: np.ndarray, params=None): 

4.def imshow(winname: str, mat: np.ndarray): 

5.PyTorch functions 

6.def torch_load(*args, **kwargs): 

7.def torch_save(*args, **kwargs): 


1.所需的库和模块

# Ultralytics 🚀 AGPL-3.0 License - https://ultralytics.com/license
# 使用 Monkey 补丁来更新/扩展现有功能。
"""Monkey patches to update/extend functionality of existing functions."""import time
from pathlib import Pathimport cv2
import numpy as np
import torch# OpenCV Multilanguage-friendly functions OpenCV 多语言友好功能------------------------------------------------------------------------------
# 这段代码定义了一个别名 _imshow ,用于 OpenCV 的 cv2.imshow 函数。这种做法通常是为了避免在后续代码中直接调用原函数时可能出现的递归错误。
# 定义了一个别名 _imshow ,它指向 OpenCV 的 cv2.imshow 函数。
# 目的 :通过这种方式,可以避免在后续代码中直接调用 cv2.imshow ,从而防止可能出现的递归错误。
# 递归错误 :递归错误通常发生在函数调用自身时,如果没有正确的退出条件,会导致无限递归,最终导致栈溢出错误。在某些情况下,如果开发者需要对 cv2.imshow 函数进行包装或修改其行为,直接调用原函数可能会导致递归调用问题。
# 应用场景 :在对 cv2.imshow 函数进行扩展或修改时,使用别名可以安全地调用原函数,确保代码的逻辑清晰且不会出现递归问题。
_imshow = cv2.imshow  # copy to avoid recursion errors    复制以避免递归错误。
# 这段代码通过定义 _imshow 别名,为 OpenCV 的 cv2.imshow 函数创建了一个安全的代理。这种做法的主要目的是避免在后续代码中直接调用原函数时可能出现的递归错误。通过使用别名,开发者可以在不影响原函数功能的前提下,对这些函数进行扩展或修改,从而实现更灵活的功能。

2.def imread(filename: str, flags: int = cv2.IMREAD_COLOR): 

# 这段代码定义了一个自定义的 imread 函数,用于从文件中读取图像。
# 定义了一个函数 imread ,它接受两个参数。
# 1.filename :一个字符串,表示图像文件的路径。
# 2.flags :一个整数,表示读取图像的模式,默认值为 cv2.IMREAD_COLOR ,表示以彩色模式读取图像。
def imread(filename: str, flags: int = cv2.IMREAD_COLOR):# 从文件中读取图像。"""Read an image from a file.Args:filename (str): Path to the file to read.flags (int, optional): Flag that can take values of cv2.IMREAD_*. Defaults to cv2.IMREAD_COLOR.Returns:(np.ndarray): The read image."""# 这是函数的核心部分,使用了 OpenCV 的 cv2.imdecode 函数来读取图像。# np.fromfile(filename, np.uint8) :从文件中读取二进制数据,并将其转换为 NumPy 数组。 np.uint8 表示数据类型为无符号8位整数。# cv2.imdecode :将从文件中读取的二进制数据解码为图像。 flags 参数决定了图像的读取模式(例如彩色、灰度等)。return cv2.imdecode(np.fromfile(filename, np.uint8), flags)
# 这段代码实现了一个自定义的 imread 函数,用于从文件中读取图像。它通过 np.fromfile 读取文件的二进制数据,并将其转换为 NumPy 数组,然后使用 cv2.imdecode 将其解码为图像。这种方法特别适用于处理非标准文件路径或需要支持多种文件格式的场景。与 OpenCV 的默认 cv2.imread 函数相比,这种方法更加灵活,能够更好地处理文件路径和编码问题。

3.def imwrite(filename: str, img: np.ndarray, params=None): 

# 这段代码定义了一个自定义的 imwrite 函数,用于将图像保存到文件中。
# 定义了一个函数 imwrite ,它接受三个参数。
# 1.filename :一个字符串,表示要保存的目标图像文件路径。
# 2.img :一个 NumPy 数组,表示要保存的图像。
# 3.params :一个可选的参数列表,用于指定保存图像时的附加参数(例如压缩格式、质量等)。默认值为 None 。
def imwrite(filename: str, img: np.ndarray, params=None):# 将图像写入文件。"""Write an image to a file.Args:filename (str): Path to the file to write.img (np.ndarray): Image to write.params (list of ints, optional): Additional parameters. See OpenCV documentation.Returns:(bool): True if the file was written, False otherwise."""# 使用 try 块来尝试执行保存图像的操作。如果在执行过程中发生异常,将捕获异常并返回 False 。try:# Path(filename).suffix :使用path lib.Path 模块获取文件的扩展名(例如 .jpg 、 .png 等)。这用于确定保存图像的格式。# cv2.imencode :将图像编码为指定格式的二进制数据。 Path(filename).suffix 提供了文件扩展名, img 是要保存的图像, params 是附加参数。# cv2.imencode(...)[1] : cv2.imencode 返回一个元组,其中第二个元素是编码后的二进制数据。# .tofile(filename) :将编码后的二进制数据写入目标文件。cv2.imencode(Path(filename).suffix, img, params)[1].tofile(filename)# 如果图像成功保存,返回 True 。return True# 如果在保存图像的过程中发生任何异常,将捕获异常。except Exception:# 如果发生异常,返回 False ,表示图像保存失败。return False
# 这段代码实现了一个自定义的 imwrite 函数,用于将图像保存到文件中。它通过 cv2.imencode 将图像编码为指定格式的二进制数据,然后使用 .tofile 方法将数据写入目标文件。函数还通过 try-except 块来处理可能发生的异常,确保在保存失败时能够返回错误信息。这种方法特别适用于需要处理文件路径和格式的场景,比 OpenCV 的默认 cv2.imwrite 函数更加灵活和健壮。

4.def imshow(winname: str, mat: np.ndarray): 

# 这段代码定义了一个自定义的 imshow 函数,用于在指定窗口中显示图像。
# 定义了一个函数 imshow ,它接受两个参数。
# 1.winname :一个字符串,表示显示图像的窗口名称。
# 2.mat :一个 NumPy 数组,表示要显示的图像。
def imshow(winname: str, mat: np.ndarray):# 在指定窗口中显示图像。"""Displays an image in the specified window.Args:winname (str): Name of the window.mat (np.ndarray): Image to be shown."""# 这是函数的核心部分,调用了 _imshow 函数来显示图像。# winname.encode("unicode_escape").decode() : winname.encode("unicode_escape") 将窗口名称字符串编码为 Unicode 转义序列。例如, "图像" 会被编码为 "\u56fe\u50cf" 。 .decode() 将编码后的 Unicode 转义序列解码回普通字符串。这一步是为了确保窗口名称在不同操作系统和语言环境下都能正确显示。# mat :传递给 _imshow 的图像数据。_imshow(winname.encode("unicode_escape").decode(), mat)
# 这段代码实现了一个自定义的 imshow 函数,用于在指定窗口中显示图像。它通过将窗口名称进行 Unicode 转义编码和解码,确保窗口名称在多语言环境下能够正确显示。这种方法特别适用于需要支持多语言窗口标题的场景。

5.PyTorch functions 

# PyTorch functions ----------------------------------------------------------------------------------------------------
# 这段代码定义了两个别名 _torch_load 和 _torch_save ,分别用于 PyTorch 的 torch.load 和 torch.save 函数。这种做法通常是为了避免在后续代码中直接调用原函数时可能出现的递归错误。
# 定义了一个别名 _torch_load ,它指向 PyTorch 的 torch.load 函数。
# 目的 :通过这种方式,可以避免在后续代码中直接调用 torch.load ,从而防止可能出现的递归错误。递归错误通常发生在函数调用自身时,如果没有正确的退出条件,会导致无限递归,最终导致栈溢出错误。
# 应用场景 :在某些情况下,开发者可能需要对 torch.load 函数进行包装或修改其行为,而直接调用原函数可能会导致递归调用问题。通过定义别名,可以安全地调用原函数。
_torch_load = torch.load  # copy to avoid recursion errors
# 定义了一个别名 _torch_save ,它指向 PyTorch 的 torch.save 函数。
# 目的 :与 _torch_load 类似,为了避免在后续代码中直接调用 torch.save ,从而防止递归错误。
# 应用场景 :在对 torch.save 函数进行扩展或修改时,使用别名可以避免直接调用原函数,确保代码的逻辑清晰且不会出现递归问题。
_torch_save = torch.save
# 这段代码通过定义 _torch_load 和 _torch_save 别名,为 PyTorch 的 torch.load 和 torch.save 函数创建了安全的代理。这种做法的主要目的是避免在后续代码中直接调用原函数时可能出现的递归错误。通过使用别名,开发者可以在不影响原函数功能的前提下,对这些函数进行扩展或修改,从而实现更灵活的功能。

6.def torch_load(*args, **kwargs): 

# 这段代码定义了一个自定义的 torch_load 函数,用于加载 PyTorch 模型或对象,并通过添加额外的参数来避免警告。
# 定义了一个函数 torch_load ,它接受可变长度的参数列表 *args 和任意关键字参数 **kwargs 。这种参数形式允许函数接受任意数量和类型的参数,并将它们传递给 torch.load 。
def torch_load(*args, **kwargs):# 使用更新的参数加载 PyTorch 模型以避免出现警告。# 此函数包装 torch.load 并为 PyTorch 1.13.0+ 添加“weights_only”参数以防止出现警告。# 注意:# 对于 PyTorch 2.0 及更高版本,如果未提供参数,此函数会自动设置“weights_only=False”,以避免出现弃用警告。"""Load a PyTorch model with updated arguments to avoid warnings.This function wraps torch.load and adds the 'weights_only' argument for PyTorch 1.13.0+ to prevent warnings.Args:*args (Any): Variable length argument list to pass to torch.load.**kwargs (Any): Arbitrary keyword arguments to pass to torch.load.Returns:(Any): The loaded PyTorch object.Note:For PyTorch versions 2.0 and above, this function automatically sets 'weights_only=False'if the argument is not provided, to avoid deprecation warnings."""# 从 ultralytics.utils.torch_utils 模块中导入 TORCH_1_13 。 TORCH_1_13 是一个布尔值,用于检查当前安装的 PyTorch 版本是否为 1.13.0 或更高版本。from ultralytics.utils.torch_utils import TORCH_1_13# 检查当前 PyTorch 版本是否为 1.13.0 或更高版本,并且检查 kwargs 中是否已经提供了 weights_only 参数。if TORCH_1_13 and "weights_only" not in kwargs:# 如果没有提供 weights_only 参数,将其设置为 False 。# 这一步是为了避免在 PyTorch 1.13.0 及以上版本中出现的警告,特别是关于 weights_only 参数的弃用警告。kwargs["weights_only"] = False# 调用 _torch_load 函数(这是 torch.load 的别名),并将 *args 和 **kwargs 传递给它。 返回加载的 PyTorch 对象。return _torch_load(*args, **kwargs)
# 这段代码实现了一个自定义的 torch_load 函数,用于加载 PyTorch 模型或对象。它通过检查 PyTorch 版本,并在必要时添加 weights_only=False 参数,避免了在 PyTorch 1.13.0 及以上版本中可能出现的警告。这种方法特别适用于需要兼容多个 PyTorch 版本的场景,确保代码的健壮性和兼容性。

7.def torch_save(*args, **kwargs): 

# 这段代码定义了一个自定义的 torch_save 函数,用于保存 PyTorch 模型或对象。它通过增加重试机制和指数退避策略来提高保存操作的鲁棒性。
# 定义了一个函数 torch_save ,它接受可变长度的参数列表 *args 和任意关键字参数 **kwargs 。这种参数形式允许函数接受任意数量和类型的参数,并将它们传递给 torch.save 。
def torch_save(*args, **kwargs):# 可选择使用 dill 序列化 lambda 函数(pickle 无法做到),通过 3 次重试和指数对峙来增强稳健性,以防保存失败。"""Optionally use dill to serialize lambda functions where pickle does not, adding robustness with 3 retries andexponential standoff in case of save failure.Args:*args (tuple): Positional arguments to pass to torch.save.**kwargs (Any): Keyword arguments to pass to torch.save."""# 使用 for 循环实现最多 3 次重试。循环变量 i 的范围是 0, 1, 2, 3 ,因此总共尝试 4 次(包括第一次尝试)。for i in range(4):  # 3 retries# 在 try 块中调用 _torch_save 函数(这是 torch.save 的别名),并将 *args 和 **kwargs 传递给它。 如果保存操作成功,返回保存的结果。try:return _torch_save(*args, **kwargs)# 如果在保存过程中发生 RuntimeError ,捕获异常并处理。 这种错误可能是由于设备正在刷新、磁盘空间不足或杀毒软件正在扫描文件等原因导致的。except RuntimeError as e:  # unable to save, possibly waiting for device to flush or antivirus scan# 如果这是第 4 次尝试(即 i == 3 ),则重新抛出异常,表示保存操作失败。if i == 3:raise e# 如果不是最后一次尝试,则使用指数退避策略等待一段时间后再尝试保存。# time.sleep((2**i) / 2) :根据尝试次数 i ,计算等待时间。例如 :# 第一次失败后等待 0.5 秒。# 第二次失败后等待 1.0 秒。# 第三次失败后等待 2.0 秒。# 这种策略可以减少因设备忙或杀毒软件扫描导致的连续失败。time.sleep((2**i) / 2)  # exponential standoff: 0.5s, 1.0s, 2.0s
# 这段代码实现了一个自定义的 torch_save 函数,用于保存 PyTorch 模型或对象。它通过增加重试机制和指数退避策略来提高保存操作的鲁棒性。这种方法特别适用于在某些情况下可能会失败的保存操作,例如磁盘空间不足、设备正在刷新或杀毒软件正在扫描文件等。通过重试和等待,可以显著提高保存操作的成功率。

相关文章:

YOLOv11-ultralytics-8.3.67部分代码阅读笔记-patches.py

patches.py ultralytics\utils\patches.py 目录 patches.py 1.所需的库和模块 2.def imread(filename: str, flags: int cv2.IMREAD_COLOR): 3.def imwrite(filename: str, img: np.ndarray, paramsNone): 4.def imshow(winname: str, mat: np.ndarray): 5.PyTorch…...

R语言LCMM多维度潜在类别模型流行病学研究:LCA、MM方法分析纵向数据

全文代码数据:https://tecdat.cn/?p39710 在数据分析领域,当我们面对一组数据时,通常会有已知的分组情况,比如不同的治疗组、性别组或种族组等(点击文末“阅读原文”获取完整代码数据)。 然而,…...

2025 年前端开发现状分析:卷疯了还是卷麻了?

一、前端现状:框架狂飙,开发者崩溃 如果你是个前端开发者,那么你大概率经历过这些场景: 早上打开 CSDN(或者掘金,随便),发现又有新框架发布了,名字可能是 VueXNext.js 之…...

RDK新一代模型转换可视化工具!!!

作者:SkyXZ CSDN:SkyXZ~-CSDN博客 博客园:SkyXZ - 博客园 之前在使用的RDK X3的时候,吴诺老师wunuo发布了新一代量化转换工具链使用教程,这个工具真的非常的方便,能非常快速的完成X3上模型的量化…...

JVM春招快速学习指南

1.说在前面 在Java相关岗位的春/秋招面试过程中,JVM的学习是必不可少的。本文主要是通过《深入理解Java虚拟机》第三版来介绍JVM的学习路线和方法,并对没有过JVM基础的给出阅读和学习建议,尽可能更加快速高效的进行JVM的学习与秋招面试的备战…...

C#中的序列化和反序列化

序列化是指将对象转换为可存储或传输的格式,例如将对象转换为JSON字符串或字节流。反序列化则是将存储或传输的数据转换回对象的过程。这两个过程在数据持久化、数据交换以及与外部系统的通信中非常常见 把对象转换成josn字符串格式 这个过程就是序列化 josn字符…...

xcode常见设置

1、如何使用cmake构建archs为$(ARCHS_STANDARD)的xcode项目 在cmake中使用如下指令 set(CMAKE_OSX_ARCHITECTURES "$(ARCHS_STANDARD)") cmake - nomadli的博客 | nomadli Blog...

PG高可用学习@2

目录标题 一、Patroni 支持在同步复制下备库故障时自动降级为异步复制?参考依据1. PostgreSQL 官方文档2. Patroni 官方文档3. 高可用和容错设计原则 二、patroni 是如何检测备库故障的?1. 心跳机制2. 监控数据库进程状态3. 查询系统视图4. 复制延迟监测5. 网络连接…...

centos 8和centos 9 stream x64的区别

以下是 CentOS 8 与 CentOS Stream 9 的主要区别,从技术架构、更新策略到适用场景等维度进行对比: AI产品独立开发实战营 联系我了解 1. 定位与更新策略 特性CentOS 8CentOS Stream 9定位原为 RHEL 8 的免费稳定复刻版RHEL 9 的上游开发分支&#xff…...

C++基础学习记录—类

1、面向对象的三大特征:封装、继承、多态 2、类和对象 2.1、类的概念 类:类是一个抽象的概念,用于描述同一类对象的特点。 对象:根据类的概念所创造的实体。 类中包含属性和行为 属性:描述类的数据,一…...

云原生时代的后端开发:架构、工具与最佳实践

随着云计算的迅猛发展,云原生(Cloud Native)逐渐成为后端开发的主流趋势。云原生后端不仅能够提高应用的灵活性和可扩展性,还能显著优化开发和运维流程。本文将围绕云原生后端的关键概念、当前热门技术及最佳实践,帮助…...

ARM Cortex-M3/M4 权威指南 笔记【一】技术综述

一、Cortex-M3/M4 处理器的一般信息 1.1 处理器类型 ARM Cortex-M 为 32 位 RISC(精简指令集)处理器,其具有: 32位寄存器32位内部数据通路32位总线接口 除了 32 位数据,Cortex-M 处理器(以及其他任何 A…...

12.项目结构

后端结构 ruoyi-admin 项目启动的入口 提供了两种启动方式 1.RuoYiApplication基于springboot,内置tomcat,直接运行。 2.RuoYiServletInitializer将springboot项目打成一个war包,用外置的servlet容器来运行。 通用功能的controller 后台登录相关的、权限控制相关的、数据字…...

保研考研机试攻略:python笔记(4)

🐨🐨🐨15各类查找 🐼🐼二分法 在我们写程序之前,我们要定义好边界,主要是考虑区间边界的闭开问题。 🐶1、左闭右闭 # 左闭右闭 def search(li, target): h = len(li) - 1l = 0#因为都是闭区间,h和l都可以取到并且相等while h >= l:mid = l + (h - l) // 2…...

高阶C语言|枚举与联合

💬 欢迎讨论:在阅读过程中有任何疑问,欢迎在评论区留言,我们一起交流学习! 👍 点赞、收藏与分享:如果你觉得这篇文章对你有帮助,记得点赞、收藏,并分享给更多对C语言感兴…...

【天梯赛】L1-104 九宫格(C++)

易忽略的错误&#xff1a;开始习惯性地看到n就以为是n*n数组了&#xff0c;实际上应该是9*9的固定大小数组&#xff0c;查了半天没查出来 题面 L1-104 九宫格 - 团体程序设计天梯赛-练习集 代码实现 #include<bits/stdc.h> using namespace std; //易错&#xff1a;开…...

现代C++多线程基础 -忆苦思甜pthread_mutex

c 老古董 文章目录 c 老古董pthread_mutex概念常用apipthread_mutex_initpthread_mutex_lockpthread_mutex_trylockpthread_mutex_unlockpthread_mutex_destroy 案例 pthread_mutex 概念 互斥锁 mutex是一种简单的加锁的方法来控制对共享资源的访问&#xff0c;mutex只有两种…...

soular基础教程-使用指南

soular是TikLab DevOps工具链的统一帐号中心&#xff0c;今天来介绍如何使用 soular 配置你的组织、工作台&#xff0c;快速入门上手。 &#xfeff; 1. 账号管理 可以对账号信息进行多方面管理&#xff0c;包括分配不同的部门、用户组等&#xff0c;从而确保账号权限和职责…...

网络安全网格架构(CSMA) 网络安全框架csf

CSRF:Cross Site Request Forgy&#xff08;跨站请求伪造&#xff09; 用户打开另外一个网站&#xff0c;可以对本网站进行操作或攻击。容易产生传播蠕虫。 CSRF攻击原理&#xff1a; 1、用户先登录A网站 2、A网站确认身份返回用户信息 3、B网站冒充用户信息而不是直接获取用…...

基于DeepSeek API和VSCode的自动化网页生成流程

1.创建API key 访问官网DeepSeek &#xff0c;点击API开放平台。 在开放平台界面左侧点击API keys&#xff0c;进入API keys管理界面&#xff0c;点击创建API key按钮创建API key&#xff0c;名称自定义。 2.下载并安装配置编辑器VSCode 官网Visual Studio Code - Code Editing…...

手游刚开服就被攻击怎么办?如何防御DDoS?

开服初期是手游最脆弱的阶段&#xff0c;极易成为DDoS攻击的目标。一旦遭遇攻击&#xff0c;可能导致服务器瘫痪、玩家流失&#xff0c;甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案&#xff0c;帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...

智慧医疗能源事业线深度画像分析(上)

引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...

智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql

智慧工地管理云平台系统&#xff0c;智慧工地全套源码&#xff0c;java版智慧工地源码&#xff0c;支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求&#xff0c;提供“平台网络终端”的整体解决方案&#xff0c;提供劳务管理、视频管理、智能监测、绿色施工、安全管…...

苍穹外卖--缓存菜品

1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得&#xff0c;如果用户端访问量比较大&#xff0c;数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据&#xff0c;减少数据库查询操作。 缓存逻辑分析&#xff1a; ①每个分类下的菜品保持一份缓存数据…...

反射获取方法和属性

Java反射获取方法 在Java中&#xff0c;反射&#xff08;Reflection&#xff09;是一种强大的机制&#xff0c;允许程序在运行时访问和操作类的内部属性和方法。通过反射&#xff0c;可以动态地创建对象、调用方法、改变属性值&#xff0c;这在很多Java框架中如Spring和Hiberna…...

ardupilot 开发环境eclipse 中import 缺少C++

目录 文章目录 目录摘要1.修复过程摘要 本节主要解决ardupilot 开发环境eclipse 中import 缺少C++,无法导入ardupilot代码,会引起查看不方便的问题。如下图所示 1.修复过程 0.安装ubuntu 软件中自带的eclipse 1.打开eclipse—Help—install new software 2.在 Work with中…...

服务器--宝塔命令

一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行&#xff01; sudo su - 1. CentOS 系统&#xff1a; yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...

面向无人机海岸带生态系统监测的语义分割基准数据集

描述&#xff1a;海岸带生态系统的监测是维护生态平衡和可持续发展的重要任务。语义分割技术在遥感影像中的应用为海岸带生态系统的精准监测提供了有效手段。然而&#xff0c;目前该领域仍面临一个挑战&#xff0c;即缺乏公开的专门面向海岸带生态系统的语义分割基准数据集。受…...

数据结构:递归的种类(Types of Recursion)

目录 尾递归&#xff08;Tail Recursion&#xff09; 什么是 Loop&#xff08;循环&#xff09;&#xff1f; 复杂度分析 头递归&#xff08;Head Recursion&#xff09; 树形递归&#xff08;Tree Recursion&#xff09; 线性递归&#xff08;Linear Recursion&#xff09;…...

鸿蒙HarmonyOS 5军旗小游戏实现指南

1. 项目概述 本军旗小游戏基于鸿蒙HarmonyOS 5开发&#xff0c;采用DevEco Studio实现&#xff0c;包含完整的游戏逻辑和UI界面。 2. 项目结构 /src/main/java/com/example/militarychess/├── MainAbilitySlice.java // 主界面├── GameView.java // 游戏核…...