状态机

简述游戏开发中的状态机

点点圈 提交于 2019-12-03 15:57:09
为什么我们需要状态机 实行较多状态的角色,把动作全写在一个部分中会导致维护成本高,拓展性低 例如:走路,跳跃,射击,躲避的相互转换,有些可以转换,有些不能,实现逻辑复杂 (满屏幕都是if - else) 状态模式switch实现 //包含着所有的状态 enum class State{StateA, StateB, StateC, ...} activeState; ... //通过switch语句切换状态,根据具体情况实现细节 switch (activeState) { case State.StateA: ... break; case State.StateB: ... break; ....... } ... 状态机的原形,用一个枚举表示当前的状态,通过填充完善switch语句实现状态之间的切换,但是依然有维护成本高拓展低的缺点(虽然确实是比用if - else堆好) Finite State Machine(FSN)有限状态机 最基本的状态机,一般来说其他状态机都是这种状态机的变体 对于状态机的理解,最好就是画个图(如图结构,方框是状态,箭头是状态之间的联系) 有限状态机强调的是状态之间的切换,以及对不同状态的封装,所以实现方法一般可以根据需求调整 以下参考了《游戏人工智能》的实现 首先需要个基类State和基类Translation //状态基类,所有状态都继承这个类

字符串匹配算法之:有限状态自动机

匿名 (未验证) 提交于 2019-12-03 00:37:01
阅读博客的朋友可以参看视频: 如何进入google,算法面试技能全面提升指南 先看一个图: 上面这个图描述的就叫一个有限状态自动机,图中两个圆圈,也叫节点,用于表示状态,从图中可以看成,它有两个状态,分别叫0和1. 从每个节点出发,都会有若干条边,当处于某个状态时,如果输入的字符跟该节点出发的某条边的内容一样,那么就会引起状态的转换。例如,如果当前状态处于0,输入是字符a,那么状态机就会从状态0进入状态1.如果当前状态是1,输入字符是b或a,那么,状态机就会从状态1进入状态0.如果当前所处的状态,没有出去的边可以应对输入的字符,那么状态机便会进入到错误状态。例如,如果当前处于状态0,输入字符是c,那么状态机就会出错,因为从状态0开始,没有哪条边对应的字符是c. 状态机会有一个初始节点,和一个接收节点,以上图为例,我们可以设置初始节点为0,接收节点为1,当进行一系列的输入,使得状态机的状态不断变化,只要最后一个输入使得状态机处于接收节点,那么就表明当前输入可以被状态机接收。例如对应字符串”abaaa”, 从初始节点0开始,状态机根据该字符串的输入所形成的状态变化序列为:{0,1,0,1,0,1}。由于最后状态机处于状态1,所以该字符串可以被状态机接收。如果输入的字符串是:abbaa, 那么状态机的变化序列为:{0,1,0,0,1,0}, 由于最后状态机处于非接收状态

状态机代码实现

