WPF 五子棋项目文档
WPF 五子棋项目文档
1. 项目概述
本项目是一个使用 Windows Presentation Foundation (WPF) 技术栈和 C# 语言实现的桌面版五子棋(Gomoku)游戏。它遵循 MVVM(Model-View-ViewModel)设计模式,旨在提供一个结构清晰、可维护、可扩展的游戏应用。
主要功能:
-
标准的 15x15 棋盘。
-
支持黑白双方轮流落子。
-
基本的落子逻辑(不能落在已有棋子的位置)。
-
简单的胜负判断逻辑(当前代码中为简化示例,需完整实现)。
-
显示当前回合玩家。
-
提供“重新开始”功能。
-
视觉上呈现棋盘网格和棋子。
技术栈:
-
UI 框架: WPF (.NET)
-
语言: C#
-
设计模式: MVVM (Model-View-ViewModel)
-
开发环境: Visual Studio 2019/2022
2. 项目结构
项目采用了分层结构,将不同的职责分离到各自的目录中:
GomokuWPF/
├── Assets/ # 静态资源目录
│ ├── Images/ # (可选) 图片资源,如棋子、背景图等
│ └── Styles/ # XAML 样式文件
│ └── BoardStyles.xaml # 棋盘和棋子的样式定义
├── Models/ # 数据模型和核心业务逻辑
│ └── GameState.cs # 游戏状态、棋盘数据和核心游戏规则
├── ViewModels/ # 视图模型,连接视图和模型
│ └── MainViewModel.cs # 主窗口对应的视图模型
├── Views/ # 用户界面 (XAML)
│ └── MainWindow.xaml # 应用程序的主窗口
├── App.xaml # WPF 应用程序入口定义
├── App.xaml.cs # App.xaml 的 C# 代码隐藏文件
└── GomokuWPF.csproj # 项目文件 (由 VS 管理)
目录说明:
-
Assets/: 存放不需要编译的静态资源,如样式、图片、字体等。
-
Styles/: 专门存放 XAML ResourceDictionary 文件,用于定义 UI 控件的外观和感觉。
-
-
Models/: 包含应用程序的核心数据结构和业务逻辑,独立于 UI。GameState.cs 负责管理棋盘状态、玩家回合、胜负判断等。
-
ViewModels/: 包含视图模型类。视图模型是视图(View)的数据上下文(DataContext),它从模型(Model)获取数据,处理用户交互(通过命令),并准备数据以便在视图中显示。
-
Views/: 包含所有的用户界面定义文件(.xaml)及其关联的代码隐藏文件(.xaml.cs)。MainWindow.xaml 是用户直接交互的主界面。
-
App.xaml/.cs: 应用程序的启动入口。App.xaml 中通常定义全局资源(如样式)和指定启动窗口 (StartupUri)。
3. 组件详解
3.1. App.xaml / App.xaml.cs
-
App.xaml:
-
定义应用程序级别的资源。通过 <Application.Resources> 和 <ResourceDictionary.MergedDictionaries>,它引入了 Assets/Styles/BoardStyles.xaml 中定义的样式,使其在整个应用程序中可用。
-
StartupUri="Views/MainWindow.xaml" 指定了应用程序启动时首先加载并显示的窗口。
-
-
App.xaml.cs:
-
是 App.xaml 的代码隐藏文件。通常包含应用程序生命周期事件的处理代码(如 OnStartup, OnExit),但在这个简单的项目中,可能保持默认或为空。
-
3.2. Models/GameState.cs
-
职责: 封装五子棋游戏的核心状态和规则,与 UI 无关。
-
Player 枚举: 定义了棋盘上可能的状态:None (空), Black (黑子), White (白子)。
-
Board 属性: Player[15, 15] 二维数组,存储棋盘上每个交叉点的状态。使用 get; 表示外部只能读取,内部逻辑通过方法修改。
-
CurrentPlayer 属性: Player 类型,指示当前轮到哪一方落子。private set; 确保只有 GameState 内部逻辑能改变玩家。
-
GameOver 属性: bool 类型,标记游戏是否已经结束。private set; 同上。
-
MakeMove(int row, int col) 方法:
-
核心落子逻辑。
-
检查游戏是否结束或目标位置是否已有棋子,如果是则直接返回。
-
在 Board 上记录当前玩家的落子。
-
调用 CheckWin() 判断当前落子是否导致胜利。
-
如果游戏胜利,设置 GameOver = true。
-
如果游戏未结束,切换 CurrentPlayer 到另一方。
-
-
CheckWin(int row, int col) 方法:
-
(注意:当前代码中返回 false,是简化示例,需要完整实现!)
-
应包含完整的五子连珠判断逻辑:检查刚落子的位置 (row, col) 的水平、垂直、两条对角线方向上,是否有连续五个同色棋子。
-
-
Reset() 方法: (注意:代码中未显式提供,但在 ViewModel 中被调用,应添加此方法)
-
用于重置游戏状态。
-
将 Board 所有位置设为 Player.None。
-
将 CurrentPlayer 设回 Player.Black。
-
将 GameOver 设为 false。
-
3.3. ViewModels/MainViewModel.cs
-
职责: 作为 MainWindow.xaml 的 DataContext,连接 GameState (Model) 和 MainWindow (View)。处理用户交互,并向 View 提供格式化后的数据和命令。
-
ObservableObject 基类: 实现了 INotifyPropertyChanged 接口,允许 ViewModel 在其属性值改变时通知 View 更新绑定。OnPropertyChanged() 方法用于触发此通知。
-
_game 字段: GameState 的私有实例,持有游戏状态模型。
-
CurrentPlayerText 属性: string 类型,根据 _game.CurrentPlayer 的值返回用户友好的文本("黑方回合" 或 "白方回合")。当 _game.CurrentPlayer 改变时,需要调用 OnPropertyChanged(nameof(CurrentPlayerText)) 来更新 UI。
-
CurrentPlayerBrush 属性: Brush 类型,根据 _game.CurrentPlayer 返回黑色或白色画刷,用于 UI 提示。同样需要 OnPropertyChanged 通知。
-
PlaceStoneCommand 属性: ICommand 类型 (使用 RelayCommand<Point>)。绑定到棋盘单元格的点击事件。
-
ExecutePlaceStone(Point position): 命令的执行逻辑。接收点击的坐标 position (相对于 ItemsControl 内的单元格),计算对应的棋盘行列 row, col。调用 _game.MakeMove(row, col) 更新模型。然后调用 OnPropertyChanged 更新 CurrentPlayerText 和 CurrentPlayerBrush 以反映状态变化。 (注意:这里需要 View 传递正确的坐标或单元格索引)。
-
-
RestartCommand 属性: ICommand 类型 (使用 RelayCommand)。绑定到“重新开始”按钮。
-
ExecuteRestart(): 调用 _game.Reset() (假设已添加) 重置游戏模型。然后调用 OnPropertyChanged 更新相关 UI 属性。
-
-
RelayCommand / RelayCommand<T>: 辅助类,提供了 ICommand 接口的简单通用实现,简化了在 ViewModel 中定义命令的过程。
3.4. Views/MainWindow.xaml
-
职责: 定义应用程序主窗口的结构、布局和外观。通过数据绑定与 MainViewModel 交互。
-
<Window.DataContext>:
<Window.DataContext><local:MainViewModel/> </Window.DataContext>
在这里创建并设置了 MainViewModel 的实例作为窗口的数据上下文。窗口内的所有绑定默认都将相对于这个 MainViewModel 实例。
-
棋盘区域 (ItemsControl):
-
ItemsSource="{Binding Board}": (注意:此绑定需要调整) GameState.Board 是一个二维数组,ItemsControl 通常期望绑定到一个一维集合(如 List<CellViewModel>)。MainViewModel 需要暴露一个适合绑定的集合,其中每个元素代表一个棋盘格,并包含其状态(Player)和位置信息。
-
<ItemsControl.ItemsPanel> 使用 UniformGrid 来将子项排列成 15x15 的网格。
-
<ItemsControl.ItemTemplate>: 定义每个棋盘格(ItemsControl 的子项)的视觉表示。
-
Border: 代表一个棋盘格单元。
-
Width="40" Height="40": 定义单元格大小。
-
Background="{StaticResource BoardCellBrush}": 应用 BoardStyles.xaml 中定义的棋盘格背景(带网格线)。
-
Command="{Binding DataContext.PlaceStoneCommand, RelativeSource={RelativeSource AncestorType=Window}}": 将单元格的交互(如点击)绑定到 MainViewModel 的 PlaceStoneCommand。RelativeSource 用于查找父级 Window 的 DataContext。
-
CommandParameter="{Binding Position}": (注意:此绑定需要调整) 需要传递当前单元格的位置(行、列或索引)给命令。如果 ItemsSource 是 CellViewModel 列表,这里可以绑定到 CellViewModel 的 Position 属性。
-
-
Ellipse: 代表棋子。
-
Width="30" Height="30": 定义棋子大小。
-
Fill="{Binding StoneBrush}": (注意:此绑定需要调整) 绑定到 CellViewModel 的一个属性(如 StoneBrush),该属性根据 CellViewModel 的状态(黑/白/空)返回相应的画刷(黑色、白色或透明)。
-
-
-
-
控制面板 (StackPanel):
-
Button Content="重新开始":
-
Command="{Binding RestartCommand}": 绑定到 MainViewModel 的 RestartCommand。
-
-
TextBlock:
-
Text="{Binding CurrentPlayerText}": 显示当前回合玩家文本。
-
Foreground="{Binding CurrentPlayerBrush}": 根据当前玩家设置文本颜色。
-
-
3.5. Assets/Styles/BoardStyles.xaml
-
职责: 集中定义棋盘、棋格和棋子的视觉样式,方便复用和修改。
-
BoardCellBrush (DrawingBrush): 定义棋盘格的背景。
-
使用 DrawingGroup 组合了一个米色背景 (RectangleGeometry) 和两条居中的灰色线条 (GeometryDrawing) 来模拟棋盘网格。
-
TileMode="Tile" 和 Viewport 设置使这个 40x40 的图案在 ItemsControl 的单元格背景中平铺,形成连续的网格。
-
-
GridPen (Pen): 定义网格线的画笔(颜色、粗细)。
-
BlackStoneBrush / WhiteStoneBrush (RadialGradientBrush): 定义黑棋和白棋的填充画刷。使用径向渐变模拟棋子的光泽和立体感。
4. 核心概念
-
MVVM (Model-View-ViewModel):
-
Model (GameState.cs): 代表数据和业务逻辑。不知道 View 和 ViewModel。
-
View (MainWindow.xaml): 代表 UI。通过数据绑定与 ViewModel 交互。直接引用 ViewModel (通常通过 DataContext),但不直接引用 Model。
-
ViewModel (MainViewModel.cs): 连接 Model 和 View 的桥梁。持有 Model 实例,向 View 暴露数据(通过属性)和操作(通过命令)。处理 View 的交互请求,更新 Model,并通过 INotifyPropertyChanged 通知 View 更新。
-
-
数据绑定 ({Binding ...} syntax): WPF 的核心机制,用于在 UI 元素(View)的属性和数据源(通常是 ViewModel)的属性之间建立连接。当数据源属性变化时,UI 会自动更新,反之亦然(对于双向绑定)。
-
命令 (ICommand): WPF 中处理用户交互(如按钮点击)的标准方式。ViewModel 实现 ICommand 接口(通常通过 RelayCommand),View 将控件的 Command 属性绑定到 ViewModel 的命令属性。这使得交互逻辑可以放在 ViewModel 中,保持 View 的简洁。
-
资源字典 (ResourceDictionary): 用于存储可重用的资源,如样式(Style)、画刷(Brush)、模板(ControlTemplate, DataTemplate)等。可以合并到 App.xaml 或控件的 Resources 中使用。StaticResource 用于在 XAML 中引用这些资源。
-
INotifyPropertyChanged: 接口,当对象的属性值更改时,向绑定客户端发出通知。ViewModel 必须实现此接口,以便在数据变化时驱动 UI 更新。ObservableObject 是一个常见的基类实现。
5. 游戏流程
-
启动: 应用程序启动,App.xaml 指定 MainWindow.xaml 作为启动窗口。
-
初始化: MainWindow.xaml 加载,其实例的 DataContext 被设置为一个新的 MainViewModel 实例。MainViewModel 在其构造函数中创建 GameState 实例和命令。
-
UI 渲染:
-
ItemsControl 尝试绑定到 MainViewModel 的 Board 属性(需要调整实现)来获取棋盘数据。
-
ItemsControl 使用 UniformGrid 创建 15x15 的布局。
-
对于每个棋盘格,ItemTemplate 被实例化。Border 的背景应用 BoardCellBrush,Ellipse 的填充根据棋盘格状态(通过绑定)设置。
-
控制面板的 TextBlock 绑定到 CurrentPlayerText 和 CurrentPlayerBrush,显示初始状态("黑方回合",黑色)。
-
"重新开始" 按钮绑定到 RestartCommand。
-
-
玩家落子:
-
玩家点击棋盘上的一个空单元格 (Border)。
-
该 Border 的 Command (绑定到 PlaceStoneCommand) 被触发。
-
MainViewModel.ExecutePlaceStone 方法被调用,传入点击位置(需要正确传递)。
-
ExecutePlaceStone 计算行列,调用 _game.MakeMove(row, col)。
-
GameState.MakeMove 更新 Board 数组,检查胜利条件,然后切换 CurrentPlayer。
-
ExecutePlaceStone 调用 OnPropertyChanged 通知 UI 更新 CurrentPlayerText 和 CurrentPlayerBrush。
-
(关键缺失/需调整): Board 数组的变化需要一种机制来更新 ItemsControl 中对应单元格的 Ellipse 的 Fill 属性。这通常通过让 ItemsSource 绑定到一个 ObservableCollection<CellViewModel>,并在 MakeMove 后更新相应的 CellViewModel 的状态属性来实现。
-
-
判断胜负:
-
GameState.CheckWin 方法(需要完整实现)在每次落子后被调用。
-
如果检测到胜利,GameState.GameOver 设置为 true。ViewModel 可以暴露这个状态给 View,例如禁用棋盘交互或显示胜利消息。
-
-
重新开始:
-
玩家点击 "重新开始" 按钮。
-
按钮的 Command (绑定到 RestartCommand) 被触发。
-
MainViewModel.ExecuteRestart 方法被调用。
-
ExecuteRestart 调用 _game.Reset() (假设已添加)。
-
GameState.Reset 清空棋盘,重置玩家和游戏状态。
-
ExecuteRestart 调用 OnPropertyChanged 更新 UI 显示(回合提示、棋盘视觉)。(同样需要机制更新棋盘所有单元格的视觉)
-
6. 如何编译和运行
-
环境: 确保已安装 Visual Studio 2019 或 2022,并包含 .NET 桌面开发工作负载。
-
打开项目: 使用 Visual Studio 打开 GomokuWPF.sln 文件(如果存在)或 GomokuWPF.csproj 文件。
-
构建项目: 在 Visual Studio 菜单中选择 "生成" -> "生成解决方案" (或按 F6)。检查 "输出" 窗口是否有编译错误。
-
注意: 根据文档分析,原始代码片段在 Board 绑定和 Reset 方法方面可能存在不一致或缺失,可能需要进行少量修改才能成功编译和按预期运行。具体来说:
-
在 GameState.cs 中添加 Reset() 方法。
-
修改 MainViewModel.cs,使其暴露一个适合 ItemsControl 绑定的棋盘数据集合(例如 ObservableCollection<CellViewModel>),并在 MakeMove 和 Reset 后更新这个集合。
-
修改 MainWindow.xaml 中的 ItemsControl 绑定 (ItemsSource, CommandParameter, Fill) 以匹配新的 ViewModel 结构。
-
-
-
运行项目: 按 F5 键或点击 Visual Studio 工具栏上的 "启动" 按钮。应用程序主窗口 (MainWindow) 应该会显示出来。
7. 潜在的扩展和改进
-
实现完整的胜负判断: 填充 GameState.CheckWin 方法的逻辑。
-
完善 ViewModel 对 Board 的暴露: 如上所述,使用 ObservableCollection<CellViewModel> 替代直接暴露二维数组,以实现正确的 UI 更新。CellViewModel 可以包含 Row, Col, Player 状态,以及用于绑定的 StoneBrush 属性。
-
游戏结束提示: 当 GameOver 为 true 时,在 UI 上明确显示胜利者,并可能禁用棋盘交互。
-
悔棋功能: 添加撤销上一步操作的逻辑。
-
平局判断: 实现棋盘满但无胜负的情况。
-
AI 对手: 添加一个 AI 逻辑模块,可以选择与电脑对战。
-
音效: 在落子、胜利时播放声音。
-
设置选项: 允许配置棋盘大小、先手方等。
-
网络对战: 实现通过网络与其他玩家对战的功能。
-
优化样式: 改进棋盘和棋子的视觉效果。
这份文档提供了对所提供代码的详细分析和解释,指出了其结构、功能和潜在需要改进的地方。希望它能帮助您理解和进一步开发这个 WPF 五子棋项目。
相关文章:
WPF 五子棋项目文档
WPF 五子棋项目文档 1. 项目概述 本项目是一个使用 Windows Presentation Foundation (WPF) 技术栈和 C# 语言实现的桌面版五子棋(Gomoku)游戏。它遵循 MVVM(Model-View-ViewModel)设计模式,旨在提供一个结构清晰、可…...
UniApp 实现兼容 H5 和小程序的拖拽排序组件
如何使用 UniApp 实现一个兼容 H5 和小程序的 九宫格拖拽排序组件,实现思路和关键步骤。 一、实现目标 支持拖动菜单项改变顺序拖拽过程实时预览移动位置拖拽松开后自动吸附回网格兼容 H5 和小程序平台 二、功能结构拆解以及完整代码 完整代码: <…...
谷歌推出统一安全平台-一个平台实现跨云网端主动防护
👋 今天要给大家带来一个超级棒的消息!谷歌云推出了全新的“谷歌统一安全平台”,感觉我们的网络安全问题有救啦!😄 随着企业基础设施变得越来越复杂,保护它们也变得越来越难。攻击面不断扩大,安…...
众趣科技丨沉浸式 VR 体验,助力酒店民宿数字化营销宣传
随着旅游季的到来,各地的旅游景区开始“摩拳擦掌”推出各种活动,吸引更多游客来此游玩。 自去年以来,冰雪游热度持续上升,尤其是对于满心期待的南方游客来说,哈尔滨仍是冰雪旅游的热门目的地。据美团数据显示ÿ…...
DAY05:【pytorch】图像预处理
1、torchvision 功能:计算视觉工具包 torchvision.transforms:常用的图像预处理方法torchvision.datasets:常用数据集的 dataset 实战,MINIST,CIFAR-10,ImageNet等torchvision.model:常用的模…...
真实企业级K8S故障案例:ETCD集群断电恢复与数据保障实践
背景描述 某跨境电商平台生产环境使用Kubernetes(v1.23.17)管理500微服务。某日机房突发市电中断,UPS未能及时接管导致: 3节点ETCD集群(v3.5.4)全部异常掉电 Control-Plane节点无法启动api-server 业务P…...
rbd块设备的id修改
背景 看到有这个需求,具体碰到什么场景了不太清楚,之前做过rbd的重构的研究,既然能重构,那么修改应该是比重构还要简单一点的,我们具体看下怎么操作 数据结构分析 rbd的元数据信息 [rootlab104 ~]# rbd create tes…...
WP最主题专业的wordpress主题开发
WP最主题(wpzui.com) WP最主题是一个提供高品质WordPress主题的平台。它注重主题的设计和功能,旨在为用户提供美观且实用的主题选择。其主题通常具有良好的用户体验、丰富的自定义选项以及优化的性能,能够满足不同类型的网站搭建…...
HomeAssistant本地化部署结合内网穿透打造跨网络智能家居中枢
文章目录 前言1. 添加镜像源2. 部署HomeAssistant3. HA系统初始化配置4. HA系统添加智能设备4.1 添加已发现的设备4.2 添加HACS插件安装设备 5. 安装cpolar内网穿透5.1 配置HA公网地址 6. 配置固定公网地址 推荐 前些天发现了一个巨牛的人工智能学习网站,通俗易懂…...
# 实时人脸性别与年龄识别:基于OpenCV与深度学习模型的实现
实时人脸性别与年龄识别:基于OpenCV与深度学习模型的实现 在当今数字化时代,计算机视觉技术正以前所未有的速度改变着我们的生活与工作方式。其中,人脸检测与分析作为计算机视觉领域的重要分支,已广泛应用于安防监控、智能交互、…...
SAP-ABAP:SAP的Open SQL和Native SQL详细对比
在SAP ABAP开发中,Open SQL和Native SQL是两种操作数据库的方式,它们的核心区别在于可移植性、功能范围及底层实现机制。以下是详细对比: 1. Open SQL:深入解析 1.1 核心特性 数据库抽象层 Open SQL 由 SAP 内核的 Database Interface (DBI) 转换为目标数据库的 SQL(如 …...
基于大模型构建金融客服的技术调研
OpenAI-SB api接口 https://openai-sb.com/ ChatGPT与Knowledge Graph (知识图谱)分享交流 https://www.bilibili.com/video/BV1bo4y1w72m/?spm_id_from333.337.search-card.all.click&vd_source569ef4f891360f2119ace98abae09f3f 《要研究的方向和准备》 https://ww…...
Python设计模式:命令模式
1. 什么是命令模式? 命令模式是一种行为设计模式,它将请求封装为一个对象,从而使您能够使用不同的请求、队列或日志请求,以及支持可撤销操作。 命令模式的核心思想是将请求的发送者与请求的接收者解耦,使得两者之间的…...
30天学Java第八天——设计模式
装饰器模式 Decorator Pattern 装饰器模式(Decorator Pattern)是一种结构型设计模式,它允许通过动态地添加功能来扩展对象的行为,而不需要修改原有的类。 这种模式通常用于增强对象的功能,与继承相比,使用…...
Spring事务系列 三
Spring事务的传播机制 Spring事务系列 一-CSDN博客 Spring事务系列 二-CSDN博客 文章目录 系列文章目录 目录 文章目录 前言 一、Spring事务的传播机制 Propagation.REQUIRED: Propagation.SUPPORTS: Propagation.MANDATORY: Propagation.REQUIRES_NEW: Propagation.NOT_SUPPO…...
文件上传做题记录
1,[SWPUCTF 2021 新生赛]easyupload2.0 直接上传php 再试一下phtml 用蚁剑连发现连不上 那就只要命令执行了 2,[SWPUCTF 2021 新生赛]easyupload1.0 当然,直接上传一个php是不行的 phtml也不行,看下是不是前端验证,…...
机器学习的监督学习与无监督学习
机器学习主要分为监督学习和无监督学习两大类,两者的核心区别在于数据是否带有标签(Label)。以下是它们的详细对比和说明: 1. 监督学习(Supervised Learning) 定义:通过带有标签的训练数据&…...
C++ 入门三:函数与模板
一、内联函数:编译期嵌入的 “高效函数” 1. 什么是内联函数? 核心特性:在编译阶段,内联函数的函数体会直接嵌入到调用它的代码中,避免了普通函数的调用开销(如压栈、跳转、返回)。语法&#…...
解析券商qmt的优缺点
现在已经对于大QMT进行了一步步的深入了解与学习,也已经开始积木式搭建策略,进行交易了,但是,随时不断的深入,发现的问题也越来越多。下面开始逐一解析: 首页 | 迅投知识库 这是详细的说明。 目前券商给大…...
CSE lesson2 chrony服务器
CSE lesson2 chrony服务器 timedatectl命令 NTP(network time protocal)网络时间协议,时钟服务器同步时间的时候会使用到该协议进行时间同步。 #关闭/开启时间同步服务 [rootlocalhost ~]# timedatectl set-ntp 0/1#设置时间(必须关闭时间同步服务才能…...
时光交响曲:杭州的科技与传统交响
故事背景 故事发生在中国浙江杭州,以现代科技与文化传统的交融为背景,展现了人与自然、历史的深刻联系。在晨曦中的茶园、宁静的运河书屋、科技堤坝等地方,每个场景都充满了生机与活力,展示了科技如何赋予传统文化新的生命&#x…...
【大模型智能体】Agent2Agent协议加上MCP协议也许会成为未来Agent智能体系统的标配
之前在文章《基于Claude MCP协议的智能体落地示例》、《MCP(Model Context Protocol) 大模型智能体第一个开源标准协议》我们已经对MCP协议做了介绍,MCP提供了将大模型连接到不同数据源和工具的标准方式,包括内容仓库、商业工具和开发环境。 以上解决的是…...
opencv(C++)处理图像颜色
文章目录 介绍使用策略设计模式比较颜色实现方案计算两个颜色向量之间的距离1. 简单方法:曼哈顿距离计算(Manhattan Distance)2.使用 OpenCV 的 cv::norm 函数3.使用 OpenCV 的 cv::absdiff 函数错误示例 使用 OpenCV 函数实现颜色检测实现方…...
2025年焊接与热切割作业证考试真题分享
焊接与热切割作业属于特种作业操作证考试,理论知识点专业性强、安全规范要求高,如何高效备考成为关键!【100分题库】焊接与热切割作业理论备考题库紧扣最新考试大纲,帮你系统掌握考点,一次通过考试! 1、下…...
AI 代码生成工具如何突破 Java 单元测试效能天花板?
一、传统单元测试的四大痛点 时间黑洞:根据 JetBrains 调研,Java 开发者平均花费 35% 时间编写测试代码覆盖盲区:手工测试覆盖率普遍低于 60%(Jacoco 全球统计数据)维护困境:业务代码变更导致 38% 的测试用…...
【C++游戏引擎开发】第13篇:光照模型与Phong基础实现
一、Phong模型数学原理 1.1 光照叠加公式 L = k a I a + k d I d max ( 0 , n ⋅ l ) + k s I s max ( 0 , r ⋅ v ) α L = k_a I_a + k_d I_d \max(0, \mathbf{n} \cdot \mathbf{l}) + k_s I_s \max(0, \mathbf{r} \cdot \mathbf{v})^\alpha L=kaIa+kdIdmax(0…...
如何在Android系统上单编ko?
文章目录 一、先了解编译驱动需要什么?二、配置makefile1、在Android系统编译LOG上找到编译器信息(一般都会打印出来)2、基于源MK构造 可独立运行的makefile3)进入docker,在此makefile目录下敲make4)最后根…...
虚拟dom工作原理以及渲染过程
浏览器渲染引擎工作流程都差不多,大致分为5步,创建DOM树——创建StyleRules——创建Render树——布局Layout——绘制Painting 第一步,用HTML分析器,分析HTML元素,构建一颗DOM树(标记化和树构建)。 第二步,用…...
无人机视觉定位,常用相机,及相机提供的数据信息
常用相机类型 单目相机:仅使用一个摄像头进行图像采集,结构简单、成本低。它可以获取无人机前方或下方的二维图像信息,包括物体的形状、颜色、纹理等。双目相机:由两个摄像头组成,模拟人类双眼视觉原理,通…...
A2L文件解析
目录 1 摘要2 A2L文件介绍2.1 A2L文件作用2.2 A2L文件格式详解2.2.1 A2L文件基本结构2.2.2 关键元素与声明2.2.3 完整A2L文件示例 3 总结 1 摘要 A2L文件(也称为ASAP2文件)是ECU开发的核心接口文件,用于标定、测量和诊断的关键配置文件&…...
Ansible:role企业级实战
文章目录 实现 nginx 角色创建task文件创建handler文件准备模板文件创建变量文件在playbook中调用角色 实现 memcached 角色创建相关目录创建相关task任务准备模板文件查看目录结构在playbook中调用角色 实现多角色的选择 实现 nginx 角色 卸载httpd,创建相关目录 a…...
vue2使用vue-echarts
1.先安装echarts npm i echarts 2.安装vue-echarts 安装的时候注意下对应的版本 "echarts": "5.5.0", "vue-echarts": "6.7.3",这是我安装的版本 注意事项: 如果安装之后报错:"export watchEffect …...
多光谱相机:海洋管道漏油(溢油)监测
每年海上溢油和化工管道漏油造成的污染事故和经济损失频发,在生态方面,漏油会带来导致水质恶化、生态系统破坏、食物链受损。在经济方面,会造成渔业损失、旅游业损失、航运业损失。在健康方面,会造成食品安全问题,直接…...
Kaggle-Digit Recognizer-(多分类+卷积神经网络CNN)
Digit Recognizer 题意: 给你每个图片的dataframe类型的数据,让你预测出每个图片可能是多少。 思考: 数据处理 1.首先把数据从dadaframe转换成numpy,数据类型改为float32,并且并且展开为1维的28281的形状…...
jQuery多库共存
在现代Web开发中,项目往往需要集成多种JavaScript库或框架来满足不同的功能需求。然而,当多个库同时使用时,可能会出现命名冲突、功能覆盖等问题。幸运的是,jQuery提供了一些机制来确保其可以与其他库和谐共存。本文将探讨如何实现…...
MCU的USB接口作为 USB CDC串口输出
前言: 如下内容是和Chatgpt的问答对话。询问了Chatgpt 关于 MCU微控制器内部的USB端口作为串口输出是怎么工作的,是否需要在上位机上安装串口驱动程序等,Chatgpt解答的很好。 正文: STM32 使用USB作为串行设备端口,需…...
VCode 的 .S 汇编文件里面的注释不显示绿色
1. 确认文件语言模式 打开 .S 文件后,查看 VS Code 右下角的状态栏,确认当前文件的识别模式(如 Assembly、Plain Text 等)。如果显示为 Plain Text 或其他非汇编模式: 点击状态栏中的语言模式(如 Plain Te…...
【数学建模】(智能优化算法)萤火虫算法(Firefly Algorithm)详解与实现
萤火虫算法(Firefly Algorithm)详解与实现 文章目录 萤火虫算法(Firefly Algorithm)详解与实现前言1. 算法原理2. 算法流程3. Python实现4. 算法特点4.1 优点4.2 缺点 5. 应用领域6. 算法变种7. 总结与展望参考文献 前言 大家好,今天给大家介绍一种有趣且高效的群体…...
链路追踪组件学习
目录 1. 为啥需要链路追踪2. 常见的链路追踪组件3. 使用过的链路追踪组件3.1. Spring Cloud Sleuth3.2. Zipkin3.3. Apache SkyWalking 4. 集成Spring Cloud Sleuth框架4.1. 流程步骤4.2 sleuth工作流程 5. 集成zipKin5.1 添加 Zipkin 相关依赖5.2 安装zipkin服务5.3 配置 Zipk…...
# 基于OpenCV与Dlib的人脸融合技术实现
从仿射变换到人脸融合:基于OpenCV和Dlib的图像处理实践 在图像处理领域,仿射变换和人脸融合是两个非常有趣且实用的技术。仿射变换可以用于图像的几何变换,而人脸融合则可以创造出令人惊叹的视觉效果。本文将通过两个具体的代码示例…...
多光谱相机:水环境监测(水体富营养化、黑臭水体、藻类水华)
随着全球水体污染问题日益严峻,水体富营养化、黑臭水体和藻类水华等生态危机对人类健康和水生系统构成重大威胁。传统监测手段(如人工采样、单点传感器)因效率低、覆盖不足、实时性差等局限,难以满足复杂水环境的动态监管需求。多…...
记录一次nginx访问前端首页,一直显示nginx首页问题(实际是nginx访问页面权限问题)
同一台服务器,nginx配置是server { listen 8081; server_name localhost; #charset koi8-r; #access_log logs/host.access.log main; location /New_mh_other { alias /home/hqu/data/new_mh_other; try…...
windows下命名管道双端通信
实现功能 1、命名管道双端通信(异步) 2、客户端断线重连 PS:多线程版本 PipeWrapper.h #include <windows.h> #include <string> #include <vector> #include "Utils/ThreadObject.h" #include "Utils/T…...
Linux自行实现的一个Shell(15)
文章目录 前言一、头文件和全局变量头文件全局变量 二、辅助函数获取用户名获取主机名获取当前工作目录获取最后一级目录名生成命令行提示符打印命令行提示符 三、命令处理获取用户输入解析命令行执行外部命令 四、内建命令添加环境变量检查和执行内建命令 五、初始化初始化环境…...
powerDesign 逆向 mysql 生成 物理模型,并用VBS脚本整理comment
学习自:https://www.cnblogs.com/xmyjcs/p/8536233.html 文章目录 Reverse Engineer格式化模型执行 VBS 脚本 Reverse Engineer 下面 DBMS 可以通过 ODBC(Open Database Connectivity,开放数据库连接)连接, 需要自己先…...
跨境全域中台:前端独立站群+后端共享云仓的协同作战体系
在全球化浪潮与互联网技术飞速发展的当下,跨境电商已然成为国际贸易领域中最为活跃的力量。据相关数据显示,过去几年跨境电商的年增长率持续保持高位,越来越多的企业投身于这片充满机遇与挑战的蓝海市场。在竞争日益激烈的跨境电商赛道上&…...
国产芯片解析:乐得瑞LDR6500C 超小封装全能芯片,赋能智能设备未来
LDR6500C是乐得瑞科技针对USB-C标准中的Bridge设备而开发的双USB-C DRP接口PD通信芯片,具备切换Data Role功能,支持最高USB PD 100W 充电,并且针对各大品牌设备的 USB-C 兼容性进行了特别优化,非常适合于 USB Type-C 设备快充转接…...
代码随想录-06-二叉树-05.10 二叉树的最小深度
二叉树的最小深度 #模板题 题目描述 给定一个二叉树,找出其最小深度。 最小深度是从根节点到最近叶子节点的最短路径上的节点数量。 说明叶子节点是指没有子节点的节点 具体思路(暴力) 层序遍历;找到cur.left null && cur.ri…...
系统与网络安全------网络通信原理(6)
资料整理于网络资料、书本资料、AI,仅供个人学习参考。 应用层解析 DNS Domain Name System,域名系统 用来完成域名与IP地址之间的映射,便于用户对网站的记忆和访问 端口号为TCP或UDP的53 DNS工作原理 FTP File Transfer Protocol 文件…...
【Vue #2】脚手架 指令
一、脚手架 脚手架:一个保证各项工作顺利开展的平台,方便我们 拿来就用,零配置 1. Vue 代码开发方式 相比直接 script 引入 vue 源码,有没有更好的方式编写vue代码呢? ① 传统开发模式: 基于html文件开发Vue&…...