Contents of blackjack.py
toggle line numbers
1: #! /usr/bin/python
2: """
3: BlackJack game with single or multiple decks containing playing
4: cards with suits and ranks making it possible to try your hand at
5: counting cards.
6:
7: Copyright (c) 2007,2009, Roger Lew
8: All rights reserved. Licensed under BSD.
9: """
10: from random import randint,shuffle
11: import sys
12:
13: def ifelse(condition, a, b):
14: """Excel-like if/else functionality for list generators"""
15: if condition : return a
16: else : return b
17:
18: class card:
19: """a playing card"""
20: def __init__(self,suit,rank,show=1):
21: self.suit,self.rank,self.show=suit,rank,show
22: if rank in ['J','Q','K'] : self.values=[10]
23: elif rank in ['A'] : self.values=[1,11]
24: else : self.values=[int(rank)]
25:
26: def __str__(self):
27: """returns string representation of card"""
28: if self.show : return '[%s%3s]'%(self.suit,self.rank)
29: else : return '[ ]'
30:
31: def __add__(self,other):
32: """operator overloaded addition, returns a list of possible values"""
33: return_values=[]
34: # test type so the recursive sum function in the blackjack class works
35: if type(other)==list:
36: for sval in self.values:
37: for oval in other:
38: return_values.append(sval+oval)
39: else:
40: for sval in self.values:
41: for oval in other.values:
42: return_values.append(sval+oval)
43: return return_values
44:
45: class deck:
46: """Single or multiple 52 card decks of playing cards"""
47: def __init__(self,num_of_decks):
48: self.cards=[]
49: self.discards=[]
50: self.num_of_decks=num_of_decks
51:
52: for i in range(num_of_decks):
53: for rank in ['2','3','4','5','6','7','8','9','10','J','Q','K','A']:
54: for suit in ['S','H','D','C']:
55: self.cards.append(card(suit,rank))
56:
57: def shuffle(self):
58: """Shuffles deck"""
59: for i in range(randint(1,100)): shuffle(self.cards)
60:
61: def draw(self,show=1):
62: """draws a single card"""
63: if len(self.cards)==0:
64: print 'Out of cards re-shuffling discards...'
65: self.cards,self.discards=self.discards,self.cards
66: self.shuffle()
67:
68: self.cards[-1].show=show
69: return self.cards.pop()
70:
71: def discard(self, x):
72: """returns a card to the discard pile"""
73: if type(x)==list : self.discards.extend(x)
74: else : self.discards.append(x)
75:
76: def __str__(self):
77: """returns string representation of deck"""
78: return ''.join([card.__str__()+'\t' for card in self.cards])
79:
80: class blackjack:
81: def __init__(self):
82: print "Let's play BlackJack!"
83: print "To quit enter 'Q' at Hit or Stand prompt.\n"
84: # Initialize deck
85: self.deck=deck(1)
86: self.deck.shuffle()
87:
88: def play(self):
89: # Deal cards
90: self.dealer=[self.deck.draw(),self.deck.draw(show=0)]
91: self.player=[self.deck.draw(),self.deck.draw()]
92: self.dealersums=self.sumcards(self.dealer)
93: self.playersums=self.sumcards(self.player)
94: self.winner=self.check4winner()
95:
96: # Hit or stand
97: choice='H'
98: while self.winner==0:
99: print self
100: choice=raw_input('[H]it or [S]tand? ')
101: if choice=='H' or choice=='h':
102: self.player.append(self.deck.draw())
103: self.playersums=self.sumcards(self.player)
104: self.winner=self.check4winner()
105:
106: elif choice=='S' or choice=='s':
107: # Dealer stands at 17
108: self.dealer[1].show=1
109: while self.winner==0 and min(self.dealersums) < 17:
110: print self
111: self.dealer.append(self.deck.draw())
112: self.dealersums=self.sumcards(self.dealer)
113: self.winner=self.check4winner()
114:
115: # Determine winner if none declared
116: if self.winner==0:
117: dealerhisum=max([ifelse(x>21,0,x) for x in self.dealersums])
118: playerhisum=max([ifelse(x>21,0,x) for x in self.playersums])
119: if playerhisum > dealerhisum : self.winner='Player Wins!'
120: elif playerhisum < dealerhisum : self.winner='Dealer Wins!'
121: else : self.winner='Tie'
122:
123: elif choice=='Q' or choice=='q':
124: print 'Good bye'
125: sys.exit()
126:
127: # Final feedback
128: print self; print self.winner
129:
130: # Clean-up
131: self.deck.discard(self.dealer); self.deck.discard(self.player)
132: if 'Player' in self.winner : return 1 # wins count
133: else : return 0
134:
135: def sumcards(self,cards):
136: """recursive card sum function returns a list of possible values"""
137: if len(cards)==2: return cards[0]+cards[1]
138: elif len(cards)>2: return cards[0]+self.sumcards(cards[1:])
139:
140: def check4winner(self):
141: """returns winner if blackjack is hit or someone busts"""
142: if 21 in self.dealersums : return 'Dealer Hit BlackJack!'
143: if 21 in self.playersums : return 'Player Hit BlackJack!'
144: if 0 not in [ifelse(x>21,1,0) for x in self.dealersums]: return 'Player Wins by Bust!'
145: if 0 not in [ifelse(x>21,1,0) for x in self.playersums]: return 'Dealer Wins by Bust!'
146: return 0 # indicates no winner
147:
148: def __str__(self):
149: return 'Dealer: '+''.join([card.__str__()+'\t' for card in self.dealer])+\
150: '\nPlayer: '+''.join([card.__str__()+'\t' for card in self.player])+'\n'
151:
152: def main():
153: BlackJack=blackjack()
154: wins=counter=0
155: while 1:
156: wins+=BlackJack.play()
157: counter+=1
158: print 'Your %i of %i.\n'%(wins,counter)
159:
160: if __name__ == "__main__":
161: main()
162:
163:
rogerlew.geekgalaxy.com / software / PyBlackJack / blackjack.php