sgf_parser 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. data/.irbrc +3 -0
  2. data/.rvmrc +4 -0
  3. data/Gemfile +10 -0
  4. data/Gemfile.lock +17 -0
  5. data/LICENSE +20 -0
  6. data/README.textile +27 -0
  7. data/Rakefile +20 -0
  8. data/TODO +0 -0
  9. data/VERSION +1 -0
  10. data/bin/sgf +28 -0
  11. data/bin/stm2dot +18 -0
  12. data/doc/sgf_state_machine.dot +58 -0
  13. data/doc/sgf_state_machine.svg +269 -0
  14. data/lib/sgf.rb +15 -0
  15. data/lib/sgf/binary_file_error.rb +4 -0
  16. data/lib/sgf/debugger.rb +15 -0
  17. data/lib/sgf/default_event_listener.rb +37 -0
  18. data/lib/sgf/model/constants.rb +19 -0
  19. data/lib/sgf/model/event_listener.rb +72 -0
  20. data/lib/sgf/model/game.rb +52 -0
  21. data/lib/sgf/model/label.rb +12 -0
  22. data/lib/sgf/model/node.rb +115 -0
  23. data/lib/sgf/model/property_handler.rb +51 -0
  24. data/lib/sgf/more/state_machine_presenter.rb +43 -0
  25. data/lib/sgf/more/stm_dot_converter.rb +139 -0
  26. data/lib/sgf/parse_error.rb +25 -0
  27. data/lib/sgf/parser.rb +56 -0
  28. data/lib/sgf/renderer.rb +25 -0
  29. data/lib/sgf/sgf_helper.rb +55 -0
  30. data/lib/sgf/sgf_state_machine.rb +174 -0
  31. data/lib/sgf/state_machine.rb +76 -0
  32. data/sgf_parser.gemspec +95 -0
  33. data/spec/fixtures/2009-11-01-1.sgf +24 -0
  34. data/spec/fixtures/2009-11-01-2.sgf +23 -0
  35. data/spec/fixtures/chinese_gb.sgf +9 -0
  36. data/spec/fixtures/chinese_utf.sgf +9 -0
  37. data/spec/fixtures/example.sgf +18 -0
  38. data/spec/fixtures/good.sgf +55 -0
  39. data/spec/fixtures/good1.sgf +167 -0
  40. data/spec/fixtures/kgs.sgf +723 -0
  41. data/spec/fixtures/test.png +0 -0
  42. data/spec/sgf/model/event_listener_spec.rb +97 -0
  43. data/spec/sgf/model/game_spec.rb +29 -0
  44. data/spec/sgf/model/node_spec.rb +84 -0
  45. data/spec/sgf/more/state_machine_presenter_spec.rb +29 -0
  46. data/spec/sgf/parse_error_spec.rb +10 -0
  47. data/spec/sgf/parser_spec.rb +210 -0
  48. data/spec/sgf/sgf_helper_spec.rb +68 -0
  49. data/spec/sgf/sgf_state_machine_spec.rb +166 -0
  50. data/spec/sgf/state_machine_spec.rb +137 -0
  51. data/spec/spec.opts +4 -0
  52. data/spec/spec_helper.rb +47 -0
  53. metadata +150 -0
