Pokouším se vytvořit jednoduchou hru Blackjack. Používám GIST, protože použití kódu trvá věčně.
Aktuální kód:
from random import randint def card_deck(): #sets the card types and values card_value = ["Ace","2","3","4","5","6","7","8","9","10","J","Q","K"] card_type = ["Hearts","Spades","Clubs","Diamonds"] deck = [] #This iterates all 52 cards into a deck for i in card_type: for j in card_value: deck.append(j + " of " + i) return deck def card_value(card): #only reading first slice to determine value of the card if card[:1] in ("J","Q","K","1"): return int(10) elif card[:1] in ("2","3","4","5","6","7","8","9"): #card[:1] example "2" out of the full "2 of Hearts" string return int(card[:1]) elif card[:1] == "A": print ("\n"+ str(card)) num = input("Do you want this to be 1 or 11?\n>") while num !="1" or num !="11": if num == "1": return int(1) elif num == "11": return int(11) else: num = input("Do you want this to be 1 or 11?\n>") def new_card(deck): return deck[randint(0,len(deck)-1)] def remove_card(deck,card): return deck.remove(card) play_again = "" while play_again != "EXIT": #deck creation, card creation, card removal from deck, values and totals new_deck = card_deck() card1 = new_card(new_deck) remove_card(new_deck,card1) card2 = new_card(new_deck) remove_card(new_deck,card2) print ("\n\n\n\n" + card1 + " and " + card2) #doing this statement first allows for selection between 1 and 11 valu1 = card_value(card1) valu2 = card_value(card2) total = valu1 + valu2 print("with a total of " + str(total) ) #dealer"s hand dealer_card1 = new_card(new_deck) remove_card(new_deck,dealer_card1) dealer_card2 = new_card(new_deck) remove_card(new_deck,dealer_card2) dealer_value1 = card_value(dealer_card1) dealer_value2 = card_value(dealer_card1) dealer_total = dealer_value1 + dealer_value2 print ("\nThe Dealer smiles as he looks at you and\n deals one card up and one card face down") print ("First a " + dealer_card1 + " and face down card.") if total == 21: print("Blackjack!") else: while total < 21: #not win or loss yet answer = input("Would you like to hit or stand?\n> ") if answer.lower() == "hit": #more card creation, removal, and value added to total more_card = new_card(new_deck) remove_card(new_deck,more_card) more_value = card_value(more_card) total += int(more_value) print (more_card + " for a new total of " + str(total)) if total > 21: #lose condition print("You LOSE!") play_again = input("Would you like to continue? EXIT to leave\n") elif total == 21: #winning condition print("You WIN BIG WIN WOO WOO") play_again = input("Would you like to continue? EXIT to leave\n") else: continue elif answer.lower() == "stand": print("The dealer nods and reveals his other card to be ") print("a " + dealer_card2 + " for a total of " + str(dealer_total)) if dealer_total < 17: print("The Dealer hits again.") dealer_more = new_card(new_deck) more_dealer_value = card_value(dealer_more) print("The card is a " + str(dealer_more)) dealer_total += int(more_dealer_value) if dealer_total > 21 and total <=21: print("Dealer Bust! You win!") elif dealer_total < 21 and dealer_total > total: print("Dealer has " + str(dealer_total) + " You lose!") else: continue elif dealer_total == total: print("Equal Deals, no winner") elif dealer_total < total: print("You win!") else: print("You Lose!") play_again = input("\nWould you like to continue? EXIT to leave\n") break print("Thank you for Playing")
Nový (je můj programový kód Blackjack tak daleko používající třídy):
from random import randint class Card: def __init__(self): pass def card_value(self): pass card_face = ["Ace","2","3","4","5","6","7","8","9","10","J","Q","K"] card_suit = ["Hearts","Spades","Clubs","Diamonds"] class Deck(Card): new_deck = [] length = len(new_deck) #testing purposes for i in Card.card_suit: for j in Card.card_face: new_deck.append(j + " of " + i) def new_card(self): #instead of return, use yield? return (self.new_deck[randint(0,len(self.new_deck)-1)]) def remove_card(self,card): self.new_deck.remove(card) deck1 = Deck() card1 = deck1.new_card() deck1.remove_card(card1) card2 = deck1.new_card() deck1.remove_card(card2) print(str(card1) + " and " + str(card2)) print(len(deck1.new_deck))
Hledám radu pro začátečníky, jak a kde začít s mým procesem při rozšiřování mých funkcí / kódu do tříd. Můj původní kód funguje pro to, co dělá, ale mám pocit, že má příliš mnoho ručního kódu, a chtěl bych nějaké tipy / rady, kam odsud jít.
Komentáře
- dobře, opravil jsem to
- chcete, abychom zkontrolovali váš kód (který ještě není dokončen) nebo vám jen pomůžeme sestavit kostru (pomoci najít správný přístup) vaší hry ?
- pomoc při hledání správného přístupu by byla skvělá, nebo pokud si všimnete čehokoli, co bych rozhodně neměl dělat, bylo by dobré na to také poukázat 🙂
- myslím opravdu si musíte přečíst dokumentaci o tom, jak fungují třídy v pythonu. Například jen zřídka byste někdy měli volně stojící kód, jak je vidět ve třídě Deck, buď byste jej vložili do funkce
__init__
nebo pod jinou funkci - Znamená to tedy, že ‚ nemůžete vůbec používat třídy?
Odpovědět
Pojďme se podívat na vaši Card
třídu.
class Card: def __init__(self): pass def card_value(self): pass card_face = ["Ace","2","3","4","5","6","7","8","9","10","J","Q","K"] card_suit = ["Hearts","Spades","Clubs","Diamonds"]
Existuje několik konstrukčních chyb.
1. Karta by neměla hodnotit svoji hodnotu, protože hodnota karty definovaná ve hře. V zásadě, pokud byste chtěli tuto třídu znovu použít například pro poker, museli byste pro kartu vytvořit podřízenou třídu, jen abyste vyhodnotili její hodnotu pro jinou hru, což je špatně.
2. Ve vašem případě třída karet ví o oblecích a hodnostech, což je podle mého názoru také špatné řešení, protože můžete použít jakýkoli jiný balíček kromě pro francouzštinu.
Takže v důsledku prvních 2 problémů se ukázalo, že vaše karta je pouze kontejner (struktura) bez jakékoli logiky uvnitř, což je jedna z nejlepších věcí, kterou lze v pythonu v namedtuple
from collections import namedtuple Card = namedtuple("Card", ("rank", "suit"))
Nyní pojďme mluvit o Deck
class Deck(Card): new_deck = [] length = len(new_deck) #testing purposes for i in Card.card_suit: for j in Card.card_face: new_deck.append(j + " of " + i) def new_card(self): #instead of return, use yield? return (self.new_deck[randint(0,len(self.new_deck)-1)]) def remove_card(self,card): self.new_deck.remove(card)
1. Balíček rozhodně není Card
dítě, Deck
je třídění sbírky karet.
2. Vaše new_card
a remove_card
metody by měly být sloučeny do jedné metody zvané draw_card
.
3. Od této chvíle víme, že Deck
není Card
, pak je nejvhodnějším místem pro sledování hodností a obleků Deck
. Zde je příklad:
class Deck: card_ranks = [] card_suits = [] def __init__(self): self.cards = [] self.refresh_deck() def refresh_deck(self): self.cards = list(map(Card, product(self.card_ranks, self.card_suits))) def shuffle(self): shuffle(self.cards) def draw_card(self): return self.cards.pop()
Třída hry
Věci jako play_game, card_value (hand_value?) a další věci / pravidla související s konkrétní hrou by měly být definovány Game
třídou
class Game: def __init__(self, deck): raise NotImplementedError def card_value(self, card): raise NotImplementedError def hand_value(self, hand): raise NotImplementedError def play(self): raise NotImplementedError
Takže jako kostra hry máme nakonec toto:
from collections import namedtuple from itertools import product from random import shuffle from typing import List Card = namedtuple("Card", ("rank", "suit")) class Deck: card_ranks = [] card_suits = [] def __init__(self) -> None: self.cards = [] self.refresh_deck() def refresh_deck(self) -> int: self.cards = map(Card, product(self.card_ranks, self.card_suits)) def shuffle(self) -> None: shuffle(self.cards) def draw_card(self) -> Card: return self.cards.pop() class FrenchDeck(Deck): card_ranks = ["Ace", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"] card_suits = ["Hearts", "Spades", "Clubs", "Diamonds"] class Game: def __init__(self, deck: Deck) -> None: raise NotImplementedError def card_value(self, card: Card) -> int: raise NotImplementedError def hand_value(self, hand: List[Card]) -> int: raise NotImplementedError def play(self) -> None: raise NotImplementedError
Komentáře
- Omlouvám se, že jsem na to neměl šanci reagovat, připojení k internetu z mého domova bylo nefunkční ~ To mi dá několik úžasných tipů a kostru, na kterou se mohu podívat a pracovat, děkuji tolik!
Odpovědět
Když „stojíte“, řekne vám to dealerům další kartu, pak zasáhne / stojany, pak můžete zasáhnout nebo stát, to není blackjack, musíte odstranit druhý zásah / stoj poté, co dealer odhalí svoji ruku.