Class: Gamefic::World::Playbook

Inherits:
Object
  • Object
show all
Defined in:
lib/gamefic/world/playbook.rb

Overview

A collection of rules for performing commands.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(commands: {}, syntaxes: [], validators: [], disambiguator: nil) ⇒ Playbook

Returns a new instance of Playbook.



16
17
18
19
20
21
# File 'lib/gamefic/world/playbook.rb', line 16

def initialize commands: {}, syntaxes: [], validators: [], disambiguator: nil
  @commands = commands
  @syntaxes = syntaxes
  @validators = validators
  @disambiguator = disambiguator
end

Instance Attribute Details

#syntaxesArray<Gamefic::Syntax> (readonly)

An array of available syntaxes.

Returns:



9
10
11
# File 'lib/gamefic/world/playbook.rb', line 9

def syntaxes
  @syntaxes
end

#validatorsArray<Proc> (readonly)

An array of defined validators.

Returns:



14
15
16
# File 'lib/gamefic/world/playbook.rb', line 14

def validators
  @validators
end

Instance Method Details

#actionsArray<Gamefic::Action>

An array of available actions.

Returns:



26
27
28
# File 'lib/gamefic/world/playbook.rb', line 26

def actions
  @commands.values.flatten
end

#actions_for(verb) ⇒ Array<Class<Action>>

Get an Array of all Actions associated with the specified verb.

Parameters:

  • verb (Symbol)

    The Symbol for the verb (e.g., :go or :look)

Returns:



66
67
68
# File 'lib/gamefic/world/playbook.rb', line 66

def actions_for verb
  @commands[verb] || []
end

#disambiguate(&block) ⇒ Object

Set the action for handling ambiguous entity references.



51
52
53
54
# File 'lib/gamefic/world/playbook.rb', line 51

def disambiguate &block
  @disambiguator = Action.subclass(nil, Query::Base.new, meta: true, &block)
  @disambiguator
end

#disambiguatorObject

Get the action for handling ambiguous entity references.



39
40
41
42
43
44
45
46
47
# File 'lib/gamefic/world/playbook.rb', line 39

def disambiguator
  @disambiguator ||= Action.subclass(nil, Query::Base.new) do |actor, entities|
    definites = []
    entities.each do |entity|
      definites.push entity.definitely
    end
    actor.tell "I don't know which you mean: #{definites.join_or}."
  end
end

#dispatch(actor, *command) ⇒ Array<Gamefic::Action>

Get an array of actions, derived from the specified command, that the actor can potentially execute. The command can either be a single string (e.g., “examine book”) or a list of tokens (e.g., :examine, @book).

Returns:



147
148
149
150
151
152
# File 'lib/gamefic/world/playbook.rb', line 147

def dispatch(actor, *command)
  result = []
  result.concat dispatch_from_params(actor, command[0], command[1..-1]) if command.length > 1
  result.concat dispatch_from_string(actor, command.join(' ')) if result.empty?
  result
end

#dispatch_from_params(actor, verb, params) ⇒ Array<Gamefic::Action>

Get an array of actions, derived from the specified verb and params, that the actor can potentially execute.

Returns:



176
177
178
179
180
181
182
183
# File 'lib/gamefic/world/playbook.rb', line 176

def dispatch_from_params actor, verb, params
  result = []
  available = actions_for(verb)
  available.each do |a|
    result.unshift a.new(actor, params) if a.valid?(actor, params)
  end
  sort_and_reduce_actions result
end

#dispatch_from_string(actor, text) ⇒ Array<Gamefic::Action>

Get an array of actions, derived from the specified command, that the actor can potentially execute. The command should be a plain-text string, e.g., “examine the book.”

Returns:



159
160
161
162
163
164
165
166
167
168
169
170
# File 'lib/gamefic/world/playbook.rb', line 159

def dispatch_from_string actor, text
  result = []
  commands = Syntax.tokenize(text, actor.syntaxes)
  commands.each do |c|
    actions_for(c.verb).each do |a|
      next if a.hidden?
      o = a.attempt(actor, c.arguments)
      result.unshift o unless o.nil?
    end
  end
  sort_and_reduce_actions result
end

#dupPlaybook

Duplicate the playbook. This method will duplicate the commands hash and the syntax array so the new playbook can be modified without affecting the original.

Returns:



190
191
192
# File 'lib/gamefic/world/playbook.rb', line 190

def dup
  Playbook.new commands: @commands.dup, syntaxes: @syntaxes.dup
end

#freezeObject



194
195
196
197
# File 'lib/gamefic/world/playbook.rb', line 194

def freeze
  @commands.freeze
  @syntaxes.freeze
end

#interpret(input, translation) ⇒ Syntax

Create an alternate Syntax for an Action. The command and its translation can be parameterized.

Examples:

Create a synonym for the Inventory Action.

interpret "catalogue", "inventory"
# The command "catalogue" will be translated to "inventory"

Create a parameterized synonym for the Look Action.

interpret "scrutinize :entity", "look :entity"
# The command "scrutinize chair" will be translated to "look chair"

Parameters:

  • input (String)

    The format of the original command

  • translation (String)

    The format of the translated command

Returns:

  • (Syntax)

    the Syntax object



135
136
137
138
139
# File 'lib/gamefic/world/playbook.rb', line 135

def interpret(input, translation)
  syn = Syntax.new(input, translation)
  add_syntax syn
  syn
end

#meta(verb, *queries) {|| ... } ⇒ Class<Gamefic::Action>

Create a Meta Action that responds to a command. Meta Actions are very similar to standard Actions, except the Plot understands them to be commands that operate above and/or outside of the actual game world. Examples of Meta Actions are commands that report the player’s current score, save and restore saved games, or list the game’s credits.

Examples:

A simple Meta Action

meta :credits do |actor|
  actor.tell "This game was written by John Smith."
end

Parameters:

  • verb (Symbol)

    An imperative verb for the command

  • queries (Array<Query::Base>)

    Filters for the command’s tokens

Yield Parameters:

Returns:



115
116
117
118
119
# File 'lib/gamefic/world/playbook.rb', line 115

def meta(verb, *queries, &proc)
  act = Action.subclass verb, *queries, meta: true, &proc
  add_action act
  act
end

#respond(verb, *queries) {|| ... } ⇒ Class<Gamefic::Action>

Create an Action that responds to a command. An Action uses the command argument to identify the imperative verb that triggers the action. It can also accept queries to tokenize the remainder of the input and filter for particular entities or properties. The block argument contains the code to be executed when the input matches all of the Action’s criteria (i.e., verb and queries).

Examples:

A simple Action.

respond :salute do |actor|
  actor.tell "Hello, sir!"
end
# The command "salute" will respond "Hello, sir!"

An Action that accepts a Character

respond :salute, Use.visible(Character) do |actor, character|
  actor.tell "#{The character} returns your salute."
end

Parameters:

  • verb (Symbol)

    An imperative verb for the command

  • queries (Array<Query::Base>)

    Filters for the command’s tokens

Yield Parameters:

Returns:



93
94
95
96
97
# File 'lib/gamefic/world/playbook.rb', line 93

def respond(verb, *queries, &proc)
  act = Action.subclass verb, *queries, &proc
  add_action act
  act
end

#validate(&block) ⇒ Object

Add a block that determines whether an action can be executed.



58
59
60
# File 'lib/gamefic/world/playbook.rb', line 58

def validate &block
  @validators.push block
end

#verbsArray<Symbol>

An array of recognized verbs.

Returns:



33
34
35
# File 'lib/gamefic/world/playbook.rb', line 33

def verbs
  @commands.keys
end