Erstellen einer "Kampfstatistik" in Python

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
schweito
User
Beiträge: 5
Registriert: Mittwoch 24. Februar 2021, 11:22

Hallo liebe Pythongemeinde,

ich bin relativ neu in der Pythonprogrammierung und bin aktuell dabei folgendes kleines Projekt zu realisieren:

- Generieren von Objekten zur Laufzeit (im Beispiel hier: Boxer) (funktioniert)
- Erstellen von zufälligen Kampfpaaren mit zufälligem Ausgang (funktioniert teilweise):

(i) funktioniert: Erstellung einer "unabhängigen" Kampfbilanz für jeweils einen Boxer

(ii) Problemstellung (habe noch nicht mal eine Ansatz für die Lösung):

Wenn man davon ausgeht, dass man 45 Kämpfer hat, die u.U. gegeinander gekämpft haben könnten - sind die Kampfstatistiken ja miteinander verflochten. Wenn Kämpfer A gegen Kämpfer B gewonnen hat
muss die Statistik für B das auch reflektieren. Da ich die zufälligen Kampfrekorde aktuell nacheinander zufällig generiert werden (jeweils eine Komplettstatistik für einen Kämpfer am Stück) - habe ich aktuell
keine Idee wie man bei der Generierung die Verflechtung der Kampfstatistiken bewerkstelligen könnte. Die Routin trackt momentan keinen der Vorgänge und vergleicht auch nichts bei der Erstellung des
Kampfrekords des nächsten Kämpfers.


Mein Code schaut aktuell wie folgt aus und generiert bisher voneinander unabhängige Kampfrekorde, das würde ich gerne so ändern, das sie Kampfbilanzen untereinander "konsistent" sind.

Code: Alles auswählen


# Code für die Statistik
    repeat = 0  # Schleifenvariable die für einen Kämpfer bis zu 45 Kämpfe für eine Statistik generiert
    upper_limit = random.randint(25, 45)  # Zufällige Anzahl an Kämpfen

    k = 0  # Schleifenvariable die den Kämpfer für die nächsten Paarungen festlegt
    while k < upper_limit:  # Solange für den Kämpfer k noch nicht alle Kämpfe generiert wurden

        while repeat < upper_limit:  # Generiere Kämpfe
            pair_var = random.randint(0, 44)  # 45 mögliche Paarungen für den Kämpfer k 
            result = random.randint(1, 3)  # 3 Resultate möglich: Gewonnen, Unentschieden, Verloren
            if k == pair_var and k < upper_limit:  # Wenn man gegen sich selbst kommt springe weiter
                pair_var = pair_var + 1
            if k == pair_var and k == upper_limit:
                break
            if pair_var == upper_limit:
                pair_var=upper_limit

            print(ai_boxer[k].fname + " " + ai_boxer[k].lname + "," + str(result) + ", " + ai_boxer[
                pair_var].fname + " " + ai_boxer[pair_var].lname)  # Ausgabe der Paarungen

            repeat = repeat + 1  # Nächster Gegner für k

        print("\n")
        if k < upper_limit:
            repeat = 0  # Zurücksetzen des Paarungsparameters
            k = k + 1  # Wähle den nächsten Gegner für Paarungen
        else:
            repeat = 0

    # Ende Statistik

Wie man sieht, haben die Stastistiken so keinen korrekten Bezug zueinander. Gibt es hier eine Möglichkeit, das konsisten zu machen?

Viele Grüße und Danke für die Mühe,
Timo
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Alles was du dafür tun musst ist doch einfach nur den Kampf bei beiden Kämpfern nachhalten. Das verändert wahlweise deine Turniergestaltung - jeder kämpft gegen jeden, und das ggf n mal - oder sorgt nur bei großen Zahlen für in etwas ausgeglichene Kampfanzahl, weil natürlich eine zufällige Wahl des Gegners einige Boxer öfter drankommen lässt. Ob das relevant ist, hängt von deiner Aufgabenstellung ab. Realistischerweise ist das ja so auch in der Realität - anders als beim Fußball gibt es ja keine Liga.
schweito
User
Beiträge: 5
Registriert: Mittwoch 24. Februar 2021, 11:22

Danke für die schnelle Antwort, wie würde denn das Nachhalten als Code aussehen?
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Jeder Boxer hat eine Liste mit Kämpfen. Wenn du zwei Gegner bestimmt hast, und den Kampf auswürfelst, trägst du das Ergebnis eben in beide Listen ein. Schon hat jeder eine vollständige und korrelierte Statistik.
schweito
User
Beiträge: 5
Registriert: Mittwoch 24. Februar 2021, 11:22

Alles klar,
das werde ich versuchen. Vielen Dank.
Sirius3
User
Beiträge: 18274
Registriert: Sonntag 21. Oktober 2012, 17:20

@schweito: wenn etwas sowohl im if-Block als auch im else-Block steht, wie das `repeat = 0`, dann kann man es auch einmalig danach schreiben.
Das `repeat = 0` steht aber sowieso an der falschen Stelle, man sollte es VOR die innere while-Schleife schreiben, Variablen initialisiert man und resetet nicht den Wert hinterher.
Die while-Schleifen sind eigentlich for-Schleifen.

k kann niemals größer oder gleich upper_limit sein, die ersten beiden if-Abfrage sind also unnötig kompliziert.
Das dritte if macht gar nichts.

Strings setzt man nicht per + zusammen, sondern nutzt Formatstrings.
Benutze keine Abkürzungen, wenn die first_name und last_name meinst, dann schreib das auch

Code: Alles auswählen

# Code für die Statistik
upper_limit = random.randint(25, 45)  # Zufällige Anzahl an Kämpfen
for k in range(upper_limit):
    boxer1 = ai_boxer[k]
    for repeat in range(upper_limit):
        pair_var = random.randint(0, 44)  # 45 mögliche Paarungen für den Kämpfer k 
        result = random.randint(1, 3)  # 3 Resultate möglich: Gewonnen, Unentschieden, Verloren
        if k == pair_var:  # Wenn man gegen sich selbst kommt springe weiter
            pair_var += 1
        boxer2 = ai_boxer[pair_var]
        print(f"{boxer1.fname} {boxer1.lname},{result}, {boxer2.fname} {boxer2.lname}")
    print("\n")
Wenn man eigentlich eine Liste hat, dann iteriert man direkt über diese Liste. Sollte diese Liste 46 Einträge haben, dann benutzt man nicht irgendwo magische Zahlen wie 45 oder 44, sondern die Länge der Liste, bzw. auch direkt random.choice.

Code: Alles auswählen

# Code für die Statistik
upper_limit = random.randint(25, len(upper_limit) - 1)  # Zufällige Anzahl an Kämpfen
for boxer1 in ai_boxer[:upper_limit]:
    for repeat in range(upper_limit):
        while True:
            boxer2 = random.choice(ai_boxer)
            if boxer1 is not boxer2:
                break
        result = random.randint(1, 3)  # 3 Resultate möglich: Gewonnen, Unentschieden, Verloren
        print(f"{boxer1.fname} {boxer1.lname},{result}, {boxer2.fname} {boxer2.lname}")
    print("\n")
Die for-Schleifen sehen immer noch komisch aus, ich hatte erwartet, dass man da eine bestimmte Anzahl an Paaren erzeugt, mit einer Schleife nicht zwei.
Antworten