Tischfussball Turniermanager: Matchmaster

 

Code Download

 

Wichtiger Hinweis:

Dieses Programm ist in der vorliegenden Form nur für 2 Gruppen voll lauffähig, kommen mehr Gruppen zustande, kann nur die Gruppenphase gespielt werden, falls Interesse besteht das Programm für den Turnierbetrieb einzusetzen, ersuche ich um eine E-Mail an 1naitsabes1@gmx.at

Ich werde dann Auskunft über den Stand der Programmierung geben und bei Fertigstellung das voll lauffähige Programm schicken!

 

 

 

Modus: Gruppenphase und anschließendes Doppel-Ko System.

 

 

Wenn die Anmeldezeit des Turniers beginnt, startet man das Programm.

 

 

Nun befindet man sich im Startfenster.

 

 

 

 

Drückt man Enter, bzw. klickt man auf den Button  , öffnet sich ein kleines Fenster, welches den Namen des Spielers bzw. des Teams verlangt, das an dem Turnier teilnehmen will.

 

 

 

Hat man den Namen korrekt eingegeben, bestätigt man die Eingabe durch Enter.

Will man dieses Fenster verlassen, ohne eine Eingabe vorzunehmen, muss man die Escape Taste drücken.

 

Der eingegebene Name erscheint nun in der Liste  und die Information über die Anzahl der Teilnehmer  zeigt an wieviele Spieler sich in dieser Liste befinden.

 

 

Wenn man irrtümlicherweise einen Namen doppelt eingibt, wird man durch einen Warnton darauf hingewiesen und die Spielerinformation  informiert darüber das der Teilnehmer bereits vorhanden ist.

 

Hat man eine falsche Eingabe vorgenommen, bzw. will man einen Spieler wieder aus der Teilnehmerliste entfernen, muss man ihn mit der Maus anwählen.

Dadurch wird der Button  aktiviert, dessen Betätigung den Spieler wieder aus der Liste entfernt.

 

Sobald man die Mindestteilnehmeranzahl von 8 Spielern erreicht hat wird der Button  aktiviert.

 

Wenn die Anmeldefrist abgelaufen ist, betätigt man diesen Button und erhält man ein Fenster,

 

 

 

 

welches über die Aufteilung in Gruppen und über die Anzahl der aufstiegsberechtigten Spieler in die Finalrunde informiert.

 

 

Schließt man dieses Fenster mittels OK Button, so wird das Turnier gestartet.

Nun können keine weiteren Spieler mehr hinzugefügt werden, was lästige Ausreden erspart.

(Es kommt leider sehr oft vor das Spieler nachträglich dem Turnier beitreten wollen, obwohl die Anmeldefrist bereits abgelaufen ist).

 

 

Die Spieler werden nunmehr in die, der Teilnehmerzahl entsprechende Anzahl von Gruppen zufällig aufgeteilt.

 

 

Man erhält ein neues Fenster, welches die Hauptinformationen über den Turnierverlauf enthält:

 

 

 

Im Bereich  sieht man nun Tabellen die Namen und Punkte der Spieler darstellen.

Man weiß nun welche Spieler in welche Gruppe aufgeteilt wurden und kann dadurch einschätzen wie hoch die Chance ist in die Finalgruppe aufzusteigen (wenn man seine Gegner kennt).

Diese Tabelle wird nach jeder Partie aktualisiert, daher kann man im Laufe des Turniers durch einen kurzen Blick auf diese Tabellen erkennen, wie es um die Platzierung der einzelnen Spieler steht, bzw. wer am besten Weg ist aufzusteigen.

 

Das Kernelement für den Turnierverlauf stellt der Bereich  dar:

Hier sind alle noch auszutragenden Spielpartien aufgelistet.

 

Will man eine Partie spielen, aktiviert man sie durch Doppelklick, wodurch diese Partie in den Bereich  übertragen wird.

Je nach Anzahl der zur Verfügung stehenden Tische wiederholt man diesen Schritt.

 

Doppelklicken dieser Partie öffnet das Ergebnisfenster.

Eine Partie ist zu Ende gespielt, bis ein Spieler ein sechstes Tor schießt, bzw. bis ein 5:5 erreicht wird.

 

 

 

Das Fenster kann durch Betätigen der Escape Taste geschlossen werden, ohne eine Ergebniseintragung vorzunehmen.

 

