No johan oli otsikko.
Olen tekemässä futiksen MMkisoista sarjataulukkoa. Nyt kuitenkin tuli ongelma vastaan.
Nyt minulla on moniuloteinen taulukko joka koostuu näin:
scores---lohko A-----joukkue 1-------pelatut ottelut | | |--------voitot | | |--------tasapelit | | |--------häviöt | | |--------tehdyt maalit | | |--------päästetyt maalit | | |--------pisteet | | | |------joukkue 2--------pelatut ottelut | | . | | . | | |--------pisteet | . . ------joukkue3 . . -lohko B .
Olen tehnyt jokaiselle lohkolle oman taulukon johon järjestän joukkueet pisteiden perusteella.
Mutta kun kahdella joukkueella on samat pisteet, niin niiden keskenäinen järjestys pitäisi saada keskinäisen ottelun tai maalieron perusteella.
Siinä vaiheessa mulla menee sormi suuhun.
Osaisiko joku ystävällisesti auttaa?
Laitetaanpa vielä tiedostot niin voi kokeilla käytännössä tuota.
standings.php
<?php $countries=file("countries.txt"); $i=0; while($countries[$i]!=""){ $countries[$i]=str_replace("\n","",$countries[$i]); $countries[$i]=str_replace("\r","",$countries[$i]); $i++; } $scores=array(); $info=array("mp"=>0, "wins"=>0, "ties"=>0, "losses"=>0, "gf"=>0, "ga"=>0, "points"=>0); for($i=0;$i<8;$i++) { $group=array( ($i*4+0) => $info, ($i*4+1) => $info, ($i*4+2) =>$info, ($i*4+3) => $info); $scores[$i]=$group; } $games=file("games.txt"); $groups=array("a","b","c","d","e","f","g","h"); for($i=0;$i<count($games);$i++) { $osat=explode("|",$games[$i]); $scores[(ceil(($osat[0]+1)/4)-1)][$osat[0]]["mp"] +=1; $scores[(ceil(($osat[0]+1)/4)-1)][$osat[1]]["mp"] +=1; $scores[(ceil(($osat[0]+1)/4)-1)][$osat[0]]["gf"] +=$osat[2]; $scores[(ceil(($osat[0]+1)/4)-1)][$osat[1]]["gf"] +=$osat[3]; $scores[(ceil(($osat[0]+1)/4)-1)][$osat[0]]["ga"] +=$osat[3]; $scores[(ceil(($osat[0]+1)/4)-1)][$osat[1]]["ga"] +=$osat[2]; if(trim($osat[2])>trim($osat[3])){ $scores[(ceil(($osat[0]+1)/4)-1)][$osat[0]]["points"] +=3; $scores[(ceil(($osat[0]+1)/4)-1)][$osat[0]]["wins"] +=1; $scores[(ceil(($osat[0]+1)/4)-1)][$osat[1]]["losses"] +=1; } elseif(trim($osat[2])<trim($osat[3])){ $scores[(ceil(($osat[0]+1)/4)-1)][$osat[1]]["points"] +=3; $scores[(ceil(($osat[0]+1)/4)-1)][$osat[1]]["wins"] +=1; $scores[(ceil(($osat[0]+1)/4)-1)][$osat[0]]["losses"] +=1; } else { $scores[(ceil(($osat[0]+1)/4)-1)][$osat[1]]["points"] +=1; $scores[(ceil(($osat[0]+1)/4)-1)][$osat[0]]["points"] +=1; $scores[(ceil(($osat[0]+1)/4)-1)][$osat[1]]["ties"] +=1; $scores[(ceil(($osat[0]+1)/4)-1)][$osat[0]]["ties"] +=1; } } echo "<table>\n\t<tr>\n"; for($i=0;$i<8;$i++) { if($i==2 || $i==4 || $i==6) echo "\t</tr>\n\t<tr>\n"; echo "\t\t<td valign=\"top\">\n"; echo "\t\t\t<table>\n"; echo "\t\t\t<tr><th class =\"country1\">". strtoupper($groups[$i]) ."</th><th>MP</th><th>W</th><th>D</th><th>L</th><th>GF</th><th>GA</th><th>Pts</th></tr>\n"; @arsort($scores[$i]); @reset($scores[$i]); foreach ($scores[$i] as $country => $teaminfo){ echo "\t\t\t\t<tr>\n\t\t\t\t\t"; echo "<td class=\"country\">".$countries[$country]."</td>\n"; echo "\t\t\t\t\t<td>".$teaminfo["mp"]."</td>\n"; echo "\t\t\t\t\t<td>".$teaminfo["wins"]."</td>\n"; echo "\t\t\t\t\t<td>".$teaminfo["ties"]."</td>\n"; echo "\t\t\t\t\t<td>".$teaminfo["losses"]."</td>\n"; echo "\t\t\t\t\t<td>".$teaminfo["gf"]."</td>\n"; echo "\t\t\t\t\t<td>".$teaminfo["ga"]."</td>\n"; echo "\t\t\t\t\t<td>".$teaminfo["points"]."</td>\n"; echo "\t\t\t\t</tr>\n"; } echo "\t\t\t</table>\n"; echo"\t\t</td>\n"; } echo "\t</tr>\n</table>\n"; ?>
countries.txt
Costa Rica Ecuador Germany Poland England Paraguay Sweden Trinidad and Tobago Argentina Côte d'Ivoire Netherlands Serbia and Montenegro Angola Iran Mexico Portugal Czech Republic Ghana Italy USA Australia Croatia Brazil Japan France Korea Republic Switzerland Togo Saudi Arabia Spain Tunisia Ukraine
games.txt esimerkki
3|2|1|4 1|2|1|2 18|19|3|1 0|3|2|2 16|17|3|3
Hitaasti mutta varmasti tuo onnistuu (ainakin teoriassa) sillä, että ensin järjestetään ne heikommalla perusteella ja vasta sitten pääasiallisella periaatteella. Käytännössä valmisfunktioiden kanssa tämä voi olla ongelma, eli oma lajittelufunktio tulisi tarpeeseen. PHP vielä mutkistaa asioita entisestään...
Nopeinta on kuitenkin etsiä ensimmäinen ja viimeinen saman pistemäärän omaava joukkue ja järjestää se väli uudestaan. Bubble Sort ja Insertion Sort voivat olla helpoimmin toteutettavat algoritmit, ja löytyypä tuolta koodivinkeistä muitakin. Pitää vain lajitella alkiot tietyltä väliltä.
Minä tekisin tuollaisen oman sorttausfunktion, ja antaisin sen usort:lle parametriksi.
Huhhuh, menee kyllä mulle vähän vaikeaksi. Kun en mikään haka php:ssä ole, kuten noista koodeista näkyy, aika moista purkkaa paikoittain.
Pitää kyllä vielä yrittää lueskella tuota manuaalia oikeen ajan kanssa, kun äkkiä vilkasin niin näytti vähän hankalalta. Tai sitten toivoa ettei tule tasatuloksia.
Voisitko selostaa tarkemmin:
- järjestysperiaatteen
- tiedoston games.txt rakenteen
Näiden tietojen perusteella voin ehkä olla avuksi.
Jokaisella maalla on oma numeronsa(countries.txt:n rivinumero), games.txt:ssa yhdellä rivillä on yksi ottelu.
maa1|maa2|maa1:n maalit|maa2:n maalit. Eli 16|17|3|3 tarkoittaisi, että Tsekki ja Ghana olisi pelannut 3-3 tasapelin.
Ja nuo kaikki tiedot saan kyllä taulukkoon ihan oikein, mutta sitten järjestäminen tuottaa ongelmia.
EDIT:
Tarkistin viralliset säännöt ja nyt tämä taisi helpottua aika lailla.
Eli, järjestysperjaate:
Joukkue jolla on eniten pisteitä on ylimpänä listassa. Jos kuitenkin joillakin joukkueilla on yhtä paljon pisteitä, heidän välinen järjestys ratkeaa maalierolla(tehdyt maalit-päästetyt maalit). Jos maalierotkin on samat niin paremman sijoituksen saa joukkue jolla on enemmän tehtyjä maaleja.
Laitetaan nytten vielä virallista tekstiä kehiin.
http://eur.i1.yimg.com/eur.yimg.com/i/eu/fifa/
The ranking of each team in each group will be determined as
follows:
a) greatest number of points obtained in all group matches;
b) goal difference in all group matches;
c) greatest number of goals scored in all group matches.
If two or more teams are equal on the basis of the above three criteria,
their rankings will be determined as follows:
XVIII. TECHNICAL RULES FOR THE FINAL COMPETITION
41
d) greatest number of points obtained in the group matches between
the teams concerned;
e) goal difference resulting from the group matches between the
teams concerned;
f) greater number of goals scored in all group matches between the
teams concerned;
g) drawing of lots by the Organising Committee for the FIFA World
Cup™.
Tuo tosiaan helpottaa järjestelyä ratkaisevasti.
Nyt riittää Blazen mainitsema usort-funktio, jolle voi ilmoittaa juuri halutunlaisen järjestelytavan.
function vertailu($a, $b) { if ($a["points"] == $b["points"]) { if ($a["gf"] - $a["ga"] == $b["gf"] - $b["ga"]) { return $b["gf"] - $a["gf"]; } else { return ($b["gf"] - $b["ga"]) - ($a["gf"] - $a["ga"]); } } else { return $b["points"] - $a["points"]; } } // muutos alkuperäiseen koodiin: @usort($scores[$i], "vertailu");
Ideana on siis se, että oma funktio vertailu saa parametreikseen kaksi taulukon alkiota, joita varsinainen järjestelyalgoritmi sillä hetkellä vertailee. Jos funktio palauttaa negatiivisen arvon, ensimmäinen parametri kuuluu järjestyksessä toisen edelle ja jos funktio palauttaa positiivisen arvon, toinen parametri kuuluu järjestyksessä ensimmäisen edelle. Nyt vertailussa voidaan ottaa huomioon samat arvot ja vertailla tilanteesta riippuen eri asioita.
muokkaus: Nuo kohdat d:stä eteenpäin ovat hankalampia. Nyt ei riitä pelkkä kahden joukkueen tietojen vertailu, vaan pitää erikseen ottaa huomioon, että käsittelyssä ovat vain tasaväkiset joukkueet. Tämän voi toteuttaa laskemalla ensimmäisen järjestelyn jälkeen erilliset tiedot tasaväkisistä joukkueista ja järjestelemällä joukkueet uudestaan laajennetulla vertailulla, mutta onkohan näin monimutkainen järjestely tarpeen omassa tapauksessasi?
Tuo toimii muuten paitsi maiden IDnumerot katoaa jonnekkin. Joten se tulostaa joka taulukkoon samat maat, ja niiden järjestys ei muutu.
Pisteiden järjestys näyttää kuitenkin olevan oikea.
Antti Laaksonen kirjoitti:
muokkaus: Nuo kohdat d:stä eteenpäin ovat hankalampia. Nyt ei riitä pelkkä kahden joukkueen tietojen vertailu, vaan pitää erikseen ottaa huomioon, että käsittelyssä ovat vain tasaväkiset joukkueet. Tämän voi toteuttaa laskemalla ensimmäisen järjestelyn jälkeen erilliset tiedot tasaväkisistä joukkueista ja järjestelemällä joukkueet uudestaan laajennetulla vertailulla, mutta onkohan näin monimutkainen järjestely tarpeen omassa tapauksessasi?
Epäilen että tämä riittää minulle. Täytyy sitten palata asiaan, jos tulee ongelmia.
Mutta jos tuohon joltakin vielä löytyisi neuvo, että miten saan maat takaisin ja vielä oikeaan järjestykseen.
Auttaisiko funktion uasort käyttö asiaan?
Nyt puolet maista katosi, mutta muut näkyy kyllä oikein.
Muutin vähän systeemin rakennetta. Laitoin joukkueiden pistelaskennan erilliseen tiedostoon, koska tarvitsen scorearrayta muuallakin.
Mulla on ollut peukalo suussa jo pidempään niin päätin vielä laittaa yritykseni tähän, ja kysyä että olenko laittanut tuon usort/uasort funktio jutun oikeen?
standings.php
<?php include("scorearray.php"); $countries=file("countries.txt"); $groups=array("a","b","c","d","e","f","g","h"); echo "<table>\n\t<tr>\n"; for($i=0;$i<8;$i++) { if($i==2 || $i==4 || $i==6) echo "\t</tr>\n\t<tr>\n"; echo "\t\t<td valign=\"top\">\n"; echo "\t\t\t<table>\n"; echo "\t\t\t<tr><th class =\"country1\">".strtoupper($groups[$i])."</th><th>MP</th><th>W</th><th>D</th><th>L</th><th>GF</th><th>GA</th><th>Pts</th></tr>\n"; @uasort($scores[$i], "vertailu"); @reset($scores[$i]); foreach ($scores[$i] as $country => $teaminfo){ echo "\t\t\t\t<tr>\n\t\t\t\t\t"; echo "<td class=\"country\">".$countries[(4*$i+$country)]."</td>\n"; echo "\t\t\t\t\t<td>".$teaminfo["mp"]."</td>\n"; echo "\t\t\t\t\t<td>".$teaminfo["wins"]."</td>\n"; echo "\t\t\t\t\t<td>".$teaminfo["ties"]."</td>\n"; echo "\t\t\t\t\t<td>".$teaminfo["losses"]."</td>\n"; echo "\t\t\t\t\t<td>".$teaminfo["gf"]."</td>\n"; echo "\t\t\t\t\t<td>".$teaminfo["ga"]."</td>\n"; echo "\t\t\t\t\t<td>".$teaminfo["points"]."</td>\n"; echo "\t\t\t\t</tr>\n"; } echo "\t\t\t</table>\n"; echo"\t\t</td>\n"; } echo "\t</tr>\n</table>\n"; ?>
scorearray.php
<?php $scores=array(); $info=array("mp"=>0, "wins"=>0, "ties"=>0, "losses"=>0, "gf"=>0, "ga"=>0, "points"=>0); for($i=0;$i<8;$i++) { $group=array( ($i*4+0) => $info, ($i*4+1) => $info, ($i*4+2) =>$info, ($i*4+3) => $info); $scores[$i]=$group; } $games=file("games.txt"); for($i=0;$i<count($games);$i++) { $osat=explode("|",$games[$i]); $scores[(ceil(($osat[0]+1)/4)-1)][$osat[0]]["mp"] +=1; $scores[(ceil(($osat[0]+1)/4)-1)][$osat[1]]["mp"] +=1; $scores[(ceil(($osat[0]+1)/4)-1)][$osat[0]]["gf"] +=$osat[2]; $scores[(ceil(($osat[0]+1)/4)-1)][$osat[1]]["gf"] +=$osat[3]; $scores[(ceil(($osat[0]+1)/4)-1)][$osat[0]]["ga"] +=$osat[3]; $scores[(ceil(($osat[0]+1)/4)-1)][$osat[1]]["ga"] +=$osat[2]; if(trim($osat[2])>trim($osat[3])){ $scores[(ceil(($osat[0]+1)/4)-1)][$osat[0]]["points"] +=3; $scores[(ceil(($osat[0]+1)/4)-1)][$osat[0]]["wins"] +=1; $scores[(ceil(($osat[0]+1)/4)-1)][$osat[1]]["losses"] +=1; } elseif(trim($osat[2])<trim($osat[3])){ $scores[(ceil(($osat[0]+1)/4)-1)][$osat[1]]["points"] +=3; $scores[(ceil(($osat[0]+1)/4)-1)][$osat[1]]["wins"] +=1; $scores[(ceil(($osat[0]+1)/4)-1)][$osat[0]]["losses"] +=1; } else { $scores[(ceil(($osat[0]+1)/4)-1)][$osat[1]]["points"] +=1; $scores[(ceil(($osat[0]+1)/4)-1)][$osat[0]]["points"] +=1; $scores[(ceil(($osat[0]+1)/4)-1)][$osat[1]]["ties"] +=1; $scores[(ceil(($osat[0]+1)/4)-1)][$osat[0]]["ties"] +=1; } } function vertailu($a, $b) { if ($a["points"] == $b["points"]) { if ($a["gf"] - $a["ga"] == $b["gf"] - $b["ga"]) { return $b["gf"] - $a["gf"]; } else { return ($b["gf"] - $b["ga"]) - ($a["gf"] - $a["ga"]); } } else { return $b["points"] - $a["points"]; } } ?>
games.txt
19|17|4|1 0|1|3|1 19|18|2|1 18|17|5|1 2|3|2|1 3|0|5|1
Aihe on jo aika vanha, joten et voi enää vastata siihen.