Mein erstes Spiel

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
Moon
User
Beiträge: 37
Registriert: Mittwoch 20. Dezember 2017, 15:21

Hey,

ich habe mal Schere Stein Papier programmiert. Wie findet ihr denn den Code dazu? Habt ihr für mich noch Verbesserungsvorschläge?

Mein Code:

Code: Alles auswählen

# 1. Spiel: Schere Stein Papier
# Wir benötigen die Bibliothek random . Diese muss zuerst importiert werden

import random

# 2. Spielanzeige 
print("Spiel1: Schere | Stein | Papier\n\n")

# 3. Figuren festlegen als liste
spielfiguren = ("Schere", "Stein", "Papier") 
            #index = 0, 1, 2

#4. playing_game als Boolean auf True setzen
playing_game = True

# 5. while schleife welche solange playing_game true ist das Spiel ausführt
while playing_game:
    
    figur = 0

    #6. Playerfigur dem User auswählen lassen 
    while figur not in (1,2,3):
        print("Wählen Sie bitte eine der folgenden Figuren aus:")
        figur = int(input("[1] Schere | [2] Stein | [3] Papier"))

    # 7. Spielfiguren haben den Index 0 = Schere, 1 = Stein, 2 = Papier. Aus diesem Grund muss von der Eingabe 1 abgezogen werden, da sonst 1 Stein wäre, ...
    player_figur = spielfiguren[figur-1]

    # 8. Computerfigur festlegen. Dies erfolgt durch random und der function randint. Die function randint gibt einen zufälligen Integer zurück. 
    #   Computer kann nur Figuren auswählen welche den index 0-2 haben. 
    # Hier wird eine zufällige Ganzzahl zwischen 0 und 2 ausgewählt
    computer_figur = spielfiguren[random.randint(0,2)]

    #****Spiellogik***

    # 9. Überprüfen ob der player die selbe Zahl wie der Computer ausgewählt hat, wenn ja Ausgabe, dass dies der Fall ist
    if player_figur == computer_figur:
        print("Sie haben die gleiche Figur wie der Computer ausgewählt. Bitte wählen sie nochmals eine Figur aus. Vielen Dank.")
    else:

        # 10. Gewinner festlegen
        # da wir nur 3 Figuren haben und schon 2 zur Überprüfung verwenden, benötigen wir nurnoch ein else, da nurnoch 1ne Figur zur Überprüfung vorhanden ist

        if player_figur == "Schere":
            if computer_figur == "Stein":
                print("Sie haben diese Runde leider verloren. Sie wählten die Figur {} und der Computer die Figur {}".format(player_figur, computer_figur))
            else:
                print("Sie haben diese Runde gewonnen. Sie wählten die Figur {} und der Computer die Figur {}".format(player_figur, computer_figur))

        if player_figur == "Stein":
            if computer_figur == "Schere":
                print("Sie haben diese Runde gewonnen. Sie wählten die Figur {} und der Computer die Figur {}".format(player_figur, computer_figur))
            else:
                print("Sie haben diese Runde leider verloren. Sie wählten die Figur {} und der Computer die Figur {}".format(player_figur, computer_figur))
        
        if player_figur == "Papier":
            if computer_figur == "Schere":
                print("Sie haben diese Runde leider verloren. Sie wählten die Figur {} und der Computer die Figur {}".format(player_figur, computer_figur))
            else:
                print("Sie haben diese Runde gewonnen. Sie wählten die Figur {} und der Computer die Figur {}".format(player_figur, computer_figur))
            

        #11. Spiel ist fertig. Nachfragen ob der User nochmal spielen möchte oder nicht
        play_again = "" 
        while play_again not in ("yes", "no"):
            play_again = input("Möchten sie das Spiel wiederholen? [y]yes [n]no")

        #12. Überprüfung ob play_again no beinhaltet, wenn ja die variable playing_game auf False setzen
        if play_again == "no":
            playing_game = False    
Benutzeravatar
pixewakb
User
Beiträge: 1409
Registriert: Sonntag 24. April 2011, 19:43

