Class: SGF::Node

Inherits:
Object
  • Object
show all
Includes:
Enumerable, Observable
Defined in:
lib/sgf/node.rb,
lib/sgf/properties.rb

Overview

Your basic node. It holds information about itself, its parent, and its children.

Constant Summary collapse

PROPERTIES =
{
 black_move:       "B",
 black_time_left:  "BL",
 bad_move:         "BM",
 doubtful:         "DO",
 interesting:      "IT",
 ko:               "KO",
 set_move_number:  "MN",
 otstones_black:   "OB",
 otstones_white:   "OW",
 tesuji:           "TE",
 white_move:       "W",
 white_time_left:  "WL",
 add_black:        "AB",
 add_empty:        "AE",
 add_white:        "AW",
 player:           "PL",
 arrow:            "AR",
 comment:          "C",
 circle:           "CR",
 dim_points:       "DD",
 even_position:    "DM", # Yep. No idea how that makes sense.
 figure:           "FG",
 good_for_black:   "GB",
 good_for_white:   "GW",
 hotspot:          "HO",
 label:            "LB",
 line:             "LN",
 mark:             "MA",
 node_name:        "N",
 print_move_node:  "PM", # Am I going to have to code this?
 selected:         "SL",
 square:           "SQ",
 triangle:         "TR",
 unclear_position: "UC",
 value:            "V",
 view:             "VW",
 application:      "AP",
 charset:          "CA",
 file_format:      "FF",
 game:             "GM",
 style:            "ST",
 size:             "SZ"
}

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(children: [], parent: nil, **opts) ⇒ Node

Creates a new node. You can pass in a hash. There are two special keys, parent and children.

  • parent: parent_node (nil by default)

  • children: [list, of, children] (empty array if nothing is passed)

Anything else passed to the hash will become an SGF identity/property pair on the node.



13
14
15
16
17
18
19
20
21
22
23
# File 'lib/sgf/node.rb', line 13

def initialize children: [], parent: nil, **opts
  # opts = { children: [], parent: nil }
  # opts.merge! args
  @depth = 0
  @children = []
  @properties = {}
  @parent = nil
  set_parent parent #opts.delete :parent
  add_children children #opts.delete :children
  add_properties opts
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method_name, *args) ⇒ Object (private)



149
150
151
152
153
154
155
156
# File 'lib/sgf/node.rb', line 149

def method_missing method_name, *args
  property = flexible(method_name)
  if property[/(.*?)=$/]
    @properties[$1] = args[0]
  else
    @properties.fetch(property, nil) || super(method_name, args)
  end
end

Instance Attribute Details

#childrenObject

Returns the value of attribute children.



6
7
8
# File 'lib/sgf/node.rb', line 6

def children
  @children
end

#depthObject

Returns the value of attribute depth.



7
8
9
# File 'lib/sgf/node.rb', line 7

def depth
  @depth
end

#parentObject

Returns the value of attribute parent.



7
8
9
# File 'lib/sgf/node.rb', line 7

def parent
  @parent
end

#propertiesObject

Returns the value of attribute properties.



6
7
8
# File 'lib/sgf/node.rb', line 6

def properties
  @properties
end

Instance Method Details

#==(other_node) ⇒ Object

Compare to another node.



85
86
87
# File 'lib/sgf/node.rb', line 85

def == other_node
  @properties == other_node.properties
end

#[](identity) ⇒ Object

Syntactic sugar for node.properties



90
91
92
# File 'lib/sgf/node.rb', line 90

def [] identity
  @properties[flexible(identity)]
end

#[]=(identity, new_value) ⇒ Object



94
95
96
# File 'lib/sgf/node.rb', line 94

def []= identity, new_value
  @properties[flexible(identity)] = new_value
end

#add_children(*nodes) ⇒ Object

Takes an arbitrary number of child nodes, adds them to the list of children, and make this node their parent.



57
58
59
60
61
62
63
# File 'lib/sgf/node.rb', line 57

def add_children *nodes
  nodes.flatten.each do |node|
    node.set_parent self
  end
  changed
  notify_observers :new_children, nodes.flatten
end

#add_properties(hash) ⇒ Object

Takes a hash => property and adds those to the current node. If a property already exists, it will append to it.



67
68
69
70
71
72
73
# File 'lib/sgf/node.rb', line 67

def add_properties hash
  hash.each do |identity, property|
    @properties[flexible identity] ||= property.class.new
    @properties[flexible identity].concat property
  end
  update_human_readable_methods
end

#each(&block) ⇒ Object



75
76
77
# File 'lib/sgf/node.rb', line 75

def each &block
  preorder self, &block
end

#each_childObject

Iterate through and yield each child.



80
81
82
# File 'lib/sgf/node.rb', line 80

def each_child
  @children.each { |child| yield child }
end

#inspectObject



98
99
100
101
102
103
104
# File 'lib/sgf/node.rb', line 98

def inspect
  out = "#<#{self.class}:#{self.object_id}, "
  out << (@parent ? "Has a parent, " : "Has no parent, ")
  out << "#{@children.size} Children, "
  out << "#{@properties.keys.size} Properties"
  out << ">"
end

#remove_parentObject



43
44
45
# File 'lib/sgf/node.rb', line 43

def remove_parent
  set_parent nil
end

#to_s(indent = 0) ⇒ Object



106
107
108
109
110
111
112
113
# File 'lib/sgf/node.rb', line 106

def to_s(indent = 0)
  properties = []
  @properties.each do |identity, property|
    properties << stringify_identity_and_property(identity, property)
  end
  whitespace = leading_whitespace(indent)
  "#{whitespace};#{properties.join("\n#{whitespace}")}"
end

#update(message, data) ⇒ Object

Observer pattern



116
117
118
119
120
# File 'lib/sgf/node.rb', line 116

def update(message, data)
  case message
    when :depth_change then set_depth(data + 1)
  end
end