Begegnungsauslosung in der Liga mit PHP. Aber wie ? :)

Bash, Shell, PHP, Python, Perl, CGI
mezga
Posts: 147
Joined: 2002-12-10 13:59

Begegnungsauslosung in der Liga mit PHP. Aber wie ? :)

Post by mezga »

Hallo,

ich hab da ein kleines Problem.

Ich programmiere zur Zeit ein "Ligascript".

Da muss ich ein "Nextfight" Script schreiben. In dem wird angezeigt, welche Teams an welchem Datum gegeneinander Spielen müssen.

Also Team1 gegen Team2 am 10.10.03 und Team3 gegen Team4 am 10.10.03.... und so weiter....

Am zweiten Spieltag dann Team1 gegen Team3 und Team2 gegen Team4.

Mit nur 4 Teams ist das ja ganz einfach, aber es sind 15 Teams. Und wie genau lass ich jetzt die Teams gegeneinander spielen, damit so wenig wie möglich Freilose für jede Mannschaft entstehen ?

Ungefähr so wie bei der Bundesliga, da muss ja auch nur ein mal ein Team aussetzen. Hab schon überall gesucht, aber ich find das nicht.

Weis einer von Euch zufällig wie ich das mit PHP "auslosen" kann ? Also ich brauche nicht direkt den Quellcode, den kann ich mir dann auch selber zusammenreimen.


Vielen Dank schon mal im Vorraus
manitwo
Posts: 59
Joined: 2003-04-05 16:07

Re: Begegnungsauslosung in der Liga mit PHP. Aber wie ? :)

Post by manitwo »

Hmm, also das würde mich auch brennend interessieren, denn ich hab selber ne CS Liga gescriptet, bin damit momentan noch in der 1. Spielsaison und sitze an den letzten Features.
Doch für die 1. Saison hab ich den Plan manuell erstellt weil ich nicht wusste wie ich es in PHP machen sollte.

Also, wer dazu ne Antwort hat, bitte bitte keine PM oder Mail sondern schön hier rein ;)

Danke schonmal
phquest
Posts: 22
Joined: 2003-08-29 09:39

Re: Begegnungsauslosung in der Liga mit PHP. Aber wie ? :)

Post by phquest »

also die anzahl der begegnungen berechnet sich bei 15 Mannschaften mit 14+13+12+...+3+2+1

vielleicht ist das ja schonmal ein anfang *g*

phquest
manitwo
Posts: 59
Joined: 2003-04-05 16:07

Re: Begegnungsauslosung in der Liga mit PHP. Aber wie ? :)

Post by manitwo »

*Hochschieb*
wgot
Posts: 1675
Joined: 2003-07-06 02:03

Re: Begegnungsauslosung in der Liga mit PHP. Aber wie ? :)

Post by wgot »

Hallo,

ich kenn das Problem nur vom Schach, die Schach-Lösung läßt sich aber auf andere Turniere übertragen.

Bei großen Schachturnieren werden natürlich fertige Tabellen verwendet (gibt's zu Kaufen, sicher auch irgendwo im Inet), bei Unterhaltungs-Schnellturnieren (pro Spiel 10 Minuten, das ganze Turnier an einem Abend) verwendet man meist ein Durchrücksystem, das sich als Basis für ein Script verwenden läßt.

Das System ist unterschiedlich für gerade und ungerade Teilnehmerzahl und geht so:

Ungerade Teilnehmerzahl, z.B. 7 Spieler:

1 setzt aus, 2-4 sitzen auf der einen Seite, 5-7 auf der anderen, so daß sich 2 und 7 gegenübersitzen. 2 hat weiß, 3 hat schwarz, 4 hat weiß.

Für die nächste Runde wandert 2 auf Platz 1 (aussetzen), 1 setzt sich auf den Platz von 7, die anderen reihum.

Rundenzahl=(Spielerzahl+1)/2


Gerade Teilnehmerzahl, z.B. 6 Spieler:

1-3 sitzen auf der einen Seite, 4-6 auf der anderen so daß sich 1 und 6 gegenübersitzen. 1 hat weiß, 2 hat schwarz, 3 hat weiß.

Für die nächste Runde bleibt 1 auf seinem Platz sitzen, 2 wandert auf den Platz von 6, die anderen reihum, das Brett, an dem 1 sitzt (und immer sitzenbleibt) wird gedreht.

Rundenzahl=Spielerzahl/2


Durch die farblich abwechselnd liegenden Bretter hat ein Spieler (fast) immer abwechselnd Weiß oder Schwarz. Statt den Farben hat man in anderen Sportarten was anderes, z.B. Heimspiel/Auswärtsspiel. Der Erstgenannte in der Paarung hat dann eben Weiß, Heimspiel oder einen anderen kleinen Vorteil.

Ich hab das mal in ein PHP-Script umgesetzt, Spielerzahl im Script eintragen und aufrufen.

Und wer schreibt nun ein Script, das mein Script prüft? :roll:

Gruß, Wolfgang

Code: Select all

<?php
$spieler=8;

function belegen($spieler)
  {
      for ($s=0;$s<$spieler;$s++)
        if ($spieler>9)
          { $ergebnis[]=sprintf('%02d',$s+1); }
        else
          { $ergebnis[]=sprintf('%d',$s+1); }
    return $ergebnis;
  }

function ausgabe($liste,$spiele,$tausche,$ungerade)
  {
    $ergebnis='';
      if ($ungerade) { $ergebnis=array_shift($liste).'-- '; }
    $liste1=array_slice($liste,0,$spiele);
    $liste2=array_reverse(array_slice($liste,$spiele,$spiele));  
      for ($n=0;$n<$spiele;$n++)
        {
          $s1=array_shift($liste1);
          $s2=array_shift($liste2);
            if ($tausche) { $ergebnis.="$s2-$s1 "; }
            else { $ergebnis.="$s1-$s2 "; }
        }
    return rtrim($ergebnis)."<br>n";
  }

function ungerade($spieler)
  {
    $liste=belegen($spieler);
    $runden=($spieler+1)/2;
    $ergebnis='';
      for ($r=0;$r<$runden;$r++)
        {
            if ($runden>9) { $ergebnis.='Runde '.sprintf('%02d',$r+1).':  '; }
            else { $ergebnis.='Runde '.sprintf('%d',$r+1).':  '; }
          $ergebnis.=ausgabe($liste,$runden-1,$r%2,1);
          $unten=array_shift($liste);
          array_push($liste,$unten);
        }
    return $ergebnis;
  }

function gerade($spieler)
  {
    $liste=belegen($spieler);
    $runden=$spieler/2;
    $ergebnis='';
      for ($r=0;$r<$runden;$r++)
        {
            if ($runden>9) { $ergebnis.='Runde '.sprintf('%02d',$r+1).':  '; }
            else { $ergebnis.='Runde '.sprintf('%d',$r+1).':  '; }
          $ergebnis.=ausgabe($liste,$runden,$r%2,0);
          $fest=array_shift($liste);
          $unten=array_shift($liste);
          array_push($liste,$unten);
          array_unshift($liste,$fest);
        }
    return $ergebnis;
  }

if (($spieler<2) or ($spieler>99)) { $ergebnis='nur fuer 2-99 Spieler'; }
else if ($spieler%2) { $ergebnis=ungerade($spieler); }
else { $ergebnis=gerade($spieler); }
echo $ergebnis;
rootmaster
Posts: 483
Joined: 2002-04-28 13:30
Location: Hannover

Re: Begegnungsauslosung in der Liga mit PHP. Aber wie ? :)

