Modul:Turnier

Aus KoschWiki
Zur Navigation springen Zur Suche springen
Dokumentation unter Modul:Turnierritter/Doku.
require("Modul:Hilfsfunktionen")

local p = {}

--Erzeuge ein Array mit Pseudozufallszahlen basierend auf dem Seed
function random(seed,count)
	local mod=1048573
	local multiplier=380985
	local inc=0
	local result={}
	result[0]=seed+1
	for i=1,count,1 do
		result[i]=(result[i-1]*multiplier+inc)%mod;
	end
	return result
end

--Erzeuge einen Integer-Hash aus einem String
function hash(str)
	local a=1
	local b=0
	for i=1,#str do
		a=(a+mw.ustring.byte(str,i,i))%65521
		b=(a+b)%65521
	end
	return b*65536+a
end

--Hole alle Wappen und Bilf für Tjoster
function holeTjosterDaten(artikel)
	local tjosterDaten=mw.smw.ask("[["..artikel.."]]"
		.."|?=#"
		.."|?Bild ist#"
		.."|?Wappen ist#"
		.."|searchlabel="
		.."|limit=1"
	)
	if tjosterDaten==nil or #tjosterDaten<1 then
		return {{[1]=artikel,['Bild ist']='Datei:Bild blanko.svg',['Wappen ist']='Datei:Wappen blanko.svg'}}
	end
	return tjosterDaten
end

--Erzeuge Tjoster-Objekt mit Metadaten und 200 vorgewürfelten Zufallszahlen
function erzeugeTjoster(baseseed,artikel,klasse)
	local daten=holeTjosterDaten(artikel)
	local tjoster={}
	tjoster['artikel']=artikel
	local base=string.match(artikel,":(.*)")
	if base==nil then
		base=artikel
	end
	tjoster['name']=string.match(base,"(.*)%svon")
	if tjoster['name']==nil then
		tjoster['name']=string.match(base,"(.*)%svom")
	end
	if tjoster['name']==nil then
		tjoster['name']=base
	end
	tjoster['wappen']=daten[1]['Wappen ist']
	tjoster['bild']=daten[1]['Bild ist']
	tjoster['klasse']=math.min(math.max(1,klasse),4)
	tjoster['sterne']=""
	if klasse==2 then tjoster['sterne']="✦" end
	if klasse==3 then tjoster['sterne']="★" end
	if klasse==4 then tjoster['sterne']="✶" end
--	for i=1,klasse-1,1 do
--		tjoster['sterne']=tjoster['sterne']..'★'
--	end
	tjoster['zaehler']=1
	tjoster['wuerfe']=random(hash(baseseed..artikel),200)
	return tjoster
end

