BlackJack: Wie kann Ich es vereinfachen?

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
pacman3011
User
Beiträge: 4
Registriert: Freitag 19. Juni 2020, 11:34

Sehr geehrte Python-Gemeinde,

ich habe mich vor knapp einer Woche dazu entschieden, eine Programmiersprache zu lernen. Nachdem ich knapp 1 Woche Basiswissen wie ein Schwamm absorbiert habe, ist mir aufgefallen, dass die praktische Umsetzung doch nicht ganz so einfach ist wie vermutet. Viele gelernte Sachen ergeben im praktischen keinen Sinn für mich. Ich habe mich nun an mein erstes Projekt rangetraut, welches Ich komplett ohne Recherche erstellen wollte(BlackJack). Ich habe es bis jetzt nur geschafft mit while-Loops und if-Statements gewisse Funktionen einzubauen. Ich weiß aber auch, dass der Code wahrscheinlich der reinste Müll ist. Zu viel Code für zu wenig Funktion. Habt ihr Tipps, wie ich das ganze vereinfachen kann? Was sollte ich mir vielleicht nochmal durchlesen?

Code: Alles auswählen

import random

wins = 0
losses = 0
ties = 0

print("BLACK JACK")

while True:
        print("%s wins, %s losses, %s ties" % (wins, losses, ties))
        while True:

            dealtCard = int(random.randint(1, 11))
            dealtCard2 = int(random.randint(1, 11))
            dealtCard3 = int(random.randint(1, 11))
            dealtCard4 = int(random.randint(1, 11))
            dealtCard5 = int(random.randint(1, 11))

            comCard = int(random.randint(1, 11))
            comCard2 = int(random.randint(1, 11))
            comCard3 = int(random.randint(1, 11))
            comCard4 = int(random.randint(1, 11))
            comCard5 = int(random.randint(1, 11))

            print("What do you wanna do?")
            hit = str(input())
            if hit == "hit":
                print(dealtCard)

            print("The dealer has " + str(comCard))

            print("What do you wanna do?")
            hit = str(input())
            if hit == "hit":
                print(dealtCard2)
                print("Your sum is: " + str(dealtCard + dealtCard2))
                if dealtCard2 + dealtCard > 21:
                    print("You lost!")
                    losses += 1
                    break
            elif hit == "check":
                continue

            print(comCard2)
            print("The dealer has " + str(comCard + comCard2))
            if comCard + comCard2 > 21:
                print("The dealer lost!")
                wins += 1
                break
            if comCard + comCard2 == 21:
                print("Dealer has Black Jack")
                break

            print("What do you wanna do?")
            hit = str(input())
            if hit == "hit":
                print(dealtCard3)
                print("Your sum is: " + str(dealtCard + dealtCard2 + dealtCard3))
                if dealtCard3 + dealtCard2 + dealtCard > 21:
                    print("You lost!")
                    losses += 1
                    break
            elif hit == "check":
                continue

            print(comCard3)
            print("The dealer has " + str(comCard + comCard2 + comCard3))
            if comCard + comCard2 + comCard3 > 21:
                print("The dealer lost!")
                wins += 1
                break
            if comCard + comCard2 + comCard3 == 21:
                print("Dealer has Black Jack")
                break

            print("What do you wanna do?")
            hit = str(input())
            if hit == "hit":
                print(dealtCard4)
                print("Your sum is: " + str(dealtCard + dealtCard2 + dealtCard3 + dealtCard4))
                if dealtCard4 + dealtCard3 + dealtCard2 + dealtCard > 21:
                    print("You lost!")
                    losses += 1
                    break
            elif hit == "check":
                continue

            print(comCard4)
            print("The dealer has " + str(comCard + comCard2 + comCard3 + comCard4))
            if comCard + comCard2 + comCard3 + comCard4 > 21:
                print("The dealer lost!")
                wins += 1
                break
            if comCard + comCard2 + comCard3 + comCard4 == 21:
                print("Dealer has Black Jack")
                break

            print("What do you wanna do?")
            hit = str(input())
            if hit == "hit":
                print(dealtCard5)
                print("Your sum is: " + str(dealtCard + dealtCard2 + dealtCard3 + dealtCard4 + dealtCard5))
                if dealtCard5 + dealtCard4 + dealtCard3 + dealtCard2 + dealtCard > 21:
                    print("You lost!")
                    losses += 1
                    break
            elif hit == "check":
                continue

            print(comCard5)
            print("The dealer has " + str(comCard + comCard2 + comCard3 + comCard4 + comCard5))
            if comCard + comCard2 + comCard3 + comCard4 + comCard5 > 21:
                print("The dealer lost!")
                wins += 1
                break
            if comCard + comCard2 + comCard3 + comCard4 + comCard5 == 21:
                print("Dealer has Black Jack")
                break
        break
