![]() |
More of my learning - Printable Version +- Python Forum (https://python-forum.io) +-- Forum: General (https://python-forum.io/forum-1.html) +--- Forum: Code sharing (https://python-forum.io/forum-5.html) +--- Thread: More of my learning (/thread-1068.html) |
More of my learning - LordHill - Dec-01-2016 Took a break while I worked a bunch of overtime, but had a rare day off yesterday. Decided to continue my learning. Read a bit about python classes. The only use for classes that popped into my head was playing cards, so I threw together a simple game of "blackjack". Hesitate to call it that as its just player vs dealer, no betting, no soft hits for dealer, etc. I'm sure your going to find LOTS of things I can do better, don't need at all, or just flat out screwed up, but I'm very new at all of this and I'm trying. Any pointers will be greatly appreciate import random import time # Card images cardpic=[''' |---| | A | |---|''',''' |---| | 2 | |---|''',''' |---| | 3 | |---|''',''' |---| | 4 | |---|''',''' |---| | 5 | |---|''',''' |---| | 6 | |---|''',''' |---| | 7 | |---|''',''' |---| | 8 | |---|''',''' |---| | 9 | |---|''',''' |---| |10 | |---|''',''' |---| | J | |---|''',''' |---| | Q | |---|''',''' |---| | K | |---|'''] # Class to give card values class Cards: def __init__(self, card, value, draw): self.card = card self.value = value self.draw = draw # Build the deck deck=[] deck.append(Cards("TWO", 2, 1)) deck.append(Cards("THREE", 3, 2)) deck.append(Cards("FOUR", 4, 3)) deck.append(Cards("FIVE", 5, 4)) deck.append(Cards("SIX", 6, 5)) deck.append(Cards("SEVEN", 7, 6)) deck.append(Cards("EIGHT", 8, 7)) deck.append(Cards("NINE", 9, 8)) deck.append(Cards("TEN", 10, 9)) deck.append(Cards("JACK", 10, 10)) deck.append(Cards("QUEEN", 10, 11)) deck.append(Cards("KING", 10, 12)) deck.append(Cards("ACE", 11, 0)) # Variables player=[] playertotal=0 cpu=[] cputotal=0 # Pick a player card def playerhit(): global playertotal global player deal=random.randint(0,12) car=deck[deal].card num=deck[deal].value image=deck[deal].draw player.append(Cards(car, num, image)) playertotal=playertotal+num # Pick a dealer card def cpuhit(): global cputotal global cpu deal=random.randint(0,12) car=deck[deal].card num=deck[deal].value image=deck[deal].draw cpu.append(Cards(car, num, image)) cputotal=cputotal+num # Draw the cards on screen def table(): for i in range(len(player)): print(cardpic[player[i].draw]) print("_____") for i in range(len(cpu)): print(cardpic[cpu[i].draw]) print("\n" * 5) # Reset the game def start(): print("\n" * 5) global player global cpu global playertotal global cputotal playertotal=0 cputotal=0 player=[] cpu=[] playerhit() playerhit() cpuhit() cpuhit() # Adjust player ACES when busted def checkplayeraces(): global playertotal for i in player: if i.value == 11: i.value = 1 playertotal=playertotal-10 # Adjust dealer ACES when busted def checkcpuaces(): global cputotal for i in cpu: if i.value == 11: i.value = 1 cputotal=cputotal-10 # Decide winner def cpustay(): if cputotal > playertotal: print() print("You Lose") print() play() elif cputotal == playertotal: print() print("Draw") print() play() elif cputotal < playertotal: print() print("You Win") print() play() # Dealers turn def cputurn(): ai=True while ai==True: time.sleep(2) if cputotal > 21: checkcpuaces() if cputotal > 21: print() print("Dealer Busts, You Win!") print() play() ai=False if cputotal < 17: cpuhit() table() else: cpustay() table() ai=False # Deal & players turn def play(): start() run=True while run==True: table() if input()=="h": playerhit() if playertotal > 21: checkplayeraces() if playertotal > 21: table() print() print("Bust! You Lose") print() play() else: cputurn() # Begin play() RE: More of my learning - stranac - Dec-01-2016 There's a lot to be said about your code, but I'll just mention a few points here:
Although, if I were you, I would address these things first and then post again for further advice. RE: More of my learning - nilamo - Dec-01-2016 The way you're using a class is really just as a sexier dict. In other languages, it'd be a nice little struct/typedef. Classes are (in my opinion) best used to bundle functionality together. If you'll notice, your playerhit() and cpuhit() functions are almost exactly the same, except the values they use to make a decision are different. Which means I'd probably start just by changing those two functions to instead be a single function. Also, deck has instances of Card, but instead of re-using those instances (that you already have, right there!), you create brand new Card instances. ...why? I don't think the Card should be the thing you need a class for, I think a player is what you need a class for. Something like: #...this maybe should be called Hand, since it doesn't clear itself... class Player(object): def __init__(self): # maybe keep track of how many chips they start with? self.cards = [] def current_total(self): total = 0 for card in self.cards: total += card.value return total def hit(self, new_card): self.cards.append(new_card) def should_hit(self, dealer_showing=0): total = self.current_total() # not actually basic strategy... if dealer_showing <= 12: return total <= 11 return total <= 16Then you'd have two or more instances of Player, which each keep track of whatever cards they're dealt and use that information to decide for themselves if they should keep getting more cards: players = [Player() for _ in range(5)] # it's full table, why not dealer = Player() dealer.hit(pick_a_card()) for player in players: player.hit(pick_a_card()) dealer_total = dealer.current_total() for player in players: while player.should_hit(dealer_total): player.hit(pick_a_card()) player_total = player.current_total() while dealer.should_hit(): dealer.hit(pick_a_card()) dealer_total = dealer.current_total() for player in players: if player_total > dealer_total: # winner! # don't forget to handle busts... and the dealer's hidden cardNow, let's talk about those card pics... They're really all the same, except you change a single character. I hate (and you should too!) seeing the same thing over and over. If you find yourself doing the copy-paste dance, there's probably a better way to do it. And there is. In this instance, probably string formatting, with a base of what all cards look like, using a placeholder for the actual value of the card. Maybe... >>> card_template = ''' ... |---| ... | {0:2}| ... |---|''' >>> cards = [str(i) for i in range(2, 11)] + list('AKQJ') >>> >>> cards ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'A', 'K', 'Q', 'J'] >>> for card in cards: ... print(card_template.format(card)) ...Which would give you...
|