Ohne es zu testen, glaube ich nicht, dass das Spiel viel Freude macht, weil du andere Eingaben haben willst, als du prüfst. Ferner sollte mehr in Funktionen ausgelagert werden und könnte dann m. E. auch gestrafft werden.
Sirius3
User
Beiträge: 17712
Registriert: Sonntag 21. Oktober 2012, 17:20

@Moon: alle Kommentare kommentieren nur das offensichtliche. Kommentare sollten beschreiben, warum etwas gemacht wird, nicht was. »spielfiguren« ist eigentliche eine Liste, von gleichartigen Elementen. Die while-Schleife sollte eine while-True-Schleife sein, die man einfach per »break« verlassen kann. Auch die innere while-Schleife ist eine while-True-Schleife, weil die Abbruchbedingung erst am Ende und nicht am Anfang geprüft werden sollte. Für computer_figur nimmt man ab besten »random.choice«. Für die Gewinnerprüfung hast Du dreimal den selben Code, das sollte in eine if-Abfrage zusammengefasst werden.

Und was pixewakb schon geschrieben hatte, solltest Du alles in ein paar Funktionen aufteilen, zumindest sollte alles in Funktionen stehen.
Benutzeravatar
noisefloor
User
Beiträge: 3843
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

Du solltest ein paar Funktionen einbauen (z.B. für die Auswertung des Ergebnisses pro Runde), nicht alles als linearen Code runter schreiben.
Dann brauchst du auch keine 4 Ebenen für die Einrückung.

`spielfiguren` ist eine Konstante und sollte von daher GROSS geschrieben werden. Als Datenstruktur würde sich ein Dict oder ein NamedTuple anbieten.

Um zufällig ein Element aus einer Liste oder eine Tuple zu wählen gibt es `random.choice()`

""Sie haben die gleiche Figur wie der Computer ausgewählt. Bitte wählen sie nochmals eine Figur aus. Vielen Dank." - Warum? Warum muss der Mensch wählen und nicht der Computer? Abgesehen davon gibt es auch bei Stein, Schere, Papier ein unentschieden...

Die Variablennamen und die Frage nochmal ist ziemlich denglisch... entweder alles auf deutsch oder alles auf Englisch - aber nicht mischen.

Gruß, noisefloor
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

Habe tatsächlich noch nie Schere, Stein, Papier geschrieben – also hier mein Erstlingswerk 8)

@Moon: auch an diesem Code mag es noch Dinge zu verbessern geben und sicher kann man das Spiel auch anders implementieren. Aber hier hast Du ein Beispiel mit Konstante und Funktionen.

Code: Alles auswählen

import random


STATES = {n: figure for n, figure in enumerate(['Schere', 'Stein', 'Papier'])}


def get_user_choice():
    while True:
        choice = input("Wähle: [0] Schere, [1] Stein, [2] Papier, [e] Ende ").lower()
        if choice == 'e':
            return choice
        try:
            choice = int(choice)
        except ValueError:
            continue
        if 0 <= choice <= 2:
            return choice

        
def print_message(choice, message):
    print('Computerwahl: {}. {}'.format(STATES[choice], message))

    
def run_game():
    while True:
        user_choice = get_user_choice()
        if user_choice == 'e':
            break
        computer_choice = random.randint(0, 2)
        delta = user_choice - computer_choice
        if not delta:
            print_message(computer_choice, "Unentschieden")
        elif delta == 1 or delta == -2:
            print_message(computer_choice, "Du hast gewonnen")
        else:
            print_message(computer_choice, "Du hast verloren")

            
def main():
    print("Spiel: Schere, Stein, Papier\n")
    run_game()
    print("Ende.")

    
main()   
Sirius3
User
Beiträge: 17712
Registriert: Sonntag 21. Oktober 2012, 17:20

@kbr: ein Wörterbuch, beim dem die Schlüssel von 0 aufsteigende ganze Zahlen sind, ist nichts anderes als eine kompliziert geschriebene Liste. `continue` sollte man vermeiden, weil es den Programmfluß undurchsichtig macht. In Zeile 15 kann man einfach einen else-Block zu except benutzen. Bei nummerischen Werten würde ich ein `delta == 0` einem `not delta` vorziehen.

