在基于OOP的文本游戏中优雅的命令解析

时间:2010-02-05 12:37:18

标签: ruby language-agnostic oop nlp

我正在玩Ruby中的MUD /文字冒险(请不要笑)。任何人都可以给我任何指向优雅,基于oop的解析输入文本的解决方案吗?

在这里,我们所说的并不比“把魔杖放在桌子上”更复杂。但一切都需要柔软;我想稍后无痛地扩展命令集。

我目前的想法,略有简化:

  1. 每个项目类(box,table,room,player)都知道如何识别“属于”它的命令。

  2. 游戏类理解一种特定于域的语言,涉及诸如“在对象Y内移动对象X”,“显示对象X的描述”等操作。

  3. 如果游戏类识别输入命令,则会询问房间中的每个项目。首先说是赢。

  4. 然后将控制权传递给处理命令的item类中的方法。此方法重新命名DSL中的命令,将其传递回游戏对象以使其发生。

  5. 必须有陈旧,优雅的方式来做这些事情。但是,似乎无法谷歌任何东西。

5 个答案:

答案 0 :(得分:3)

Interpreter design pattern是我所知道的解析最多面向对象的方法,但我确信编译专家会指出更强大的算法。

答案 1 :(得分:2)

听起来你需要一个解析器。

将输入字符串拆分为标记(单词)。然后将令牌一次一个地送入状态机。我发现下推自动机是一种非常直观且功能强大的方式来编写这样的文档。

答案 2 :(得分:1)

对于命令解释器,我非常喜欢这种简单,而不是那种优雅的模式。动态语言中的模式往往涉及比GOF模式更少的框和行。

class Thing

  # Handle a command by calling the method "cmd_" + command.
  # Raise BadCommand exception if there is no method for that command.

  def handle_command(command, args)
    method_name = "cmd_#{command}"
    raise BadCommand, command unless respond_to?(method_name)
    send(method_name, args)
  end

  def cmd_quit(args)
    # the code for command "quit"
  end

  def cmd_list(args)
    # the code for command "list"
  end

  ...

end

通过这种方式,添加新命令只是添加一个新方法。不需要调整表格或案例陈述。

答案 3 :(得分:0)

将其拆分为令牌,格式始终为:
[command] [object1]([refering] [object2])

您可以在房间的[object1]上调用method [command],并将[object2]传递给它。

答案 4 :(得分:0)

确定。所以你需要一个语义? (转动是一个动作,点亮一个物体,一个参数......(我与你对dbemerlin的评论有关))。

为什么不定义语法?嗯......我猜lex和yacc不是一个选择? (因为它根本不是OOP,但你想做的是“编译”用户输入以产生一些东西 - 执行一些改变房间数据的代码,并输出结果)

您可以为对象及其操作设置OOP设计(例如,所有对象都有.describeMe()方法..),旁边还有输入解析器+编译器。

我是否完全脱离了这个主题?

编辑:在查看Marc Seeman指出的解释器模式之后,似乎是在OOP中想要它的方式。 (但你会在某种程度上重新发明轮子)