Rechts von den jeweiligen Teilnehmernamen werden die erzielten Tore entweder durch Anklicken und Auswählen, bzw. durch Tasteneingabe festgelegt.

 

Kommt ein gültiges Ergebnis zustande, wird im Bereich  der Spielausgang wiedergegeben und der Button OK aktiviert.

 

 

Die Betätigung des OK Buttons bestätigt das Ergebnis und man gelangt zum "Partienfenster" zurück.

 

Das Ergebnis wird in Punkte umgerechnet und den jeweiligen Spielern zugerechnet und deren Platzierung innerhalb der Gruppe aktualisiert.

 

 

Wird ein Tisch durch Spielbeendigung frei, belegt man ihn mit einer weiteren Partie aus der Liste der ausstehenden Partien.

So verfährt man bis keine ausstehenden Partien mehr vorhanden sind.

 

Im Bereich  können Informationen über den Turnierverlauf der Spieler ermittelt werden.

 

 

Durch Auswählen der einzelnen Spieler aus den jeweiligen Gruppen,

öffnet sich ein weiteres Fenster, welches Informationen über Punkte und Torverhältnis sowie eine Liste der bisherigen Begegnungen enthält.

 

 

 

Ein positives Torverhältnis wird grün, ein negatives rot dargestellt.

 

Die Tabelle enthält die Namen der Gegner und den Ausgang der gespielten Partie.

 

Die Spalte "Tore +" listet die erzielten Tore auf, die Spalte "Tore -" die  erhaltenen Tore. Um einen schnellen Überblick zu erlangen, werden verlorenen Partien durch rote Untermalung der Toranzahl und gewonnene Partien durch grüne Untermalung dargestellt.

Um dieses Fenster zu schließen, betätigt man den Button EXIT.

 

Der Bereich  stellt Informationen darüber dar, wer aufsteigt.

 

 

Sind die Austiegsberechtigten der jeweiligen Gruppen für die nächste Runde festgelegt, wird dies durch deren Auflistung und der Information, dass die Gruppe fertig ist, bestätigt.

 

Im Fall von Punktegleichstand von potentiellen aufstiegsberechtigten Teilnehmern,

 

 

wird geprüft wer das bessere Torverhältnis hat. Ist dieses ebenfalls identisch,

sind Entscheidungpartien notwendig, die in der Lister der ausstehenden Partien angezeigt werden.

 

 

Nun verfährt man wie zuvor, bis sämtliche Aufstiegsberechtigten feststehen.

 

 

 

Ist dies der Fall erscheint ein OK Button, durch dessen Betätigung eine Liste dargestellt wird.

Spieler, die den Aufstieg in die Finalrunde nicht geschafft haben, werden entsprechend ihrer Endplatzierung aufgelistet.

 

 

 

Die Spieler, die es geschafft haben in die Endrunde aufzusteigen, werden einem Doppel-Ko Raster zugeordnet, der sich aus einer Gewinnerseite und einer Verliererseite zusammen setzt.

 

 

Die Liste der ausstehenden Partien erhält nun weitere Partien.

Die Tordifferenz dieser Begegnungen ist nun irrelevant und ein Unentschieden ist nicht möglich.

 

Jeder Spieler kann einmal Verlieren und hat trotzdem noch die Chance das Turnier zu gewinnen.

 

Hat er seine zweite Partie verloren, wird seine Platzierung in der Ergebnisliste dargestellt.

Wenn alle Platzierungen feststehen ist das Turnier beendet.

 

 

 

 

Installation

 

 

Der Ordner Turniermanager wird direkt auf die Laufwerkspartition C: kopiert.

C:\Turniermanager.

In diesem Verzeichnis findet man eine Datein namen Turnier, die man an einem Ballicon erkennt.

Durch Doppelklick auf diese Datei startet man das Programm.

 


Klassendiagramm

 

Alle Variablen und Methoden, die der Darstellung, bzw. Bearbeitung von Grafikkomponenten dienen, sind in diesem Klassendiagramm nicht enthalten.

 


Implementierung:

 

Erklärung der Klassen:

Da das Programm sehr viele Klassen enthält die lediglich für die Darstellung der Komponenten verantwortlich sind, habe ich nur ein paar Klassen und ein paar deren Methoden ausgewählt, die einen kleinen Einblick in das Programm gewähren sollen.

 

Mischer:

 

