%D \module %D [ file=games-go, %D version=2008.01.10, %D title=\CONTEXT\ User Module, %D subtitle=Go, %D author=Wolfgang Schuster, %D date=\currentdate, %D copyright=Wolfgang Schuster, %D email=schuster.wolfgang@googlemail.com, %D license=Public Domain] \writestatus{loading}{Context User Module / Games - Go} \unprotect %D The \type{\definegame} command creates the new goban environment, it is %D important to use the goban environment in a document and not the game %D environment itself because in sgf mode the content untill \type{\stopgoban} %D is read and \type{\endgame} is executed at the end of the parsing process. \definegame[\v!goban][\v!go] % not final %\definegame[\v!weiqi][\v!go] %\definegame[\v!baduk][\v!go] %D Convert number into labels for the board, could be replaced with \type{\ifcase} solution (faster?) \def\sgfchar#1% {\ifnum#1<9 \char\number\numexpr#1+64\relax \else\ifnum#1<26 \char\number\numexpr#1+65\relax \fi\fi} %D List with the commands for the user interface \def\go!commands {newboard,saveboard,useboard,drawboard,marker,stone,move,line,arrow} \def\go!copygamecommands {\expanded{\copyparameters[][go!][\go!commands]}} \setvalue{\e!begin\????gm\????gm\v!go}% {\go!copygamecommands \go!backgroundcolor \go!backgroundimage \go!boardsize % should I set the size with \newboard? \go!boardvalues \go!inputtype} % input has to be the last command \def\go!inputtype {\doif{\gameparameter\c!option}\v!sgf\go!inputtype!sgf} \def\go!inputtype!sgf {\grabuntil{\if!!gameenvironment\e!stop\currentname\else\s!do\e!stop\v!game\fi}\dogo!inputtype!sgf} \def\dogo!inputtype!sgf#1% {\newboard \parsesgf{#1}% \drawboard \dostopgame} \defineoverlay[overlay:go][\overlaybutton{JS(Walk_Field{games!go})}] \setvalue{\e!end\????gm\????gm\v!go}% {\doif{\gameparameter\c!interactive}\v!yes\go!fieldstack} \def\go!fieldstack {\expanded{\definefieldstack[games!go][\go!list!symbols][\c!frame=\v!off]}% \framed [\c!frame=\v!off, \c!background={foreground,overlay:go}, \c!offset=\v!overlay] {\fieldstack[games!go]}} \def\go!backgroundcolor {\doifsomethingelse{\gameparameter\c!backgroundcolor} {\ctxlua{thirddata.games.go.setup['backgroundcolor'] = '\gameparameter\c!backgroundcolor' }}% {\ctxlua{thirddata.games.go.setup['backgroundcolor'] = nil }}} \def\go!backgroundimage % use groups to keep the dimensions local {\doifsomethingelse{\gameparameter\c!backgroundimage} {\ctxlua{thirddata.games.go.setup['backgroundimage'] = '\gameparameter\c!backgroundimage' }% \getfiguredimensions[\gameparameter\c!backgroundimage][scale=500]% I need a scale parameter \ctxlua{thirddata.games.go.setup.figurewidth = \number\dimexpr\figurewidth \relax }% \ctxlua{thirddata.games.go.setup.figureheight = \number\dimexpr\figureheight\relax }}% {\ctxlua{thirddata.games.go.setup.backgroundimage = nil }}} \def\go!boardsize {\assignvalue{\gameparameter\c!size}\go!board!size{9}{13}{19}% size is only used for hoshi points \assignvalue{\gameparameter\c!nx }\go!board!nx {9}{13}{19}% \assignvalue{\gameparameter\c!ny }\go!board!ny {9}{13}{19}% \ctxlua{thirddata.games.go.setup.board = \number\go!board!size }% \ctxlua{thirddata.games.go.setup.nx = \number\go!board!nx }% \ctxlua{thirddata.games.go.setup.ny = \number\go!board!ny }} \def\go!boardvalues {\startlua thirddata.games.go.setup.dx = \number\dimexpr\gameparameter\c!dx\relax ; thirddata.games.go.setup.dy = \number\dimexpr\gameparameter\c!dy\relax ; thirddata.games.go.setup.offset = \number\dimexpr\gameparameter\c!frameoffset\relax ; thirddata.games.go.setup.labeldistance = \number\dimexpr\gameparameter\c!labeldistance\relax ; thirddata.games.go.setup.stonesize = \number\dimexpr\gameparameter\c!stonesize\relax ; thirddata.games.go.setup.symbolset = '\gameparameter\c!symbolset' ; thirddata.games.go.setup.alternative = '\gameparameter\c!alternative' ; \stoplua} %D User command with protected names \def\go!newboard {\ctxlua{thirddata.games.go.board_new()}% \doif{\gameparameter\c!interactive}\v!yes\go!symbol} % too early, I should take care of \stone \def\go!saveboard#1% {\ctxlua{thirddata.games.go.board_copy( 0, '#1' )}} \def\go!useboard#1% {\ctxlua{thirddata.games.go.board_copy( '#1', 0 )}} \def\go!drawboard {\doifnot{\gameparameter\c!interactive}\v!yes {\go!setboard{0}% \go!getboard{0}}} \def\go!setboard#1% {\ctxlua{thirddata.games.go.board_draw("games:go:#1")}} \def\go!getboard#1% {\useMPgraphic{games:go:#1}} \def\go!marker {\dodoubleempty\dogo!marker} \def\dogo!marker[#1][#2]#3#4% {\ifsecondargument % needed for labels \ctxlua{thirddata.games.go.field[0][#3][#4]['label'] = '#2' }% \fi \ctxlua{thirddata.games.go.field[0][#3][#4]['marker'] = '#1' }} \def\go!stone[#1]#2#3% {\bgroup % keep \stonecolor as local command, this is no problem because Lua calls are global \processaction [#1] [\v!black=>\chardef\stonecolor\plusone, \v!white=>\chardef\stonecolor\plustwo]% \ctxlua{thirddata.games.go.field[0][#2][#3]['color'] = \number\stonecolor }% \ctxlua{thirddata.games.go.lastcolor = \number\stonecolor }% \doif{\gameparameter\c!calculate}\v!yes{\ctxlua{thirddata.games.go.deadstone.processtones()}}% \egroup} \def\go!move {\dosingleempty\dogo!move} \def\dogo!move[#1]#2#3% {\iffirstargument \go!stone[#1]{#2}{#3}% \fi \doif{\gameparameter\c!interactive}\v!yes\go!symbol} \newcount\go!count!symbols \let\go!list!symbols\empty \def\go!symbol {\expanded{\advance\go!count!symbols\plusone}% \expanded{\go!setboard{\number\go!count!symbols}}% \expanded{\definesymbol[go!symbol!\number\go!count!symbols][\noexpand\go!getboard{\number\go!count!symbols}]}% \expanded{\appendtocommalist{go!symbol!\number\go!count!symbols}}\go!list!symbols} \def\go!line#1#2#3#4% {\ctxlua{thirddata.games.go.line(#1,#2,#3,#4)}} \def\go!arrow#1#2#3#4% {\ctxlua{thirddata.games.go.arrow(#1,#2,#3,#4)}} %D Stones % simple/pure style \starttexdefinition go:stone:pure:black #1#2#3 fill fullcircle scaled #1 shifted (#2,#3) ; draw fullcircle scaled #1 shifted (#2,#3) ; \stoptexdefinition \starttexdefinition go:stone:pure:white #1#2#3 fill fullcircle scaled (#1-.2) shifted (#2,#3) withcolor white ; draw fullcircle scaled (#1-.2) shifted (#2,#3) ; \stoptexdefinition % complex/shade style \starttexdefinition go:stone:shade:black #1#2#3 circular_shade ( fullcircle scaled (#1+.4) shifted (#2,#3) , 4 , .8white , black ) ; \stoptexdefinition \starttexdefinition go:stone:shade:white #1#2#3 circular_shade ( fullcircle scaled (#1+.4) shifted (#2,#3) , 2 , .8white , white ) ; \stoptexdefinition %D Marker % #1 = nx % #2 = ny % #3 = dx % #4 = dy % #5 = stonesize % #6 = hoffset % #7 = voffset % #8 = frameoffset \starttexdefinition go:marker:circle #1#2#3#4#5#6#7#8 draw fullcircle scaled (0.6*#5) shifted (#6,#7) ; \stoptexdefinition \starttexdefinition go:marker:square #1#2#3#4#5#6#7#8 draw fullsquare scaled (sqrt(2)*(#5-.4)/2) shifted (#6,#7) ; \stoptexdefinition \starttexdefinition go:marker:cross #1#2#3#4#5#6#7#8 draw (((-(#5-.4)/2,0)--((#5-.4)/2,0)) rotated -45) shifted (#6,#7) ; draw (((-(#5-.4)/2,0)--((#5-.4)/2,0)) rotated +45) shifted (#6,#7) ; \stoptexdefinition \starttexdefinition go:marker:triangle #1#2#3#4#5#6#7#8 draw (origin--((3*(#5-.4))/(2*sqrt(3)),0)--((3*(#5-.4))/(2*sqrt(3)),0) rotated 60--cycle) shifted (#6-(3*(#5-.4))/(2*sqrt(3))/2,#7-(#5-.4)/4) ; \stoptexdefinition \starttexdefinition go:marker:select #1#2#3#4#5#6#7#8 width := #1*#2+2*#8 ; % I have to do this height := #2*#4+2*#8 ; % in a better way board := currentpicture ; currentpicture := nullpicture ; mine := unitsquare xyscaled (width,height) shifted (-#8,-#8) -- reverse % fullsquare scaled sqrt(5*4mm) shifted (#6,#7)--cycle ; clip board to mine ; currentpicture := board ; fill fullsquare scaled sqrt(2.5*4mm) shifted (#6,#7) ; \stoptexdefinition \starttexdefinition go:marker:hash #1#2#3#4#5#6#7#8 % make a hole in the board, should only be done if no stone is on this position width := #1*#3+2*#8 ; % I have to do this height := #2*#4+2*#8 ; % in a better way board := currentpicture ; currentpicture := nullpicture ; mine := unitsquare xyscaled (width,height) shifted (-#8,-#8) -- reverse % fullsquare scaled sqrt(5*4mm) shifted (#6,#7) -- cycle ; clip board to mine ; currentpicture := board ; % draw the pattern board := currentpicture ; currentpicture := nullpicture ; for i=-5 upto 5: draw ((sqrt((#2**2)/2)*i*.25,-5mm)--(sqrt((#2**2)/2)*i*.25,5mm)) rotated - 45 shifted (#6,#7) ; endfor ; % why do I need a simikolon here, it worked in MPdrawing without them (related to obeylines in texdefintion?) clip currentpicture to fullsquare xyscaled (#2,#4) shifted (#6,#7) ; addto board also currentpicture ; currentpicture := board ; \stoptexdefinition \starttexdefinition go:marker:label #1#2#3 label(textext("\doattributes{\????gm\currentgame}{style}{color}{#1}"),(#2,#3)) ; \stoptexdefinition \starttexdefinition go:marker:label #1#2#3 label(textext("\doattributes{\????gm\currentgame}{style}{color}{#1}"),(#2,#3)) ; \stoptexdefinition \starttexdefinition go:marker:hoshi #1#2#3 fill fullcircle scaled #1 shifted (#2,#3) ; \stoptexdefinition %D Hoshi points \def\definehoshi #1 #2 #3 {\resetvalue{go:hoshi:#2:#3:#1}} % #1 = boardsize % #1 = column % #3 = row %D small board: 9 \definehoshi 9 3 3 \definehoshi 9 3 7 \definehoshi 9 5 5 \definehoshi 9 7 3 \definehoshi 9 7 7 %D medium board: 13 \definehoshi 13 4 4 \definehoshi 13 4 10 \definehoshi 13 7 7 \definehoshi 13 10 4 \definehoshi 13 10 10 %D big board: 19 \definehoshi 19 4 4 \definehoshi 19 4 10 \definehoshi 19 4 16 \definehoshi 19 10 4 \definehoshi 19 10 10 \definehoshi 19 10 16 \definehoshi 19 16 4 \definehoshi 19 16 10 \definehoshi 19 16 16 %D Mapping from SGF code to TeX commands \def\sgfflush#1{\ctxlua{thirddata.games.sgf.parse("#1")}} \def\sgfnumber#1% {\ifnum`#1>105 \number\numexpr`#1-97\relax \else\ifnum`#1>96 \number\numexpr`#1-96\relax \else\ifnum`#1<73 \number\numexpr`#1-39\relax \else \number\numexpr`#1-40\relax \fi\fi\fi} \def\convertsgfnumber#1#2\relax {\edef\valuea{\sgfnumber{#1}}% \edef\valueb{\sgfnumber{#1}}} \starttexdefinition parsesgf #1 \sgfflush{#1} \stoptexdefinition \starttexdefinition sgf!node #1 \sgfflush{#1} \stoptexdefinition \starttexdefinition sgf!white #1 \expandafter\convertsgfnumber#1\relax \move[white]\valuea\valueb \stoptexdefinition \starttexdefinition sgf!black #1 \expandafter\convertsgfnumber#1\relax \move[black]\valuea\valueb \stoptexdefinition \starttexdefinition sgf!addwhite #1 \expandafter\convertsgfnumber#1\relax \stone[white]\valuea\valueb \stoptexdefinition \starttexdefinition sgf!comment #1 % no output \stoptexdefinition %D Lua functions are saved in a separate file \ctxloadluafile{games-go}{} %D Setup for the default values \setupgame % \setupgame[go] == \setupgoban [\v!go] [\c!size=\v!medium, \c!stonesize=.92\bodyfontsize, \c!nx=\gameparameter\c!size, \c!ny=\gameparameter\c!size, \c!dx=\bodyfontsize, \c!dy=\gameparameter\c!dx, \c!style=\txx, \c!color=, \c!labelstyle=\txx, \c!labelcolor=, \c!symbolset=\v!pure, % \v!shade \c!labeldistance=.25\bodyfontsize, \c!frameoffset=2\bodyfontsize, \c!interactive=\v!no, \c!calculate=\v!no, \c!option=\v!tex, \c!alternative=\v!b, \c!backgroundcolor=, \c!backgroundimage=] \protect \endinput