-
Notifications
You must be signed in to change notification settings - Fork 12
Home
First, apologies because I suck at writing documentation.
So… What is this gem? It’s a gem to parse the (Smart Game Format), a plain-text format to record board games such as Backgammon, Chess and Go/Weiqi/Baduk.
It works with Ruby >1.8.7 (ree, 1.9, etc).
It supports SGF format FF4 - the current format. If you have any files in a prior format (FF3 or FF1), you may want to look for a converter. I think it should work, but it is not guaranteed.
How would you use it? Well, you can use it with an SGF in String format, with a local path to an SGF file, or with a File handler: something like File.open(‘my.sgf).
require 'sgf' parser = SGF::Parser.new tree = parser.parse 'sgf_file'
Why is it a tree? Well, it’s actually a class that represents the entire file. SGF is basically a linked list of nodes, so in a way, this is a metaclass that holds high-level constructs. For instance:
tree.games # => yields an array of the games contained in the file. game = tree.games.first # => yields a SGF::Game object, the first in the array, most likely what you care about.
There are many game-level properties that you may want to know about, and you can get to them with the following instance-level methods on the Game objects. Some are only available for some games, and these are optional anyway, so if they’re not available on your instance, you’ll get a SGF::NoIdentityError.
PROPERTIES = {"annotator"=>"AN", "black_octisquares"=>"BO", #Octi "black_rank"=>"BR", "black_team"=>"BT", "copyright"=>"CP", "date"=>"DT", "event"=>"EV", "game_content"=>"GC", "handicap"=>"HA", #Go "initial_position"=>"IP", #Lines of Action "invert_y_axis"=>"IY", #Lines of Action "komi"=>"KM", #Go "match_information"=>"MI", #Backgammon "name"=>"GN", "prongs"=>"NP", #Octi "reserve"=>"NR", #Octi "superprongs"=>"NS", #Octi "opening"=>"ON", "overtime"=>"OT", "black_player"=>"PB", "place"=>"PC", "puzzle"=>"PZ", "white_player"=>"PW", "result"=>"RE", "round"=>"RO", "rules"=>"RU", "setup_type"=>"SU", #Lines of Action "source"=>"SO", "time"=>"TM", "data_entry"=>"US", "white_octisquares"=>"WO", #Octi "white_rank"=>"WR", "white_team"=>"WT"}
You can navigate through the main branch fairly easily:
node = game.current_node # => returns the game's first node by default node = game.next_node # => returns the next node in the current branch, and changes game.current_node to point to this node.
So… What can you do with nodes? Well, you can summon the basic properties like this: (I need to make them more human-friendly, refer to issue #18).
node.properties #=> returns a hash of the properties.
A single property can be called, like the comments, for instance, like so:
node.C #=> returns the comments for this node node.pw #=> returns the value of PW (Player White) if it exists on this node node["AW"] #=> same as node.aw or node.properties["AW"] node[:AW] #=> same as the previous line node.comments #=> syntactic sugar, only works for comments node.comment #=> same as the previous line
When you’re done, I’m sure you’ll want to save the file:
tree.save 'destination_filename.sgf'
There’s also an executable to indent the SGF and makes it a little more readable:
$ sgf_indent source.sgf destination.sgf