class Node

Constants

DEFAULTS

Define possible node types

Public Class Methods

load(file='save.yaml') click to toggle source

Load node structure from YAML file

# File lib/mr_holmes/node.rb, line 26
def self.load(file='save.yaml')
  yaml = YAML::load_file(file)
end
new(parent=nil, tag=nil, defaults={}, &block) click to toggle source

Initialize node

Calls superclass method
# File lib/mr_holmes/node.rb, line 45
def initialize(parent=nil, tag=nil, defaults={}, &block)
  super()
  defaults.each { |k,v| send("#{k}=", v) }
  self.parent = parent
  self.parent.children << self unless parent.nil?
  self.tag = tag
  self.children = []
  instance_eval(&block) unless block.nil?
end
root(&block) click to toggle source

Create root

# File lib/mr_holmes/node.rb, line 56
def self.root(&block)
  Node.new(nil, :root, &block)
end
save(node, file='save.yaml') click to toggle source

Save node structure to YAML

# File lib/mr_holmes/node.rb, line 19
def self.save(node, file='save.yaml')
  File.open(file, 'w+') do|f|
    f.puts node.to_yaml
  end
end

Public Instance Methods

ancestors(list=[]) click to toggle source
# File lib/mr_holmes/node.rb, line 180
def ancestors(list=[])
  if parent.nil?
    return list
  else
    list << parent
    return parent.ancestors(list)
  end
end
describe() click to toggle source
# File lib/mr_holmes/node.rb, line 247
def describe
  base = ""
  if !described? && respond_to?(:desc)
    self.described = true
    base << desc
  elsif respond_to?(:short_desc)
    base << short_desc
  else
    base << "You are in #{tag}"
  end

  # Append presence of children nodes if open
  if open
    children.each do|c|
      base << (c.presence || '')
    end
  end

  puts
  puts base

end
described?() click to toggle source

—————————————————————– Descriptions

# File lib/mr_holmes/node.rb, line 239
def described?
  if respond_to?(:described)
    self.described
  else 
    false
  end
end
find(node_data) click to toggle source

Method to find node

# File lib/mr_holmes/node.rb, line 86
def find(node_data)
  case node_data
  when Symbol
    find_by_tag(node_data)
  when String
    find_by_string(node_data)
  when Array 
    find_by_string(node_data)
  when Node 
    node_data
  end
end
find_by_name(words, nodes=[]) click to toggle source

Find node by name

# File lib/mr_holmes/node.rb, line 110
def find_by_name(words, nodes=[])
  words = words.split unless words.is_a?(Array)
  nodes << self if words.include?(name)
  children.each do |c|
    c.find_by_name(words, nodes)
  end
  return nodes
end
find_by_string(words) click to toggle source

Find node by string

# File lib/mr_holmes/node.rb, line 120
def find_by_string(words)
  words = words.split unless words.is_a?(Array)
  nodes = find_by_name(words)
  if nodes.empty?
    puts "I don't see that here"
    return nil
  end
  # Score nodes by number of matching adjectives
  nodes.each do |i|
    i.search_score = (words & i.words).length
  end
  # Sort highest scoring nodes to beginning of list
  nodes.sort! do |a,b|
    a.search_score <=> b.search_score
  end
  # Remove nodes with a lower score than the first node in the list
  nodes.delete_if do |i|
    i.search_score < nodes.first.search_score
  end
  # Interpret the results
  if nodes.length == 1
    return nodes.first
  else
    puts "Which item do you mean?"
    nodes.each do |i|
      puts " * #{i.name} (#{i.words.join(', ')})"
    end
    return nil
  end
end
find_by_tag(tag) click to toggle source

Find node by tag

# File lib/mr_holmes/node.rb, line 100
def find_by_tag(tag)
  return self if self.tag == tag
  children.each do |c|
    result = c.find_by_tag(tag)
    return result unless result.nil?
  end
  return nil
end
get_location() click to toggle source

Get location

# File lib/mr_holmes/node.rb, line 163
def get_location
  if parent.tag == :root
    return self
  else
    return parent.get_location
  end
end
get_root() click to toggle source

Get root