Diese Klasse bekommt das Array mit den Spielernamen übergeben, aus welchen Instanzen der Klasse Spieler erzeugt werden.

Die Position der Spieler im Array wird dann zufällig gemischt und sie werden in Gruppen eingeteilt.

 

Das Programm teilt Spieler in Gruppen ein, dafür ist die Berechnung der Größe der einzelnen Gruppen notwendig: wie dieser Algorithmus funktioniert wird nun erläutert.

 

Gruppe A:

erhält immer die Gesamtzahl der Spieler dividiert durch die Anzahl der Gruppen.

 

Gruppe B:

 

Bei insgesamt 2 Gruppen:

Entspricht der Größe der Gruppe A und der Anzahl der restlichen Spieler (falls die Anzahl von Mitspielern ungerade ist).

 

Bei insgesamt 3 Gruppen:

Entspricht der Größe der Gruppe A und der Hälfte der Anzahl des Restes (falls die Anzahl der Mitspieler nicht restlos durch 3 teilbar ist und wenn der Rest der Division der Anzahl der Mitspieler durch die Anzahl der Gruppen größer als 1 ist).

 

Bei insgesamt 4 Gruppen:

Entspricht der Größe der Gruppe A und einem Drittel der Anzahl des Restes (wenn der Rest der Division der Anzahl der Mitspieler durch die Anzahl der Gruppen größer als 2 ist).

 

Gruppe C:

 

Bei insgesamt 3 Gruppen:

Entspricht der Größe der Gruppe A und der Hälfte des Restes (wenn der Rest der Division der Anzahl der Mitspieler durch die Anzahl der Gruppen 2), bzw. den Rest dieser Division.

 

Bei insgesamt 4 Gruppen:

Entspricht der Größe der Gruppe A und einem Drittel des Restes (wenn der Rest der Division der Anzahl der Mitspieler durch die Anzahl der Gruppen 3 ist),

bzw. die Hälfte wenn der Rest dieser Division 2 ist

 

Gruppe D:

Je nach Größe des Restes der Division der Anzahl der Mitspieler durch die Anzahl der Gruppen.

Ein Drittel wenn der Rest 3 beträgt, die Hälfte wenn der Rest 2 beträgt, bzw. den gesamten Rest wenn dieser 1 oder 0 beträgt.

 

 

Klasse Spieler:

 

Wichtige Variablen:

 

Object [][] gegnerarray

 

Hier werden die Daten über die bereits gespielten Partien gespeichert.

 

int pruefsumme

 

speichert die Prüfsumme für die Prüfung, ob Entscheidungspartien notwendig sind.

 

Wichtige Methoden:

 

public void toreadd (int toreg, int toree)

 

Diese Schnittstelle ist dafür zuständig, dem Spieler seine Punkte zuzuteilen.

toreg bedeutet geschossene Tore und toree bedeutet erhaltene Tore.

Diese Informationen werden in Punkte umgerechnet und die Anzahl der Tore um deren Wert erhöht, um das Torverhältnis errechnen zu können.

 

public int pruefsumme()

 

Die Prüfsumme ist sehr wichtig um einen Spieler eindeutig eine Platzierung innerhalb seiner Gruppe zuzuordnen.

 

Es steigen pro Gruppe jeweils 2 oder 3 Spieler auf.

Die in der Spielerklasse implementierte CompareTo Methode sortiert die Spieler anhand einiger Variablen, allerdings platziert der Computer, wenn es Gleichstand gibt, einen Spieler vor einem anderen.

 

Man muss nun überprüfen können ob der Spieler der auf zB. Platz 4 geführt wird, wirklich ein schlechteres Ergebnis hat als der, dem Platz 3 zugeordnet wurde, denn theoretisch könnten die beiden ja exakt die selbe Punkteanzahl und das gleiche Torverhältnis haben und der Spieler, der die vierte Position in der Gruppe hat, würde dann ungerechterweise nicht aufsteigen können.

 

Die Formel lautet:         pruefsumme = ((Punkte*1000)+(tv)+(ent*100))

 

Da der maximale Wert den ein Integer erreichen kann 2147483647 ist brauche ich mir keine Sorgen machen das dieser Wert erreicht, bzw. überschritten wird.

 

Das Torverhältnis (tv) kann ohne Vergrößerung dazugezählt werden um den Platz einesSpielers eindeutig zu identifizieren.

