Documentation[voir] [modifier] [historique] [purger]

Utilisation modifier

Fonctions exportables :

  • board(frame) – affiche un échiquier à partir d'une position des pièces fournie sous forme de tableau (précisions ci-dessous).
  • fen2ascii(frame) – convertit une notation FEN en une position des pièces fournie sous forme de tableau.
  • ascii2fen(frame) – convertit une position des pièces fournie sous forme de tableau en une notation FEN.

Autres fonctions : Sans objet

Modules externes et autres éléments dont ce module a besoin pour fonctionner : Sans objet

board( frame ) modifier

Paramètres modifier

  • 1 ou align - alignement - alignement de l'échiquier, tleft, tright.
  • 2 ou header - titre - titre de l'échiquier.
  • 3 à 66 (pour un échiquier 8x8) - case - contenu de chaque case (de a8 à h1).
  • 67 (pour un échiquier 8x8) ou footer - explications - texte affiché sous l'échiquier.
  • fen - notation FEN - en remplacement des paramètres 3 à 66
  • size - taille des cases
  • width - nombre de cases de l’échiquier en largeur (8 par défaut)
  • height - nombre de cases de l’échiquier en hauteur (8 par défaut)
  • reverse - true pour afficher les pièces à l'envers
  • letters - endroit où afficher les lettres repérant les colonnes (top, bottom ou both)
  • numbers - endroit où afficher les numéros repérant les lignes (left, right ou both)

Exemple modifier

abcdefgh
8
Tour noire sur case blanche a8
Cavalier noir sur case noire b8
Fou noir sur case blanche c8
Dame noire sur case noire d8
Roi noir sur case blanche e8
Fou noir sur case noire f8
Tour noire sur case noire h8
Pion noir sur case blanche b7
Pion noir sur case noire e7
Pion noir sur case blanche f7
Pion noir sur case noire g7
Pion noir sur case blanche h7
Pion noir sur case blanche a6
Pion noir sur case noire d6
Cavalier noir sur case noire f6
Cavalier blanc sur case noire d4
Pion blanc sur case blanche e4
Cavalier blanc sur case noire c3
Pion blanc sur case blanche a2
Pion blanc sur case noire b2
Pion blanc sur case blanche c2
Pion blanc sur case noire f2
Pion blanc sur case blanche g2
Pion blanc sur case noire h2
Tour blanche sur case noire a1
Fou blanc sur case noire c1
Dame blanche sur case blanche d1
Roi blanc sur case noire e1
Fou blanc sur case blanche f1
Tour blanche sur case blanche h1
8
77
66
55
44
33
22
11
abcdefgh
Variante Najdorf. Position après 5...a6.
{{#invoke:Échiquier|board
| tright
|
|rd|nd|bd|qd|kd|bd|  |rd
|  |pd|  |  |pd|pd|pd|pd
|pd|  |  |pd|  |nd|  |  
|  |  |  |  |  |  |  |  
|  |  |  |nl|pl|  |  |  
|  |  |nl|  |  |  |  |  
|pl|pl|pl|  |  |pl|pl|pl
|rl|  |bl|ql|kl|bl|  |rl
|Variante Najdorf. Position après 5...a6.}}
abcdefgh
8
Tour noire sur case blanche a8
Cavalier noir sur case noire b8
Fou noir sur case blanche c8
Dame noire sur case noire d8
Roi noir sur case blanche e8
Fou noir sur case noire f8
Tour noire sur case noire h8
Pion noir sur case blanche b7
Pion noir sur case noire e7
Pion noir sur case blanche f7
Pion noir sur case noire g7
Pion noir sur case blanche h7
Pion noir sur case blanche a6
Pion noir sur case noire d6
Cavalier noir sur case noire f6
Cavalier blanc sur case noire d4
Pion blanc sur case blanche e4
Cavalier blanc sur case noire c3
Pion blanc sur case blanche a2
Pion blanc sur case noire b2
Pion blanc sur case blanche c2
Pion blanc sur case noire f2
Pion blanc sur case blanche g2
Pion blanc sur case noire h2
Tour blanche sur case noire a1
Fou blanc sur case noire c1
Dame blanche sur case blanche d1
Roi blanc sur case noire e1
Fou blanc sur case blanche f1
Tour blanche sur case blanche h1
8
77
66
55
44
33
22
11
abcdefgh
Variante Najdorf. Position après 5...a6.
{{#invoke:Échiquier|board
| tright
|fen=rnbqkb1r/1p2pppp/p2p1n2/8/3NP3/2N5/PPP2PPP/R1BQKB1R14
|footer=Variante Najdorf. Position après 5...a6.
}}

