基于文本的RPG命令解释器

时间:2010-08-23 09:01:26

标签: interpreter

我刚刚玩了一个基于文本的RPG,我想知道,命令解释器究竟是如何实现的,现在有更好的方法来实现类似的东西吗?制作大量的if语句很容易,但这看起来很麻烦,特别是考虑到大部分pick up the goldpick up gold相同,其效果与take gold相同。我确信这是一个非常深入的问题,我只想知道如何实现这样的解释器的一般概念。或者,如果有一个开源游戏,有一个体面和有代表性的翻译,那将是完美的。

答案可以与语言无关,但要尽量保持合理,而不是prolog或golfscript等。我不确定该标记到底是什么。

2 个答案:

答案 0 :(得分:6)

这种游戏的通常名称是文本冒险或互动小说(如果是单人游戏),或MUD(如果是多人游戏)。

有几种用于编写交互式小说的特殊用途编程语言,例如Inform 6Inform 7(一种编译为Inform 6的全新语言),TADS,{{3等等。

以下是Inform 7中的一个游戏示例,它有一个房间,一个房间内的物体,你可以拾取,放下和操纵对象:

"Example Game" by Brian Campbell

The Alley is a room. "You are in a small, dark alley." A bronze key is in the 
Alley. "A bronze key lies on the ground."

播放时产生:

Example Game
An Interactive Fiction by Brian Campbell
Release 1 / Serial number 100823 / Inform 7 build 6E59 (I6/v6.31 lib 6/12N) SD

Alley
You are in a small, dark alley.

A bronze key lies on the ground.

>take key
Taken.

>drop key
Dropped.

>take the key
Taken.

>drop key
Dropped.

>pick up the bronze key
Taken.

>put down the bronze key
Dropped.

>

对于通常比交互式小说引擎更简单的解析器的多人游戏,您可以查看Hugo列表。

如果您想编写自己的解析器,可以先从正则表达式中检查输入。例如,在Ruby中(因为您没有指定语言):

case input
  when /(?:take|pick +up)(?: +(?:the|a))? +(.*)/
    take_command(lookup_name($3))
  when /(?:drop|put +down)(?: +(?:the|a))? +(.*)/
    drop_command(lookup_name($3))
end

您可能会发现这会在一段时间后变得很麻烦。您可以使用一些简写来简化它以避免重复:

OPT_ART = "(?: +(?:the|a))?"  # shorthand for an optional article
case input
  when /(?:take|pick +up)#{OPT_ART} +(.*)/
    take_command(lookup_name($3))
  when /(?:drop|put +down)#{OPT_ART} +(.*)/
    drop_command(lookup_name($3))
end

如果您有很多命令,这可能会开始变慢,并且它会依次检查每个命令的输入。您也可能会发现它仍然难以阅读,并且涉及一些难以简单地提取为短序的重复。

此时,您可能希望查看MUD serverslexers,这个话题对我来说太大了,无法在此回复。有许多词法分析器和解析器生成器,给出一个语言的描述,将产生一个能够解析该语言的词法分析器或解析器;查看链接文章的一些起点。

作为解析器生成器如何工作的示例,我将在基于Ruby的解析器生成器parsers中给出一个示例:

grammar Adventure
  rule command
    take / drop
  end

  rule take
    ('take' / 'pick' space 'up') article? space object {
      def command
        :take
      end
    }
  end

  rule drop
    ('drop' / 'put' space 'down') article? space object {
      def command
        :drop
      end
    }
  end

  rule space
    ' '+
  end

  rule article
    space ('a' / 'the')
  end

  rule object
    [a-zA-Z0-9 ]+
  end
end

可以使用如下:

require 'treetop'
Treetop.load 'adventure.tt'

parser = AdventureParser.new
tree = parser.parse('take the key')
tree.command            # => :take
tree.object.text_value  # => "key"

答案 1 :(得分:1)

如果通过“基于文本的RPG”指的是交互式小说,则有针对此的特定编程语言。我最喜欢的(我认识的唯一一个; P)是Inform:http://en.wikipedia.org/wiki/Inform

rec.arts.int-fiction常见问题解答提供了更多信息:http://www.plover.net/~textfire/raiffaq/FAQ.htm