Hat wer Verbessrungsvorschläge? Tic Tac Toe

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
KeozFPV
User
Beiträge: 12
Registriert: Montag 12. Juli 2021, 19:18

Hallo,
ich habe mich mal an ein Praxisprojet "Tic Tac Toe" gewagt. Hat alles mit Internet und diesem sehr nettem Forum geklappt. :D
Nun zu meiner Frage: hat eventuell jemand Verbesserungsvorschläge? Zum Beispiel bei zu kompliziert geschriebenen Sachen oder einfach nur Tipps?
Dies ist mein erstes richtiges Programm. Davor habe ich schonmal Schwachsinn ausprobiert. ; D Aber nichts ernstes.
Ich habe schon eine Vermutung das wenn man hunderte Spiele spielt es zu Problemen kommen könnte da das Spiel nie wirklich beendet wird, sondern sich eher in sich selbst öffnet. Stimmt das?

Hier der Code:

Code: Alles auswählen

#written by Keoz




def empty ():
    print("")
    print("")
    print("")
    print("")
    print("")
    print("")
    print("")
    print("")
    print("")
    print("")
    print("")
    print("")
    print("")
    print("")
    print("")



def menu ():
    current_player = "null"              #welcher Spieler ist an der Reihe

    current_player = input("Which player should start? X or O:")

    if current_player == "X" or current_player == "O":          #Spielstart
        empty()
        print('If you want to restart the game write "stop".')
        print("")
        game(current_player)

    if current_player != "X" or "O":        #falsche Eingabe
        empty()
        print("WRONG INPUT!")
        menu()




def game (var):
    stopvar = 1
    current_player = var

    one = "1"
    two = "2"
    tree = "3"
    four = "4"
    five = "5"
    six = "6"
    seven = "7"
    eight = "8"
    nine = "9"

    while stopvar == 1:                                    #Spielfeld
        print(seven + " | " + eight + " | " + nine)
        print(four + " | " + five + " | " + six)
        print(one + " | " + two + " | " + tree)

        print("")
        playerinput = input("It's your turn " + current_player + ":")

        if playerinput == "stop":           #spielstop
            empty()
            print("The game has been stopped.")
            print("")
            menu()

        if playerinput == one or playerinput == two or playerinput == tree or playerinput == four or playerinput == five or playerinput == six or playerinput == seven or playerinput == eight or playerinput == nine:
                                                #Gültigkeitsabfrage
            empty()

            if playerinput == "1":              #XO zuweisung
                one = current_player
            elif playerinput == "2":
                two = current_player
            elif playerinput == "3":
                tree = current_player
            elif playerinput == "4":
                four = current_player
            elif playerinput == "5":
                five = current_player
            elif playerinput == "6":
                six = current_player
            elif playerinput == "7":
                seven = current_player
            elif playerinput == "8":
                eight = current_player
            elif playerinput == "9":
                nine = current_player
            else:
                empty()
                print("WRONG INPUT!")
                continue

            if one == two == tree:          #gewinner bestimmung
                won(current_player)
            elif four == five == six:
                won(current_player)
            elif seven == eight == nine:
                won(current_player)
            elif seven == four == one:
                won(current_player)
            elif eight == five == two:
                won(current_player)
            elif nine == six == tree:
                won(current_player)
            elif seven == five == tree:
                won(current_player)
            elif nine == five == one:
                won(current_player)
            else:

                if current_player == "X":               #spielertausch
                    current_player = "O"
                else:
                    current_player = "X"

            if "1" != one and "2" != two and "3" != tree and "4" != four and "5" != five and "6" != six and "7" != seven and "8" != eight and "9" != nine:
                tie()               #unentschieden bestimmung

        else:
            empty()
            print("WRONG INPUT!")


def won (var):                  #gewonnen
    current_player = var
    print('Player "' + current_player + '" won the game!')
    print("")
    menu()


def tie ():                     #unentschieden
    print("It's a tie. I'm sorry.")
    print("")
    menu()

menu()
Danke schonmal im Voraus.
Gruß Jakob
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