ent bezeichnet die Punkte die bei (eventuell notwendigen) Entscheidungspartien gesammelt werden.

Dieser Wert wird mit 100 multipliziert, da er sonst theoretisch größer bzw. gleich dem Torverhältnis sein kann.

Auf den ersten Blick scheint es zwar so als könnte das Probleme verursachen doch ein Torverhältnis von +100 ist bei dieser Art von Turnier unmöglich.

 

(das wären mindestens 17 Partien, das entspräche einer Gruppe von 18 Teilnehmern, wobei zu Bedenken ist das der zweite dann genau gleich viele Punkte erreichen müsste, da der erste sonst bereits einen Vorsprung von 3000 Punkten hat.

Wenn man das berücksichtigt erhöht sich die Anzahl der zu spielenden Partien, bzw. der Teilnehmer pro Gruppe weiter.

Da die Spieler auf maximal 4 Gruppen aufgeteilt werden entspräche das mindestens 18*3+19=73 Spieler und für eine so grosse Anzahl von Spielern ist dieser Turniermodus sowieso nicht geeignet, da das Turnier dann bestimmt einige Tage dauern würde)

 

Die Variable „ent“ scheint jedoch Potential zu haben, gleich groß zu sein wie ein Punkt, (wenn 10 Entscheidungspartien gespielt werden) aber auf jeden Fall ist sie größer als das Torverhältnis.

 

Nun könnte man Bedenken haben, wenn 4 Spieler dieselbe Punkteanzahl haben jedoch zwei von ihnen ein etwas besseres Torverhältnis (das auch ident ist).

Spieler A Tv=+10

Spieler B Tv=+10

Spieler C Tv=+8

Spieler D Tv=+8

Es werden nun zwei Entscheidungspartien gespielt (zwischen A und B sowie zwischen C und D)

Gewinnt A ist er sicher erster, gewinnt C hätte er eine höhere Prüfsumme als der Spieler B.

 

Warum das allerdings kein Problem darstellt wird in der Klasse Haupt beschrieben.

 

 

Klasse Gruppen:

 

 

Wichtige Variable:

 

jTable1:

 

In dieser Tabelle werden die Spieler und deren Punkte dargestellt um einen Überblick über die momentane Platzierung der Spieler innerhalb ihrer Gruppe zu erlangen.

Dieser JTable wird mit einem DefaultTableModel und einem DefaultColumnModel instanziert.

 

Wichtige Methoden:

 

dtm.setDataVector(getSpieler(tn), columnNames)

dtm ist der Name meines DefaultTableModels, dem ich einen DataVector übergebe, welcher sich die Daten durch Aufruf der Methode „getSpieler“ holt.

ColumnNames ist ein Array von zwei Strings, dieser Wert wird nicht verändert, er beinhaltet lediglich die Namen der Spalten sowie Anweisungen für die Spaltenbreite und ihre Editierbarkeit.

 

public Object[][] getSpieler(Spieler [] tn)

 

Hier wird der Daten Vektor für den JTable erzeugt.

Dafür wird die Methode „sort“ aufgerufen, die die Spieler innerhalb ihrer Gruppe sortiert

Das wird durch die Implementierung von Comparable und der entsprechenden  CompareTo Methode in der Klasse Spieler ermöglicht.

Dadurch wird die Platzierung der Spieler, entsprechend ihrer Punkten, bzw. bei Gleichstand ihres Torverhältnisses in entsprechender Reihenfolge, nach jeder Änderung der Daten (Ergebnis einer Partie) aktualisiert.

 

public void spielen(Spieler[] sgra)

 

Diese Methode errechnet die zu spielenden Partien.

 

Dafür wird das Programm mit einer „for“ Anweisung beauftragt, (der Anzahl der Spieler entsprechend) eine zweite for Anweisung auszuführen welche so lange Instanzen von Partien (durch Übergabe von 2 Spielern und deren Gruppeneinteilung) erzeugt, bis die Position im Array erreicht wird die der erste Spieler inne hat, dann wird diese Position um eins erhöht und für die nächsten Spieler genauso verfahren.

Dadurch werden so viele Partien erzeugt, das jeder Spieler einmal gegen jeden anderen Spieler spielt.

 

 

Klasse Haupt:

 

 

Hier wird der gesamte Turnierverlauf gesteuert,