Ich weiß auch, dass einige Funktionen des Spiels fehlen, jedoch bin Ich dafür noch zu blöd. Seit bitte nicht zu hart zu mir! :D

mfg

Pacman3011
einfachTobi
User
Beiträge: 512
Registriert: Mittwoch 13. November 2019, 08:38

Zunächst handelt es sich nicht um die Umsetzung eines Blackjack-Spiels. Das ist eine Mischung aus den zwei ähnlichen, aber im Detail unterschiedlichen Spielen 17+4 und Blackjack.
Zum Code: Variablen werden klein_mit_unterstrich geschrieben. MixedCase ist für Klassen vorgesehen. Anstatt Variablen zu nummerieren, solltest du Listen verwenden. Verwende keine Abkürzungen in den Namen, wenn nicht zwingend erforderlich oder absolut üblich. Den Rückgabewert von `input()` musst du nicht zu einem String machen - das ist bereits ein String. Es ist leicht zu erkennen, dass sich bestimmte Codeteile wiederholen: Verwende dafür Funktionen. Es reicht, wenn du die Karten und ihre Zufallswerte erzeugst, wenn sie tatsächlich gezogen werden. Verwende einen sog. main guard.
pacman3011
User
Beiträge: 4
Registriert: Freitag 19. Juni 2020, 11:34

einfachTobi hat geschrieben: Freitag 19. Juni 2020, 12:33 Zunächst handelt es sich nicht um die Umsetzung eines Blackjack-Spiels. Das ist eine Mischung aus den zwei ähnlichen, aber im Detail unterschiedlichen Spielen 17+4 und Blackjack.
Zum Code: Variablen werden klein_mit_unterstrich geschrieben. MixedCase ist für Klassen vorgesehen. Anstatt Variablen zu nummerieren, solltest du Listen verwenden. Verwende keine Abkürzungen in den Namen, wenn nicht zwingend erforderlich oder absolut üblich. Den Rückgabewert von `input()` musst du nicht zu einem String machen - das ist bereits ein String. Es ist leicht zu erkennen, dass sich bestimmte Codeteile wiederholen: Verwende dafür Funktionen. Es reicht, wenn du die Karten und ihre Zufallswerte erzeugst, wenn sie tatsächlich gezogen werden. Verwende einen sog. main guard.
Vielen Dank für deine schnelle und hilfreiche Antwort!
einfachTobi
User
Beiträge: 512
Registriert: Mittwoch 13. November 2019, 08:38

Ergänzung: `random.randint()` liefert dir bereits einen Integer-Wert. Also ist auch dort die Umwandlung nicht erforderlich. Der Name `hit` für die Auswahl des Spielers mutet merkwürdig an, wenn man sich die Zeile `elif hit == "check":` ansieht.
Es bietet sich an die Grundlagen noch etwas zu vertiefen, zum Beispiel mit dem offiziellen Tutorial https://docs.python.org/3/tutorial/index.html.

