信息发布→ 登录 注册 退出

如何用C++实现一个有限状态机(FSM)?C++游戏AI与协议解析【设计模式】

发布时间:2025-12-16

点击量:
用类封装状态与转移逻辑最直观,如游戏AI中“巡逻”“追击”“逃跑”各实现enter/update/exit/transitionTo;协议解析可用枚举+函数指针或std::function轻量跳转;模板元编程可做编译期状态转移合法性检查;需注意幂等性、粘包处理及共享上下文。

如何用c++实现一个有限状态机(fsm)?c++游戏ai与协议解析【设计模式】

用类封装状态与转移逻辑

最直观的方式是为每个状态定义一个类,让状态自己管理行为和转移条件。比如游戏AI中“巡逻”“追击”“逃跑”三个状态,各自实现 enter()update()exit()transitionTo() 方法。FSM 主控制器持有一个指向当前状态的指针(如 std::unique_ptr),每次更新时调用 current->update(),状态内部根据游戏数据决定是否返回新状态对象 —— 若返回,主控就接管所有权并调用旧状态的 exit() 和新状态的 enter()

用枚举+函数指针或 std::function 实现轻量级跳转

适合协议解析等状态数量固定、逻辑较扁平的场景。先定义状态枚举:enum class ParseState { Idle, ReadingHeader, ReadingPayload, Done }; 再用 std::map> 或 switch-case 绑定每个状态的行为。关键在于把“读到某字节后该进哪个状态”写成查表逻辑,例如:

  • ReadingHeader 中,解析出 payload 长度后,直接赋值 state = ParseState::ReadingPayload
  • 每轮循环只执行当前状态对应函数,不嵌套、不递归,避免栈溢出
  • 错误处理统一设为 state = ParseState::Idle 并清空缓冲区

用模板元编程做编译期状态检查(进阶)

如果状态流转规则严格且不变(如通信协议 RFC 明确规定不允许从 StateA 直接跳 StateC),可用模板参数约束转移合法性。例如定义 template struct CanTransition; 特化允许的组合,状态切换时用 static_assert(CanTransition::value, "Invalid state transition");。这样非法跳转在编译期报错,比运行时断言更安全,适合车载、航天等高可靠性场景。

晓象AI资讯阅读神器 晓象AI资讯阅读神器

晓象-AI时代的资讯阅读神器

晓象AI资讯阅读神器 72 查看详情 晓象AI资讯阅读神器

避免常见坑:状态残留与事件丢失

游戏AI中常因帧率波动导致 update() 被跳过多次,状态行为没执行完就切走了;协议解析则可能因 TCP 粘包,一次 recv() 包含多个完整消息,但 FSM 只处理了第一个就停了。解决方法:

立即学习“C++免费学习笔记(深入)”;

  • 状态的 update() 必须是幂等的,或带内部步进计数器(如“已读 header 3 字节”)
  • 协议解析用 while 循环反复 dispatch,直到输入缓冲区不足以触发下一次状态转移
  • 所有状态共享一个上下文结构体(如 struct Context { std::vector buf; int payload_len; ... };),避免用全局变量或裸指针传参
基本上就这些。不复杂但容易忽略细节。

以上就是如何用C++实现一个有限状态机(FSM)?C++游戏AI与协议解析【设计模式】的详细内容,更多请关注其它相关文章!


相关文章: mysql备份恢复性能优化_mysql备份恢复性能优化方法  “音游” × “怪文书” 题材的节奏冒险游戏 《晕晕电波症候群》确定于2026年4月发售!  妖精漫画网页版登录入口免费_妖精漫画官网主页直接阅读漫画  小红书网页版入口链接分享 小红书官网直接进  美团外卖商家服务中心入口 美团商家版官网入口  文本文档写html代码怎么运行_文本文档html代码运行步骤【教程】  Win11怎么关闭快速启动_Win11彻底关机设置教程  steam官方入口大全 steam账号注册及操作指南  poki免费入口快捷访问 poki人气小游戏直接玩站点  印象笔记如何设提醒任务防漏执行_印象笔记设提醒任务防漏执行【任务提醒】  EMS快递官网app_中国邮政速递物流手机客户端  J*aScript教程:根据元素文本内容动态设置背景色  必由学官网首页入口 必由学教师网页版登录指南  《铁拳8》黑皮辣妹新实机:元气满满的18岁少女!  拷贝漫画电脑版官网入口 拷贝漫画(PC版)在线直达  在WordPress中通过REST API访问受BasicAuth保护的站点内容  蛙漫限时开放最深处链接_蛙漫全站漫画会员同款秒开地址  QQ邮箱电脑版登录入口_QQ邮箱官方网站登录平台  C++如何使用AddressSanitizer(ASan)_C++调试工具中检测内存访问错误的利器  Go RPC HTTP服务正确实现与常见陷阱解析  J*aScript中在Map循环中检测并处理空数组元素  向日葵客户端怎么进行远程CentOS控制_向日葵客户端远程CentOS控制操作教程  PowerPoint如何制作滚动字幕结尾彩蛋_PowerPoint路径动画实现平滑滚动字幕效果  在Runstone环境中高效处理TasteDive API的JSON数据  163邮箱官方主页登录 直达网易邮箱登录核心页面  AngularJS $http POST请求数据传递与Go后端接收实践  Sublime Text怎么显示空格和制表符_Sublime显示不可见字符设置  AO3官方镜像站点汇总 AO3同人作品网页版直达链接  特斯拉自动驾驶房车计划曝光 原型车将于2027年亮相  UC浏览器如何安装插件 UC浏览器添加扩展程序详细教程【进阶】  蛙漫漫画官网在线入口 蛙漫全本漫画免费阅读平台  J*aScript动态修改指定div内所有a标签样式指南  CKEditor 5 自定义构建在React应用中渲染失败的调试与解决  Windows7怎么硬盘安装 Windows7提取ISO镜像到非系统盘并运行setup.exe实现硬盘直装【教程】  圆通快递查询实时追踪 圆通物流包裹状态快速查看  使用CSS更改登录屏幕输入框中PNG图标颜色的策略与局限性  在J*a中如何开发简易仓库管理与库存统计_仓库管理库存统计项目实战解析  PHP中高效并行检查多链接状态的教程  漫蛙网页登录入口 漫蛙漫画官方授权网址  MinIO大规模对象列表性能瓶颈深度解析与外部元数据管理策略  qq邮箱日历功能怎么用_创建日程与会议邀请的技巧  谷歌浏览器如何快速清除某个网站的数据_Chrome网站缓存清理方法  Win11怎么设置鼠标指针速度_Win11提高鼠标指针精确度选项  微信客户端如何收红包_微信客户端接收红包使用教程  微信网页版官方入口教程 微信网页版网页版快速登录步骤  AO3网页版合集入口 Archive of Our Own同人作品浏览指南  TikTok搜索结果不显示如何解决 TikTok搜索刷新优化方法  win11 arm版怎么安装 M1/M2 Mac虚拟机安装ARM win11的方法  Win10系统服务哪些可以禁用 Win10安全优化服务列表【干货】  深入理解J*aScript Promise异步执行与微任务队列 

在线客服
服务热线

服务热线

4008988990

微信咨询
二维码
返回顶部
×二维码

截屏,微信识别二维码

打开微信

微信号已复制,请打开微信添加咨询详情!