Difference between revisions of "Module:Chessboard/sandbox"

From blackwiki
Jump to navigation Jump to search
blackwiki>Frietjes
blackwiki>Frietjes
Line 1: Line 1:
 
local p = {}
 
local p = {}
  
function chessboard( position, size, reverse )
+
function chessboard( position, size, reverse, offset)
 
     local piecenames = { p = 'Pawn', r = 'Rook', n = 'Knight', b = 'Bishop', q = 'Queen', k = 'King' }
 
     local piecenames = { p = 'Pawn', r = 'Rook', n = 'Knight', b = 'Bishop', q = 'Queen', k = 'King' }
 
     local colornames = { l = 'White', d = 'Black' }
 
     local colornames = { l = 'White', d = 'Black' }
Line 23: Line 23:
 
]=], size * 8, size * 8))
 
]=], size * 8, size * 8))
  
 +
    offset = offset or 0
 
     for row = 1,8 do
 
     for row = 1,8 do
 
       for file = 1,8 do
 
       for file = 1,8 do
           local piece = position[8*(row-1) + file]
+
           local piece = position[8*(row-1) + file + offset]
 
           if piece
 
           if piece
 
           then
 
           then
Line 37: Line 38:
 
     table.insert(result, '</div>')
 
     table.insert(result, '</div>')
 
     return result
 
     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
 
end
  
Line 74: Line 63:
 
end
 
end
  
--[[
+
function convertPositionToFen( position, offset )
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 nullOrWhitespace( s ) return not s or s:match( '^%s*(.-)%s*$' ) == '' end
 
     function piece( s )  
 
     function piece( s )  
Line 89: Line 71:
 
      
 
      
 
     local res = ''
 
     local res = ''
     for row = 0, 7 do
+
    offset = offset or 0
         for file = 0, 7 do
+
     for row = 1, 8 do
             res = res .. piece( args[3 + row * 8 + file] )
+
         for file = 1, 8 do
 +
             res = res .. piece( position[8*(row - 1) + file + offset] )
 
         end
 
         end
         if row < 7 then res = res .. '/' end
+
         if row < 8 then res = res .. '/' end
 
     end
 
     end
 
     return mw.ustring.gsub(res, '1+', function( s ) return #s end )
 
     return mw.ustring.gsub(res, '1+', function( s ) return #s end )
Line 104: Line 87:
 
     local reverse = ( (args.reverse or pargs.reverse) or '' ):lower() == "true"
 
     local reverse = ( (args.reverse or pargs.reverse) or '' ):lower() == "true"
 
     local fen = args.fen or pargs.fen
 
     local fen = args.fen or pargs.fen
 +
    local offset = 0
 
     local position = {}
 
     local position = {}
  
Line 109: Line 93:
 
      
 
      
 
     if (fen)  
 
     if (fen)  
       then position = convertFenToPosition( fen )
+
       then  
       else position = convertArgsToPosition( pargs )
+
          position = convertFenToPosition( fen )
 +
       else  
 +
          position = pargs
 +
          offset = 2
 
     end
 
     end
  
Line 119: Line 106:
 
     local b = convertFenToPosition( frame.args.fen )
 
     local b = convertFenToPosition( frame.args.fen )
 
     local res = ''
 
     local res = ''
     for row = 0,7 do
+
     for row = 1,8 do
         res = res .. '|' .. table.concat(b, '|', 8*row + 1, 8*row + 8) .. '|=\n'
+
         res = res .. '|' .. table.concat(b, '|', 8*(row-1) + 1, 8*(row-1) + 8) .. '|=\n'
 
     end
 
     end
 
     res = mw.ustring.gsub(res,'\| \|', '|  |')
 
     res = mw.ustring.gsub(res,'\| \|', '|  |')
 
     res = mw.ustring.gsub(res,'\| \|', '|  |')
 
     res = mw.ustring.gsub(res,'\| \|', '|  |')
 
     return res
 
     return res
 +
end
 +
 +
function p.ascii2fen(frame)
 +
    return diagramToFen( frame.args, frame.args.offset or 1 )
 
end
 
end
  
 
return p
 
return p

Revision as of 15:59, 15 May 2013

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

local p = {}

function chessboard( position, size, reverse, offset)
    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))

    offset = offset or 0
    for row = 1,8 do
       for file = 1,8 do
          local piece = position[8*(row-1) + file + offset]
          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 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 convertPositionToFen( position, 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( position[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 = pargs
          offset = 2
    end

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

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

function p.ascii2fen(frame)
    return diagramToFen( frame.args, frame.args.offset or 1 )
end

return p