# File lib/mr_holmes/node.rb, line 172
def get_root
  if tag == :root || parent.nil?
    return self
  else
    return parent.get_root
  end
end
get_scene() click to toggle source

Get scene

# File lib/mr_holmes/node.rb, line 154
def get_scene
  if parent.parent.tag == :root
    return self
  else
    return parent.get_scene
  end
end
hidden?() click to toggle source

Check if node is hidden

# File lib/mr_holmes/node.rb, line 192
def hidden?
  if parent.tag == :root || parent.tag == :location
    return false
  elsif parent.open == false
    return true
  else
    return parent.hidden?
  end
end
init_with(c) click to toggle source

Method to fix YAML conversions and handling

# File lib/mr_holmes/node.rb, line 8
def init_with(c)
  c.map.keys.each do|k|
    instance_variable_set("@#{k}", c.map[k])
  end

  @table.keys.each do|k|
    new_ostruct_member(k)
  end
end
item(tag, name, *words, &block) click to toggle source

Create item

# File lib/mr_holmes/node.rb, line 71
def item(tag, name, *words, &block)
  i = Node.new(self, tag, DEFAULTS[:item])
  i.name = name
  i.words = words
  i.instance_eval(&block) if block_given?
end
location(tag, &block) click to toggle source

Create location

# File lib/mr_holmes/node.rb, line 61
def location(tag, &block)
  Node.new(self, tag, DEFAULTS[:location], &block)
end
long_description() click to toggle source
# File lib/mr_holmes/node.rb, line 278
def long_description
  if respond_to?(:desc)
    desc
  else
    tag.to_s
  end
end
move(object, to, check=true) click to toggle source

Move node

# File lib/mr_holmes/node.rb, line 205
def move(object, to, check=true)
  item = find(object)
  dest = find(to)
  return if item.nil?
  if check && item.hidden?
    puts "You can't get to that right now"
    return
  end
  return if dest.nil?
  if check && dest.hidden? || dest.open == false
    puts "You can't put that there"
    return
  end
  if dest.ancestors.include?(item)
    puts "Are you trying to destroy the universe?"
    return
  end
  item.parent.children.delete(item)
  dest.children << item
  item.parent = dest
end
player(&block) click to toggle source

Create player

# File lib/mr_holmes/node.rb, line 79
def player(&block)
  Player.new(self, :player, DEFAULTS[:player], &block)
end
puts(*s) click to toggle source

Override ‘puts’ method for scene descriptions

# File lib/mr_holmes/node.rb, line 31
def puts(*s)
  STDOUT.puts( s.join(' ').word_wrap )
end
scene(tag, &block) click to toggle source

Create scene

# File lib/mr_holmes/node.rb, line 66
def scene(tag, &block)
  Node.new(self, tag, DEFAULTS[:scene], &block)
end
script(key, *args) click to toggle source

—————————————————————– Executing Script

# File lib/mr_holmes/node.rb, line 229
def script(key, *args)
  if respond_to?("script_#{key}")
    return eval(self.send("script_#{key}"))
  else
    return true
  end
end
short_description() click to toggle source
# File lib/mr_holmes/node.rb, line 270
def short_description
  if respond_to?(:short_desc)
    short_desc
  else
    tag.to_s
  end
end
to_s(verbose=false, indent='') click to toggle source

Render node structure

# File lib/mr_holmes/node.rb, line 289
def to_s(verbose=false, indent='')
  bullet = if parent && parent.tag == :root
             '#'
           elsif parent && parent.parent.tag == :root
             '*'
           elsif tag == :player
             '@'
           elsif tag == :root
             '>'
           elsif open == true
             'O'
           else
             '-'
           end

  str = "#{indent}#{bullet} #{tag}\n"

  if verbose
    self.table.each do|k,v|
      if k == :children
        str << "#{indent+'  '}#{k}=#{v.map(&:tag)}\n"
      elsif v.is_a?(Node)
        str << "#{indent+'  '}#{k}=#{v.tag}\n"
      else
        str << "#{indent+'  '}#{k}=#{v}\n"
      end
    end
  end

  children.each do|c|
    str << c.to_s(verbose, indent + '  ')
  end

  return str
end