Modul:Chess
This module provides various function to be used in Chess templates. The functions can be called with {{#invoke:Chess|functionname|arguments}}
.
local p = {};
local function pagename2pgn()
local pagename = mw.title.getCurrentTitle().text
if pagename:sub(1, 23) == "Chess Opening Theory/1." then
return pagename:sub(22):gsub("/", " "):gsub("[0-9]+%.%.%.", "")
else
return ''
end
end
function p.pagename2pgn( frame )
local pgn = frame.args[1] or ''
if pgn == '' then
pgn = pagename2pgn()
end
local enc = mw.uri.encode( pgn )
return string.format( '[https://lichess.org/analysis/pgn/%s %s]', enc, pgn )
end
-- Determines whether it's White's or Black's turn. Returns ' w' if arg contains
-- three dots, ' b' if arg contains one dot, or '' otherwise.
local function whoseTurn( subpagename )
local _, count = subpagename:gsub( "%.", "" )
if count == 3 then
return " w" -- White
elseif count == 1 then
return " b" -- Black
else
return ""
end
end
-- From [[w:Module:Chessboard]].
-- Generates "rnbqkbnr/pppp1ppp/8/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R b" if args =
-- {'rd','nd','bd','qd','kd','bd','nd','rd',
-- 'pd','pd','pd','pd',' ','pd','pd','pd',
-- ' ',' ',' ',' ',' ',' ',' ',' ',
-- ' ',' ',' ',' ','pd',' ',' ',' ',
-- ' ',' ',' ',' ','pl',' ',' ',' ',
-- ' ',' ',' ',' ',' ','nl',' ',' ',
-- 'pl','pl','pl','pl',' ','pl','pl','pl',
-- 'rl','nl','bl','ql','kl','bl',' ','rl',}
local function convertArgsToFen( args, offset )
local function nullOrWhitespace( s ) return not s or s:match( '^%s*(.-)%s*$' ) == '' end
local 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 = ''
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
res = mw.ustring.gsub( res, '1+', function( s ) return #s end )
return res .. whoseTurn( mw.title.getCurrentTitle().subpageText )
end
-- From [[w:Module:Chessboard]].
-- Inverse function of convertArgsToFen
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 p.ascii2fen( frame )
local pargs = frame:getParent().args
local fen
if pargs[3] then
fen = convertArgsToFen( pargs, 2 )
else
local moves = require('Module:Pgn2fen').pgn2fen( pagename2pgn() )
fen = moves[#moves]
end
local enc = mw.uri.encode( fen, 'WIKI' )
return string.format('[https://lichess.org/analysis/standard/%s#explorer %s]', enc, fen)
end
function p.board( frame )
local pargs = frame:getParent().args
if pargs[3] then
return frame:expandTemplate{ title='Chess diagram', args=pargs }
else
local moves = require('Module:Pgn2fen').pgn2fen( pagename2pgn() )
local fen = moves[#moves]
if fen and fen ~= '' then
return frame:expandTemplate{ title='Chess diagram', args=convertFenToArgs(fen) }
end
end
end
return p