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. 游戏流程

  1. 启动: 应用程序启动,App.xaml 指定 MainWindow.xaml 作为启动窗口。

  2. 初始化: MainWindow.xaml 加载,其实例的 DataContext 被设置为一个新的 MainViewModel 实例。MainViewModel 在其构造函数中创建 GameState 实例和命令。

  3. UI 渲染:

    • ItemsControl 尝试绑定到 MainViewModel 的 Board 属性(需要调整实现)来获取棋盘数据。

    • ItemsControl 使用 UniformGrid 创建 15x15 的布局。

    • 对于每个棋盘格,ItemTemplate 被实例化。Border 的背景应用 BoardCellBrush,Ellipse 的填充根据棋盘格状态(通过绑定)设置。

    • 控制面板的 TextBlock 绑定到 CurrentPlayerText 和 CurrentPlayerBrush,显示初始状态("黑方回合",黑色)。

    • "重新开始" 按钮绑定到 RestartCommand。

  4. 玩家落子:

    • 玩家点击棋盘上的一个空单元格 (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 的状态属性来实现。

  5. 判断胜负:

    • GameState.CheckWin 方法(需要完整实现)在每次落子后被调用。

    • 如果检测到胜利,GameState.GameOver 设置为 true。ViewModel 可以暴露这个状态给 View,例如禁用棋盘交互或显示胜利消息。

  6. 重新开始:

    • 玩家点击 "重新开始" 按钮。

    • 按钮的 Command (绑定到 RestartCommand) 被触发。

    • MainViewModel.ExecuteRestart 方法被调用。

    • ExecuteRestart 调用 _game.Reset() (假设已添加)。

    • GameState.Reset 清空棋盘,重置玩家和游戏状态。

    • ExecuteRestart 调用 OnPropertyChanged 更新 UI 显示(回合提示、棋盘视觉)。(同样需要机制更新棋盘所有单元格的视觉)

6. 如何编译和运行

  1. 环境: 确保已安装 Visual Studio 2019 或 2022,并包含 .NET 桌面开发工作负载。

  2. 打开项目: 使用 Visual Studio 打开 GomokuWPF.sln 文件(如果存在)或 GomokuWPF.csproj 文件。

  3. 构建项目: 在 Visual Studio 菜单中选择 "生成" -> "生成解决方案" (或按 F6)。检查 "输出" 窗口是否有编译错误。

    • 注意: 根据文档分析,原始代码片段在 Board 绑定和 Reset 方法方面可能存在不一致或缺失,可能需要进行少量修改才能成功编译和按预期运行。具体来说:

      • 在 GameState.cs 中添加 Reset() 方法。

      • 修改 MainViewModel.cs,使其暴露一个适合 ItemsControl 绑定的棋盘数据集合(例如 ObservableCollection<CellViewModel>),并在 MakeMove 和 Reset 后更新这个集合。

      • 修改 MainWindow.xaml 中的 ItemsControl 绑定 (ItemsSource, CommandParameter, Fill) 以匹配新的 ViewModel 结构。

  4. 运行项目: 按 F5 键或点击 Visual Studio 工具栏上的 "启动" 按钮。应用程序主窗口 (MainWindow) 应该会显示出来。

7. 潜在的扩展和改进

  • 实现完整的胜负判断: 填充 GameState.CheckWin 方法的逻辑。

  • 完善 ViewModel 对 Board 的暴露: 如上所述,使用 ObservableCollection<CellViewModel> 替代直接暴露二维数组,以实现正确的 UI 更新。CellViewModel 可以包含 Row, Col, Player 状态,以及用于绑定的 StoneBrush 属性。

  • 游戏结束提示: 当 GameOver 为 true 时,在 UI 上明确显示胜利者,并可能禁用棋盘交互。

  • 悔棋功能: 添加撤销上一步操作的逻辑。

  • 平局判断: 实现棋盘满但无胜负的情况。

  • AI 对手: 添加一个 AI 逻辑模块,可以选择与电脑对战。

  • 音效: 在落子、胜利时播放声音。

  • 设置选项: 允许配置棋盘大小、先手方等。

  • 网络对战: 实现通过网络与其他玩家对战的功能。

  • 优化样式: 改进棋盘和棋子的视觉效果。


这份文档提供了对所提供代码的详细分析和解释,指出了其结构、功能和潜在需要改进的地方。希望它能帮助您理解和进一步开发这个 WPF 五子棋项目。

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

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

相关文章

计算机操作系统——死锁(详细解释和处理死锁)

系列文章目录 计算机操作系统-计算机系统中的死锁 文章目录 系列文章目录前言一、资源问题&#xff1a; 计算机系统当中的死锁&#xff1a; 二、死锁的定义、必要条件和处理方法&#xff1a; 1.死锁的定义&#xff1a;2.产生死锁的必要条件&#xff1a;3.处理死锁的方法&#…

Springboot项目正常启动,访问资源却出现404错误如何解决?

我在自己的springboot项目中的启动类上同时使用了SprinBootApplication和ComponentScan注解, 虽然项目能够正常启动,但是访问资源后,返回404错误,随后在启动类中输出bean,发现controller创建失败: 而后我将ComponentScan去掉后资源就能访问到了. 原因 SprinBootApplication本身…

第十五届蓝桥杯C/C++B组省赛真题讲解(分享去年比赛的一些真实感受)

试题A——握手问题 一、解题思路 直接用高中学的排列组合思路 二、代码示例 #include<bits/stdc.h> using namespace std; int fun(int n) {int sum0;for(int i0;i<n;i){for(int ji1;j<n;j)sum; } return sum; } int main() {cout<<fun(50)-fun(7); }三、…

动态规划(6)——01背包问题

欢迎来到博主的专栏&#xff1a;算法解析 博主ID&#xff1a;代码小号 文章目录 牛客网——【模板】01背包题目解析题目1算法原理题目1题解代码。问题2算法原理问题2题解代码01背包问题的滚动数组优化 牛客网——【模板】01背包 题目解析 关于I/O相关的东西博主就不多赘述了&a…

TQTT_KU5P开发板教程---实现流水灯

文档实现功能介绍 本文档是学习本开发板的基础&#xff0c;通过设置计数器使led0到led7依次闪烁&#xff0c;让用户初步认识vivado基本的开发流程以及熟悉项目的创建。本开发板的所有教程所使用的软件都是vivado2024.1版本的。可以根据网上的教程下载与安装。 硬件资源 此次教程…

Spring 中的 @Cacheable 缓存注解

1 什么是缓存 第一个问题&#xff0c;首先要搞明白什么是缓存&#xff0c;缓存的意义是什么。 对于普通业务&#xff0c;如果要查询一个数据&#xff0c;一般直接select数据库进行查找。但是在高流量的情况下&#xff0c;直接查找数据库就会成为性能的瓶颈。因为数据库查找的…

SEER: Self-Aligned Evidence Extraction for Retrieval-AugmentedGeneration

一、动机 如何从检索到的段落中提取证据&#xff0c;以降低计算成本并提升最终的RAG性能&#xff0c;然而这一问题仍然具有挑战性。 现有方法 严重依赖于基于启发式的增强&#xff0c;面临以下几个问题&#xff1a; &#xff08;1&#xff09;由于手工制作的上下文过滤&…

毫米波测试套装速递!高效赋能5G/6G、新材料及智能超表面(RIS)研发

德思特&#xff08;Tesight&#xff09;作为全球领先的测试测量解决方案提供商&#xff0c;始终致力于为前沿技术研发提供高精度、高效率的测试工具。 针对毫米波技术在高频通信、智能超表面&#xff08;RIS&#xff09;、新材料等领域的快速应用需求&#xff0c;我们推出毫米…

三维激光测量助力企业检测效率提升3倍

智能制造与数字化浪潮席卷下&#xff0c;三维扫描技术已成为工业检测领域不可或缺的工具。面对传统检测手段的精度瓶颈与效率局限&#xff0c;三维扫描仪&#xff0c;以毫米级精度、非接触式测量与超高速扫描三大核心优势&#xff0c;为汽车制造、航空航天、消费电子等行业的品…

SQL:Normalization(范式化)

目录 Normalization&#xff08;范式化&#xff09; 为什么需要 Normalization&#xff1f; &#x1f9e9; 表格分析&#xff1a; 第一范式&#xff08;1NF&#xff09; 什么是第一范式&#xff08;First Normal Form&#xff09;&#xff1f; 第二范式&#xff08;2NF&am…

#MES系统运维问题分析思路

一套适用于90% MES运维现场问题的排查分析思维模型&#xff0c;叫做&#xff1a; &#x1f50d; MES系统问题分析七步法&#xff08;现场实战适用&#xff09; ✅ 第一步&#xff1a;明确问题现象&#xff08;What&#xff09; 问题要说清楚&#xff0c;“不能操作”这种模糊描…

达梦数据库-学习-18-ODBC数据源配置(Linux)

一、环境信息 名称值CPU12th Gen Intel(R) Core(TM) i7-12700H操作系统CentOS Linux release 7.9.2009 (Core)内存4G逻辑核数2DM版本1 DM Database Server 64 V8 2 DB Version: 0x7000c 3 03134284194-20240703-234060-20108 4 Msg Versi…

js 效果展示 拿去练手

自学完整功能&#xff0c;拿去练手。 鼠标移动放大 通过网盘分享的文件&#xff1a;图片放大 链接: https://pan.baidu.com/s/1w8SjtKi4kUNDnZtRDfYMeQ?pwd95p6 提取码: 95p6 通过网盘分享的文件&#xff1a;图片动画效果 链接: https://pan.baidu.com/s/1Pjphx-Cc4HQQNNujr…

使用 TFIDF+分类器 范式进行企业级文本分类(二)

1.开场白 上一期讲了 TF-IDF 的底层原理&#xff0c;简单讲了一下它可以将文本转为向量形式&#xff0c;并搭配相应分类器做文本分类&#xff0c;且即便如今的企业实践中也十分常见。详情请见我的上一篇文章 从One-Hot到TF-IDF&#xff08;点我跳转&#xff09; 光说不练假把…

硬件设计-MOS管快速关断的原因和原理

目录 简介&#xff1a; 来源&#xff1a; MOS管快关的原理 先简单介绍下快关的原理&#xff1a; 同电阻时为什么关断时间会更长 小结 简介&#xff1a; 本章主要介绍MOS快速关断的原理和原因。 来源&#xff1a; 有人会问&#xff0c;会什么要求快速关断&#xff0c;而…

Linux进阶命令

目录 一、touch 1. 基本语法 2. 常用选项 二、which 1. 基本语法 2. 主要功能 3. 常用选项 三、find 1. 基本语法 2. 常用选项和表达式 四、more 1. 基本语法 2. 常用操作 3. 对比 more 和 less 五、grep 1. 基本语法 2. 常用选项 六、wc 1. 基本语法 2. 常…

阿里云实时计算Flink版产品体验测评

阿里云实时计算Flink版产品体验测评 什么是阿里云实时计算Flink应用场景实时计算Flink&自建Flink集群性价比开发效率运维管理企业安全 场景落地 什么是阿里云实时计算Flink 实时计算Flink大家可能并不陌生&#xff0c;在实时数据处理上&#xff0c;可能会有所接触&#xf…

用户登录不上linux服务器

一般出现这种问题&#xff0c;重新用root用户修改lsy用户的密码即可登录&#xff0c;但是当修改了还是登录不了的时候&#xff0c;去修改一个文件用root才能修改&#xff0c; 然后在最后添加上改用户的名字&#xff0c;例如 原本是只有user的&#xff0c;现在我加上了lsy了&a…

Android Jetpack架构组件——用Compose工具包构建基本的布局

推荐文章 构建基本布局 | Android Basics Compose - First Android app | Android Developers 向 Android 应用添加图片 | Android Developers

SLAM(七)-卡尔曼滤波

SLAM&#xff08;七&#xff09;-卡尔曼滤波 一、卡尔曼滤波(KF)二、扩展卡尔曼滤波(EKF)三、误差状态卡尔曼滤波(ESKF) 参考《概率机器人》、《Principles of GNSS&#xff0c;lnertial and Multisensor lntegrated Navigation Systems (Second Edition)》 一、卡尔曼滤波(KF)…