Aller au contenu

Module:Échiquier

Une page de Wikipédia, l'encyclopédie libre.
Ceci est une version archivée de cette page, en date du 3 avril 2015 à 13:13 et modifiée en dernier par NicoV (discuter | contributions) (Amélioration). Elle peut contenir des erreurs, des inexactitudes ou des contenus vandalisés non présents dans la version actuelle.

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

Utilisation

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 )

Paramètres

  • 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

abcdefgh
8
Tour noire sur case blanche a8
Cavalier noir sur case noire b8
Fou noir sur case blanche c8
Reine noire sur case noire d8
Roi noir sur case blanche e8
Fou noir sur case noire f8
Case blanche g8 vide
Tour noire sur case noire h8
Case noire a7 vide
Pion noir sur case blanche b7
Case noire c7 vide
Case blanche d7 vide
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
Case noire b6 vide
Case blanche c6 vide
Pion noir sur case noire d6
Case blanche e6 vide
Cavalier noir sur case noire f6
Case blanche g6 vide
Case noire h6 vide
Case noire a5 vide
Case blanche b5 vide
Case noire c5 vide
Case blanche d5 vide
Case noire e5 vide
Case blanche f5 vide
Case noire g5 vide
Case blanche h5 vide
Case blanche a4 vide
Case noire b4 vide
Case blanche c4 vide
Cavalier blanc sur case noire d4
Pion blanc sur case blanche e4
Case noire f4 vide
Case blanche g4 vide
Case noire h4 vide
Case noire a3 vide
Case blanche b3 vide
Cavalier blanc sur case noire c3
Case blanche d3 vide
Case noire e3 vide
Case blanche f3 vide
Case noire g3 vide
Case blanche h3 vide
Pion blanc sur case blanche a2
Pion blanc sur case noire b2
Pion blanc sur case blanche c2
Case noire d2 vide
Case blanche e2 vide
Pion blanc sur case noire f2
Pion blanc sur case blanche g2
Pion blanc sur case noire h2
Tour blanche sur case noire a1
Case blanche b1 vide
Fou blanc sur case noire c1
Reine blanche sur case blanche d1
Roi blanc sur case noire e1
Fou blanc sur case blanche f1
Case noire g1 vide
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
Reine noire sur case noire d8
Roi noir sur case blanche e8
Fou noir sur case noire f8
Case blanche g8 vide
Tour noire sur case noire h8
Case noire a7 vide
Pion noir sur case blanche b7
Case noire c7 vide
Case blanche d7 vide
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
Case noire b6 vide
Case blanche c6 vide
Pion noir sur case noire d6
Case blanche e6 vide
Cavalier noir sur case noire f6
Case blanche g6 vide
Case noire h6 vide
Case noire a5 vide
Case blanche b5 vide
Case noire c5 vide
Case blanche d5 vide
Case noire e5 vide
Case blanche f5 vide
Case noire g5 vide
Case blanche h5 vide
Case blanche a4 vide
Case noire b4 vide
Case blanche c4 vide
Cavalier blanc sur case noire d4
Pion blanc sur case blanche e4
Case noire f4 vide
Case blanche g4 vide
Case noire h4 vide
Case noire a3 vide
Case blanche b3 vide
Cavalier blanc sur case noire c3
Case blanche d3 vide
Case noire e3 vide
Case blanche f3 vide
Case noire g3 vide
Case blanche h3 vide
Pion blanc sur case blanche a2
Pion blanc sur case noire b2
Pion blanc sur case blanche c2
Case noire d2 vide
Case blanche e2 vide
Pion blanc sur case noire f2
Pion blanc sur case blanche g2
Pion blanc sur case noire h2
Tour blanche sur case noire a1
Case blanche b1 vide
Fou blanc sur case noire c1
Reine blanche sur case blanche d1
Roi blanc sur case noire e1
Fou blanc sur case blanche f1
Case noire g1 vide
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 )

Paramètres

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

Exemple