匿名 (未验证) 提交于 2019-12-03 00:08:02
因为这篇文章的目的是游戏界面的状态机实现,所以专门写了一个state_demo.py文件,让大家可以更加方便的看代码。 游戏启动代码 开始是 pygame的初始化,设置屏幕大小为c.SCREEN_SIZE(800, 600)。所有的常量都保存在单独的constants.py中。 import os import pygame as pg import constants as c pg.init() pg.event.set_allowed([pg.KEYDOWN, pg.KEYUP, pg.QUIT]) pg.display.set_caption(c.ORIGINAL_CAPTION) SCREEN = pg.display.set_mode(c.SCREEN_SIZE) SCREEN_RECT = SCREEN.get_rect() 1 2 3 4 5 6 7 8 9 load_all_gfx函数查找指定目录下所有符合后缀名的图片,使用pg.image.load函数加载,保存在graphics set中。 GFX 保存在resources/graphics目录找到的所有图片,后面获取各种图形时会用到。 def load_all_gfx(directory, colorkey=(255,0,255), accept=('.png', '.jpg', '.bmp', '.gif'

Unity进阶:PlayMaker

匿名 (未验证) 提交于 2019-12-02 23:57:01
本文原创首发于以下网站: 博客园『优梦创客』的空间:https://www.cnblogs.com/raymondking123 优梦创客的官方博客:https://91make.top 优梦创客的游戏讲堂:https://91make.ke.qq.com 『优梦创客』的微信公众号:umaketop 您可以自由转载,但必须加入完整的版权声明 PlayMaker基于状态机的可视化编程工具,playmaker内部实现会为其创建一个类,在其实例化和序列化时会有开销(建立通过缓冲池避免),对复杂度要求较高的逻辑也可以将其封装到PlayMaker的Action中 playMaker基于有限状态机,一个状态机包括若干个状态节点,组合在一起形成游戏逻辑。每个状态节点包括若干Action,这些Action对应的就是Unity内的具体游戏功能,如播放动画,移动位置 PlayMaker状态机不能单独存在(其本身也是继承自MonoBehaviour),选择一个GameObjec,- PlayerMaker -> Components -> Add FSM to Selected Objects;将状态机指定给选中的GameObject,一个GameObject可以有多个状态机 State(状态) 创建状态机后,默认拥有一个状态节点,也就是起始节点,名为State1 在PlayMaker窗口中点击鼠标右键

【状态机】谈谈自我经验和应用场景

匿名 (未验证) 提交于 2019-12-02 23:57:01
前言   状态机在计算机领域中出现比较多,最近在做DM对话管理的时候,就有有限状态图的概念,又呼应了之前在钛动学到的一些状态机概念,当时状态机在整个公司纵横,但我不知道能灵活运用的人有多少。 FMS 有限状态机   先谈,有限状态机(FMS),FSM 解决一个输入序列,经过 FSM,最终停留在什么状态这样一个问题。比较注重的是系统的状态,和状态之间的转换,状态是历史输入的一种结果,对于一个系统而言,其输入和输出、边界、影响方面的因素都可能会改变状态,一般而言,输入会导致状态改变,而状态改变就可能会有输出,或者做出某些相应。 前端框架 React   前端框架的一种,这个自称是状态机实现,每一个组件都是状态机,这个是我认为最符合状态机定义的,点解?因为React接受外界输入action后,会根据state重新渲染组件,所以会带有观察者模式的感觉,所以我认为它更接近状态机的本质 ―― 状态驱动 ״̬ģʽ   状态模式是设计模式的内容,但和状态机不态一样。一个类如果有状态,那么其状态的表示是非常多的,而状态模式很多时候就用一个状态类代表其所处的状态。而DM就不一样, 对话系统的状态是很难穷举的。所以状态模式是一种比较低级的应用了。 来源:博客园 作者: 饭小胖 链接:https://www.cnblogs.com/iCanhua/p/11444420.html

Raft协议备注

匿名 (未验证) 提交于 2019-12-02 23:45:01
Raft协议 Raft协议基于日志实现了一致性 实现备份的是机制:复制状态机Replicated State Machine,如果两个相同的、确定性的状态机从同一状态开始,以相同顺序输入相同的日志,则两个状态机最终也会保持一致 Raft了实现Consensus Module Consensus Module作为一致性模块对外服务,负责接收客户端的消息,响应请求,并追加到本地日志,一致性模块保证每个机器上的log的一致性 请求到来时,带上(term,commitindex)和append log 去要求Follower追加消息,Follower会先判断(term,index)是否和当前最大的消息相同,如果相同就会追加,否则会拒绝 一致性模块负责复制消息到其他服务器节点,本地日志commit成功后立即应用到状态机 CNew用于服务器增加或者减少节点的情况 Leader:处理与客户端交互,处理消息 Follower:选民,转发请求到leader Candidate:候选人,可以参选成为leader,不是所有Follower都能成为Candidate,只有数据较完整的才可以。如果Candidate发现自己的term落后了就会退回到Follower RequestVote:选举期间的RPC消息 AppendEntries:leader选出后向Follow复制日志的RPC消息

OSPF 状态机

匿名 (未验证) 提交于 2019-12-02 22:56:40
[R1] Oct 17 2018 10:28:26-08:00 R1 %%01OSPF/4/NBR_CHANGE_E(l)[6]:Neighbor changes event: neighbor status changed. (ProcessId=256, NeighborAddress=2.12.12.12, NeighborEvent=HelloReceived, NeighborPreviousState=Down, NeighborCurrentState=Init) ------没有收到对方的HEELO报文或者字段没有对方的RouteID! [R1] Oct 17 2018 10:28:26-08:00 R1 %%01OSPF/4/NBR_CHANGE_E(l)[7]:Neighbor changes event: neighbor status changed. (ProcessId=256, NeighborAddress=2.12.12.12, NeighborEvent=2WayReceived, NeighborPreviousState=Init, NeighborCurrentState=2Way) ------选举双方收到HELLO报文、邻居字段有对方的RouteID、选举DR\BDR! [R1] Oct 17 2018 10:28:52-08:00

C++基础之状态机

匿名 (未验证) 提交于 2019-12-02 22:56:40
Doc: https://download.csdn.net/download/qccz123456/10567668 PDF: https://download.csdn.net/download/qccz123456/10567664 State Machine Design in C++ A compact C++ finite state machine (FSM) implementation that's easy to use on embedded and PC-based systems. https://www.codeproject.com/Articles/1087619/State-Machine-Design-in-Cplusplus In 2000, I wrote an article entitled " State Machine Design in C++ Why another state machine design? Certainly by now there's an existing implementation out there that can be used, right? Maybe. On occasion, I'll try a new state machine and find it doesn't fit my

java幂等性的解决方案

匿名 (未验证) 提交于 2019-12-02 21:52:03
摘自:https://www.cnblogs.com/baizhanshi/p/10449306.html 一、幂等性概念 在编程中.一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同。幂等函数,或幂等方法,是指可以使用相同参数重复执行,并能获得相同结果的函数。这些函数不会影响系统状态,也不用担心重复执行会对系统造成改变。例如,“getUsername()和setTrue()”函数就是一个幂等函数. 更复杂的操作幂等保证是利用唯一交易号(流水号)实现. 我的理解:幂等就是一个操作,不论执行多少次,产生的效果和返回的结果都是一样的。 二、幂等性场景 1、查询操作:查询一次和查询多次,在数据不变的情况下,查询结果是一样的。select是天然的幂等操作; 2、删除操作:删除操作也是幂等的,删除一次和多次删除都是把数据删除。(注意可能返回结果不一样,删除的数据不存在,返回0,删除的数据多条,返回结果多个) ; 3、唯一索引:防止新增脏数据。比如:支付宝的资金账户,支付宝也有用户账户,每个用户只能有一个资金账户,怎么防止给用户创建资金账户多个,那么给资金账户表中的用户ID加唯一索引,所以一个用户新增成功一个资金账户记录。要点:唯一索引或唯一组合索引来防止新增数据存在脏数据(当表存在唯一索引,并发时新增报错时,再查询一次就可以了,数据应该已经存在了,返回结果即可); 4

状态机的写法

假装没事ソ 提交于 2019-12-02 15:45:56
三段式状态机: 用三个always语句块分别实现三个功能:同步状态转移、当前状态判断次态、输出 已10010串的检测为例 moore状态机 module fsmcheck (output z, input clk, input rst, input a ); reg [3:0] nextstate, currentstate; paramtet S0 = 4'b0000; paramter S1 = 4'b0001; paramter S2 = 4'b0010; paramter S3 = 4'b0011; paramter S4 = 4'b0100; paramter S5 = 4'b0101; always @ (posedge clk or negedge rst) begin if(!rst) currentstate <= S0; else currentstate <= nextstate; end always @ (posedge clk or negedge rst) begin if(!rst) currentstate <= S0; else begin case(currentstate) S0: if(a==1) nextstate <= S1; else nexrstate <= S0; S1: if (a==0) nextstate <= S2;