采访问:检测格斗游戏动作

时间:2015-09-09 01:36:13

标签: algorithm data-structures state

我把这作为一个面试问题,我想知道设计这个系统的最佳方式是什么。问题:

假设你有一个格斗游戏,其中某些按钮组合代表一个特殊的举动。实现2个函数 register_move([button combo],movename),它包含一个按钮输入列表和一个movename字符串以及 on_keypress(按钮),它记录当前的按键并打印如果已激活按钮组合,则为movename。这些按钮表示为字符:' U',' D'' L'' R'' A' ;,' B'

示例:

register_move(['A','B','U'],"Uppercut")
on_keypress('A')
on_keypress('B')
on_keypress('U') -> print "Uppercut"

你可以假设在on_keypress之前注册了动作,所以你不必追溯回看之前的按键。您可以使用任何您喜欢的语言

2 个答案:

答案 0 :(得分:3)

建立Deterministic Finite State Automaton。初始状态是“无密钥识别”。在每个按键上,转换到一个新的状态;如果它是最终状态你就有动作。所有未定义的转换都转换为起始状态。对于你的例子,

S --(a)--> A
A --(b)--> AB
AB --(u) --> ABU: process "Uppercut", move to S
X --(x)--> S

其中X是任何州,x是规则未涵盖的任何输入。

更实际,理论上更少,你最终得到trie,所以使用trie库就足够了。 Root是“无输入”,直到一片叶子,或者在压印时重新启动。

答案 1 :(得分:0)

考虑到移动次数有限,您无需使用超高效的有限状态机来处理此问题。

您可以简单地将字符串存储在WITH onlyone as ( SELECT DISTINCT TRANS_ID, SCENARIO FROM T1 T ) SELECT DISTINCT p.TRANS_ID, STUFF(( SELECT ',' + CAST(T.SCENARIO as varchar(10) ) FROM onlyone T WHERE T.TRANS_ID = p.TRANS_ID ORDER BY T.SCENARIO FOR XML PATH('') ), 1, 1, '') AS SCENARIO FROM onlyone p 中,并让register_move记住最后一个可能有效的序列。

  • 如果当前键序列是至少一个移动的前缀(例如“AB”是“ABU”的前缀),则表示已完成(只需等待下一次按键以查看是否已达到组合) 。
  • 如果序列没有前缀,则将序列重置为最后一个按键(例如“ABD” - >“D”)。这将清除以前与无移动相对应的按键。
  • 如果序列对应于移动,请执行移动(好,至少打印)并重置序列。

这需要在每个可能的移动组合上进行前缀搜索,如果你只有十几个,那么这个搜索非常快。如果由于某种原因你想要更快,你确实可以将你的组合列表变成一个前缀树,但它需要更多的代码才能获得很少的收益。