Und dann kann man die Wiederholungen von Schere, etc und den magischen Zahlen vermeiden.

Code: Alles auswählen

import random
 
STATES = ['Schere', 'Stein', 'Papier']
MESSAGES = [
    "Unentschieden",
    "Du hast gewonnen",
    "Du hast verloren"
]

def get_user_choice():
    while True:
        choice = input("Wähle: {}, [e] Ende ".format(", ".join(
            "[{}] {}".format(n,m) for n,m in enumerate(STATES)
        ))).lower()
        if choice == 'e':
            return choice
        try:
            choice = int(choice)
        except ValueError:
            pass
        else:
            if 0 <= choice < len(STATES):
                return choice
 
def run_game():
    while True:
        user_choice = get_user_choice()
        if user_choice == 'e':
            break
        computer_choice = random.randrange(len(STATES))
        delta = user_choice - computer_choice
        print('Computerwahl: {}. {}'.format(
            STATES[computer_choice], MESSAGES[delta % 3]))
           
def main():
    print("Spiel: {}\n".format(", ".join(STATES)))
    run_game()
    print("Ende.")
 
if __name__ == '__main__':
    main()
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

@Sirius3: wenn Du Dich nicht gemeldet hättest, wäre ich fast schon enttäuscht gewesen. Ja, die Nutzung einer Liste ist auch ok. Was mich etwas wurmt, ist das delta modulo - darauf hätte ich auf die Schnelle ruhig selbst kommen können. Aber was das continue betrifft: ich kenne diesen Standpunkt, verstehe ihn auch, teile ihn aber in dieser Pauschalität nicht. Im Gegenteil: Continue, gut eingesetzt, kann dazu beitragen, Code lesbar zu halten.
Moon
User
Beiträge: 37
Registriert: Mittwoch 20. Dezember 2017, 15:21

Hey,

erstmal viele Dank für die vielen Rückmeldungen und Codebeispiele wie man es doch besser machen kann. Der Code ist an manchen Stellen doch etwas komplex.

@pixewakb: Ich möchte andere Eingaben als ich prüfe? Ich sehe dies nicht so. Ich überprüfe doch welche Eingaben ich möchte.

@Sirius3: Ok. Alles klar. Ja ich habe eben laufe des Erlernens einer anderen Programmiersprache gelernt, dass das Kommentieren des Codes wichtig ist, damit auch jemand anderes den einfach versteht, die Funktionsweise, usw. Ja das tupel habe ich falsch kommentiert.

@noisefloor: Spielfiguren ist eine Konstante? Nein. Ein Tupel. Ja mein Englisch ist nicht so gut. Darum mische ich es. Alles klar. Dann muss ich mehr Englisch lernen.

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

@Moon: der Kommentar ist richtig (nur halt überflüssig), die Datenstruktur ist die falsche. `spielfiguren` muß eine Liste sein und darüber hinaus ist es auch noch eine Konstante.
Benutzeravatar
noisefloor
User
Beiträge: 3843
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

Konstante heißt, dass du die Werte nicht änderst. Es bleibt das ganze Spiel über Stein, Schere, Papier. Und diese Variablennamen schreibt man per Konvention groß, also SPIELFIGUREN (oder bei Sirius3: STATES).
Ja mein Englisch ist nicht so gut. Darum mische ich es.
Also für den Hausgebrauch (sprich, man hat keine Ambitionen, die Software zu verteilen) kannst du ja auch alles auf deutsch schreiben. Nur eben nicht mischen.

Gruß, noisefloor
MegaMark
User
Beiträge: 5
Registriert: Sonntag 14. Januar 2018, 22:07

Hey,
tolles Spiel
wenn du etwas Fortgeschrittener bist kannst du das bald auch besser.
Schau dir Mal Tkinter Buttons an(einfach und gut)
Gruß Mark
Moon
User
Beiträge: 37
Registriert: Mittwoch 20. Dezember 2017, 15:21

Hey,

ok alles klar. Ich werde dieses Spiel auch noch erweitern und dann das neue Script hier vorstellen und eure Meinung dazu einholen.

Grüße,
Moon
Antworten