Skip to content

Commit

Permalink
[Go] Extract from_sgf (#1184)
Browse files Browse the repository at this point in the history
  • Loading branch information
sotetsuk committed Mar 25, 2024
1 parent b23b0fc commit e919532
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 53 deletions.
47 changes: 47 additions & 0 deletions pgx/experimental/go.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import jax

from pgx.go import Go


def from_sgf(sgf: str):
indexes = "abcdefghijklmnopqrs"
infos = sgf.split(";")
game_info = infos[1]
game_record = infos[2:]
# assert game_info[game_info.find('GM') + 3] == "1"
# set default to 19
size = 19
if game_info.find("SZ") != -1:
sz = game_info[game_info.find("SZ") + 3 : game_info.find("SZ") + 5]
if sz[1] == "]":
sz = sz[0]
size = int(sz)
env = Go(size=size)
init = jax.jit(env.init)
step = jax.jit(env.step)
key = jax.random.PRNGKey(0)
state = init(key)
has_branch = False
for reco in game_record:
if reco[-2] == ")":
# The end of main branch
print("this sgf has some branches")
print("loaded main branch")
has_branch = True
if reco[2] == "]":
# pass
state = step(state, size * size)
# check branches
if has_branch:
return state
continue
pos = reco[2:4]
yoko = indexes.index(pos[0])
tate = indexes.index(pos[1])
action = yoko + size * tate
state = step(state, action)
# We only follow the main branch
# Return when the main branch ends
if has_branch:
return state
return state
62 changes: 9 additions & 53 deletions tests/test_go.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

from pgx._src.games.go import _count_ji, _count_point
from pgx.go import Go, State
from pgx.experimental.go import from_sgf


# only for debug
Expand All @@ -25,51 +26,6 @@ def _show(state: State) -> None:
print()


# load sgf
def _from_sgf(sgf: str):
indexes = "abcdefghijklmnopqrs"
infos = sgf.split(";")
game_info = infos[1]
game_record = infos[2:]
# assert game_info[game_info.find('GM') + 3] == "1"
# set default to 19
size = 19
if game_info.find("SZ") != -1:
sz = game_info[game_info.find("SZ") + 3 : game_info.find("SZ") + 5]
if sz[1] == "]":
sz = sz[0]
size = int(sz)
env = Go(size=size)
init = jax.jit(env.init)
step = jax.jit(env.step)
key = jax.random.PRNGKey(0)
state = init(key)
has_branch = False
for reco in game_record:
if reco[-2] == ")":
# The end of main branch
print("this sgf has some branches")
print("loaded main branch")
has_branch = True
if reco[2] == "]":
# pass
state = step(state, size * size)
# check branches
if has_branch:
return state
continue
pos = reco[2:4]
yoko = indexes.index(pos[0])
tate = indexes.index(pos[1])
action = yoko + size * tate
state = step(state, action)
# We only follow the main branch
# Return when the main branch ends
if has_branch:
return state
return state


BOARD_SIZE = 5
env = Go(size=BOARD_SIZE)
init = jax.jit(env.init)
Expand Down Expand Up @@ -157,7 +113,7 @@ def test_step():


def test_from_sgf():
state = _from_sgf("(;GM[1]FF[4]DT[2023-06-22 19 51 52]SZ[9]KM[6.5]RU[japanese]PB[AI (KataGo)ㅤ​]BR[9d]PW[AI (KataGo)ㅤ​]WR[9d]RE[B+1.5]CA[UTF-8]AP[KaTrain:1.13.0]KTV[1.0]C[SGF generated by KaTrain 1.13.0ㅤ​];B[fe];W[de];B[ec];W[cc];B[cg];W[gc];B[ef];W[fd];B[ed];W[ee];B[ge];W[ff];B[eg];W[fc];B[he];W[cf];B[fb];W[gb];B[eb];W[db];B[bf];W[ce];B[hc];W[hb];B[ic];W[bg];B[bh];W[dg];B[ch];W[gg];B[ib];W[eh];B[fg];W[fh];B[gf];W[dh];B[ag];W[hg];B[ac];W[df];B[ff];W[ab];B[ae];W[bc];B[ad];W[ie];B[if];W[ig];B[id];W[hf];B[ga];W[cb];B[di];W[be];B[ha];W[ei];B[ci];W[ea];B[dd];W[ie];B[bb];W[ba];B[if];W[ah];B[ai];W[ie];B[da];W[ca];B[if];W[da];B[ie];W[cd];B[gd];W[fa];B[af];W[bd];B[dc];W[];B[])")
state = from_sgf("(;GM[1]FF[4]DT[2023-06-22 19 51 52]SZ[9]KM[6.5]RU[japanese]PB[AI (KataGo)ㅤ​]BR[9d]PW[AI (KataGo)ㅤ​]WR[9d]RE[B+1.5]CA[UTF-8]AP[KaTrain:1.13.0]KTV[1.0]C[SGF generated by KaTrain 1.13.0ㅤ​];B[fe];W[de];B[ec];W[cc];B[cg];W[gc];B[ef];W[fd];B[ed];W[ee];B[ge];W[ff];B[eg];W[fc];B[he];W[cf];B[fb];W[gb];B[eb];W[db];B[bf];W[ce];B[hc];W[hb];B[ic];W[bg];B[bh];W[dg];B[ch];W[gg];B[ib];W[eh];B[fg];W[fh];B[gf];W[dh];B[ag];W[hg];B[ac];W[df];B[ff];W[ab];B[ae];W[bc];B[ad];W[ie];B[if];W[ig];B[id];W[hf];B[ga];W[cb];B[di];W[be];B[ha];W[ei];B[ci];W[ea];B[dd];W[ie];B[bb];W[ba];B[if];W[ah];B[ai];W[ie];B[da];W[ca];B[if];W[da];B[ie];W[cd];B[gd];W[fa];B[af];W[bd];B[dc];W[];B[])")
state.save_svg("tests/assets/go/from_sgf_001.svg")
expected_board: jnp.ndarray = jnp.array(
[
Expand All @@ -177,43 +133,43 @@ def test_from_sgf():


# 検討譜は読み込めない
state = _from_sgf("(;FF[4]GM[1]CA[UTF-8]AP[besogo:0.0.0-alpha]SZ[9]ST[0];B[fe];W[de];B[ec];W[fg](;B[ef];W[eg];B[df];W[cc];B[gg];W[gf];B[hg];W[hf];B[ge];W[ff];B[he];W[if];B[dg];W[ce];B[ee];W[bg];B[db];W[cb];B[ca];W[ba];B[da];W[ab];B[dh];W[eh];B[ei];W[fi];B[di];W[gh];B[ie];W[hh];B[cf];W[bf];B[bh];W[cg];B[dd];W[cd];B[ch];W[dc];B[eb];W[ed];B[fd];W[ah];B[bi];W[ag];B[ai];W[be];B[dd];W[];B[ed];W[])(;B[cc];W[hf];B[ef];W[];B[]))")
state = from_sgf("(;FF[4]GM[1]CA[UTF-8]AP[besogo:0.0.0-alpha]SZ[9]ST[0];B[fe];W[de];B[ec];W[fg](;B[ef];W[eg];B[df];W[cc];B[gg];W[gf];B[hg];W[hf];B[ge];W[ff];B[he];W[if];B[dg];W[ce];B[ee];W[bg];B[db];W[cb];B[ca];W[ba];B[da];W[ab];B[dh];W[eh];B[ei];W[fi];B[di];W[gh];B[ie];W[hh];B[cf];W[bf];B[bh];W[cg];B[dd];W[cd];B[ch];W[dc];B[eb];W[ed];B[fd];W[ah];B[bi];W[ag];B[ai];W[be];B[dd];W[];B[ed];W[])(;B[cc];W[hf];B[ef];W[];B[]))")
state.save_svg("tests/assets/go/from_sgf_002.svg")
# 分岐先は終局しているが主分岐は終局していない
assert not state.terminated

# 初手からの分岐
state = _from_sgf("(;FF[4]GM[1]CA[UTF-8]AP[besogo:0.0.0-alpha]SZ[9]ST[0](;B[ee])(;B[eg])(;B[ec]))")
state = from_sgf("(;FF[4]GM[1]CA[UTF-8]AP[besogo:0.0.0-alpha]SZ[9]ST[0](;B[ee])(;B[eg])(;B[ec]))")
state.save_svg("tests/assets/go/from_sgf_003.svg")
board = jnp.clip(state._x.chain_id_board, -1, 1)
assert board[40] == 1
assert not state.terminated

# 19×19
state = _from_sgf("(;AP[GOWrite:2.3.48]GM[1]CA[UTF-8]SZ[19]FF[4]ST[2]PB[FanHui]BR[二段]PW[AlphaGo]WR[Google]KM[3又3/4]RE[W+1又1/4子]EV[FanHui_AlphaGo対戦]RO[1]DT[2015-10-05]OT[3x30 Byo-yomi]TM[60]SO[新浪囲棋]PC[Google,London];B[pd];W[dd];B[pp];W[dq];B[co];W[dl];B[dn];W[fp];B[bq];W[jq];B[cf];W[ch];B[fd];W[df];B[dg];W[cg];B[dc];W[ce];B[cc];W[hc];B[fb];W[nc];B[qf];W[pb];B[bf];W[be];B[ef];W[de];B[qc];W[kc];B[qn];W[cm];B[cr];W[mq];B[oq];W[qm];B[pm];W[ql];B[rn];W[pl];B[om];W[qi];B[hq];W[hp];B[gq];W[gp];B[iq];W[ip];B[jr];W[kq];B[er];W[rg];B[qg];W[rf];B[re];W[qh];B[kr];W[ln];B[sf];W[rh];B[qb];W[fe];B[el];W[ek];B[fk];W[ej];B[fl];W[dm];B[fj];W[il];B[fi];W[ei];B[fh];W[gd];B[dh];W[ci];B[di];W[cj];B[fn];W[em];B[hn];W[in];B[en];W[oo];B[np];W[nn];B[po];W[hm];B[fm];W[nl];B[og];W[nr];B[or];W[nh];B[oj];W[ol];B[oh];W[ni];B[oi];W[ng];B[nf];W[mf];B[ne];W[me];B[gc];W[hb];B[bd];W[ed];B[fc];W[ff];B[ae];W[bg];B[af];W[eh];B[fg];W[eg];B[ge];W[hd];B[gf];W[ee];B[if];W[fa];B[ga];W[gb];B[ea];W[ec];B[eb];W[nd];B[je];W[pe];B[oe];W[od];B[of];W[pc];B[qd];W[jh];B[kd];W[lc];B[nj];W[hh];B[hg];W[mj];B[mk];W[lj];B[nk];W[lk];B[pa];W[rm];B[mp];W[lp];B[lr];W[lq];B[bn];W[qq];B[rp];W[rq];B[qp];W[ag];B[ad];W[cp];B[bp];W[oa];B[qa];W[dr];B[ds];W[ob];B[ml];W[nm];B[pn];W[hj];B[kg];W[jg];B[kf];W[kh];B[bl];W[bm];B[am];W[bk];B[jc];W[jb];B[lm];W[km];B[mn];W[mo];B[mm];W[no];B[kl];W[jm];B[ll];W[lg];B[jk];W[cl];B[qj];W[rj];B[gm];W[ho];B[al];W[ak];B[an];W[ic];B[mr];W[nq];B[ns];W[op];B[pq];W[jd];B[pj];W[sg];B[ii];W[se];B[sd];W[ih];B[ji];W[hi];B[ie];W[ld];B[ke];W[he];B[gg];W[eq];B[fq];W[ep];B[cq];W[gn];B[ki];W[li];B[ik];W[sn];B[so];W[sm];B[dp];W[eo];B[id];W[jc];B[do];W[fo];B[hk];W[hl];B[cb];W[ph];B[pg];W[qk];B[ha];W[ia];B[fa];W[ca];B[ba];W[dj];B[cd];W[sf];B[gl];W[gj];B[gk];W[ij];B[kk];W[lh];B[ig];W[lf];B[le];W[gh];B[kj];W[jf];B[hf];W[jl];B[jj];W[gi];B[pi];W[cn];B[pk];W[ok];B[on]C[271手白1又1/4子勝])")
state = from_sgf("(;AP[GOWrite:2.3.48]GM[1]CA[UTF-8]SZ[19]FF[4]ST[2]PB[FanHui]BR[二段]PW[AlphaGo]WR[Google]KM[3又3/4]RE[W+1又1/4子]EV[FanHui_AlphaGo対戦]RO[1]DT[2015-10-05]OT[3x30 Byo-yomi]TM[60]SO[新浪囲棋]PC[Google,London];B[pd];W[dd];B[pp];W[dq];B[co];W[dl];B[dn];W[fp];B[bq];W[jq];B[cf];W[ch];B[fd];W[df];B[dg];W[cg];B[dc];W[ce];B[cc];W[hc];B[fb];W[nc];B[qf];W[pb];B[bf];W[be];B[ef];W[de];B[qc];W[kc];B[qn];W[cm];B[cr];W[mq];B[oq];W[qm];B[pm];W[ql];B[rn];W[pl];B[om];W[qi];B[hq];W[hp];B[gq];W[gp];B[iq];W[ip];B[jr];W[kq];B[er];W[rg];B[qg];W[rf];B[re];W[qh];B[kr];W[ln];B[sf];W[rh];B[qb];W[fe];B[el];W[ek];B[fk];W[ej];B[fl];W[dm];B[fj];W[il];B[fi];W[ei];B[fh];W[gd];B[dh];W[ci];B[di];W[cj];B[fn];W[em];B[hn];W[in];B[en];W[oo];B[np];W[nn];B[po];W[hm];B[fm];W[nl];B[og];W[nr];B[or];W[nh];B[oj];W[ol];B[oh];W[ni];B[oi];W[ng];B[nf];W[mf];B[ne];W[me];B[gc];W[hb];B[bd];W[ed];B[fc];W[ff];B[ae];W[bg];B[af];W[eh];B[fg];W[eg];B[ge];W[hd];B[gf];W[ee];B[if];W[fa];B[ga];W[gb];B[ea];W[ec];B[eb];W[nd];B[je];W[pe];B[oe];W[od];B[of];W[pc];B[qd];W[jh];B[kd];W[lc];B[nj];W[hh];B[hg];W[mj];B[mk];W[lj];B[nk];W[lk];B[pa];W[rm];B[mp];W[lp];B[lr];W[lq];B[bn];W[qq];B[rp];W[rq];B[qp];W[ag];B[ad];W[cp];B[bp];W[oa];B[qa];W[dr];B[ds];W[ob];B[ml];W[nm];B[pn];W[hj];B[kg];W[jg];B[kf];W[kh];B[bl];W[bm];B[am];W[bk];B[jc];W[jb];B[lm];W[km];B[mn];W[mo];B[mm];W[no];B[kl];W[jm];B[ll];W[lg];B[jk];W[cl];B[qj];W[rj];B[gm];W[ho];B[al];W[ak];B[an];W[ic];B[mr];W[nq];B[ns];W[op];B[pq];W[jd];B[pj];W[sg];B[ii];W[se];B[sd];W[ih];B[ji];W[hi];B[ie];W[ld];B[ke];W[he];B[gg];W[eq];B[fq];W[ep];B[cq];W[gn];B[ki];W[li];B[ik];W[sn];B[so];W[sm];B[dp];W[eo];B[id];W[jc];B[do];W[fo];B[hk];W[hl];B[cb];W[ph];B[pg];W[qk];B[ha];W[ia];B[fa];W[ca];B[ba];W[dj];B[cd];W[sf];B[gl];W[gj];B[gk];W[ij];B[kk];W[lh];B[ig];W[lf];B[le];W[gh];B[kj];W[jf];B[hf];W[jl];B[jj];W[gi];B[pi];W[cn];B[pk];W[ok];B[on]C[271手白1又1/4子勝])")
state.save_svg("tests/assets/go/from_sgf_004.svg")
# ダウンロードした棋譜がpassまで書いていないためterminatedになっていないが、有効手はすべて打ち終わっている
assert not state.terminated

state = _from_sgf("(;EV[第40期棋聖戦Bリーグ1組]RO[7回戦]DT[2015/09/03]KM[6.5]PB[瀬戸大樹]PW[黄翊祖]BR[八段]WR[七段]PC[関西棋院]RE[W+R]GC[186手完白中押し勝ち];B[pd];W[dp];B[qp];W[dc];B[de];W[op];B[fd];W[pn];B[qn];W[pm];B[qm];W[pl];B[eb];W[qq];B[rq];W[pq];B[rr];W[jp];B[cn];W[eo];B[dl];W[ce];B[cf];W[df];B[dd];W[cd];B[bf];W[ec];B[cc];W[cb];B[bc];W[fc];B[fe];W[gd];B[ge];W[hd];B[he];W[id];B[hq];W[co];B[er];W[bn];B[cq];W[cm];B[nc];W[rd];B[qd];W[re];B[rc];W[rb];B[qc];W[qg];B[jc];W[ie];B[if];W[ke];B[jf];W[kd];B[kc];W[kh];B[cl];W[em];B[lp];W[iq];B[hp];W[ko];B[mn];W[lm];B[nq];W[qo];B[ro];W[po];B[or];W[pr];B[kq];W[ir];B[mr];W[rl];B[rm];W[ql];B[sl];W[sk];B[sm];W[fq];B[fr];W[gr];B[hr];W[hs];B[gq];W[gs];B[fk];W[gl];B[gk];W[hk];B[hj];W[ij];B[fl];W[gm];B[ik];W[hl];B[hi];W[ii];B[ih];W[jh];B[lg];W[lh];B[mh];W[mg];B[fm];W[fn];B[gn];W[hn];B[go];W[ho];B[il];W[hm];B[kj];W[hh];B[ig];W[gj];B[gi];W[fj];B[ej];W[fi];B[gh];W[di];B[cj];W[dj];B[dk];W[ci];B[bi];W[bj];B[bk];W[aj];B[bh];W[ck];B[bm];W[dm];B[cj];W[ji];B[ck];W[bb];B[ng];W[mf];B[bd];W[sn];B[rn];W[am];B[bl];W[mi];B[mm];W[ml];B[ln];W[kn];B[jr];W[an];B[ai];W[dq];B[dr];W[bq];B[br];W[cp];B[cr];W[rj];B[nh];W[ni];B[nf];W[me];B[ph];W[mc];B[mb];W[nd];B[lc];W[oe];B[ll];W[km];B[nl];W[mk];B[nk];W[md];B[oc];W[mj];B[oi];W[oj];B[nj];W[li])")
state = from_sgf("(;EV[第40期棋聖戦Bリーグ1組]RO[7回戦]DT[2015/09/03]KM[6.5]PB[瀬戸大樹]PW[黄翊祖]BR[八段]WR[七段]PC[関西棋院]RE[W+R]GC[186手完白中押し勝ち];B[pd];W[dp];B[qp];W[dc];B[de];W[op];B[fd];W[pn];B[qn];W[pm];B[qm];W[pl];B[eb];W[qq];B[rq];W[pq];B[rr];W[jp];B[cn];W[eo];B[dl];W[ce];B[cf];W[df];B[dd];W[cd];B[bf];W[ec];B[cc];W[cb];B[bc];W[fc];B[fe];W[gd];B[ge];W[hd];B[he];W[id];B[hq];W[co];B[er];W[bn];B[cq];W[cm];B[nc];W[rd];B[qd];W[re];B[rc];W[rb];B[qc];W[qg];B[jc];W[ie];B[if];W[ke];B[jf];W[kd];B[kc];W[kh];B[cl];W[em];B[lp];W[iq];B[hp];W[ko];B[mn];W[lm];B[nq];W[qo];B[ro];W[po];B[or];W[pr];B[kq];W[ir];B[mr];W[rl];B[rm];W[ql];B[sl];W[sk];B[sm];W[fq];B[fr];W[gr];B[hr];W[hs];B[gq];W[gs];B[fk];W[gl];B[gk];W[hk];B[hj];W[ij];B[fl];W[gm];B[ik];W[hl];B[hi];W[ii];B[ih];W[jh];B[lg];W[lh];B[mh];W[mg];B[fm];W[fn];B[gn];W[hn];B[go];W[ho];B[il];W[hm];B[kj];W[hh];B[ig];W[gj];B[gi];W[fj];B[ej];W[fi];B[gh];W[di];B[cj];W[dj];B[dk];W[ci];B[bi];W[bj];B[bk];W[aj];B[bh];W[ck];B[bm];W[dm];B[cj];W[ji];B[ck];W[bb];B[ng];W[mf];B[bd];W[sn];B[rn];W[am];B[bl];W[mi];B[mm];W[ml];B[ln];W[kn];B[jr];W[an];B[ai];W[dq];B[dr];W[bq];B[br];W[cp];B[cr];W[rj];B[nh];W[ni];B[nf];W[me];B[ph];W[mc];B[mb];W[nd];B[lc];W[oe];B[ll];W[km];B[nl];W[mk];B[nk];W[md];B[oc];W[mj];B[oi];W[oj];B[nj];W[li])")
state.save_svg("tests/assets/go/from_sgf_005.svg")
# 中押し勝(降参)
assert not state.terminated

state = _from_sgf("(;CA[shift_jis]SZ[19]AP[MultiGo:4.4.4]GN[Google Challenge Match #4]EV[Google DeepMind Challenge Match 第4局]DT[2016-03-13]PC[韓国]PB[AlphaGo]BR[1p]BT[Google]PW[李世ドル]WR[9p]WT[韓国]KM[7.5]TM[2h]RE[W+R]MULTIGOGM[1];B[pd];W[dp];B[cd];W[qp];B[op];W[oq];B[nq];W[pq];B[cn];W[fq];B[mp];W[po];B[iq];W[ec];B[hd];W[cg];B[ed];W[cj];B[dc];W[bp];B[nc];W[qi];B[ep];W[eo];B[dk];W[fp];B[ck];W[dj];B[ej];W[ei];B[fi];W[eh];B[fh];W[bj];B[fk];W[fg];B[gg];W[ff];B[gf];W[mc];B[md];W[lc];B[nb];W[id];B[hc];W[jg];B[pj];W[pi];B[oj];W[oi];B[ni];W[nh];B[mh];W[ng];B[mg];W[mi];B[nj];W[mf];B[li];W[ne];B[nd];W[mj];B[lf];W[mk];B[me];W[nf];B[lh];W[qj];B[kk];W[ik];B[ji];W[gh];B[hj];W[ge];B[he];W[fd];B[fc];W[ki];B[jj];W[lj];B[kh];W[jh];B[ml];W[nk];B[ol];W[ok];B[pk];W[pl];B[qk];W[nl];B[kj];W[ii];B[rk];W[om];B[pg];W[ql];B[cp];W[co];B[oe];W[rl];B[sk];W[rj];B[hg];W[ij];B[km];W[gi];B[fj];W[jl];B[kl];W[gl];B[fl];W[gm];B[ch];W[ee];B[eb];W[bg];B[dg];W[eg];B[en];W[fo];B[df];W[dh];B[im];W[hk];B[bn];W[if];B[gd];W[fe];B[hf];W[ih];B[bh];W[ci];B[ho];W[go];B[or];W[rg];B[dn];W[cq];B[pr];W[qr];B[rf];W[qg];B[qf];W[jc];B[gr];W[sf];B[se];W[sg];B[rd];W[bl];B[bk];W[ak];B[cl];W[hn];B[in];W[hp];B[fr];W[er];B[es];W[ds];B[ah];W[ai];B[kd];W[ie];B[kc];W[kb];B[gk];W[ib];B[qh];W[rh];B[qs];W[rs];B[oh];W[sl];B[of];W[sj];B[ni];W[nj];B[oo];W[jp]N[B resigned])")
state = from_sgf("(;CA[shift_jis]SZ[19]AP[MultiGo:4.4.4]GN[Google Challenge Match #4]EV[Google DeepMind Challenge Match 第4局]DT[2016-03-13]PC[韓国]PB[AlphaGo]BR[1p]BT[Google]PW[李世ドル]WR[9p]WT[韓国]KM[7.5]TM[2h]RE[W+R]MULTIGOGM[1];B[pd];W[dp];B[cd];W[qp];B[op];W[oq];B[nq];W[pq];B[cn];W[fq];B[mp];W[po];B[iq];W[ec];B[hd];W[cg];B[ed];W[cj];B[dc];W[bp];B[nc];W[qi];B[ep];W[eo];B[dk];W[fp];B[ck];W[dj];B[ej];W[ei];B[fi];W[eh];B[fh];W[bj];B[fk];W[fg];B[gg];W[ff];B[gf];W[mc];B[md];W[lc];B[nb];W[id];B[hc];W[jg];B[pj];W[pi];B[oj];W[oi];B[ni];W[nh];B[mh];W[ng];B[mg];W[mi];B[nj];W[mf];B[li];W[ne];B[nd];W[mj];B[lf];W[mk];B[me];W[nf];B[lh];W[qj];B[kk];W[ik];B[ji];W[gh];B[hj];W[ge];B[he];W[fd];B[fc];W[ki];B[jj];W[lj];B[kh];W[jh];B[ml];W[nk];B[ol];W[ok];B[pk];W[pl];B[qk];W[nl];B[kj];W[ii];B[rk];W[om];B[pg];W[ql];B[cp];W[co];B[oe];W[rl];B[sk];W[rj];B[hg];W[ij];B[km];W[gi];B[fj];W[jl];B[kl];W[gl];B[fl];W[gm];B[ch];W[ee];B[eb];W[bg];B[dg];W[eg];B[en];W[fo];B[df];W[dh];B[im];W[hk];B[bn];W[if];B[gd];W[fe];B[hf];W[ih];B[bh];W[ci];B[ho];W[go];B[or];W[rg];B[dn];W[cq];B[pr];W[qr];B[rf];W[qg];B[qf];W[jc];B[gr];W[sf];B[se];W[sg];B[rd];W[bl];B[bk];W[ak];B[cl];W[hn];B[in];W[hp];B[fr];W[er];B[es];W[ds];B[ah];W[ai];B[kd];W[ie];B[kc];W[kb];B[gk];W[ib];B[qh];W[rh];B[qs];W[rs];B[oh];W[sl];B[of];W[sj];B[ni];W[nj];B[oo];W[jp]N[B resigned])")
state.save_svg("tests/assets/go/from_sgf_006.svg")
# 中押し勝(降参)
assert not state.terminated

# 分岐あり
state = _from_sgf("(;FF[4]GM[1]CA[UTF-8]AP[besogo:0.0.0-alpha]SZ[19]ST[0];B[pd];W[qf];B[nc](;W[rd];B[qc];W[qi])(;W[qd];B[qc];W[rc];B[qe];W[rd];B[pf];W[re];B[pe];W[qg]))")
state = from_sgf("(;FF[4]GM[1]CA[UTF-8]AP[besogo:0.0.0-alpha]SZ[19]ST[0];B[pd];W[qf];B[nc](;W[rd];B[qc];W[qi])(;W[qd];B[qc];W[rc];B[qe];W[rd];B[pf];W[re];B[pe];W[qg]))")
state.save_svg("tests/assets/go/from_sgf_007.svg")
board = jnp.clip(state._x.chain_id_board, -1, 1)
assert board[168] == -1
assert board[55] == 0

# from_sgf_006と全く同じだが分岐がある
state = _from_sgf("(;CA[shift_jis]SZ[19]AP[MultiGo:4.4.4]GN[Google Challenge Match #4]EV[Google DeepMind Challenge Match 第4局]DT[2016-03-13]PC[韓国]PB[AlphaGo]BR[1p]BT[Google]PW[李世ドル]WR[9p]WT[韓国]KM[7.5]TM[2h]RE[W+R]MULTIGOGM[1];B[pd];W[dp];B[cd];W[qp];B[op];W[oq];B[nq];W[pq];B[cn];W[fq];B[mp];W[po];B[iq];W[ec];B[hd];W[cg];B[ed];W[cj];B[dc];W[bp];B[nc];W[qi];B[ep];W[eo];B[dk];W[fp];B[ck];W[dj];B[ej](;W[ei];B[fi];W[eh];B[fh];W[bj];B[fk];W[fg];B[gg];W[ff];B[gf];W[mc];B[md];W[lc];B[nb];W[id];B[hc];W[jg];B[pj];W[pi];B[oj];W[oi];B[ni];W[nh];B[mh];W[ng];B[mg];W[mi];B[nj];W[mf];B[li];W[ne];B[nd];W[mj];B[lf];W[mk];B[me];W[nf];B[lh];W[qj];B[kk];W[ik];B[ji];W[gh];B[hj];W[ge];B[he];W[fd];B[fc];W[ki];B[jj];W[lj];B[kh];W[jh];B[ml];W[nk];B[ol];W[ok];B[pk];W[pl];B[qk];W[nl];B[kj];W[ii];B[rk];W[om];B[pg];W[ql];B[cp];W[co];B[oe];W[rl];B[sk];W[rj];B[hg];W[ij];B[km];W[gi];B[fj];W[jl];B[kl];W[gl];B[fl];W[gm];B[ch];W[ee];B[eb];W[bg];B[dg];W[eg];B[en];W[fo];B[df];W[dh];B[im];W[hk];B[bn];W[if];B[gd];W[fe];B[hf];W[ih];B[bh];W[ci];B[ho];W[go];B[or];W[rg];B[dn];W[cq];B[pr];W[qr];B[rf];W[qg];B[qf];W[jc];B[gr];W[sf];B[se];W[sg];B[rd];W[bl];B[bk];W[ak];B[cl];W[hn];B[in];W[hp];B[fr];W[er];B[es];W[ds];B[ah];W[ai];B[kd];W[ie];B[kc];W[kb];B[gk];W[ib];B[qh];W[rh];B[qs];W[rs];B[oh];W[sl];B[of];W[sj];B[ni];W[nj];B[oo];W[jp]N[B resigned])(;W[ek];B[bj];W[bi];B[bk];W[dh];B[fj];W[el];B[en];W[fn];B[em];W[fm];B[dl];W[gk];B[fh]))")
state = from_sgf("(;CA[shift_jis]SZ[19]AP[MultiGo:4.4.4]GN[Google Challenge Match #4]EV[Google DeepMind Challenge Match 第4局]DT[2016-03-13]PC[韓国]PB[AlphaGo]BR[1p]BT[Google]PW[李世ドル]WR[9p]WT[韓国]KM[7.5]TM[2h]RE[W+R]MULTIGOGM[1];B[pd];W[dp];B[cd];W[qp];B[op];W[oq];B[nq];W[pq];B[cn];W[fq];B[mp];W[po];B[iq];W[ec];B[hd];W[cg];B[ed];W[cj];B[dc];W[bp];B[nc];W[qi];B[ep];W[eo];B[dk];W[fp];B[ck];W[dj];B[ej](;W[ei];B[fi];W[eh];B[fh];W[bj];B[fk];W[fg];B[gg];W[ff];B[gf];W[mc];B[md];W[lc];B[nb];W[id];B[hc];W[jg];B[pj];W[pi];B[oj];W[oi];B[ni];W[nh];B[mh];W[ng];B[mg];W[mi];B[nj];W[mf];B[li];W[ne];B[nd];W[mj];B[lf];W[mk];B[me];W[nf];B[lh];W[qj];B[kk];W[ik];B[ji];W[gh];B[hj];W[ge];B[he];W[fd];B[fc];W[ki];B[jj];W[lj];B[kh];W[jh];B[ml];W[nk];B[ol];W[ok];B[pk];W[pl];B[qk];W[nl];B[kj];W[ii];B[rk];W[om];B[pg];W[ql];B[cp];W[co];B[oe];W[rl];B[sk];W[rj];B[hg];W[ij];B[km];W[gi];B[fj];W[jl];B[kl];W[gl];B[fl];W[gm];B[ch];W[ee];B[eb];W[bg];B[dg];W[eg];B[en];W[fo];B[df];W[dh];B[im];W[hk];B[bn];W[if];B[gd];W[fe];B[hf];W[ih];B[bh];W[ci];B[ho];W[go];B[or];W[rg];B[dn];W[cq];B[pr];W[qr];B[rf];W[qg];B[qf];W[jc];B[gr];W[sf];B[se];W[sg];B[rd];W[bl];B[bk];W[ak];B[cl];W[hn];B[in];W[hp];B[fr];W[er];B[es];W[ds];B[ah];W[ai];B[kd];W[ie];B[kc];W[kb];B[gk];W[ib];B[qh];W[rh];B[qs];W[rs];B[oh];W[sl];B[of];W[sj];B[ni];W[nj];B[oo];W[jp]N[B resigned])(;W[ek];B[bj];W[bi];B[bk];W[dh];B[fj];W[el];B[en];W[fn];B[em];W[fm];B[dl];W[gk];B[fh]))")
state.save_svg("tests/assets/go/from_sgf_008.svg")
assert not state.terminated

Expand Down

0 comments on commit e919532

Please sign in to comment.