@@ -0,0 +1,76 @@
1
+ module SGF
2
+ class StateMachine
3
+ include SGF::Debugger
4
+
5
+ Transition = Struct.new(:description, :condition, :before_state, :event_pattern, :after_state, :callback)
6
+
7
+ attr_reader :start_state, :transitions
8
+ attr_reader :before_state, :input
9
+ attr_accessor :state, :context, :buffer
10
+
11
+ def initialize start_state
12
+ @start_state = @state = start_state
13
+ @transitions = {}
14
+ @buffer = ""
15
+ end
16
+
17
+ def desc description
18
+ @description = description
19
+ end
20
+
21
+ def transition before_state, event_pattern, after_state, callback = nil
22
+ transition_if nil, before_state, event_pattern, after_state, callback
23
+ end
24
+
25
+ def transition_if condition, before_state, event_pattern, after_state, callback = nil
26
+ if before_state.class == Array
27
+ saved_description = @description
28
+ before_state.each do |s|
29
+ @description = saved_description
30
+ transition_if(condition, s, event_pattern, after_state, callback)
31
+ end
32
+ return
33
+ end
34
+
35
+ transition = self.transitions[before_state] ||= []
36
+ transition << Transition.new(@description, condition, before_state, event_pattern, after_state, callback)
37
+
38
+ @description = nil
39
+ end
40
+
41
+ def reset
42
+ @state = @start_state
43
+ end
44
+
45
+ def event input
46
+ debug "'#{@state}' + '#{input}'"
47
+ @before_state = @state
48
+ @input = input
49
+
50
+ transitions_for_state = self.transitions[@state]
51
+ return false unless transitions_for_state
52
+
53
+ transition = transitions_for_state.detect do |t|
54
+ next false if t.condition and not t.condition.call(self)
55
+
56
+ (input.nil? and t.event_pattern.nil?) or input =~ t.event_pattern
57
+ end
58
+
59
+ if transition
60
+ @state = transition.after_state unless transition.after_state.nil?
61
+ transition.callback.call(self) unless transition.callback.nil?
62
+ true
63
+ else
64
+ false
65
+ end
66
+ end
67
+
68
+ def end
69
+ event nil
70
+ end
71
+
72
+ def clear_buffer
73
+ self.buffer = ""
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,95 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{sgf_parser}
8
+ s.version = "0.1.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Guoliang Cao"]
12
+ s.date = %q{2011-11-28}
13
+ s.description = %q{A simple SGF parser}
14
+ s.email = %q{gcao99@gmail.com}
15
+ s.executables = ["stm2dot", "sgf"]
16
+ s.extra_rdoc_files = [
17
+ "LICENSE",
18
+ "README.textile",
19
+ "TODO"
20
+ ]
21
+ s.files = [
22
+ ".irbrc",
23
+ ".rvmrc",
24
+ "Gemfile",
25
+ "Gemfile.lock",
26
+ "LICENSE",
27
+ "README.textile",
28
+ "Rakefile",
29
+ "TODO",
30
+ "VERSION",
31
+ "bin/sgf",
32
+ "bin/stm2dot",
33
+ "doc/sgf_state_machine.dot",
34
+ "doc/sgf_state_machine.svg",
35
+ "lib/sgf.rb",
36
+ "lib/sgf/binary_file_error.rb",
37
+ "lib/sgf/debugger.rb",
38
+ "lib/sgf/default_event_listener.rb",
39
+ "lib/sgf/model/constants.rb",
40
+ "lib/sgf/model/event_listener.rb",
41
+ "lib/sgf/model/game.rb",
42
+ "lib/sgf/model/label.rb",
43
+ "lib/sgf/model/node.rb",
44
+ "lib/sgf/model/property_handler.rb",
45
+ "lib/sgf/more/state_machine_presenter.rb",
46
+ "lib/sgf/more/stm_dot_converter.rb",
47
+ "lib/sgf/parse_error.rb",
48
+ "lib/sgf/parser.rb",
49
+ "lib/sgf/renderer.rb",
50
+ "lib/sgf/sgf_helper.rb",
51
+ "lib/sgf/sgf_state_machine.rb",
52
+ "lib/sgf/state_machine.rb",
53
+ "sgf_parser.gemspec",
54
+ "spec/fixtures/2009-11-01-1.sgf",
55
+ "spec/fixtures/2009-11-01-2.sgf",
56
+ "spec/fixtures/chinese_gb.sgf",
57
+ "spec/fixtures/chinese_utf.sgf",
58
+ "spec/fixtures/example.sgf",
59
+ "spec/fixtures/good.sgf",
60
+ "spec/fixtures/good1.sgf",
61
+ "spec/fixtures/kgs.sgf",
62
+ "spec/fixtures/test.png",
63
+ "spec/sgf/model/event_listener_spec.rb",
64
+ "spec/sgf/model/game_spec.rb",
65
+ "spec/sgf/model/node_spec.rb",
66
+ "spec/sgf/more/state_machine_presenter_spec.rb",
67
+ "spec/sgf/parse_error_spec.rb",
68
+ "spec/sgf/parser_spec.rb",
69
+ "spec/sgf/sgf_helper_spec.rb",
70
+ "spec/sgf/sgf_state_machine_spec.rb",
71
+ "spec/sgf/state_machine_spec.rb",
72
+ "spec/spec.opts",
73
+ "spec/spec_helper.rb"
74
+ ]
75
+ s.homepage = %q{http://github.com/gcao/discuz_robot}
76
+ s.require_paths = ["lib"]
77
+ s.rubygems_version = %q{1.4.2}
78
+ s.summary = %q{A SGF parser}
79
+
80
+ if s.respond_to? :specification_version then
81
+ s.specification_version = 3
82
+
83
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
84
+ s.add_development_dependency(%q<jeweler>, [">= 0"])
85
+ s.add_development_dependency(%q<rspec>, ["~> 1.3.0"])
86
+ else
87
+ s.add_dependency(%q<jeweler>, [">= 0"])
88
+ s.add_dependency(%q<rspec>, ["~> 1.3.0"])
89
+ end
90
+ else
91
+ s.add_dependency(%q<jeweler>, [">= 0"])
92
+ s.add_dependency(%q<rspec>, ["~> 1.3.0"])
93
+ end
94
+ end
95
+
@@ -0,0 +1,24 @@
1
+ (;GM[1]
2
+ FF[4]
3
+ SZ[19]
4
+ PW[supertjc]
5
+ WR[7d]
6
+ PB[S41nt]
7
+ BR[3d]
8
+ DT[2009-11-01]
9
+ PC[The KGS Go Server at http://www.gokgs.com/]
10
+ KM[0.50]
11
+ RE[W+Time]
12
+ RU[Japanese]
13
+ OT[2x10 byo-yomi]
14
+ CA[UTF-8]
15
+ ST[2]
16
+ AP[CGoban:3]
17
+ TM[0]
18
+ HA[4]
19
+ AB[dd]
20
+ [pd]
21
+
22
+ [dp]
23
+ [pp]
24
+ ;W[qf];B[qh];W[nc];B[pf];W[qc];B[pc];W[qd];B[qe];W[re];B[pe];W[rf];B[jc];W[qn];B[nq];W[pg];B[og];W[ph];B[qj];W[pi];B[qi];W[ql];B[pj];W[nh];B[oj];W[ne];B[nf];W[mf];B[oh];W[oi];B[ni];W[qg];B[mh];W[nj];B[mi];W[nk];B[pl];W[qp];B[qq];W[po];B[rp];W[pm];B[ol];W[lk];B[qo];W[nn];B[mm];W[nm];B[nl];W[ml];B[ll];W[mk];B[lm];W[jk];B[rl];W[rm];B[qk];W[qm];B[ok];W[rk];B[rj];W[sl];B[sj];W[rh];B[rn];W[sn];B[ro];W[mo];B[oo];W[om];B[kk];W[kj];B[kl];W[lj];B[jj];W[kh];B[me];W[ji];B[ij];W[md];B[le];W[mg];B[lg];W[hi];B[hj];W[gj];B[il];W[ii];B[gi];W[gk];B[hl];W[jm];B[jl];W[ej];B[gh];W[fm];B[hg];W[if];B[ge];W[kd];B[jd];W[ke];B[ld];W[kf];B[lf];W[kc];B[lc];W[lb];B[mb];W[jb];B[hc];W[fq];B[ho];W[fo];B[cn];W[jo];B[lo];W[lp];B[ko];W[kp];B[jp];W[mq];B[ip];W[cq];B[dq];W[cp];B[co];W[dr];B[er];W[cr];B[eq];W[fr];B[es];W[do];B[eo];W[dn];B[en];W[dm];B[fn];W[cm])
@@ -0,0 +1,23 @@
1
+ (;GM[1]
2
+ FF[4]
3
+ SZ[19]
4
+ PW[eve]
5
+ WR[7d]
6
+ PB[nya]
7
+ BR[4d]
8
+ DT[2009-11-01]
9
+ PC[The KGS Go Server at http://www.gokgs.com/]
10
+ KM[0.50]
11
+ RE[B+30.50]
12
+ RU[Japanese]
13
+ OT[5x10 byo-yomi]
14
+ CA[UTF-8]
15
+ ST[2]
16
+ AP[CGoban:3]
17
+ TM[60]
18
+ HA[3]
19
+ AB[pd]
20
+ [dp]
21
+
22
+ [pp]
23
+ ;W[ed];B[cd];W[cf];B[de];W[cc];B[bc];W[dc];B[be];W[dh];B[ee];W[fd];B[fe];W[hd];B[ge];W[ic];B[fh];W[ck];B[qn];W[bf];B[fq];W[ae];B[dd];W[ad];B[gd];W[gc];B[ec];W[fc];B[eb];W[nc];B[nd];W[md];B[mc];W[ob];B[pc];W[pb];B[qb];W[rb];B[qc];W[lc];B[mb];W[lb];B[me];W[ld];B[nb];W[oc];B[od];W[ma];B[pa];W[na];B[pi];W[kp];B[iq];W[pr];B[oq];W[or];B[mq];W[nq];B[nr];W[np];B[lr];W[qp];B[qq];W[pq];B[rp];W[op];B[qo];W[on];B[mp];W[mn];B[lo];W[qk];B[qj];W[pk];B[qr];W[qh];B[rk];W[rl];B[rj];W[qm];B[oh];W[rn];B[ro];W[pm];B[po];W[og];B[ng];W[nh];B[ni];W[mh];B[pg];W[of];B[ph];W[mi];B[nj];W[nf];B[mf];W[mg];B[pf];W[kr];B[kq];W[jq];B[jr];W[lq];B[ks];W[ir];B[kq];W[qs];B[rs];W[kr];B[js];W[gq];B[jp];W[hq];B[ip];W[ho];B[fp];W[jo];B[io];W[in];B[kq];W[hp];B[jq];W[hn];B[co];W[gi];B[fi];W[fj];B[gj];W[gh];B[gg];W[ih];B[di];W[ci];B[fk];W[ej];B[dj];W[ek];B[dk];W[el];B[dl];W[ei];B[eh];W[dg];B[fg];W[cj];B[cl];W[em];B[bk];W[bj];B[bl];W[bh];B[mj];W[lj];B[lk];W[kk];B[li];W[kj];B[jn];W[jm];B[kn];W[km];B[kf];W[kh];B[ne];W[fr];B[er];W[bd];B[ac];W[ce];B[cb];W[fb];B[gr];W[hr];B[fs];W[eo];B[fa];W[ga];B[ea];W[hb];B[hg];W[hh];B[dn];W[en];B[os];W[mk];B[nk];W[ml];B[jg];W[jh];B[ps];W[mo];B[oq];W[ln];B[ko];W[pj];B[ep];W[qi];B[qg];W[sk];B[rh];W[je];B[ke];W[ig];B[kd];W[jc];B[kc];W[kb];B[dm];W[fo];B[sj];W[hf];B[he];W[ie];B[jf];W[if];B[lg];W[lh];B[nl];W[nm];B[ol];W[pl];B[oo];W[no];B[gp];W[hs];B[go];W[gn];B[gs];W[sm];B[so];W[sn];B[sl];W[mr];B[ms];W[sk];B[oe];W[ng];B[sl];W[le];B[lf];W[sk];B[ha];W[ia];B[sl];W[qa];B[ra];W[sk];B[af];W[ag];B[sl];W[oa];B[qa];W[sk];B[jd];W[id];B[sl];W[bb];B[db];W[sk];B[aj];W[ai];B[ak];W[sl];B[ba];W[om];B[oi];W[];B[])
@@ -0,0 +1,9 @@
1
+ (;AB[pd][dp]AW[dd][pp]SZ[19]GN[������]DT[����]PW[��ɽ����]PB[���ٸ�]RE[��ʤ]
2
+ ;W[cn];B[cl];W[en];B[el];W[fp];B[hq];W[fr];B[hn];W[hp];B[ip];W[ho];B[io];W[iq]
3
+ ;B[jq];W[ir];B[gq];W[hr];B[fo];W[gn];B[go];W[gp];B[eo];W[ep];B[dn];W[in];B[hm];W[jn]
4
+ ;B[ko];W[jo];B[jp];W[kp];B[kq];W[lp];B[dq];W[er];B[lq];W[mp];B[mq];W[nq];B[oq];W[np]
5
+ ;B[nr];W[or];B[pr];W[mr];B[os];W[lr];B[op];W[oo];B[no];W[mo];B[po];W[nn];B[on];W[no]
6
+ ;B[pn];W[pq];B[or];W[rq];B[qr];W[rp];B[rr];W[rn];B[rm];W[qn];B[qm];W[pm];B[om];W[pl]
7
+ ;B[pk];W[ql];B[rl];W[qk];B[rk];W[qj];B[rj];W[qi];B[ri];W[rh];B[qh];W[rg];B[qo];W[ro]
8
+ ;B[qg];W[qf];B[pf];W[qe];B[oi];W[ol];B[nm];W[mm];B[nl];W[nk];B[lo];W[mn];B[ml];W[kn]
9
+ ;B[ok];W[oj];B[nj];W[pj];B[ni];W[mk];B[lm];W[ln];B[lk];W[mj];B[li])
@@ -0,0 +1,9 @@
1
+ (;AB[pd][dp]AW[dd][pp]SZ[19]GN[遇仙谱]DT[南宋]PW[骊山老媪]PB[刘仲甫]RE[黑胜]
2
+ ;W[cn];B[cl];W[en];B[el];W[fp];B[hq];W[fr];B[hn];W[hp];B[ip];W[ho];B[io];W[iq]
3
+ ;B[jq];W[ir];B[gq];W[hr];B[fo];W[gn];B[go];W[gp];B[eo];W[ep];B[dn];W[in];B[hm];W[jn]
4
+ ;B[ko];W[jo];B[jp];W[kp];B[kq];W[lp];B[dq];W[er];B[lq];W[mp];B[mq];W[nq];B[oq];W[np]
5
+ ;B[nr];W[or];B[pr];W[mr];B[os];W[lr];B[op];W[oo];B[no];W[mo];B[po];W[nn];B[on];W[no]
6
+ ;B[pn];W[pq];B[or];W[rq];B[qr];W[rp];B[rr];W[rn];B[rm];W[qn];B[qm];W[pm];B[om];W[pl]
7
+ ;B[pk];W[ql];B[rl];W[qk];B[rk];W[qj];B[rj];W[qi];B[ri];W[rh];B[qh];W[rg];B[qo];W[ro]
8
+ ;B[qg];W[qf];B[pf];W[qe];B[oi];W[ol];B[nm];W[mm];B[nl];W[nk];B[lo];W[mn];B[ml];W[kn]
9
+ ;B[ok];W[oj];B[nj];W[pj];B[ni];W[mk];B[lm];W[ln];B[lk];W[mj];B[li])
@@ -0,0 +1,18 @@
1
+ (;CA[gb2312]FF[4]AP[PilotGOne:0.8.1b3]SZ[19]GM[1]GN[2009 US Go Open]EV[Us open]
2
+ RO[2]DT[2009-08-03]PB[Ke Lu]PW[Juan Pablo Quizon]KM[7.5]TM[2hrs]MULTIGOGM[1]
3
+ ;B[pd];W[dp];B[qp];W[op];B[dd];W[qq];B[rq];W[pq];B[ro];W[kq];B[pm];W[cf];B[fc];W[bd]
4
+ ;B[cc];W[ci];B[mc];W[qf];B[qd];W[qi];B[fq];W[hq];B[cq];W[dq];B[cp];W[do];B[dr];W[er]
5
+ ;B[cr];W[eq];B[cn];W[rm];B[qj];W[rj];B[rk];W[qk];B[pj];W[ri];B[ql];W[sk];B[rl];W[sl]
6
+ ;B[qm];W[pi];B[oi];W[oh];B[ni];W[of];B[mg];W[re];B[rd];W[ne];B[nd];W[le];B[kd];W[mh]
7
+ ;B[nh];W[ng];B[ph];W[og];B[mi];W[lh];B[li];W[lg];B[ki];W[nm];B[ln];W[mp];B[nn];W[on]
8
+ ;B[om];W[mn];B[mm];W[no];B[nl];W[lm];B[nn];W[co];B[bo];W[nm];B[qh];W[rh];B[nn];W[bp]
9
+ ;B[bn];W[nm];B[fo];W[fr];B[nn];W[bq];B[br];W[nm];B[ml];W[kn];B[gq];W[gr];B[ho];W[hp]
10
+ ;B[jo];W[lo];B[im];W[bc];B[dh];W[ch];B[df];W[dg];B[eg];W[cg];B[jf];W[de];B[ef];W[ee]
11
+ ;B[fe];W[ed];B[ec];W[cd];B[dc];W[fd];B[gd];W[ce];B[gf];W[cl];B[dk];W[gc];B[hc];W[gb]
12
+ ;B[hb];W[hd];B[ge];W[cb];B[fb];W[eh];B[di];W[dj];B[ei];W[ej];B[fi];W[dn];B[ck];W[cj]
13
+ ;B[dl];W[fj];B[gj];W[jg];B[ig];W[jh];B[kf];W[md];B[nc];W[ke];B[je];W[ih];B[hg];W[gi]
14
+ ;B[fh];W[gk];B[hj];W[hk];B[fm];W[dm];B[cm];W[el];B[ik];W[ij];B[jk];W[gh];B[gg];W[jj]
15
+ ;B[kk];W[sd];B[sc];W[se];B[rb];W[io];B[ip];W[in];B[jn];W[hn];B[hm];W[gn];B[go];W[jp]
16
+ ;B[gm];W[iq];B[fn];W[ip];B[db];W[rr];B[sr];W[rs];B[bb];W[ab];B[ba];W[ds];B[bs];W[jm]
17
+ ;B[jl];W[km];B[lf];W[mf];B[ld];W[me];B[ji];W[ii];B[rn];W[kj];B[lj];W[ll];B[lk];W[rg]
18
+ ;B[sj];W[si];B[sm];W[pp];B[po];W[bj];B[bk];W[pn];B[hh];W[hi];B[pe])
@@ -0,0 +1,55 @@
1
+ (;GM[1]FF[3]
2
+ RU[Japanese]SZ[19]HA[0]KM[5.5]
3
+ PW[White]
4
+ PB[Black]
5
+ GN[White (W) vs. Black (B)]
6
+ DT[1999-07-28]
7
+ SY[Cgoban 1.9.2]TM[30:00(5x1:00)];
8
+ AW[ea][eb][ec][bd][dd][ae][ce][de][cf][ef][cg][dg][eh][ci][di][bj][ej]
9
+ AB[da][db][cc][dc][cd][be][bf][ag][bg][bh][ch][dh]LB[bd:A]PL[2]
10
+ C[guff plays A and adum tenukis to fill a 1-point ko. white to kill.
11
+ ]
12
+ (;W[bc];B[bb]
13
+ (;W[ca];B[cb]
14
+ (;W[ab];B[ba]
15
+ (;W[bi]
16
+ C[RIGHT
17
+ black can't push (but no such luck in the actual game)
18
+ ])
19
+
20
+ (;W[ad];B[af])
21
+
22
+ (;W[ac];B[af])
23
+ )
24
+
25
+ (;W[bi];B[ac])
26
+ )
27
+
28
+ (;W[ab];B[ac]
29
+ (;W[ad];B[af])
30
+
31
+ (;W[ba];B[ad])
32
+
33
+ (;W[ca];B[ad])
34
+ )
35
+
36
+ (;W[bi];B[ac])
37
+
38
+ (;W[cb];B[ca])
39
+
40
+ (;W[ba];B[ac]
41
+ (;W[cb];B[ad])
42
+
43
+ (;W[ca];B[ad])
44
+ )
45
+
46
+ (;W[ac];B[ab];W[ca];B[ad])
47
+ )
48
+
49
+ (;W[bi];B[bc]
50
+ (;W[ah];B[ad])
51
+
52
+ (;W[ad];B[ac])
53
+ )
54
+
55
+ )
@@ -0,0 +1,167 @@
1
+ (;FF[4]AP[Primiview:3.1]GM[1]SZ[19]GN[Gametree 1: properties]US[Arno Hollosi]
2
+
3
+ (;B[pd]N[Moves, comments, annotations]
4
+ C[Nodename set to: "Moves, comments, annotations"];W[dp]GW[1]
5
+ C[Marked as "Good for White"];B[pp]GB[2]
6
+ C[Marked as "Very good for Black"];W[dc]GW[2]
7
+ C[Marked as "Very good for White"];B[pj]DM[1]
8
+ C[Marked as "Even position"];W[ci]UC[1]
9
+ C[Marked as "Unclear position"];B[jd]TE[1]
10
+ C[Marked as "Tesuji" or "Good move"];W[jp]BM[2]
11
+ C[Marked as "Very bad move"];B[gd]DO[]
12
+ C[Marked as "Doubtful move"];W[de]IT[]
13
+ C[Marked as "Interesting move"];B[jj];
14
+ C[White "Pass" move]W[];
15
+ C[Black "Pass" move]B[tt])
16
+
17
+ (;AB[dd][de][df][dg][do:gq]
18
+ AW[jd][je][jf][jg][kn:lq][pn:pq]
19
+ N[Setup]C[Black & white stones at the top are added as single stones.
20
+
21
+ Black & white stones at the bottom are added using compressed point lists.]
22
+ ;AE[ep][fp][kn][lo][lq][pn:pq]
23
+ C[AddEmpty
24
+
25
+ Black stones & stones of left white group are erased in FF[3\] way.
26
+
27
+ White stones at bottom right were erased using compressed point list.]
28
+ ;AB[pd]AW[pp]PL[B]C[Added two stones.
29
+
30
+ Node marked with "Black to play".];PL[W]
31
+ C[Node marked with "White to play"])
32
+
33
+ (;AB[dd][de][df][dg][dh][di][dj][nj][ni][nh][nf][ne][nd][ij][ii][ih][hq]
34
+ [gq][fq][eq][dr][ds][dq][dp][cp][bp][ap][iq][ir][is][bo][bn][an][ms][mr]
35
+ AW[pd][pe][pf][pg][ph][pi][pj][fd][fe][ff][fh][fi][fj][kh][ki][kj][os][or]
36
+ [oq][op][pp][qp][rp][sp][ro][rn][sn][nq][mq][lq][kq][kr][ks][fs][gs][gr]
37
+ [er]N[Markup]C[Position set up without compressed point lists.]
38
+
39
+ ;TR[dd][de][df][ed][ee][ef][fd:ff]
40
+ MA[dh][di][dj][ej][ei][eh][fh:fj]
41
+ CR[nd][ne][nf][od][oe][of][pd:pf]
42
+ SQ[nh][ni][nj][oh][oi][oj][ph:pj]
43
+ SL[ih][ii][ij][jj][ji][jh][kh:kj]
44
+ TW[pq:ss][so][lr:ns]
45
+ TB[aq:cs][er:hs][ao]
46
+ C[Markup at top partially using compressed point lists (for markup on white stones); listed clockwise, starting at upper left:
47
+ - TR (triangle)
48
+ - CR (circle)
49
+ - SQ (square)
50
+ - SL (selected points)
51
+ - MA ('X')
52
+
53
+ Markup at bottom: black & white territory (using compressed point lists)]
54
+ ;LB[dc:1][fc:2][nc:3][pc:4][dj:a][fj:b][nj:c]
55
+ [pj:d][gs:ABCDEFGH][gr:ABCDEFG][gq:ABCDEF][gp:ABCDE][go:ABCD][gn:ABC][gm:AB]
56
+ [mm:12][mn:123][mo:1234][mp:12345][mq:123456][mr:1234567][ms:12345678]
57
+ C[Label (LB property)
58
+
59
+ Top: 8 single char labels (1-4, a-d)
60
+
61
+ Bottom: Labels up to 8 char length.]
62
+
63
+ ;DD[kq:os][dq:hs]
64
+ AR[aa:sc][sa:ac][aa:sa][aa:ac][cd:cj]
65
+ [gd:md][fh:ij][kj:nh]
66
+ LN[pj:pd][nf:ff][ih:fj][kh:nj]
67
+ C[Arrows, lines and dimmed points.])
68
+
69
+ (;B[qd]N[Style & text type]
70
+ C[There are hard linebreaks & soft linebreaks.
71
+ Soft linebreaks are linebreaks preceeded by '\\' like this one >o\
72
+ k<. Hard line breaks are all other linebreaks.
73
+ Soft linebreaks are converted to >nothing<, i.e. removed.
74
+
75
+ Note that linebreaks are coded differently on different systems.
76
+
77
+ Examples (>ok< shouldn't be split):
78
+
79
+ linebreak 1 "\\n": >o\
80
+ k<
81
+ linebreak 2 "\\n\\r": >o\
82
+
83
+ k<
84
+ linebreak 3 "\\r\\n": >o\
85
+ k<
86
+ linebreak 4 "\\r": >o\
87
+ k<]
88
+
89
+ (;W[dd]N[W d16]C[Variation C is better.](;B[pp]N[B q4])
90
+ (;B[dp]N[B d4])
91
+ (;B[pq]N[B q3])
92
+ (;B[oq]N[B p3])
93
+ )
94
+ (;W[dp]N[W d4])
95
+ (;W[pp]N[W q4])
96
+ (;W[cc]N[W c17])
97
+ (;W[cq]N[W c3])
98
+ (;W[qq]N[W r3])
99
+ )
100
+
101
+ (;B[qr]N[Time limits, captures & move numbers]
102
+ BL[120.0]C[Black time left: 120 sec];W[rr]
103
+ WL[300]C[White time left: 300 sec];B[rq]
104
+ BL[105.6]OB[10]C[Black time left: 105.6 sec
105
+ Black stones left (in this byo-yomi period): 10];W[qq]
106
+ WL[200]OW[2]C[White time left: 200 sec
107
+ White stones left: 2];B[sr]
108
+ BL[87.00]OB[9]C[Black time left: 87 sec
109
+ Black stones left: 9];W[qs]
110
+ WL[13.20]OW[1]C[White time left: 13.2 sec
111
+ White stones left: 1];B[rs]
112
+ C[One white stone at s2 captured];W[ps];B[pr];W[or]
113
+ MN[2]C[Set move number to 2];B[os]
114
+ C[Two white stones captured
115
+ (at q1 & r1)]
116
+ ;MN[112]W[pq]C[Set move number to 112];B[sq];W[rp];B[ps]
117
+ ;W[ns];B[ss];W[nr]
118
+ ;B[rr];W[sp];B[qs]C[Suicide move
119
+ (all B stones get captured)])
120
+ )
121
+
122
+ (;FF[4]AP[Primiview:3.1]GM[1]SZ[19]C[Gametree 2: game-info
123
+
124
+ Game-info properties are usually stored in the root node.
125
+ If games are merged into a single game-tree, they are stored in the node\
126
+ where the game first becomes distinguishable from all other games in\
127
+ the tree.]
128
+ ;B[pd]
129
+ (;PW[W. Hite]WR[6d]RO[2]RE[W+3.5]
130
+ PB[B. Lack]BR[5d]PC[London]EV[Go Congress]W[dp]
131
+ C[Game-info:
132
+ Black: B. Lack, 5d
133
+ White: W. Hite, 6d
134
+ Place: London
135
+ Event: Go Congress
136
+ Round: 2
137
+ Result: White wins by 3.5])
138
+ (;PW[T. Suji]WR[7d]RO[1]RE[W+Resign]
139
+ PB[B. Lack]BR[5d]PC[London]EV[Go Congress]W[cp]
140
+ C[Game-info:
141
+ Black: B. Lack, 5d
142
+ White: T. Suji, 7d
143
+ Place: London
144
+ Event: Go Congress
145
+ Round: 1
146
+ Result: White wins by resignation])
147
+ (;W[ep];B[pp]
148
+ (;PW[S. Abaki]WR[1d]RO[3]RE[B+63.5]
149
+ PB[B. Lack]BR[5d]PC[London]EV[Go Congress]W[ed]
150
+ C[Game-info:
151
+ Black: B. Lack, 5d
152
+ White: S. Abaki, 1d
153
+ Place: London
154
+ Event: Go Congress
155
+ Round: 3
156
+ Result: Balck wins by 63.5])
157
+ (;PW[A. Tari]WR[12k]KM[-59.5]RO[4]RE[B+R]
158
+ PB[B. Lack]BR[5d]PC[London]EV[Go Congress]W[cd]
159
+ C[Game-info:
160
+ Black: B. Lack, 5d
161
+ White: A. Tari, 12k
162
+ Place: London
163
+ Event: Go Congress
164
+ Round: 4
165
+ Komi: -59.5 points
166
+ Result: Black wins by resignation])
167
+ ))