ascii2fen( frame ) modifier

Paramètres modifier

  • 1 -
  • 2 à 65 - case - contenu de chaque case (de a8 à h1).

Exemple modifier

{{#invoke:Échiquier|ascii2fen|
|rd|nd|bd|qd|kd|bd|  |rd
|  |pd|  |  |pd|pd|pd|pd
|pd|  |  |pd|  |nd|  |  
|  |  |  |  |  |  |  |  
|  |  |  |nl|pl|  |  |  
|  |  |nl|  |  |  |  |  
|pl|pl|pl|  |  |pl|pl|pl
|rl|  |bl|ql|kl|bl|  |rl
}}

Résultat : rnbqkb1r/1p2pppp/p2p1n2/8/3NP3/2N5/PPP2PPP/R1BQKB1R14

fen2ascii( frame ) modifier

Paramètres modifier

  • fen - notation FEN.

Exemple modifier

{{#invoke:Échiquier|fen2ascii
|fen=rnbqkb1r/1p2pppp/p2p1n2/8/3NP3/2N5/PPP2PPP/R1BQKB1R14
}}
|rd|nd|bd|qd|kd|bd|  |rd
|  |pd|  |  |pd|pd|pd|pd
|pd|  |  |pd|  |nd|  | 
|  |  |  |  |  |  |  | 
|  |  |  |nl|pl|  |  | 
|  |  |nl|  |  |  |  | 
|pl|pl|pl|  |  |pl|pl|pl
|rl|  |bl|ql|kl|bl|  |rl


local p = {}

-- Construit le commentaire associé à une case vide
--
-- Paramètres:
--  -row: numéro de ligne de l'échiquier
--  -col: numéro de colonne de l'échiquier
--  -colchar: lettres des colonnes
local function comment_empty( row, col, colchar )
	if ((row + col) % 2 == 1) then
		return 'Case blanche ' .. colchar[col] .. row .. ' vide'
	else
		return 'Case noire ' .. colchar[col] .. row .. ' vide'
	end
end

