Die Dokumentation für dieses Modul kann unter Modul:Schachbrett/Doku erstellt werden
local p = {}
function chessboard( position, size, reverse)
local colornames = { l = 'White', d = 'Black' }
local piecenames = { p = 'pawn', r = 'rook', n = 'knight', b = 'bishop', q = 'queen', k = 'king', a = 'archbishop',
c = 'chancelor', z = 'champion', w = 'wizard', t = 'fool', h = 'upside-down pawn', m = 'upside-down rook',
s = 'upside-down knight', f = 'upside-down king', e = 'upside-down bishop', g = 'upside-down queen'}
local symnames = { xx = 'black cross', ox = 'white cross', xo = 'black circle', oo = 'white circle',
ul = 'up-left arrow', ua = 'up arrow', ur = 'up-right arrow', la = 'left arrow', ra = 'right arrow',
dl = 'down-left arrow', da = 'down arrow', dr = 'down-right arrow', lr = 'left-right arrow', ud = 'up-down arrow',
x0='zero', x1='one', x2='two', x3='three', x4='four', x5='five', x6='six', x7='seven', x8='eight', x9='nine'}
function rowchar( row ) return 9 - row end
function filechar( file ) return ( "abcdefgh" ):sub( file, file ) end
function coord( ind ) return ( reverse and ( 8 - ind ) * size ) or ( ind - 1 ) * size end
function piecediv( pc, row, file, res )
local color = mw.ustring.gsub(pc,'^.*(%w)(%w).*$', '%2') or ''
local piece = mw.ustring.gsub(pc,'^.*(%w)(%w).*$', '%1') or ''
local alt = filechar(file) .. rowchar(row) .. ' '
if (colornames[color] and piecenames[piece]) then
alt = alt .. colornames[color] .. ' ' .. piecenames[piece]
else
alt = alt .. (symnames[ piece .. color ] or (piece .. ' ' .. color))
end
local img = string.format('[[File:Chess %s%st45.svg|%dx%dpx|alt=%s|%s]]', piece, color, size, size, alt, alt)
table.insert( res, string.format('<div style="position:absolute;z-index:3;top:%dpx;left:%dpx;">%s</div>', coord( row ), coord( file ), img) )
end
local result = {}
table.insert(result, string.format([=[
<div class="chess-board" style="position:relative;">
[[File:Chessboard480.png|%dx%dpx|link=]]
]=], size * 8, size * 8))
for row = 1,8 do
for file = 1,8 do
local piece = position[8*(row-1) + file]
if piece
then
if (piece:match("%a%w"))
then
piecediv( piece, row, file, result )
end
end
end
end
table.insert(result, '</div>')
return result
end
function convertFenToPosition( fen )
-- converts FEN notation to 64 entry array of positions
local res = {}
-- Loop over rows, which are delimited by /
for srow in string.gmatch("/" .. fen, "/%w+") do
-- Loop over all letters and numbers in the row
for piece in srow:gmatch( "%w" ) do
if (piece:match("%d"))
then -- if a digit
for k=1,piece do
table.insert(res,' ')
end
else -- not a digit
local color = piece:match( '%u' ) and 'l' or 'd'
piece = piece:lower()
table.insert(res, piece .. color )
end
end
end
return res
end
function convertArgsToPosition( args, offset )
-- copies args to 64 entry array of positions
local res = {}
-- Loop over rows, which are delimited by /
for row = 1,8 do
for file = 1,8 do
table.insert(res, args[8*(row-1) + file + offset])
end
end
return res
end
function convertPositionToFen( args, offset )
-- converts a position array to Fen
function nullOrWhitespace( s ) return not s or s:match( '^%s*(.-)%s*$' ) == '' end
function piece( s )
return nullOrWhitespace( s ) and 1
or s:gsub( '%s*(%a)(%a)%s*', function( a, b ) return b == 'l' and a:upper() or a end )
end
local res = ''
offset = offset or 0
for row = 1, 8 do
for file = 1, 8 do
res = res .. piece( args[8*(row - 1) + file + offset] )
end
if row < 8 then res = res .. '/' end
end
return mw.ustring.gsub(res, '1+', function( s ) return #s end )
end
function p.board(frame)
local args = frame.args
local pargs = frame:getParent().args
local size = (args.size or pargs.size) or '26px'
local reverse = ( (args.reverse or pargs.reverse) or '' ):lower() == "true"
local fen = args.fen or pargs.fen
local offset = 0
local position = {}
size = mw.ustring.gsub(size, '^[^%d]*(%d[%d]*)[^%d]*$', '%1') -- remove px from size
if (fen)
then
position = convertFenToPosition( fen )
else
position = convertArgsToPosition( pargs, 2)
end
return table.concat( chessboard(position, size, reverse), "\n")
end
function p.fen2ascii(frame)
-- {{#invoke:Chessboard|fen2ascii|fen=...}}
local b = convertFenToPosition( frame.args.fen )
local res = '|=\n'
for row = 1,8 do
local n = (9 - row)
res = res .. n .. ' |' .. table.concat(b, '|', 8*(row-1) + 1, 8*(row-1) + 8) .. '|=\n'
end
res = mw.ustring.gsub(res,'\| \|', '| |')
res = mw.ustring.gsub(res,'\| \|', '| |')
res = res .. ' a b c d e f g h'
return res
end
function p.ascii2fen(frame)
-- {{#invoke:Chessboard|ascii2fen|kl|....}}
return convertPositionToFen( frame.args, frame.args.offset or 1 )
end
return p