Difference between revisions of "Module:Chessboard/sandbox"

From blackwiki
Jump to navigation Jump to search
blackwiki>Frietjes
blackwiki>Frietjes
Line 19: Line 19:
 
     local result = {}
 
     local result = {}
 
table.insert(result, string.format([=[
 
table.insert(result, string.format([=[
<div class="chess-fen" style="position:relative;">
+
<div class="chess-board" style="position:relative;">
 
[[File:Chessboard480.png|%dx%dpx|link=]]
 
[[File:Chessboard480.png|%dx%dpx|link=]]
 
]=], size * 8, size * 8))
 
]=], size * 8, size * 8))
Line 40: Line 40:
  
 
function convertArgsToPosition( args )
 
function convertArgsToPosition( args )
 +
    -- copies args[3] to args[66] into a 64 entry array of positions
 
     local res = {}
 
     local res = {}
 
     for row = 1,8 do
 
     for row = 1,8 do
Line 51: Line 52:
  
 
function convertFenToPosition( fen )
 
function convertFenToPosition( fen )
 +
    -- converts FEN notation to 64 entry array of positions
 
     local res = {}
 
     local res = {}
 
     -- Loop over rows, which are delimited by /
 
     -- Loop over rows, which are delimited by /
Line 110: Line 112:
 
       else position = convertArgsToPosition( pargs )
 
       else position = convertArgsToPosition( pargs )
 
     end
 
     end
--    return table.concat( position, '|')
+
 
 
     return table.concat( chessboard(position, size, reverse), "\n")
 
     return table.concat( chessboard(position, size, reverse), "\n")
 
end
 
end

Revision as of 20:01, 14 May 2013

Documentation for this module may be created at Module:Chessboard/sandbox/doc

local p = {}

function chessboard( position, 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 = mw.ustring.gsub(piece,'^.*(%w)(%w).*$', '%2')
        piece = mw.ustring.gsub(piece,'^.*(%w)(%w).*$', '%1')
        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

    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%a"))
            then
              piecediv( piece, row, file, result )
            end
          end
       end
    end
    table.insert(result, '</div>')
    return result
end

function convertArgsToPosition( args )
    -- copies args[3] to args[66] into a 64 entry array of positions
    local res = {}
    for row = 1,8 do
        for col = 1,8 do
            table.insert(res, args[8*(row-1) + col + 2])
        end
    end
    
    return res
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

--[[
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 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 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 )
    end

    return table.concat( chessboard(position, size, reverse), "\n")
end

function p.fen2ascii(frame)
    local b = convertFenToPosition( frame.args.fen )
    local res = ''
    for row = 0,7 do
        res = res .. '|' .. table.concat(b, '|', 8*row + 1, 8*row + 8) .. '|=\n'
    end
    res = mw.ustring.gsub(res,'\| \|', '|  |')
    res = mw.ustring.gsub(res,'\| \|', '|  |')
    return res
end

return p