-- Construit le code HTML pour l'image d'une case
--
-- Paramètres:
--  -img_empty: true si les images de case vide doivent être générées
--  -pc: code de la pièce sur la case
--       (cf. fullpiecenames, piecenames + colornames, symnames)
--  -row: numéro de ligne de l'échiquier
--  -col: numéro de colonne de l'échiquier
--  -size: taille en pixels d'une case
-- Retour:
--  Code HTML pour l'image d'une case
local function image_square( img_empty, pc, row, col, size )
	local piecenames = { 
		p = {l = 'Pion blanc', d = 'Pion noir', u = 'Pion'},
		r = {l = 'Tour blanche', d = 'Tour noire', u = 'Tour'},
		n = {l = 'Cavalier blanc', d = 'Cavalier noir', u = 'Cavalier'},
		b = {l = 'Fou blanc', d = 'Fou noir', u = 'Fou'},
		q = {l = 'Dame blanche', d = 'Dame noire', u = 'Dame'},
		k = {l = 'Roi blanc', d = 'Roi noir', u = 'Roi'},
		z = {l = '\'\'Champion\'\' blanc', d = '\'\'Champion\'\' noir', u = 'Roi'},
		w = {l = '\'\'Wizard\'\' blanc', d = '\'\'Wizard\'\' noir', u = 'Roi'},
		t = {l = '\'\'Fool\'\' blanc', d = '\'\'Fool\'\' noir', u = 'Fool'},
		a = {l = 'Princesse blanche', d = 'Princesse noire', u = 'Princesse'},
		c = {l = 'Impératrice blanche', d = 'Impératrice noire', u = 'Impératrice'},
		h = {l = 'Pion blanc renversé', d = 'Pion noir renversé', u = 'Pion renversé'},
		m = {l = 'Tour blanche renversée', d = 'Tour noire renversée', u = 'Tour renversée'},
		e = {l = 'Fou blanc renversé', d = 'Fou noir renversé', u = 'Fou renversé'},
		s = {l = 'Cavalier blanc renversé', d = 'Cavalier noir renversé', u = 'Cavalier renversé'},
		f = {l = 'Roi blanc renversé', d = 'Roi noir renversé', u = 'Roi renversé'},
		g = {l = 'Dame blanche renversée', d = 'Dame noire renversée', u = 'Dame renversée'},
	}
	local symnames = {
		xx = 'croix noire',
		xb = 'croix bleue',
		xg = 'croix verte',
		xr = 'croix rouge',
		xy = 'croix jaune',
		ox = 'croix blanche',
		xo = 'cercle noir',
		oo = 'cercle blanc',
		ul = 'haut gauche',
		ua = 'haut',
		ur = 'haut droite',
		la = 'gauche',
		ra = 'droite',
		dl = 'bas gauche',
		da = 'bas',
		dr = 'bas droite',
		lr = 'gauche droite',
		ud = 'haut bas',
		x0 = 'zéro',
		x1 = 'un',
		x2 = 'deux',
		x3 = 'trois',
		x4 = 'quatre',
		x5 = 'cinq',
		x6 = 'six',
		x7 = 'sept',
		x8 = 'huit',
		x9 = 'neuf',
		HL = 'encadré',
	}
	local colchar = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'}
	local piece = mw.ustring.gsub( pc, '^.*(%w)(%w).*$', '%1' ) or ''
	local color = mw.ustring.gsub( pc, '^.*(%w)(%w).*$', '%2' ) or ''
	local colorSquare = ''
	if ((row + col) % 2 == 1) then
		colorSquare = 'l'
		colorSquareName = 'blanche'
	else
		colorSquare = 'd'
		colorSquareName = 'noire'
	end
	if color ~='L' and color ~= 'D' then
		colorSquare = ((mw.ustring.gsub( pc, '^.*(%w)(%w)(%w).*$', '%3' ) ~= pc) and mw.ustring.gsub( pc, '^.*(%w)(%w)(%w).*$', '%3' )) or 't'
	end
	
	local alt =  '' --Définition du nom de l'image
	if piecenames[piece] and piecenames[piece][color]  then
		alt = piecenames[piece][color] .. ' sur case ' .. colorSquareName .. ' ' .. colchar[col] .. row
	elseif symnames[piece .. color] then
		alt = symnames[piece .. color] .. ' sur case ' .. colorSquareName .. ' ' .. colchar[col] .. row
	elseif piecenames[piece] then
		alt = piecenames[piece]['u'] .. ' sur case ' .. colorSquareName .. ' ' .. colchar[col] .. row
	elseif img_empty then
		alt = comment_empty(row, col, colchar)
		if ((row + col) % 2 == 1) then
			colorSquare = 'l'
		else
			colorSquare = 'd'
		end
	else return nil
	end

	return string.format( '[[File:Chess %s%s%s45.svg|%dx%dpx|alt=%s|%s|link=|class=notpageimage|top]]', piece, color, colorSquare, size, size, alt, alt )

end