{{#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 )

Paramètres

  • fen - notation FEN.

Exemple

{{#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 code HTML pour l'image d'une case
--
-- Paramètres:
--  -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( pc, row, col, size )
	local colornames = { l = 'blanc', d = 'noir' }
	local piecenames = { 
		z = 'champion',
		w = 'wizard',
		t = 'fool',
		h = 'upside-down pawn',
		m = 'upside-down rook',
		s = 'upside-down knight',
		f = 'upside-down king',
		e = 'upside-down bishop',
		g = 'upside-down queen',
	}
	local fullpiecenames = {
		pl = 'Pion blanc',
		pd = 'Pion noir',
		rl = 'Tour blanche',
		rd = 'Tour noire',
		nl = 'Cavalier blanc',
		nd = 'Cavalier noir',
		bl = 'Fou blanc',
		bd = 'Fou noir',
		ql = 'Reine blanche',
		qd = 'Reine noire',
		kl = 'Roi blanc',
		kd = 'Roi noir',
		al = 'Princesse blanche',
		ad = 'Princesse noire',
		cl = 'Impératrice blanche',
		cd = 'Impératrice noire',
	}
	local symnames = {
		xx = 'croix noire',
		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',
	}
	local colchar = {'a','b','c','d','e','f','g','h'}
	local color = mw.ustring.gsub( pc, '^.*(%w)(%w).*$', '%2' ) or ''
	local colorLower = string.lower(color)
	local piece = mw.ustring.gsub( pc, '^.*(%w)(%w).*$', '%1' ) or ''
	local alt =  ''
	local colorSquare = 't'
	if ((row + col) % 2 == 1) then
		colorSquare = 'l'
	else
		colorSquare = 'd'
	end
	local caseName = piece .. color .. colorSquare

	if fullpiecenames[piece .. colorLower] or (colornames[colorLower] and piecenames[colorLower]) then
		if fullpiecenames[piece .. colorLower] then
			alt = alt .. fullpiecenames[piece .. colorLower]
		else
			alt = alt .. colornames[colorLower] .. ' ' .. piecenames[piece]
		end
		alt = alt .. ' sur case '
		if ((row + col) % 2 == 1) then
			alt = alt .. 'blanche'
		else
			alt = alt .. 'noire'
		end
		alt = alt .. ' ' .. colchar[col] .. row
	else
		alt = alt .. 'Case '
		if ((row + col) % 2 == 1) then
			alt = alt .. 'blanche'
		else
			alt = alt .. 'noire'
		end
		alt = alt .. ' ' .. colchar[col] .. row .. ' vide'
		caseName = colorSquare
	end

	return string.format( '[[File:Chess %s45.svg|%dx%dpx|alt=%s|%s]]', caseName, size, size, alt, alt )

end

-- Construit le code HTML interne de l'échiquier
--
-- Paramètres:
--  -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(args, size, rev)
	local root = mw.html.create('div')
	root:addClass('chess-board')
		:css('position', 'relative')
		:wikitext(string.format( '[[File:Chessboard480.svg|%dx%dpx|link=]]', 8 * size, 8 * size ))

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

	return tostring(root)
end

-- Construit le code HTML de l'échiquier
--
-- Paramètres:
--  -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(args, size, rev, letters, numbers, header, footer, align, clear)
	function letters_row( rev, num_lt, num_rt )
		local letters = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'}
		local root = mw.html.create('')
		if num_lt then
			root:tag('td')
				:css('vertical-align', 'inherit')
				:css('padding', '0')
		end
		for k = 1,8 do
			root:tag('td')
				:css('padding', '0')
				:css('vartical-align', 'inherit')
				:css('height', '18px')
				:css('width', size .. 'px')
				:wikitext(rev and letters[9-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 = 8 * 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 8) 
	end
	local td = tablerow:tag('td')
		:attr('colspan', 8)
		:attr('rowspan', 8)
		:css('padding', '0')
		:css('vertical-align', 'inherit')
		:wikitext(innerboard(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 8) 
	end
	if ( numbers_lt or numbers_rt ) then
		for trow = 2, 8 do
			local idx = rev and trow or ( 9 - 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 footer = args.footer or pargs.footer or args[67] or pargs[67] 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

	size = mw.ustring.match( size, '[%d]+' ) or '26' -- remove px from size
	if (fen) then
		return chessboard( convertFenToArgs( fen ), size, reverse, letters, numbers, header, footer, align, clear )
	end
	if args[3] then
		return chessboard(args, size, reverse, letters, numbers, header, footer, align, clear)
	else
		return chessboard(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