--Hole die nächste vorgewürfelte Zufallszahl und rechne sie in W20 um
function holeNaechstenWurf(tjoster)
	if(tjoster['zaehler']>#tjoster['wuerfe']) then
		tjoster['zaehler']=1
	end
	local result=tjoster['wuerfe'][tjoster['zaehler']]%20+1
	tjoster['zaehler']=tjoster['zaehler']+1
	return result
end

--Würfle Klasse+1 mal den W20 und gib den höchsten Wert sowie eine Textliste aller Werte zurück
function holeNaechstesErgebnis(tjoster)
	local result=0
	local log=''
	local anzahl=tjoster['klasse']+1
	for i=1,anzahl,1 do
		local wurf=holeNaechstenWurf(tjoster)
		log=log..wurf..","
		if wurf>result then
			result=wurf
		end
	end
	return {['wert']=result,['log']=log:sub(1, -2)}
end

--Anzeige Tjoster
function zeigeTjoster(tjoster)
	return '<div style="width:100%;height:2.5em;overflow:hidden;word-wrap:no-wrap;">[['..tjoster['wappen']..'|30x30px|link=]] [['..tjoster['bild']..'|30x30px|link=]] [[Hauptdarsteller ist::'..tjoster['artikel']..'|'..tjoster['name']..']] '..tjoster['sterne']..'</div>'
end

--Lasse zwei Tjoster so lange gegeneinander antreten, bis einer die angegebene Anzahl Siege errungen hat
--Gib den Sieger und Wikisource für die Anzeige zurück
function paarung(tjoster1,tjoster2,lanzen)
	local siege1=0
	local siege2=0
	local log='<div style="width:65%;display:inline-block;">'..zeigeTjoster(tjoster1)..zeigeTjoster(tjoster2).."</div>"
		..'<div style="width:35%;display:inline-block;">'
	while (siege1<lanzen) and (siege2<lanzen) do
		local wurf1=holeNaechstesErgebnis(tjoster1)
		local wurf2=holeNaechstesErgebnis(tjoster2)
		if wurf1['wert']>wurf2['wert'] then
			log=log..'[['..tjoster1['wappen']..'|20x20px|link=|'..wurf1['log'].."/"..wurf2['log']..']] '
			siege1=siege1+1
		end
		if wurf2['wert']>wurf1['wert'] then
			log=log..'[['..tjoster2['wappen']..'|20x20px|link=|'..wurf1['log'].."/"..wurf2['log']..']] '
			siege2=siege2+1
		end
		if wurf2==wurf1 then
			log=log..'[[Datei:Wappen blanko.svg|20x20px|link=|'..wurf1.."/"..wurf2..']] '
		end
	end
	log=log..'</div>'
	local sieger=nil
	if siege1==lanzen then
		sieger=tjoster1
	end
	if siege2==lanzen then
		sieger=tjoster2
	end
	return {['sieger']=sieger,['log']=log}
end

--Aufruf
--1: Anzahl Tjoster, die 2^n entsprechen muss
--2/4/6/... Artikel der Tjoster
--3/5/7/... Klasse der Tjoster (1 bis 4)
function p.turnier(frame)
	--lies Parameter ein und erzeuge Tjoster
	local baseseed=mw.title.getCurrentTitle().text
	local anzahl=tonumber(robusttrim(frame.args[1]))
	local tjoster={}
	for i=1,anzahl,1 do
		local artikel=robusttrim(frame.args[i*2])
		local klasse=tonumber(robusttrim(frame.args[i*2+1]))
		tjoster[i]=erzeugeTjoster(baseseed,artikel,klasse)
	end

	--mische die Tjoster pseudozufällig
	local order={}
	local i=1
	for k, v in spairs(tjoster,function(tjoster,a,b)
    	return tjoster[a]['artikel']<tjoster[b]['artikel']
	end) do
    	order[i]=k
    	i=i+1
	end
	local shuffle=random(hash(baseseed),100)
	for i=1,anzahl,1 do
		local i1=1+shuffle[i*2-1]%anzahl
		local i2=1+shuffle[i*2]%anzahl
		local buf=order[i1]
		order[i1]=order[i2]
		order[i2]=buf
	end
	local tj={}
	for i=1,anzahl,1 do
		tj[i]=tjoster[order[i]]
	end

	--berechne iterativ die Paarungen
	spalten=1+math.log(anzahl)/math.log(2)
	local s='<div style="display:flex;flex-direction:row;width:100%;height:'..(anzahl*3)..'em;">'
	local paare=anzahl/2
	local farbe='hell'
	while paare>=1 do
		local colspan=anzahl/(paare*2)
		s=s..'<div style="width:'..(100/spalten)..'%;height:100%;">'
		for i=1,paare,1 do
			s=s..'<div class="'..farbe..'" style="display:flex;align-items:center;justify-content:center;width:100%;height:'..(100/paare)..'%;text-align:left;">'
			local ergebnis=paarung(tj[i*2-1],tj[i*2],3)
			s=s..ergebnis['log']
			tj[i]=ergebnis['sieger']
			s=s..'</div>'
		if farbe=='hell' then farbe='dunkel' else farbe='hell' end
		end
		paare=paare/2
		s=s..'</div>'
	end
	
	--Zeige den Sieger an
	s=s..'<div style="width:'..(100/spalten)..'%;height:100%;">'
	s=s..'<div class="'..farbe..'" style="display:flex;align-items:center;justify-content:center;width:100%;height:100%;text-align:left;">'
	s=s..'<div style="width:100%;display:inline-block;">'..zeigeTjoster(tj[1])..'</div>'
	s=s..'</div>'
	s=s..'</div>'
	s=s..'</div>'

	return s
end

return p