יחידה:Chess

מתוך ויקיספר, אוסף הספרים והמדריכים החופשי

ניתן ליצור תיעוד על היחידה הזאת בדף יחידה:Chess/תיעוד

local p = {}
local pgnModule = require('Module:Pgn')

--[[Fetch pgn from Wikidata
]]
local function wdEntityToPgn(entity)
	local moveList = mw.wikibase.getBestStatements(entity, 'P5286')
	local participants = mw.wikibase.getBestStatements(entity, 'P710')
	local gameDate = mw.wikibase.getBestStatements(entity, 'P585')
	local metadata = {}
	
	-- metadata: participants P710 (player), P2868 (color)
	for k, v in pairs(participants) do
		local playId = v and v.mainsnak and v.mainsnak.datavalue and v.mainsnak.datavalue.value.id
		local roleId = v.qualifiers and v.qualifiers['P2868'] and v.qualifiers['P2868'][1].datavalue.value.id
		if playId and roleId then
			local player = mw.wikibase.label(playId)
			local role = roleId
			if role == 'Q23444' then 
				table.insert(metadata, '[White "'..player..'"]')
			elseif role == 'Q23445' then
				table.insert(metadata, '[Black "'..player..'"]')
			end
		end
	end
	
	-- metadata: event date
	if gameDate and gameDate[1] and gameDate[1].mainsnak and gameDate[1].mainsnak.datavalue and gameDate[1].mainsnak.datavalue.value then
		local DateModule = require('יחידה:תאריך')
		local eventDate = DateModule.newFromWikidataValue(gameDate[1].mainsnak.datavalue.value):toString()
		table.insert(metadata, '[EventDate "'..eventDate..'"]')
	end
	
	-- moves to algebric notation
	local moves = {}
	for k, v in pairs(moveList) do
		local move = mw.ustring.format('%s. %s', v.qualifiers['P1545'][1].datavalue.value, v.mainsnak.datavalue.value)
		table.insert(moves, {v.qualifiers['P1545'][1].datavalue.value, move})
	end
	table.sort(moves, function(a,b) return tonumber(a[1])<tonumber(b[1]) end) -- dont assume the moves are sort in wikidata
	local algebricNotation={}
	for k, v in pairs( moves ) do table.insert(algebricNotation, v[2]) end
	algebricNotation = table.concat(algebricNotation, ' ')
	
	-- concat metadata and moves
	if #metadata>0 then 
		res = table.concat(metadata, '\n')..'\n\n' ..algebricNotation
		mw.log('PGN for ' .. entity .. ':')
		mw.logObject(res)
		return res
	else
		mw.log('Algebric notiation for ' .. entity .. ':')
		mw.logObject(algebricNotation)
		return algebricNotation
	end
end

--[[Translates PGN to FEN]]
local function wdEntityToFen(entity, index)
	local pgn = wdEntityToPgn(entity)
	local metadata, moves = pgnModule.main(pgn)
	mw.log('moves:')
	mw.logObject(moves)
	mw.log('index: ', index)
	mw.log('moves[index]')
	mw.logObject(moves[index])
	-- the default is to take the last move
	if index==nil then
		index = #moves
	end
	return moves[tonumber(index)]
end

--[[
Create dynamic chess game
]]
function pgnFromWikidata(frame)
	local allArgs = {}
	
	for k, v in pairs(frame:getParent().args) do allArgs[k] = v end
	for k, v in pairs(frame.args) do allArgs[k] = v end
	local dynamicStyle = (allArgs['type'] ~= 'static')
	local templateArgs 
	local pgnExtractor
	if dynamicStyle then
		templateArgs = { 'pgn' }
		pgnExtractor = wdEntityToPgn
	else
		templateArgs = { 'לוח שחמט מ-FEN' }
		pgnExtractor = wdEntityToFen
	end
	
	for k, v in pairs(allArgs) do
		if type(k) == 'number' then
			table.insert(templateArgs, pgnExtractor(v, allArgs['index']))  -- quick and dirty. this is needed to set the game to specific move
		elseif k ~= 'type' and k~= 'index' then
			table.insert(templateArgs, mw.ustring.format(' %s = %s ', k, v))
		end
	end
	local template = mw.ustring.format('{{%s}}', table.concat(templateArgs, '|'))
	return frame:preprocess(template)
end


--[[
Extract PGN from Wikidata
]]
function rawPgnFromWikidata(frame)
	local allArgs = {}
	local entityId = frame.args[1]
	if entityId == nil then
		entityId = mw.wikibase.getEntityIdForCurrentPage()
	end
	return wdEntityToPgn(entityId)
end

p.pgnFromWikidata = pgnFromWikidata
p.rawPgnFromWikidata = rawPgnFromWikidata
return p