summaryrefslogtreecommitdiff
path: root/Master
diff options
context:
space:
mode:
Diffstat (limited to 'Master')
-rw-r--r--Master/texmf-dist/tex/context/third/games/games-go.lua521
-rw-r--r--Master/texmf-dist/tex/context/third/games/games-go.tex381
-rw-r--r--Master/texmf-dist/tex/context/third/games/games-hex.lua90
-rw-r--r--Master/texmf-dist/tex/context/third/games/games-hex.tex119
-rw-r--r--Master/texmf-dist/tex/context/third/games/holz280.jpgbin0 -> 4759 bytes
-rw-r--r--Master/texmf-dist/tex/context/third/games/t-games.tex97
-rwxr-xr-xMaster/tlpkg/bin/tlpkg-ctan-check2
-rwxr-xr-xMaster/tlpkg/libexec/ctan2tds1
-rw-r--r--Master/tlpkg/tlpsrc/collection-context.tlpsrc1
-rw-r--r--Master/tlpkg/tlpsrc/context-games.tlpsrc4
10 files changed, 1215 insertions, 1 deletions
diff --git a/Master/texmf-dist/tex/context/third/games/games-go.lua b/Master/texmf-dist/tex/context/third/games/games-go.lua
new file mode 100644
index 00000000000..444bfd06378
--- /dev/null
+++ b/Master/texmf-dist/tex/context/third/games/games-go.lua
@@ -0,0 +1,521 @@
+if not modules then modules = { } end modules ['games-go'] = {
+ version = 1.000,
+ comment = "Go",
+ author = "Wolfgang Schuster",
+ copyright = "Wolfgang Schuster",
+ email = "schuster.wolfgang@googlemail.com",
+ license = "Public Domain"
+}
+
+do
+
+thirddata = thirddata or { }
+thirddata.games = thirddata.games or { }
+thirddata.games.go = thirddata.games.go or { }
+thirddata.games.go.field = thirddata.games.go.field or { }
+thirddata.games.go.setup = thirddata.games.go.setup or { }
+thirddata.games.go.deadstone = thirddata.games.go.deadstone or { }
+
+local nx = function() return thirddata.games.go.setup.nx end
+local ny = function() return thirddata.games.go.setup.ny end
+local dx = function() return thirddata.games.go.setup.dx end
+local dy = function() return thirddata.games.go.setup.dy end
+local offset = function() return thirddata.games.go.setup.offset end
+local size = function() return thirddata.games.go.setup.stonesize end
+local board = function() return thirddata.games.go.setup.board end
+local distance = function() return thirddata.games.go.setup.labeldistance end
+local symbolset = function() return thirddata.games.go.setup.symbolset end
+local bp = function(value) return number.tobasepoints(value) end
+local sp = function(value) return value * 65536/(7227/7200) end
+local line = function(k,v,s) return bp(thirddata.games.go.lines [k][v]*s) end
+local arrow = function(k,v,s) return bp(thirddata.games.go.arrows[k][v]*s) end
+
+-- Drawing functions
+
+thirddata.games.go.lastcolor = 0
+thirddata.games.go.currentmove = 0
+
+function thirddata.games.go.move(color)
+ thirddata.games.go.lastcolor = color
+ thirddata.games.go.currentmove = thirddata.games.go.currentmove + 1
+end
+
+thirddata.games.go.linecount = 0
+thirddata.games.go.lines = { }
+
+function thirddata.games.go.line(x1,y1,x2,y2)
+ thirddata.games.go.linecount = thirddata.games.go.linecount + 1
+ thirddata.games.go.lines[thirddata.games.go.linecount] = { x1, y1, x2, y2 }
+end
+
+thirddata.games.go.arrowcount = 0
+thirddata.games.go.arrows = { }
+
+function thirddata.games.go.arrow(x1,y1,x2,y2)
+ thirddata.games.go.arrowcount = thirddata.games.go.arrowcount + 1
+ thirddata.games.go.arrows[thirddata.games.go.arrowcount] = { x1, y1, x2, y2 }
+end
+
+function thirddata.games.go.board_color()
+ if thirddata.games.go.setup['backgroundcolor'] ~= nil then
+ tex.sprint("board := currentpicture ;")
+ tex.sprint("currentpicture := nullpicture ;")
+ tex.sprint("fill unitsquare xyscaled (" .. bp((nx()-1)*dx()+2*offset()) .. "," .. bp((ny()-1)*dy()+2*offset()) .. ")")
+ tex.sprint("shifted (" .. bp(-offset()) .. "," .. bp(-offset()) .. ")")
+ tex.sprint("withcolor \\MPcolor{" .. thirddata.games.go.setup['backgroundcolor'] .. "} ;")
+ tex.sprint("addto currentpicture also board ;")
+ end
+end
+
+thirddata.games.go.setup.figurewidth = 0
+thirddata.games.go.setup.figureheight = 0
+
+function thirddata.games.go.board_figure()
+ local width = thirddata.games.go.setup.figurewidth
+ local height = thirddata.games.go.setup.figureheight
+ local columns = math.floor( ((nx()-1)*dx()+2*offset()) / width ) -- floor and not ceil because
+ local rows = math.floor( ((ny()-1)*dy()+2*offset()) / height ) -- I start from 0 and not 1
+ if thirddata.games.go.setup['backgroundimage'] ~= nil then
+ tex.sprint("board := currentpicture ;")
+ tex.sprint("currentpicture := nullpicture ;")
+ for row=0,rows do
+ for col=0,columns do
+ tex.sprint('externalfigure "' .. thirddata.games.go.setup['backgroundimage'] .. '"')
+ tex.sprint('xyscaled (' .. bp(width) .. ',' .. bp(height) .. ')')
+ tex.sprint('shifted (' .. bp(-offset()+row*width) .. ',' .. bp(-offset()+col*height) .. ') ;')
+ end
+ end
+ tex.sprint("mine := unitsquare xyscaled (" .. bp((nx()-1)*dx()+2*offset()) .. "," .. bp((ny()-1)*dy()+2*offset()) .. ")")
+ tex.sprint(" shifted (" .. bp(-offset()) .. "," .. bp(-offset()) .. ") ;")
+ tex.sprint("clip currentpicture to mine ;")
+ tex.sprint("addto currentpicture also board ;")
+ end
+end
+
+function thirddata.games.go.board_new()
+ local xy = 0
+ thirddata.games.go.field[0] = { }
+ for col=0,nx()+1 do
+ thirddata.games.go.field[0][col] = { }
+ for row=0,ny()+1 do
+ if col==0 then
+ xy = 3
+ elseif col==nx()+1 then
+ xy = 3
+ elseif row==0 then
+ xy = 3
+ elseif row==ny()+1 then
+ xy = 3
+ else
+ xy = 0
+ end
+ thirddata.games.go.field[0][col][row] = { color = xy, marker = nil, label = nil, move = nil }
+ end
+ end
+end
+
+function thirddata.games.go.board_copy(from,to)
+ thirddata.games.go.field[to] = { }
+ for k,v in pairs(thirddata.games.go.field[from]) do
+ thirddata.games.go.field[to][k] = { }
+ for x,y in pairs(thirddata.games.go.field[from][k]) do
+ thirddata.games.go.field[to][k][x] = { }
+ for a,b in pairs(thirddata.games.go.field[from][k][x]) do
+ thirddata.games.go.field[to][k][x][a] = thirddata.games.go.field[from][k][x][a]
+ end
+ end
+ end
+end
+
+function thirddata.games.go.board_lines()
+ for col=1,nx() do
+ tex.sprint("draw (" .. bp((col-1)*dx()) .. ",0) -- (" .. bp((col-1)*dx()) .. "," .. bp((ny()-1)*dy()) .. ") ;")
+ end
+ for row=1,ny() do
+ tex.sprint("draw (0," .. bp((row-1)*dy()) .. ") -- (" .. bp((nx()-1)*dx()) .. "," .. bp((row-1)*dy()) .. ") ;")
+ end
+end
+
+function thirddata.games.go.board_lines_alt()
+ -- draw horizontal rules
+ for row=2,ny()-1 do
+ for col=1,nx()-1 do
+ if thirddata.games.go.field[0][col][row]['color'] == 0 then
+ tex.sprint("draw (" .. bp((col-1)*dx()) .. "," .. bp((row-1)*dy()) .. ") -- (" .. bp((col)*dx()) .. "," .. bp((row-1)*dy()) .. ") ;")
+ else
+ if thirddata.games.go.field[0][col+1][row]['color'] == 0 then
+ tex.sprint("draw (" .. bp((col-1)*dx()) .. "," .. bp((row-1)*dy()) .. ") -- (" .. bp((col)*dx()) .. "," .. bp((row-1)*dy()) .. ") ;")
+ end
+ end
+ end
+ end
+ -- draw vertical rules
+ for col=2,nx()-1 do
+ for row=1,ny()-1 do
+ if thirddata.games.go.field[0][col][row]['color'] == 0 then
+ tex.sprint("draw (" .. bp((col-1)*dx()) .. "," .. bp((row-1)*dy()) .. ") -- (" .. bp((col-1)*dx()) .. "," .. bp((row)*dy()) .. ") ;")
+ else
+ if thirddata.games.go.field[0][col][row+1]['color'] == 0 then
+ tex.sprint("draw (" .. bp((col-1)*dx()) .. "," .. bp((row-1)*dy()) .. ") -- (" .. bp((col-1)*dx()) .. "," .. bp((row)*dy()) .. ") ;")
+ end
+ end
+ end
+ end
+ -- draw border frame
+ tex.sprint("draw (0,0) -- (0," .. bp((ny()-1)*dy()) .. ") ;")
+ tex.sprint("draw (" .. bp((nx()-1)*dx()).. ",0) -- (" .. bp((nx()-1)*dx()).. "," .. bp((ny()-1)*dy()) .. ") ;")
+ tex.sprint("draw (0,0) -- (" .. bp((nx()-1)*dx()) .. ",0) ;")
+ tex.sprint("draw (0," .. bp((ny()-1)*dy()).. ") -- (" .. bp((nx()-1)*dx()).. "," .. bp((ny()-1)*dy()) .. ") ;")
+end
+
+function thirddata.games.go.board_hoshi()
+ for col=1,nx() do
+ for row=1,ny() do
+ tex.sprint("\\ifcsname go:hoshi:" .. row .. ":" .. col .. ":" .. board() .. "\\endcsname")
+ tex.sprint("\\csname go:marker:hoshi\\endcsname")
+ tex.sprint("{" .. bp(size()/5) .. "}")
+ tex.sprint("{" .. bp((col-1)*dx()) .. "}")
+ tex.sprint("{" .. bp((row-1)*dy()) .. "}")
+ tex.sprint("\\fi")
+ end
+ end
+end
+
+function thirddata.games.go.board_stones()
+ for col=1,nx() do
+ for row=1,ny() do
+ local color = thirddata.games.go.field[0][col][row]['color']
+ if color==1 then
+ tex.sprint("\\csname go:stone:" .. symbolset() .. ":black\\endcsname")
+ tex.sprint("{" .. bp(size()) .. "}")
+ tex.sprint("{" .. bp((col-1)*dx()) .. "}")
+ tex.sprint("{" .. bp((row-1)*dy()) .. "}")
+ elseif color==2 then
+ tex.sprint("\\csname go:stone:" .. symbolset() .. ":white\\endcsname")
+ tex.sprint("{" .. bp(size()) .. "}")
+ tex.sprint("{" .. bp((col-1)*dx()) .. "}")
+ tex.sprint("{" .. bp((row-1)*dy()) .. "}")
+ end
+ end
+ end
+end
+
+function thirddata.games.go.board_marker()
+ for col=1,nx() do
+ for row=1,ny() do
+ local marker = thirddata.games.go.field[0][col][row]['marker']
+ local label = thirddata.games.go.field[0][col][row]['label']
+ if marker==nil then
+ elseif marker=='label' then
+ tex.sprint("\\csname go:marker:label\\endcsname")
+ tex.sprint("{" .. label .. "}")
+ tex.sprint("{" .. bp((col-1)*dx()) .. "}")
+ tex.sprint("{" .. bp((row-1)*dy()) .. "}")
+ else
+ tex.sprint("\\ifcsname go:marker:" .. marker .. "\\endcsname")
+ tex.sprint("\\csname go:marker:" .. marker .. "\\endcsname")
+ tex.sprint("{" .. nx() .. "}")
+ tex.sprint("{" .. ny() .. "}")
+ tex.sprint("{" .. bp(dx()) .. "}")
+ tex.sprint("{" .. bp(dy()) .. "}")
+ tex.sprint("{" .. bp(size()) .. "}")
+ tex.sprint("{" .. bp((col-1)*dx()) .. "}")
+ tex.sprint("{" .. bp((row-1)*dy()) .. "}")
+ tex.sprint("{" .. bp(offset()) .. "}")
+ tex.sprint("\\fi")
+ end
+ end
+ end
+end
+
+function thirddata.games.go.board_label()
+ for col=1,nx() do
+ tex.sprint('label.bot(textext("\\doattributes{@@@@gmgo}{labelstyle}{labelcolor}{\\sgfchar{' .. col .. '}}"),%')
+ tex.sprint('(' .. bp((col-1)*dx()) .. ',' .. bp(-distance()) .. ')) ;')
+ end
+ for row=1,ny() do
+ tex.sprint('label.lft(textext("\\doattributes{@@@@gmgo}{labelstyle}{labelcolor}{' .. row .. '}"),%')
+ tex.sprint('(' .. bp(-distance()) .. ',' .. bp((row-1)*dy()) .. ')) ;')
+ end
+end
+
+function thirddata.games.go.board_markerlines()
+ for k, v in pairs(thirddata.games.go.lines) do
+ tex.sprint("draw (" .. line(k,1,dx()) .. "," .. line(k,2,dy()) .. ") -- ")
+ tex.sprint(" (" .. line(k,3,dx()) .. "," .. line(k,4,dy()) .. ") ; ")
+ end
+end
+
+function thirddata.games.go.board_markerarrows()
+ for k, v in pairs(thirddata.games.go.arrows) do
+ tex.sprint("drawarrow (" .. arrow(k,1,dx()) .. "," .. arrow(k,2,dy()) .. ") -- ")
+ tex.sprint(" (" .. arrow(k,3,dx()) .. "," .. arrow(k,4,dy()) .. ") ; ")
+ end
+end
+
+function thirddata.games.go.board_size()
+ tex.sprint("setbounds currentpicture to unitsquare %")
+ tex.sprint("xyscaled (" .. bp((nx()-1)*dx()+2*offset()) .. "," .. bp((ny()-1)*dy()+2*offset()) .. ")")
+ tex.sprint("shifted (" .. bp(-offset()) .. "," .. bp(-offset()) .. ") ;")
+ tex.sprint("draw boundingbox currentpicture withpen pensquare scaled 1.2 ;")
+end
+
+function thirddata.games.go.board_draw(name)
+ tex.sprint("\\startuseMPgraphic{" .. name .. "}{}")
+ tex.sprint("path mine ; picture board ;")
+ -- thirddata.games.go.board_figure() -- not here, I have to do this at the end
+ -- thirddata.games.go.board_lines()
+ thirddata.games.go.board_lines_alt()
+ thirddata.games.go.board_hoshi()
+ thirddata.games.go.board_stones()
+ thirddata.games.go.board_marker()
+ thirddata.games.go.board_markerlines()
+ thirddata.games.go.board_markerarrows()
+ thirddata.games.go.board_label()
+ thirddata.games.go.board_size()
+ thirddata.games.go.board_color()
+ thirddata.games.go.board_figure()
+ tex.sprint("\\stopuseMPgraphic")
+end
+
+
+-- Deadstone calculator
+
+local stone = function() return thirddata.games.go.deadstone.stone end
+local enemy = function() return thirddata.games.go.deadstone.enemy end
+local wall = function() return thirddata.games.go.deadstone.wall end
+local marked = function() return thirddata.games.go.deadstone.marked end
+local error = function() return thirddata.games.go.deadstone.error end
+local dead = function() return thirddata.games.go.deadstone.dead end
+
+function thirddata.games.go.deadstone.black()
+ thirddata.games.go.deadstone.stone = 1
+ thirddata.games.go.deadstone.enemy = 2
+ thirddata.games.go.deadstone.wall = 3
+ thirddata.games.go.deadstone.marked = 4
+ thirddata.games.go.deadstone.error = 6
+ thirddata.games.go.deadstone.dead = 7
+end
+
+function thirddata.games.go.deadstone.white()
+ thirddata.games.go.deadstone.stone = 2
+ thirddata.games.go.deadstone.enemy = 1
+ thirddata.games.go.deadstone.wall = 3
+ thirddata.games.go.deadstone.marked = 5
+ thirddata.games.go.deadstone.error = 6
+ thirddata.games.go.deadstone.dead = 7
+end
+
+thirddata.games.go.deadstone.deadcount = 2
+
+function thirddata.games.go.deadstone.doprocesstones()
+ for i=1,2 do -- for the moment, I have to check the code
+ thirddata.games.go.deadstone.markstones()
+ end
+ thirddata.games.go.deadstone.deadstones()
+ for n=1,thirddata.games.go.deadstone.deadcount do
+ thirddata.games.go.deadstone.checkstones()
+ end
+ thirddata.games.go.deadstone.revertstones()
+end
+
+function thirddata.games.go.deadstone.processtones()
+ -- we placed a black stone
+ if thirddata.games.go.lastcolor==1 then
+ thirddata.games.go.deadstone.process_white()
+ thirddata.games.go.deadstone.process_black()
+ -- we placed a white stone
+ elseif thirddata.games.go.lastcolor==2 then
+ thirddata.games.go.deadstone.process_black()
+ thirddata.games.go.deadstone.process_white()
+ end
+end
+
+function thirddata.games.go.deadstone.process_black()
+ thirddata.games.go.deadstone.black()
+ thirddata.games.go.deadstone.doprocesstones()
+end
+
+function thirddata.games.go.deadstone.process_white()
+ thirddata.games.go.deadstone.white()
+ thirddata.games.go.deadstone.doprocesstones()
+end
+
+local field = function(x,y) return thirddata.games.go.field[0][x][y]['color'] end
+-- local field_top = function(x,y) return thirddata.games.go.field[0][x][y+1]['color'] end
+-- local field_bottom = function(x,y) return thirddata.games.go.field[0][x][y-1]['color'] end
+local field_bottom = function(x,y) return thirddata.games.go.field[0][x][y+1]['color'] end
+local field_top = function(x,y) return thirddata.games.go.field[0][x][y-1]['color'] end
+local field_left = function(x,y) return thirddata.games.go.field[0][x-1][y]['color'] end
+local field_right = function(x,y) return thirddata.games.go.field[0][x+1][y]['color'] end
+
+--[[ldx--
+<p>The <ldx:function>markstones</ldx:function> mark the stones if they
+have the right stones on their sides or let them keep untouched.</p>
+--ldx]]--
+
+function thirddata.games.go.deadstone.markstones()
+ for col=1,nx() do
+ for row=1,ny() do
+ if field(col,row)==stone() then
+ if (field_left(col,row)==wall()
+ or field_left(col,row)==enemy()
+ or field_left(col,row)==marked())
+ and (field_right(col,row)==wall()
+ or field_right(col,row)==enemy()
+ or field_right(col,row)==stone())
+ and (field_bottom(col,row)==wall()
+ or field_bottom(col,row)==enemy()
+ or field_bottom(col,row)==marked())
+ and (field_top(col,row)==wall()
+ or field_top(col,row)==enemy()
+ or field_top(col,row)==stone())
+ then
+ thirddata.games.go.field[0][col][row]['color'] = marked()
+ end
+ end
+ end
+ end
+end
+
+--[[ldx--
+<p>The <ldx:function>deadstones</ldx:function> set stones with the value marked
+to dead if the conditions in the function are true.</p>
+--ldx]]--
+
+function thirddata.games.go.deadstone.deadstones()
+ for col=nx(),1,-1 do
+ for row=ny(),1,-1 do
+ if field(col,row)==marked() then
+ if (field_left(col,row)==wall()
+ or field_left(col,row)==enemy()
+ or field_left(col,row)==marked())
+ and (field_right(col,row)==enemy()
+ or field_right(col,row)==wall()
+ or field_right(col,row)==dead())
+ and (field_bottom(col,row)==enemy()
+ or field_bottom(col,row)==wall()
+ or field_bottom(col,row)==dead())
+ then
+ thirddata.games.go.field[0][col][row]['color'] = dead()
+ end
+ end
+ end
+ end
+end
+
+--[[ldx--
+<p>Because the <ldx:function>deadstones</ldx:function> can sometimes set
+already living stones to dead. To prevent this in the final result this
+function looks through all stones with a loop in reverse direction and
+reset the values to their original value if the stone is not dead and
+should remain on the board. The function is currently called twice within
+processtones but this can be changed with the counter deadcount.</p>
+--ldx]]--
+
+function thirddata.games.go.deadstone.checkstones()
+ for col=1,nx() do
+ for row=1,ny() do
+ if field(col,row)==marked() then
+ thirddata.games.go.field[0][col][row]['color'] = stone()
+ elseif thirddata.games.go.field[0][col][row]['color']==dead() then
+ if (field_left(col,row)==dead()
+ or field_left(col,row)==enemy()
+ or field_left(col,row)==wall())
+ and (field_right(col,row)==dead()
+ or field_right(col,row)==enemy()
+ or field_right(col,row)==wall())
+ and (field_bottom(col,row)==dead()
+ or field_bottom(col,row)==enemy()
+ or field_bottom(col,row)==wall())
+ and (field_top(col,row)==dead()
+ or field_top(col,row)==enemy()
+ or field_top(col,row)==wall())
+ then
+ thirddata.games.go.field[0][col][row]['color'] = dead()
+ else
+ thirddata.games.go.field[0][col][row]['color'] = stone()
+ end
+ end
+ end
+ end
+end
+
+--[[ldx--
+<p>The last thing to do after all dead stones are found on the board
+is to remove them and to reset all other stones which are still in a
+marked state or we will get wrong input for the next move.</p>
+--ldx]]--
+
+function thirddata.games.go.deadstone.revertstones()
+ for col=1,nx() do
+ for row=1,ny() do
+ if thirddata.games.go.field[0][col][row]['color']==marked() then
+ thirddata.games.go.field[0][col][row] = stone()
+ elseif thirddata.games.go.field[0][col][row]['color']==dead() then
+ thirddata.games.go.field[0][col][row]['color'] = 0
+ end
+ end
+ end
+end
+
+end
+
+
+-- SGF parser
+
+do
+
+ thirddata = thirddata or { }
+ thirddata.games = thirddata.games or { }
+ thirddata.games.sgf = thirddata.games.sgf or { }
+
+ local function command(name,x)
+ tex.sprint(string.format("\\csname sgf!%s\\endcsname{%s}",name,x))
+ end
+
+ local nodes = { }
+
+ function nodes.B (x) command("black" ,x) end
+ function nodes.W (x) command("white" ,x) end
+ function nodes.AW(x) command("addwhite" ,x) end
+ function nodes.C (x) command("comment" ,x) end
+
+ local function action(what,data)
+ local a = nodes[what]
+ if a then
+ for w in string.gmatch(data, "%b[]") do
+ a(string.sub(w,2,-2))
+ end
+ else
+ print("unknown action: " .. what)
+ end
+ end
+
+ local function nodecontent(str)
+ tex.sprint(string.format("\\csname sgf!node\\endcsname{%s}",string.sub(str,2)))
+ end
+
+ local space = lpeg.S(' \r\n')^1
+ local lcletter = lpeg.R("az")
+ local ucletter = lpeg.R("AZ")
+ local letter = lcletter + ucletter
+
+ local propindent = ucletter^1
+
+ local property = lpeg.C(propindent) * lpeg.C{ (lpeg.P("[") * (1 - lpeg.S"[]")^0 * lpeg.P("]"))^1} / action
+
+ local function nest(str)
+ tex.sprint(tex.ctxcatcodes,string.format("\\parsesgf{%s}",string.sub(str,2,-2)))
+ end
+
+ local node = lpeg.P{ ";" * (propindent * (lpeg.P("[") * (1 - lpeg.S"[]")^0 * lpeg.P("]"))^1)^1} / nodecontent
+ local branch = lpeg.P{ "(" * ((1 - lpeg.S"()") + lpeg.V(1))^0 * ")" } / nest
+
+ local parser = (branch + node + property + space)^0
+
+ function thirddata.games.sgf.parse(str)
+ parser:match(str)
+ end
+
+end
diff --git a/Master/texmf-dist/tex/context/third/games/games-go.tex b/Master/texmf-dist/tex/context/third/games/games-go.tex
new file mode 100644
index 00000000000..b02480862d2
--- /dev/null
+++ b/Master/texmf-dist/tex/context/third/games/games-go.tex
@@ -0,0 +1,381 @@
+%D \module
+%D [ file=games-go,
+%D version=2008.12.30,
+%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{\e!stop\currentname}\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' ;
+ \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!backgroundcolor=,
+ \c!backgroundimage=]
+
+\protect \endinput
diff --git a/Master/texmf-dist/tex/context/third/games/games-hex.lua b/Master/texmf-dist/tex/context/third/games/games-hex.lua
new file mode 100644
index 00000000000..b8aee372d42
--- /dev/null
+++ b/Master/texmf-dist/tex/context/third/games/games-hex.lua
@@ -0,0 +1,90 @@
+if not modules then modules = { } end modules ['games-hex'] = {
+ version = 1.000,
+ comment = "Hex",
+ author = "Wolfgang Schuster",
+ copyright = "Wolfgang Schuster",
+ email = "schuster.wolfgang@googlemail.com",
+ license = "Public Domain"
+}
+
+do
+
+thirddata = thirddata or { }
+thirddata.games = thirddata.games or { }
+thirddata.games.hex = thirddata.games.hex or { }
+thirddata.games.hex.setup = thirddata.games.hex.setup or { }
+
+local nx = function() return thirddata.games.hex.setup.nx end
+local ny = function() return thirddata.games.hex.setup.ny end
+local dx = function() return thirddata.games.hex.setup.dx end
+local dy = function() return thirddata.games.hex.setup.dy end
+local offset = function() return thirddata.games.hex.setup.offset end
+local size = function() return thirddata.games.hex.setup.size end
+local distance = function() return thirddata.games.hex.setup.distance end
+local bp = function(value) return number.tobasepoints(value) end
+local sp = function(value) return value * 65536/(7227/7200) end
+
+function thirddata.games.hex.board_new()
+ thirddata.games.hex.field = { }
+ for col=1,nx() do
+ thirddata.games.hex.field[col] = { }
+ for row=1,ny() do
+ thirddata.games.hex.field[col][row] = { color = 0 }
+ end
+ end
+end
+
+function thirddata.games.hex.board_lines()
+ for row=1,ny() do
+ for col=1,ny() do
+ tex.sprint("draw (")
+ for rot=0,5 do
+ tex.sprint("(" .. bp(size()) .. ",0) rotated (" .. rot*60+90 .. ") --")
+ end
+ tex.sprint("cycle) shifted (" .. bp(math.cos(math.pi/6)*size()*(2*(col-1)+(row-1))) .. "," .. bp(-size()*1.5*(row-1)) .. ") ; ")
+ end
+ end
+end
+
+function thirddata.games.hex.board_labels()
+ for col=1,nx() do
+ tex.sprint('label.top(textext("\\doattributes{@@@@gmhex}{labelstyle}{labelcolor}{\\sgfchar{' .. col .. '}}"),%')
+ tex.sprint('(' .. bp(-(size()+distance())*math.tan(math.pi/6)+2*(col-1)*math.cos(math.pi/6)*size()) .. ',' .. bp(size()+distance()) .. ')) ;')
+ end
+ for row=1,ny() do
+ tex.sprint('label.lft(textext("\\doattributes{@@@@gmhex}{labelstyle}{labelcolor}{' .. row .. '}"),%')
+ tex.sprint('(' .. bp(-math.cos(math.pi/6)*size()-distance()+(row-1)*math.cos(math.pi/6)*size()) .. ',' .. bp(-1.5*(row-1)*size()) .. ')) ;')
+ end
+end
+
+function thirddata.games.hex.board_stones()
+ local color = function(x,y) return thirddata.games.hex.field[x][y]['color'] end
+ for col=1,nx() do
+ for row=1,ny() do
+ if color(col,row)==1 then
+ thirddata.games.hex.stone(math.cos(math.pi/6)*size()*(2*(col-1)+(row-1)),-size()*1.5*(row-1),"red")
+ elseif color(col,row)==2 then
+ thirddata.games.hex.stone(math.cos(math.pi/6)*size()*(2*(col-1)+(row-1)),-size()*1.5*(row-1),"blue")
+ end
+ end
+ end
+end
+
+function thirddata.games.hex.stone(x,y,color)
+ tex.sprint("fill (")
+ for rot=0,5 do
+ tex.sprint("(" .. bp(size()) .. ",0) rotated (" .. rot*60+90 .. ") --")
+ end
+ tex.sprint("cycle) shifted (" .. bp(x) .. "," .. bp(y) .. ")")
+ tex.sprint("withcolor \\MPcolor{" .. color .. "} ;")
+end
+
+function thirddata.games.hex.board_draw(name)
+ tex.sprint("\\startuniqueMPgraphic{" .. name .. "}{}")
+ thirddata.games.hex.board_stones()
+ thirddata.games.hex.board_lines()
+ thirddata.games.hex.board_labels()
+ tex.sprint("\\stopuniqueMPgraphic")
+end
+
+end
diff --git a/Master/texmf-dist/tex/context/third/games/games-hex.tex b/Master/texmf-dist/tex/context/third/games/games-hex.tex
new file mode 100644
index 00000000000..e03554a16fa
--- /dev/null
+++ b/Master/texmf-dist/tex/context/third/games/games-hex.tex
@@ -0,0 +1,119 @@
+%D \module
+%D [ file=games-hex,
+%D version=2008.10.29,
+%D title=\CONTEXT\ User Module,
+%D subtitle=Hex,
+%D author=Wolfgang Schuster,
+%D date=\currentdate,
+%D email=schuster.wolfgang@googlemail.com,
+%D copyright=Wolfgang Schuster]
+
+\writestatus{loading}{Context User Module / Games - Hex}
+
+\unprotect
+
+\definegame[\v!hexgame][\v!hex]
+
+\def\sgfchar#1%
+ {\ifnum#1<9
+ \char\number\numexpr#1+64\relax
+ \else\ifnum#1<26
+ \char\number\numexpr#1+65\relax
+ \fi\fi}
+
+\def\hex!commands
+ {newboard,drawboard,player}
+
+\def\hex!copygamecommands
+ {\expanded{\copyparameters[][hex!][\hex!commands]}}
+
+\setvalue{\e!begin\????gm\????gm\v!hex}%
+ {\hex!copygamecommands
+ \hex!boardsize
+ \hex!gamevalues}
+
+\defineoverlay[overlay:hex][\overlaybutton{JS(Walk_Field{games!hex})}]
+
+\setvalue{\e!end\????gm\????gm\v!hex}%
+ {\doif{\gameparameter\c!interactive}\v!yes\hex!fieldstack}
+
+\def\hex!fieldstack
+ {\expanded{\definefieldstack[games!hex][\hex!list!symbols][\c!frame=\v!off]}%
+ \framed
+ [\c!frame=\v!off,
+ \c!background={foreground,overlay:hex},
+ \c!offset=\v!overlay]
+ {\fieldstack[games!hex]}}
+
+\def\hex!boardsize % what are common values for hex
+ {\assignvalue{\gameparameter\c!nx}\hex!board!nx{11}{14}{19}%
+ \assignvalue{\gameparameter\c!ny}\hex!board!ny{11}{14}{19}%
+ \ctxlua{thirddata.games.hex.setup.nx = \number\hex!board!nx }%
+ \ctxlua{thirddata.games.hex.setup.ny = \number\hex!board!ny }}
+
+\def\hex!gamevalues
+ {\startlua
+ thirddata.games.hex.setup.size = \number\dimexpr\gameparameter\c!stonesize\relax ;
+ thirddata.games.hex.setup.dx = \number\dimexpr\gameparameter\c!dx\relax ;
+ thirddata.games.hex.setup.dy = \number\dimexpr\gameparameter\c!dy\relax ;
+ thirddata.games.hex.setup.offset = \number\dimexpr\gameparameter\c!frameoffset\relax ;
+ thirddata.games.hex.setup.distance = \number\dimexpr\gameparameter\c!labeldistance\relax ;
+ \stoplua}
+
+%D User commands
+
+\def\hex!newboard
+ {\ctxlua{thirddata.games.hex.board_new()}}
+
+\def\hex!drawboard
+ {\doifnot{\gameparameter\c!interactive}\v!yes
+ {\hex!setboard{0}%
+ \hex!getboard{0}}}
+
+\def\hex!setboard#1%
+ {\ctxlua{thirddata.games.hex.board_draw("games:hex:#1")}}
+
+\def\hex!getboard#1%
+ {\uniqueMPgraphic{games:hex:#1}}
+
+\def\hex!player[#1]#2#3%
+ {\bgroup
+ \processaction
+ [#1]
+ [ \v!red=>\chardef\stonecolor\plusone,
+ \v!blue=>\chardef\stonecolor\plustwo]%
+ \ctxlua{thirddata.games.hex.field[#2][#3] = { color = \number\stonecolor }}%
+ \egroup
+ \doif{\gameparameter\c!interactive}\v!yes\hex!symbol}
+
+\newcount\hex!count!symbols
+
+\let\hex!list!symbols\empty
+
+\def\hex!symbol
+ {\expanded{\advance\hex!count!symbols\plusone}%
+ \expanded{\hex!setboard{\number\hex!count!symbols}}%
+ \expanded{\definesymbol[hex!symbol!\number\hex!count!symbols][\noexpand\hex!getboard{\number\hex!count!symbols}]}%
+ \expanded{\appendtocommalist{hex!symbol!\number\hex!count!symbols}}\hex!list!symbols}
+
+%D Lua functions
+
+\ctxloadluafile{games-hex}{}
+
+%D Default values
+
+\setupgame
+ [\v!hex]
+ [\c!size=\v!small,
+ \c!nx=\gameparameter\c!size,
+ \c!ny=\gameparameter\c!size,
+ \c!stonesize=\bodyfontsize,
+ \c!dx=\gameparameter\c!stonesize,
+ \c!dy=\gameparameter\c!dx,
+ \c!frameoffset=0pt,
+ \c!labeldistance=0pt,
+ \c!labelstyle=\tx,
+ \c!labelcolor=,
+ \c!interaction=\v!no]
+
+\protect \endinput
diff --git a/Master/texmf-dist/tex/context/third/games/holz280.jpg b/Master/texmf-dist/tex/context/third/games/holz280.jpg
new file mode 100644
index 00000000000..9d7f23fc016
--- /dev/null
+++ b/Master/texmf-dist/tex/context/third/games/holz280.jpg
Binary files differ
diff --git a/Master/texmf-dist/tex/context/third/games/t-games.tex b/Master/texmf-dist/tex/context/third/games/t-games.tex
new file mode 100644
index 00000000000..3cc11617f7a
--- /dev/null
+++ b/Master/texmf-dist/tex/context/third/games/t-games.tex
@@ -0,0 +1,97 @@
+%D \module
+%D [ file=t-games,
+%D version=2008.10.29,
+%D title=\CONTEXT\ User Module,
+%D subtitle=Games,
+%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}
+
+\unprotect
+
+%D Constants
+
+\startinterface all
+ \setinterfaceconstant {labelstyle} {labelstyle}
+ \setinterfaceconstant {labelcolor} {labelcolor}
+ \setinterfaceconstant {labeldistance} {labeldistance}
+ \setinterfaceconstant {stonesize} {stonesize}
+ \setinterfaceconstant {backgroundimage} {backgroundimage}
+ \setinterfaceconstant {interactive} {interactive}
+\stopinterface
+
+%D Variables
+
+\startinterface all
+ \setinterfacevariable {black} {black}
+ \setinterfacevariable {white} {white}
+ \setinterfacevariable {go} {go}
+ \setinterfacevariable {hex} {hex}
+ \setinterfacevariable {goban} {goban}
+ \setinterfacevariable {hexgame} {hexgame}
+ \setinterfacevariable {red} {red}
+ \setinterfacevariable {blue} {blue}
+ \setinterfacevariable {weiqi} {weiqi}
+ \setinterfacevariable {baduk} {baduk}
+ \setinterfacevariable {pure} {pure}
+ \setinterfacevariable {shade} {shade}
+ \setinterfacevariable {tex} {tex}
+ \setinterfacevariable {sgf} {sgf}
+ \setinterfacevariable {chess} {chess}
+\stopinterface
+
+%D Namespace
+
+\def\????ga{@@@@ga}
+\def\????gm{@@@@gm}
+
+\def\gameparameter#1%
+ {\csname\????gm\currentgame#1\endcsname}
+
+%D Game environment, not more than a simple wrapper to load the real
+%D environments in the from \type {\????gm\????gm...}.
+
+\def\dostartgame
+ {\dotripleempty\dodostartgame}
+
+\def\dodostartgame[#1][#2][#3]%
+ {\bgroup
+ \edef\currentname{#1}% needed for the parser
+ \edef\currentgame{#2}% I should look for better names
+ \gameparameter\c!before
+ \ifsecondargument
+ \setupgame[#2][#3]%
+ \fi
+ \executeifdefined{\e!begin\????gm\????gm\currentgame}{\@EA\gobbleuntil\csname\e!stop\currentname\endcsname}}
+
+\def\dostopgame
+ {\executeifdefined{\e!end\????gm\????gm\currentgame}\donothing
+ \gameparameter\c!after
+ \egroup}
+
+\def\definegame
+ {\dodoubleargument\dodefinegame}
+
+\def\dodefinegame[#1][#2]%
+ {\setvalue{\e!start#1}{\dostartgame[#1][#2]}%
+ \setvalue{\e!stop #1}{\dostopgame}%
+ \setvalue{\e!setup#1\e!endsetup}{\setupgame[#2]}}
+
+%D Setup command.
+
+\def\setupgame
+ {\dodoubleargument\dosetupgame}
+
+\def\dosetupgame[#1][#2]%
+ {\getparameters[\????gm#1][#2]}
+
+%D Load the games with their own macros.
+
+\input games-go
+\input games-hex
+
+\protect \endinput
diff --git a/Master/tlpkg/bin/tlpkg-ctan-check b/Master/tlpkg/bin/tlpkg-ctan-check
index 0f221a373f3..569cfbdb7d4 100755
--- a/Master/tlpkg/bin/tlpkg-ctan-check
+++ b/Master/tlpkg/bin/tlpkg-ctan-check
@@ -56,7 +56,7 @@ my @WorkingTLP = qw(
computational-complexity confproc constants
context-account context-bnf context-chromato
context-construction-plan context-degrade context-french
- context-gnuplot
+ context-games context-gnuplot
context-letter context-lettrine context-lilypond context-mathsets
context-taspresent
context-typearea context-vim
diff --git a/Master/tlpkg/libexec/ctan2tds b/Master/tlpkg/libexec/ctan2tds
index 170c50eedea..ce4e389a1d3 100755
--- a/Master/tlpkg/libexec/ctan2tds
+++ b/Master/tlpkg/libexec/ctan2tds
@@ -134,6 +134,7 @@ chdir $startdir || die "chdir($startdir) failed: $!"; # back to raw
'context-construction-plan', "&MAKEcopy",
'context-degrade', "&MAKEcopy",
'context-french', "&MAKEcopy",
+ 'context-games', "&MAKEcopy",
'context-gnuplot', "&MAKEcopy",
'context-letter', "&MAKEcopy",
'context-lettrine', "&MAKEcopy",
diff --git a/Master/tlpkg/tlpsrc/collection-context.tlpsrc b/Master/tlpkg/tlpsrc/collection-context.tlpsrc
index d0d4ecbfa7b..456e9316c1a 100644
--- a/Master/tlpkg/tlpsrc/collection-context.tlpsrc
+++ b/Master/tlpkg/tlpsrc/collection-context.tlpsrc
@@ -13,6 +13,7 @@ depend context-chromato
depend context-construction-plan
depend context-degrade
depend context-french
+depend context-games
depend context-gnuplot
depend context-letter
depend context-lettrine
diff --git a/Master/tlpkg/tlpsrc/context-games.tlpsrc b/Master/tlpkg/tlpsrc/context-games.tlpsrc
new file mode 100644
index 00000000000..a3bc59cc8d8
--- /dev/null
+++ b/Master/tlpkg/tlpsrc/context-games.tlpsrc
@@ -0,0 +1,4 @@
+name context-games
+category Package
+runpattern d texmf-dist/tex/context/third/account
+