`Rekursion` ist kein genereller Ersatz für Schleifen. Wenn ein `game` zu Ende ist, muß die Funktion zurückkehren und darf nicht `menu` aufrufen.
Warum nennst Du Deine Argumente alle `var` um sie gleich danach an einen sinnvollen Namen zu binden?
In `menu` hast Du einen Fehler in der zweiten if-Bedingung, die aber nicht weiter auffällt, wenn Du eh willst, dass der zweite if-Block immer betreten wird. Das macht man aber dann statt mit einem weiteren `if` mit `else`. `current_player` an den Wert "null" zu binden ist Unsinn, weil Du den Wert nie benutzt und in der nächsten Zeile immer überschreibst.
`stopvar` sollte den Wert `True` haben, irgendwann aber auch mal auf den Wert `False` gesetzt werden und einen besseren Namen bekommen. Was soll das Anhängsel `var`? Statt neun Variablen für die neun Felder benutze eine Liste.
KeozFPV
User
Beiträge: 12
Registriert: Montag 12. Juli 2021, 19:18

@Sirius3
Vielen Dank für die detaillierte Antwort. Ich werde diesmal alles Schritt für Schritt umsetzten! In Listen muss ich mich auf jeden Fall einlesen. Im Menü mit dem 2 Mal If hasst du Recht. Da habe ich was verpatzt. Und zu den Argumenten: ich wusste nicht das Ich die Argumente wie eine variable behandeln kann. Ich dachte man kann sie nur auslesen und nicht bearbeiten. Das "current_player = null" ist noch ein Überbleibsel vom testen. Und die "stopvar" sollte eigendlich benutzt werden um die Schleife zu unterbrechen. Jetzt habe ich leider eine Rekursion. Änder ich sofort.

Danke für deine Arbeit und Geduld. Ich hätte mir die vorigen Antworten mehr Anschauen sollen. Tut mir leid. Ich wollte nicht negativ aufgefallen.
Zwangsgestörter
User
Beiträge: 20
Registriert: Freitag 23. Oktober 2020, 19:00

Moin,

- Dein Spiel hat einen kleinen Bug. Bereits belegte Felder können noch mal überschrieben werden.
- Wenn du deine Eingabe nach dem prüfen auf ein "stop" in einen integer umwandelst, kannst du die Felder (natürlich vorher in eine Liste umwandeln) direkt adressieren und musst nicht mit einem ewigen if/else Konstrukt hantieren.
- Die Auswertung gehört in eine eigene Funktion.
- Dein "empty" kannst du auch mit print("\n"*20) machen statt der ewigen Wiederholung von print.

Grüße
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

@Zwangsgestörter: unbelegte Felder haben den Inhalt "1" bis "9", belegte Felder dagegen ein "X", bzw. ein "O". In der "Gültigkeitsabfrage" wird genau das geprüft, so dass in Kombination mit den `if`s bei "XO zuweisung" keine Felder überschrieben werden können. Ob das so geplant ist, kann ich natürlich nicht sagen, weil es doch etwas schwierig durchzusteigen ist.
KeozFPV
User
Beiträge: 12
Registriert: Montag 12. Juli 2021, 19:18

@Sirius3
Ja das ist so gedacht. Mit Sicherheit ist das aber nicht die schönste und sauberste Lösung.
KeozFPV
User
Beiträge: 12
Registriert: Montag 12. Juli 2021, 19:18

@Zwangsgestörter
Danke für die Anregungen!
Jedoch kann man nichts überschreiben.
Mit der Mischung "XO Zuweisung" und " Gültigkeitsabfrage" wird das verhindert.
Der Code ist ein bisschen kompliziert und unübersichtlich geschrieben.
Mein Fehler
Zwangsgestörter
User
Beiträge: 20
Registriert: Freitag 23. Oktober 2020, 19:00

ja, bei der Eingabe solltest du nur den eingegebenen Wert auf den passenden bereich prüfen und dann nur das eine Feld, was der Spieler beschreiben will testen.
Das macht das übersichtlicher und man weiß sofort, was das werden soll. Ich hatte dein riesen if (übrigens zu viele zeichen auf einer Zeile) als Prüfen der Benutzereingabe fehlgedeutet.

PS: Das in eine Funktion zu stecken macht das ganze deutlich lesbarer, weil dann nicht mehr "if playerinput == one or playerinput == two or playerinput == tree or playerinput == four or playerinput == five or playerinput == six or playerinput == seven or playerinput == eight or playerinput == nine:" dasteht, sondern s.Bsp: "if is_valid_player_input(input):"

Grüße,
Antworten