Module:Chessboard/sandbox: Difference between revisions

Content deleted Content added
No edit summary
No edit summary
Line 1:
local p = {}
 
function chessboard( positionargs, size, reverserev, letters, numbers, header, footer, align, clear)
function image_square( pc, row, col, size )
local colornames = { l = 'white', d = 'black' }
local piecenames = { plocal = 'pawn', rcolornames = 'rook',{ nl = 'knightwhite', bd = 'bishopblack', q = 'queen', k = 'king', a = 'archbishop',}
local piecenames = {
c = 'chancelor', z = 'champion', w = 'wizard', t = 'fool', h = 'upside-down pawn', m = 'upside-down rook',
p = 'pawn',
s = 'upside-down knight', f = 'upside-down king', e = 'upside-down bishop', g = 'upside-down queen'}
r = 'rook',
local symnames = { xx = 'black cross', ox = 'white cross', xo = 'black circle', oo = 'white circle',
n = 'knight',
ul = 'up-left arrow', ua = 'up arrow', ur = 'up-right arrow', la = 'left arrow', ra = 'right arrow',
b = 'bishop',
dl = 'down-left arrow', da = 'down arrow', dr = 'down-right arrow', lr = 'left-right arrow', ud = 'up-down arrow',
q = 'queen',
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 endk = 'king',
a = 'archbishop',
function filechar( file ) return ( "abcdefgh" ):sub( file, file ) end
c = 'chancelor',
function coord( ind ) return ( reverse and ( 8 - ind ) * size ) or ( ind - 1 ) * size end
z = 'champion',
w = 'wizard',
function piecediv( pc, row, file, res )
local color t = mw.ustring.gsub(pc,'^.*(%w)(%w).*$fool', '%2') or ''
local piece h = mw.ustring.gsub(pc,'^.*(%w)(%w).*$upside-down pawn', '%1') or ''
local alt = filechar(file) ..m rowchar(row) ..= 'upside-down rook',
s = 'upside-down knight',
if (colornames[color] and piecenames[piece]) then
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 colchar( col )
return ( 'abcdefgh' ):sub( col, col )
end
local color = mw.ustring.gsub( pc, '^.*(%w)(%w).*$', '%2' ) or ''
local piece = mw.ustring.gsub( pc, '^.*(%w)(%w).*$', '%1' ) or ''
local alt = colchar( col ) .. 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,return string.format( '<div[[File:Chess style="position:absolute;z-index:3;top:%dpx;left:s%st45.svg|%dx%dpx;">|alt=%s</div>|%s]]', coord(piece, rowcolor, )size, coord( filesize, )alt, img)alt )
end
 
function letters_row( rev, num_lt, num_rt )
local result = {}
local td = '<td style="padding: 0; vertical-align: inherit;height:18px;width:' .. size .. 'px;">'
table.insert(result, string.format([=[
local legends = 'abcdefgh'
<div class="chess-board" style="position:relative;">
local l = mw.text.split( rev and legends:reverse() or legends, '' )
[[File:Chessboard480.png|%dx%dpx|link=]]
return '<tr style="vertical-align:middle">\n'
]=], size * 8, size * 8))
.. ( num_lt and '<td style="vertical-align: inherit; padding: 0"></td>' or '' )
.. td
.. table.concat( l, '</td>' .. td )
.. '</td>'
.. ( num_rt and '<td style="vertical-align: inherit; padding: 0"></td>' or '' )
.. '\n</tr>'
end
local letters_tp = letters:match( 'both' ) or letters:match( 'top' )
local letters_bt = letters:match( 'both' ) or letters:match( 'bottom' )
local numbers_lt = numbers:match( 'both' ) or numbers:match( 'left' )
local numbers_rt = numbers:match( 'both' ) or numbers:match( 'right' )
local width = 8 * size + 2
if ( numbers_lt ) then width = width + 18 end
if ( numbers_rt ) then width = width + 18 end
 
forlocal rowb = 1,8 do''
local for filecaption = 1,8 do''
local piece = position[8*(row-1) + file]
if ( letters_tp ) then b = b .. letters_row( rev, numbers_lt, numbers_rt ) .. '\n' end
if piece
b = b .. '<tr style="vertical-align:middle">'
then
if ( numbers_lt ) then b = b .. '<td style="padding: 0; vertical-align: inherit; width:18px;height:' .. size .. 'px">' .. (rev and 1 or 8) .. '</td>' end
if (piece:match("%a%w"))
b = b .. '<td colspan=8 rowspan=8 style="padding: 0; vertical-align: inherit;"><div class="chess-board" style="position:relative;">'
then
b = b .. string.format( '[[File:Chessboard480.svg|%dx%dpx|link=]]', 8 * size, 8 * size )
piecediv( piece, row, file, result )
for trow = 1,8 do
local row = rev and trow or ( 9 - trow )
for tcol = 1,8 do
local col = rev and ( 9 - tcol ) or tcol
local piece = args[8 * ( 8 - row ) + col + 2] or ''
if piece:match( '%w%w' ) then
local img = image_square(piece:match('%w%w'), row, col, size )
b = b .. string.format(
'<div style="position:absolute;z-index:3;top:%dpx;left:%dpx;width:' .. size .. 'px;height:' .. size .. 'px;">%s</div>\n',
( trow - 1 ) * size, ( tcol - 1 ) * size, img )
end
end
end
b = b .. '</div></td>'
if ( numbers_rt ) then b = b .. '<td style="width:18px;height:' .. size ..'px;padding:0">' .. (rev and 1 or 8) .. '</td>' end
b = b .. '</tr>'
if ( numbers_lt or numbers_rt ) then
for trow = 2, 8 do
local row = rev and trow or ( 9 - trow )
b = b .. '<tr style="vertical-align:middle">'
if ( numbers_lt ) then b = b .. '<td style="padding: 0; vertical-align: inherit;height:' .. size .. 'px">' .. row .. '</td>' end
if ( numbers_rt ) then b = b .. '<td style="padding: 0; vertical-align: inherit;height:' .. size .. 'px">' .. row .. '</td>' end
b = b .. '</tr>\n'
end
end
if ( letters_bt ) then b = b .. letters_row( rev, numbers_lt, numbers_rt ) .. '\n' end
table.insert(result, '</div>')
 
return result
if footer:match( '^%s*$' )
then
else
caption = '<div class="thumbcaption">' .. footer .. '</div>\n'
end
return '<div class="thumb ' .. align .. '" style="clear:' .. clear .. '; text-align:center;">'
.. header .. '\n<div class="thumbinner" style="width:' .. width .. 'px;">\n'
.. '<table cellpadding=0 cellspacing=0 style="background:white; font-size:88%; border:1px #b0b0b0 solid; padding:0; '
.. 'margin:auto;">\n' .. b .. '\n</table>\n' .. caption .. '</div></div>'
end
 
function convertFenToPositionconvertFenToArgs( fen )
-- converts FEN notation to 64 entry array of positions, offset by 2
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
then -- if a digitfor k=1,piece do
for k=1 table.insert(res,piece' do')
table.insert(res,' ')end
end
else -- not a digit
local color = piece:match( '%u' ) and 'l' or 'd'
piece = piece:lower()
table.insert( res, piece .. color )
end
end
Line 72 ⟶ 155:
end
 
function convertArgsToPositionconvertArgsToFen( 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 )
Line 106 ⟶ 176:
local args = frame.args
local pargs = frame:getParent().args
local size = (args.size or pargs.size) or '26px26'
local reverse = ( (args.reverse or pargs.reverse) or '' ):lower() == "true"
local letters = ( args.letters or pargs.letters or 'both' ):lower()
local numbers = ( args.numbers or pargs.numbers or 'both' ):lower()
local header = args[2] or pargs[2] or ''
local footer = args[67] or pargs[67] or ''
local align = ( args[1] or pargs[1] or 'tright' ):lower()
local clear = args.clear or pargs.clear or ( align:match('tright') and 'right' ) or 'none'
local fen = args.fen or pargs.fen
local offset = 0
size = mw.ustring.match( size, '[%d]+' ) or '26' -- remove px from size
local position = {}
if (fen) then
 
align = args.align or pargs.align or 'tright'
size = mw.ustring.gsub(size, '^[^%d]*(%d[%d]*)[^%d]*$', '%1') -- remove px from size
clear = args.clear or pargs.clear or ( align:match('tright') and 'right' ) or 'none'
header = args.header or pargs.header or ''
if (fen)
footer = args.footer or pargs.footer or ''
then
return chessboard( convertFenToArgs( fen ), size, reverse, letters, numbers, header, footer, align, clear )
position = convertFenToPosition( fen )
else end
if args[3] then
position = convertArgsToPosition( pargs, 2)
return chessboard(args, size, reverse, letters, numbers, header, footer, align, clear)
else
return chessboard(pargs, size, reverse, letters, numbers, header, footer, align, clear)
end
 
return table.concat( chessboard(position, size, reverse), "\n")
end
 
function p.fen2ascii(frame)
-- {{#invoke:Chessboard|fen2ascii|fen=...}}
local b = convertFenToPositionconvertFenToArgs( frame.args.fen )
local res = '|=\n'
local offset = 2
for row = 1,8 do
local n = (9 - row)
res = res .. n .. ' |' ..
table.concat(b, '|', 8*(row-1) + 1 + offset, 8*(row-1) + 8 + offset) .. '|=\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 convertPositionToFenconvertArgsToFen( frame.args, frame.args.offset or 1 )
end