Module:Chessboard
Εμφάνιση
Τεκμηρίωση module[δημιουργία] [ανανέωση]
local p = {}
function chessboard(args, size, rev, letters, numbers, header, footer, align, clear)
function image_square( pc, row, col, size )
local piecenames = {
p = 'πιόνι', --σ
r = 'πύργος', --π
n = 'ίππος', --ι
b = 'αξιωματικός', --α
q = 'βασίλισσα', --β
k = 'βασιλιάς', --ρ
a = 'αρχηγός', --χ ο=ανεστραμμένος (δεσμευμένο για πιθανή μελλοντική χρήση)
c = 'καγγελάριος', --κ λ=ανεστραμμένος
z = 'πρωταθλητής', --ω θ=ανεστραμμένος
w = 'μάγος', --μ δ=ανεστραμμένος
t = 'τρελλός', --τ υ=ανεστραμμένος
e = 'ελέφαντας', --ε
s = 'πλοίο', --ψ
h = 'ανεστραμμένο πιόνι', --η
m = 'ανεστραμμένος πύργος', --ζ
N = 'ανεστραμμένος ίππος', --ν
j = 'ανεστραμμένος αξιωματικός',--ξ
g = 'ανεστραμμένη βασίλισσα', --γ
f = 'ανεστραμμένος βασιλιάς' --φ ς=u=μονόκερος (δεσμευμένο για μελλοντική χρήση)
}
local symnames = {
xx = 'μαύρο χι', --χχ
ox = 'λευκό χι', --οχ
xo = 'μαύρος κύκλος', --χο
oo = 'λευκός κύκλος', --οο
ud = 'τόξο πάνω-κάτω', --τ0
dl = 'τόξο κάτω-αριστερά', --τ1
da = 'τόξο κάτω', --τ2
dr = 'τόξο κάτω-δεξιά', --τ3
la = 'τόξο αριστερά', --τ4
lr = 'τόξο αριστερά-δεξιά', --τ5
ra = 'τόξο δεξιά', --τ6
ul = 'τόξο πάνω-αριστερά', --τ7
ua = 'τόξο πάνω', --τ8
ur = 'τόξο πάνω-δεξιά', --τ9
x0 = 'μηδέν', --χ0
x1 = 'ένα', --χ1
x2 = 'δύο', --χ2
x3 = 'τρία', --χ3
x4 = 'τέσσερα', --χ4
x5 = 'πέντε', --χ5
x6 = 'έξι', --χ6
x7 = 'επτά', --χ7
x8 = 'οκτώ', --χ8
x9 = 'εννιά' --χ9
}
local colornames_m = {
l = 'λευκός', --λ
d = 'μαύρος', --μ
L = 'λευκός', --Λ
D = 'μαύρος', --Μ
r = 'κόκκινος', --κ
g = 'πράσινος', --π
b = 'μπλε', --ε
y = 'κίτρινος', --ι
}
local colornames_f = {
l = 'λευκή', --λ
d = 'μαύρη', --μ
L = 'λευκή', --Λ
D = 'μαύρη', --Μ
r = 'κόκκινη', --κ
g = 'πράσινη', --π
b = 'μπλε', --ε
y = 'κίτρινη', --ι
}
local colornames_u = {
l = 'λευκό', --λ
d = 'μαύρο', --μ
L = 'λευκό', --Λ
D = 'μαύρο', --Μ
r = 'κόκκινο', --κ
g = 'πράσινο', --π
b = 'μπλε', --ε
y = 'κίτρινο', --ι
}
function colornames( color, piece )
if mw.ustring.find( 'phs', piece, 1 ) then
return colornames_u[color]
elseif mw.ustring.find( 'qg', piece, 1 ) then
return colornames_f[color]
else
return colornames_m[color]
end
end
function is_color( color )
return ( color == '' ) and nil or ( mw.ustring.find( 'ldLDrgby', color, 1 ) )
end
function convert_color( color )
if color == '' then
return ''
else
local i = mw.ustring.find( 'λμΛΜκπει', color, 1 ) --λευκά, μαύρα, κόκκινα, πράσινα, μπλε, κίτρινα (τα κεφαλαία για τύπο ΜΜ)
if ( i ) then
return mw.ustring.sub( 'ldLDrgby', i, i ) --light, dark, red, green, blue, yellow
else
return color
end
end
end
function convert_piece( piece )
if piece == '' then
return ''
else
local i = mw.ustring.find( 'σπιαβρχκωμτηζνξγφεψ', piece, 1 ) --τα 'δλθους' είναι δεσμευμένα
if ( i ) then
return mw.ustring.sub( 'prnbqkaczwthmNjgfes', i, i ) --τα 'dilouvxy' είναι δεσμευμένα
else
return piece
end
end
end
function colchar( col )
return mw.ustring.sub( 'αβγδεζηθ', col, col )
end
local piece = mw.ustring.len( pc ) == 2 and mw.ustring.sub( pc, 1 , 1 ) or ''
local color = mw.ustring.len( pc ) == 2 and mw.ustring.sub( pc, 2 , 2 ) or ''
local tmp = piece .. color
local alt = colchar( col ) .. row .. ' '
local idx = mw.ustring.find( 'τ0 τ1 τ2 τ3 τ4 τ5 τ6 τ7 τ8 τ9 χχ χο οχ οο',
( piece == '' and 'x' or piece ) .. ( color == '' and 'x' or color ), 1 )
if idx then
piece = mw.ustring.sub( 'ud dl da dr la lr ra ul ua ur xx xo ox oo', idx, idx )
color = mw.ustring.sub( 'ud dl da dr la lr ra ul ua ur xx xo ox oo', idx + 1, idx + 1 )
else
idx = mw.ustring.find( '1234567890', ( color == '' and 'x' or color ), 1 )
if idx then
if piece:match( 'χ' ) then piece = 'x' else idx = nil end
end
if idx
then
else
piece = convert_piece( piece )
color = convert_color( color )
end
end
idx = 't45.svg'
if piecenames[piece] and is_color( color ) then
alt = alt .. colornames( color, piece ) .. ' ' .. piecenames[piece]
if color:match( 'L' ) or color:match( 'D' ) then
idx = piece
piece = 'Maurizio Monge Fantasy ' .. ( color:match( 'L' ) and 'w' or 'b' )
color = idx
idx = '.svg' --Chess Maurizio Monge Fantasy wb.svg
end
else
alt = alt .. ( symnames[piece .. color] or tmp )
end
return string.format( '[[File:Chess %s%s%s|%dx%dpx|alt=%s|%s]]', piece, color, idx, size, size, alt, alt )
end
function letters_row( rev, num_lt, num_rt )
local td = '<td style="padding: 0; vertical-align: inherit;height:18px;width:' .. size .. 'px;">'
local l = { 'α', 'β', 'γ', 'δ', 'ε', 'ζ', 'η', 'θ' }
local r = { 'θ', 'η', 'ζ', 'ε', 'δ', 'γ', 'β', 'α' }
return '<tr style="vertical-align:middle">\n'
.. ( num_lt and '<td style="vertical-align: inherit; padding: 0"></td>' or '' )
.. td
.. table.concat( rev and r or 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
local b = ''
local caption = ''
if ( letters_tp ) then b = b .. letters_row( rev, numbers_lt, numbers_rt ) .. '\n' end
b = b .. '<tr style="vertical-align:middle">'
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
b = b .. '<td colspan=8 rowspan=8 style="padding: 0; vertical-align: inherit;"><div class="chess-board" style="position:relative;">'
b = b .. string.format( '[[File:Chessboard480.svg|%dx%dpx|link=]]', 8 * size, 8 * size )
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 ''
local img = image_square(piece, 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
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
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
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 convertFenToArgs( 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
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 convertArgsToFen( args, offset )
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 '26'
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
size = mw.ustring.match( size, '[%d]+' ) or '26' -- remove px from size
if (fen) then
align = args.align or pargs.align or 'tright'
clear = args.clear or pargs.clear or ( align:match('tright') and 'right' ) or 'none'
header = args.header or pargs.header or ''
footer = args.footer or pargs.footer or ''
return chessboard( convertFenToArgs( fen ), size, reverse, letters, numbers, header, footer, align, clear )
end
if args[3] then
return chessboard(args, size, reverse, letters, numbers, header, footer, align, clear)
else
return chessboard(pargs, size, reverse, letters, numbers, header, footer, align, clear)
end
end
function p.fen2ascii(frame)
-- {{#invoke:Chessboard|fen2ascii|fen=...}}
local b = convertFenToArgs( 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 .. ' α β γ δ ε ζ η θ'
return res
end
function p.ascii2fen( frame )
-- {{#invoke:Chessboard|ascii2fen|kl| | |....}}
return convertArgsToFen( frame.args, frame.args.offset or 1 )
end
return p