Du hast meiner Meinung nach einen guten Ansatz gewählt, um ans Programmieren zu kommen. Erstmal ausprobieren, Fehler machen (völlig normal) und daraus lernen. Sobald du dich mit Funktionen und dem Kontrollieren des Programmablauf auseinandergesetzt hast, wird das sicher deutlich besser werden und einfacher fallen.
Benutzeravatar
__blackjack__
User
Beiträge: 14052
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@pacman3011: Ergänzend noch Anmerkungen: Eingerückt wird per Konvention vier Leerzeichen pro Ebene.

`ties` wird als 0 definiert und in jeder Runde ausgegeben, aber nirgends tatsächlich verändert. Die Variable kann also weg, oder die dafür notwendige Programmlogik müsste tatsächlich noch implementiert werden.

Momentan ist es so, dass es weder als Gewinn noch ale Verlust für den Spieler gewertet wird wenn der Dealer „black jack“ hat. Da sollte doch der Dealer gewonnen haben, oder? Und der Spieler kann kein „black jack“ haben, beziehungsweise das lässt ihn tatsächlich nicht gewinnen?

Den ``%``-Operator würde ich nicht mehr zum formatieren von Werten in Zeichenketten verwenden. Dafür gibt es die `format()`-Methode auf Zeichenketten und ab Python 3.6 f-Zeichenkettenliterale.

Das zusammenstückeln von Zeichenketten und Werten mittels ``+`` und `str()` ist eher BASIC als Python. Auch hier wieder: Es gibt die `format()`-Methode und f-Zeichenkettenliterale.

Das zusammenaddieren der Kartensumme bei Spieler und Dealer steht da jeweils mehrfach, statt das man das *einmal* ausrechnet und sich merkt.

`input()` kann man ein Argument übergeben, dann kann man sich das `print()` davor sparen.

Man sollte auch immer damit rechnen das der Benutzer etwas anderes eingibt, als man vorgesehen hat. Entsprechend vorsichtig sollte man beim verhalten des Programms in dem Fall sein. Im Moment ist es im Programm so das alles ausser "hit" und "check" als implizites "stand" interpretiert wird, was echt doof ist wenn man sich vertippt. Das würde ich explizit machen und wenn der Spieler nicht "hit", "check", "stand", oder gar nichts eingibt, die Frage wiederholen.

Zwischenstand (ungetestet):

Code: Alles auswählen

#!/usr/bin/env python3
import random


def draw_card():
    return random.randint(1, 11)


def play_one_card(player_cards, dealer_cards):
    print()
    print("You have:", sum(player_cards))
    print("The dealer has:", sum(dealer_cards))
    while True:
        answer = input(
            "What do you wanna do? (hit, check, or stand (default))\n"
        )
        if answer in ["stand", ""]:
            break

        if answer == "check":
            return None

        if answer == "hit":
            player_cards.append(draw_card())
            print(player_cards[-1])
            cards_total = sum(player_cards)
            print("Your sum is:", cards_total)
            if cards_total > 21:
                print("You lost!")
                return False
            #
            # TODO What about the player having a „black jack“ at this point? If
            #   this should be handled the same as for the dealer having „black
            #   jack“ then this is so similar code that another function should
            #   be pulled from this.
            #
            break

        print("Invalid answer!")

    dealer_cards.append(draw_card())
    cards_total = sum(dealer_cards)
    print("The dealer has now", cards_total)
    if cards_total > 21:
        print("The dealer lost!")
        return True

    if cards_total == 21:
        print("Dealer has Black Jack")
        return False

    return None


def play_round():
    player_cards = [draw_card()]
    dealer_cards = [draw_card()]
    while True:
        result = play_one_card(player_cards, dealer_cards)
        if result is not None:
            return result


def main():
    try:
        print("BLACK JACK")
        wins = 0
        losses = 0
        while True:
            print(f"{wins} wins, {losses} losses.")
            if play_round():
                wins += 1
            else:
                losses += 1
    except KeyboardInterrupt:
        print("Thank you for playing.")


if __name__ == "__main__":
    main()
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Antworten