-- Construit le code HTML interne de l'échiquier
--
-- Paramètres:
--  -board_name: nom de l'image de fond de l'échiquier
--  -board_width: largeur de l'échiquier
--  -board_height: hauteur de l'échiquier
--  -args: arguments divers
--  -size: taille en pixels d'une case de l'échiquier
--  -rev: true si l'échiquier doit être inversé
-- Retour:
--  Code HTML pour l'échiquier
local function innerboard(board_name, board_width, board_height, args, size, rev)
	local colchar = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'}
	local root = mw.html.create('div')
	local img_name = board_name or 'Chessboard480.svg'
	root:addClass('chess-board')
		:css('position', 'relative')
		:wikitext(string.format( '[[File:%s|%dx%dpx|link=]]', img_name, board_width * size, board_height * size ))

	local widthValue = size .. 'px'
	local heightValue = size .. 'px'
	for trow = 1, board_height do
		local row = rev and trow or ( board_height + 1 - trow )
		local topValue = tostring(( trow - 1 ) * size) .. 'px'
		for tcol = 1,board_width do
			local leftValue = tostring(( tcol - 1 ) * size) .. 'px'
			local col = rev and ( board_width + 1 - tcol ) or tcol
			local piece = args[board_width * ( board_height - row ) + col + 2] or ''
			local pc = piece:match( '%w%w' ) or '  '
			local img = image_square(board_name == nil, pc, row, col, size)
			if img then
				root:tag('div')
					:css('position', 'absolute')
					:css('z-index', '3')
					:css('top', topValue)
					:css('left', leftValue)
					:css('width', widthValue)
					:css('height', heightValue)
					:wikitext(img)
			else
				root:tag('div')
					:attr('title', comment_empty(row, col, colchar))
					:css('position', 'absolute')
					:css('z-index', '3')
					:css('top', topValue)
					:css('left', leftValue)
					:css('width', widthValue)
					:css('height', heightValue)
			end
		end
	end

	return tostring(root)
end

-- Construit le code HTML de l'échiquier
--
-- Paramètres:
--  -board_name: nom de l'image de fond de l'échiquier
--  -board_width: largeur de l'échiquier
--  -board_height: hauteur de l'échiquier
--  -args: arguments divers
--  -size: taille en pixels d'une case de l'échiquier
--  -rev: true si l'échiquier doit être inversé
--  -letters: lettres à utiliser pour identifier les colonnes
--  -numbers: numéros à utiliser pour identifier les lignes
--  -header: en-tête
--  -footer: détails
--  -align: alignement de l'échiquier sur la page
--  -clear:
-- Retour:
--  Code HTML pour l'échiquier
function chessboard(board_name, board_width, board_height, args, size, rev, letters, numbers, header, footer, align, clear)
	function letters_row( rev, num_lt, num_rt, width )
		local letters = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'}
		local root = mw.html.create('')
		if num_lt then
			root:tag('td')
				:css('vertical-align', 'inherit')
				:css('padding', '0')
		end
		for k = 1,board_width do
			root:tag('td')
				:css('padding', '0')
				:css('vertical-align', 'inherit')
				:css('height', '18px')
				:css('width', size .. 'px')
				:wikitext(rev and letters[board_width+1-k] or letters[k])
		end
		if num_rt then
			root:tag('td')
				:css('vertical-align', 'inherit')
				:css('padding', '0')
		end
		return tostring(root)
	end

	local letters_tp = letters:match( 'both' ) or letters:match( 'top' )
	local letters_bt = letters:match( 'both' ) or letters:match( 'bottom' )
	local numbers_lt = numbers:match( 'both' ) or numbers:match( 'left' )
	local numbers_rt = numbers:match( 'both' ) or numbers:match( 'right' )
	local width = board_width * size + 2
	if ( numbers_lt ) then width = width + 18 end
	if ( numbers_rt ) then width = width + 18 end

	local root = mw.html.create('div')
		:addClass('thumb')
		:addClass(align)
		:css('clear', clear)
		:css('text-align', 'center')
		:wikitext(header)
	local div = root:tag('div')
		:addClass('thumbinner')
		:css('width', width .. 'px')
	local b = div:tag('table')
		:attr('cellpadding', '0')
		:attr('cellspacing', '0')
		:css('background', 'white')
		:css('font-size', '88%')
		:css('border' , '1px #b0b0b0 solid')
		:css('padding', '0')
		:css('margin', 'auto')

	if ( letters_tp ) then
		b:tag('tr')
			:css('vertical-align', 'middle')
			:wikitext(letters_row( rev, numbers_lt, numbers_rt ))
	end
	local tablerow = b:tag('tr'):css('vertical-align','middle')
	if ( numbers_lt ) then 
		tablerow:tag('td')
			:css('padding', '0')
			:css('vertical-align', 'inherit')
			:css('width', '18px')
			:css('height', size .. 'px')
			:wikitext(rev and 1 or board_height) 
	end
	local td = tablerow:tag('td')
		:attr('colspan', board_width)
		:attr('rowspan', board_height)
		:css('padding', '0')
		:css('vertical-align', 'top')
		:wikitext(innerboard(board_name, board_width, board_height, args, size, rev))

	if ( numbers_rt ) then 
		tablerow:tag('td')
			:css('padding', '0')
			:css('vertical-align', 'inherit')
			:css('width', '18px')
			:css('height', size .. 'px')
			:wikitext(rev and 1 or board_height) 
	end
	if ( numbers_lt or numbers_rt ) then
		for trow = 2, board_height do
			local idx = rev and trow or ( board_height + 1 - trow )
			tablerow = b:tag('tr')
				:css('vertical-align', 'middle')
			if ( numbers_lt ) then 
				tablerow:tag('td')
					:css('padding', '0')
					:css('vertical-align', 'inherit')
					:css('height', size .. 'px')
					:wikitext(idx)
			end
			if ( numbers_rt ) then 
				tablerow:tag('td')
					:css('padding', '0')
					:css('vertical-align', 'inherit')
					:css('height', size .. 'px')
					:wikitext(idx)
			end
		end
	end
	if ( letters_bt ) then
		b:tag('tr')
			:css('vertical-align', 'middle')
			:wikitext(letters_row( rev, numbers_lt, numbers_rt ))
	end

	if (footer and footer ~= '') then
		div:tag('div')
			:addClass('thumbcaption')
			:wikitext(footer)
	end

	return tostring(root)