Post by rootmaster »

im prinzip dürfte es auch so funzen, dass man die möglichen gegner pro team in einer 15x15-matrix speichert und die aktuellen begegnungen mittels zufallsvektor ermittelt. gezogene begegnungen sind dann in der matrix und vektor zu markieren:

also, man ordne den mannschaften nummern zu und ordne sie als 2D-array an. da eine mannschaft nicht gegen sich selbst spielen kann, sind in der hauptdiagonalen nullen:

m[1]=(0,2,3,..,15)
m[2]=(1,0,3,..,15)
...
m[15]=(1,...,14,0)

die ziehungen, dargestellt als paare, erfolgen folgendermaßen:

-- 1. spieltag --

spiel 1: mannschaft 1 hat frei (1,0)

der zufallsvektor ist also v(1)=(0,1,..,1)

spiel 2:
man ermittle in v(1) die nächste position != 0, also die 2.
man bilde das array der produkte m[2][k]*v(1)[k]
man wähle aus dem 1D-array zufällig ein element !=0 und merke sich die position n.
jetzt werden die positionen 2 und n in v(1) genullt und ebenfalls die positionen n in m[2] und 2 in m[n].
also
v'(1)=(0,0,1,..0,..1)
m[2]=(1,0,3,..,0,..15)
m[n]=(1,0,3,..,0,..15)

das 2. paar ist (2,n)

spiel 3:
man ermittle in v'(1) die nächste position != 0, zb die 2<u<=15.
man bilde das array der produkte m[k]*v'(1)[k]
man wähle aus dem 1D-array zufällig ein element !=0 und merke sich die position n'.
jetzt werden die positionen u und n' in v'(1) genullt und ebenfalls die positionen u in m[n'] und n' in m.
also
v''(1)=(0,0,1,..,0,1,..,0,1,..,0,..1)
m=(1,2,3,..,0,..,0,..15)
m[n']=(1,2,3,..,0,..,0,..15)

das 3. paar ist (u,n')

usw. usf. bis v'..'(1)=(0,0,0,..,0), das entspricht (15-1)/2 spielen + 1 "freispiel".

-- 2. spieltag --

spiel 1: manschaft 2 hat frei (2,0)

der zufallsvektor ist also v(2)=(1,0,1,..,1)

spiel 2:
man ermittle in v(2) die nächste position != 0, also die 3.
man bilde das array der produkte m[3][k]*v(2)[k]
man wähle aus dem 1D-array zufällig ein element !=0 und merke sich die position n.
jetzt werden die positionen 3 und n in v(2) genullt und ebenfalls die positionen n in m[3] und 3 in m[n].
also
v'(2)=(1,0,0,1,..0,..1)
m[3]=(1,2,0,..,0,..15)
m[n]=(1,2,0,..,0,..15)

das 2. paar ist (3,n)

spiel 3: usw. usf. s.o.

am 15. spieltag hat dann mannschaft 15 frei und die restlichen begegnungen wie oben.

bem. der zufallsvektor wird zyklisch durchlaufen, also positionen != 0 werden am ende des vektors wieder ab 1. position durchlaufen !
für die "rückrunde" sind die paare zu permutieren.

ps: dieser algorithmus ist ungetestet sollte aber verständlich und entsprechend leicht zb in php zu implementieren sein ;)

"back to the roots"