Jump to content

Module:Chessboard/sandbox

From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by Frietjes (talk | contribs) at 17:25, 11 May 2013 (testing). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.
(diff) ← Previous revision | Latest revision (diff) | Newer revision → (diff)
local p = {}

function chessboard( fen, size, reverse )
    local piecenames = { p = 'Pawn', r = 'Rook', n = 'Knight', b = 'Bishop', q = 'Queen', k = 'King' }
    local colornames = { l = 'White', d = 'Black' }

    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( piece, row, file, res )
        local color = piece:match( '%u' ) and 'l' or 'd'
        piece = piece:lower()
        local alt =  string.format("%s%s %s %s", filechar( file ), rowchar( row ), colornames[color], piecenames[piece] or piece)
        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

    function oneRow( s, row, res )
        local file = 1
        for piece in s:gmatch( "%w" ) do -- if a digit, increment "file" by the digit. else, add the piece _and_ increment file by 1
            file = file + ( piece:match("%d") or piecediv( piece, row, file, res ) or 1 )
        end
    end

    local result = {}
	table.insert(result, string.format([=[
<div class="chess-fen" style="position:relative;">
[[File:Chessboard480.png|%dx%dpx|link=]]
	]=], size * 8, size * 8))

    local row = 0
    for srow in string.gmatch("/" .. fen, "/%w+") do
        row = row + 1
        oneRow(srow, row, result)
    end
    table.insert(result, '</div>')
    return result
end

--[[
this function is to be used only from Template:Chess diagram. 
it provides part of the FEN string - the part that describes the board itself.
unfortunately, the template does not carry enough information to create the 2nd
part of the FEN, which includes information about whose turn is it, en-passant state,
castling, etc.
]]
function diagramToFen( args )
    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 = ''
    for row = 0, 7 do
        for file = 0, 7 do
            res = res .. piece( args[3 + row * 8 + file] )
        end
        if row < 7 then res = res .. '/' end
    end
    return ( res.gsub('1+', function( s ) return #s end ) )
end

function p.board(frame)
	local args = frame.args
    local size = args.size or 30
    local reverse = ( args.reverse or '' ):lower() == "true"
    local result = ''

    if args.fen 
      then result = table.concat(chessboard( args.fen, size, reverse ), "\n")
      else result = table.concat(chessboard( diagramToFen(args), size, reverse), "\n")
    end
    
    return result
end