Zum Inhalt springen

Modul:Schachbrett

aus Wikipedia, der freien Enzyklopädie
Dies ist eine alte Version dieser Seite, zuletzt bearbeitet am 15. Mai 2013 um 21:28 Uhr durch Frietjes (Diskussion | Beiträge) (align). Sie kann sich erheblich von der aktuellen Version unterscheiden.

Die Dokumentation für dieses Modul kann unter Modul:Schachbrett/Doku erstellt werden

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

function convertArgsToPosition( 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 ) 
        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 '26px'
    local reverse = ( (args.reverse or pargs.reverse) or '' ):lower() == "true"
    local fen = args.fen or pargs.fen
    local offset = 0
    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, 2)
    end

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

function p.fen2ascii(frame)
    -- {{#invoke:Chessboard|fen2ascii|fen=...}}
    local b = convertFenToPosition( frame.args.fen )
    local res = '|=\n'
    for row = 1,8 do
        local n = (9 - row)
        res = res .. n .. ' |' .. table.concat(b, '|', 8*(row-1) + 1, 8*(row-1) + 8) .. '|=\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 convertPositionToFen( frame.args, frame.args.offset or 1 )
end

return p