die Klasse wird aufgerufen indem man ihr ein Array übergibt das Gruppen enthält.

 

 

Wichtige Methoden:

 

public void spieleberechnen(Partie apartie[])

 

hier wird dem DefaultListModel der JList, sowie der Hilfsliste ein String zugeführt, der den Namen der Partie enthält und der Partieliste wird die Partie zugeführt.

 

private void laufendKlick(MouseEvent mouseevent)

 

wird auf ein Element der JList der laufenden Partien geklickt, wird zunächst geprüft ob ein Doppelklick durchgeführt wurde, dann wird eine neue Instanz von Ergebnis erzeugt, der die Partie übergeben wird.

 

Allerdings enthält das DefaultListModel der JList, welche die laufenden Partien enthält nur den Namen der Partie und nicht sie selbst.

Da aber eine Partie übergeben werden muss, wird gefragt welchen Index der Name der Partie in der Hilfsliste hat.

Dieser Index entspricht dem der Partieliste.

Dann wird abgefragt welcher Gruppe die Partie zugeordnet wurde, das können Werte von 1-4 für Gruppe A-D; 5-8 für die Entscheidungsspiele der jeweiligen Gruppe und 9-33 für die Partien des Doppel-Ko Systems (Finale) sein.

 

Wenn das DefaultListModel 1 und das DefaultListModel 2.kein Element mehr beinhalten (keine ausstehende und keine laufende Partie mehr), wird geprüft ob die Gruppeneinteilung kleiner als 9 ist (das bedeutet, es handelt sich um kein Finalspiel).

Ist das der Fall wird die Methode auswerten() aufgerufen.

 

 

 

 

 

auswerten()

 

Hier wird je nach Anzahl der Gruppen geswitcht, und die Methode entscheidungsspiele aufgerufen.

Mit den Daten die diese Methode erzeugt, kann entschieden werden ob noch Entscheidungsspiele zu spielen sind, oder ob mit dem Doppel-Ko System begonnen werden kann.

 

Wenn es soweit ist das das Doppelko System beginnt, werden die Spieler, welche unglücklicherweise den Aufstieg in die Finalrunde nicht geschafft haben, ArrayListen zugeführt, aus welchen sich dann die Tabelle, welche das Ergebnis des Turniers abbildet bedient, um den Spielern ihre Platzierungen zuzuweisen.

 

entscheidungsspiele(Spieler aspieler[], int i)

 

Hier werden die Prüfsummen der ersten 3 Spieler abgefragt.

 

Dann wird der erste Spieler einer ArrayList zugeführt und mit einer „for-Schleife“ geprüft, ob die anderen Spieler die gleiche Prüfsumme haben, wenn ja werden sie ebenfalls dieser ArrayList zugeführt.

 

(Hier ist zu erkennen das das „Problem“ das in der Klasse Spieler beschrieben wurde kein solches ist.

Die Spieler werden durch die in der Spielerklasse überschriebene CompareTo Methode sortiert, hier wird erst nach dem Ergebnis der Entscheidungspartien verglichen wenn es einen Gleichstand bei dem Torverhältnis gibt, welches wiederum nur verglichen wird wenn es Punktegleichstand gibt.

 

Folglich kann der als zweiter positionierte Spieler eine höhere Prüfsumme haben, das ist völlig egal, da ja nur geprüft wird ob die Prüfsumme ident ist.)

 

Dann wird geprüft ob diese ArrayList mehr als ein Element enthält, da zu Beginn ein Spieler zugeführt wurde, ist dies der Fall wird einer anderen ArrayList eine neue Gruppe hinzugefügt, welche die Spieler mit Punktegleichstand enthält.

 

Dann wird die erste ArrayList wieder gelöscht und der zweite Spieler wird gefragt ob seine Prüfsumme der des ersten entspricht.

Ist dies der Fall, wurde er bereits in die Gruppe der „gleichen“ Spieler, die in der ArrayList der ausstehenden Gruppen gespeichert wird, aufgenommen, sonst durchläuft er denselben Prozess, der vorher für den ersten Spieler beschrieben wurde.

Derselben Prüfung unterzieht sich nun auch der dritte Spieler.

 

Der Methode auswerten wird dann die ArrayList, welche die Gruppen enthält übergeben.

(diese prüft ob diese ArrayList überhaupt Elemente enthält und verhält sich dementsprechend).