end

-- Construit une notation FEN en code utilisable pour board()
--
-- Paramètres:
--  -fen: notation FEN
-- Retour:
--  Equivalent de la notation FEN pour board()
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

-- Construit un code utilisable pour board() en une notation FEN
--
-- Paramètres:
--  -args: arguments
--  -offset: décalage si le contenu de l'échiquier ne commence pas à l'argument 2
-- Retour:
--  Notation FEN équivalente
function convertArgsToFen( args, 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( 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 '26'
	local reverse = ( args.reverse or pargs.reverse or '' ):lower() == "true"
	local letters = ( args.letters or pargs.letters or 'both' ):lower() 
	local numbers = ( args.numbers or pargs.numbers or 'both' ):lower() 
	local header = args.header or pargs.header or args[2] or pargs[2] or ''
	local board_width = args.width or pargs.width or 8
	local board_height = args.height or pargs.height or 8
	local footer = args.footer or pargs.footer or args[board_width * board_height + 3] or pargs[board_width * board_height + 3] or ''
	local align = (args.align or pargs.align or args[1] or pargs[1] or 'tright' ):lower()
	local clear = args.clear or pargs.clear or ( align:match('tright') and 'right' ) or 'none'
	local fen = args.fen or pargs.fen
	local board_name = nil
	if (board_width == 8) and (board_height == 8) then
		board_name = 'Chessboard480.svg'
	end

	size = mw.ustring.match( size, '[%d]+' ) or '26' -- remove px from size
	if (fen) then
		return chessboard(board_name, board_width, board_height, convertFenToArgs(fen), size, reverse, letters, numbers, header, footer, align, clear)
	end
	if args[3] then
		return chessboard(board_name, board_width, board_height, args, size, reverse, letters, numbers, header, footer, align, clear)
	else
		return chessboard(board_name, board_width, board_height, pargs, size, reverse, letters, numbers, header, footer, align, clear)
	end
end

function p.fen2ascii(frame)
	-- {{#invoke:Chessboard|fen2ascii|fen=...}}
	local b = convertFenToArgs( frame.args.fen )
	local res = ''
	local offset = 2
	for row = 1,8 do
		local n = (9 - row)
		res = res .. ' |' .. 
		table.concat(b, '|', 8*(row-1) + 1 + offset, 8*(row-1) + 8 + offset) .. '\n'
	end
	res = mw.ustring.gsub( res,'\| \|', '|  |' )
	res = mw.ustring.gsub( res,'\| \|', '|  |' )
	return res
end

function p.ascii2fen( frame )
	-- {{#invoke:Chessboard|ascii2fen|kl| | |....}}
	return convertArgsToFen( frame.args, frame.args.offset or 1 )
end

return p