Skip to content

Instantly share code, notes, and snippets.

@jakab922
Created March 30, 2017 15:52
Show Gist options
  • Save jakab922/8dfd439b58be823a3258abae2675fc29 to your computer and use it in GitHub Desktop.
Save jakab922/8dfd439b58be823a3258abae2675fc29 to your computer and use it in GitHub Desktop.
Command line blackjack game
from random import shuffle, randint as ri
from itertools import product
PLAYER, OP, BOTH, NEITHER = range(4)
suits = ["clubs", "diamonds", "hearts", "spades"]
values = [
"ace", "two", "three", "four", "five",
"six", "seven", "eight", "nine", "ten",
"jack", "queen", "king"]
class EmptyDeck(Exception):
pass
class Card(object):
def __init__(self, suit, value):
self.suit = suit
self.value = value
def __str__(self):
return "%s of %s" % (self.value, self.suit)
class DeckState(object):
def __init__(self):
self._cards = [
Card(suit, value) for suit, value in
product(suits, values)]
shuffle(self._cards)
self._top = 51
@property
def next(self):
if self._top < 0:
raise EmptyDeck()
self._top -= 1
return self._cards[self._top + 1]
class PlayerState(object):
def __init__(self):
self.cards = []
@property
def score(self):
cvalues = [0]
for card in self.cards:
if card.value == "ace":
lv = len(cvalues)
for i in xrange(lv):
cvalues.append(cvalues[i] + 11)
cvalues[i] += 1
else:
i = values.index(card.value)
v = i + 1 if i < 10 else 10
lv = len(cvalues)
for i in xrange(lv):
cvalues[i] += v
mv = min(cvalues)
if mv > 21:
return mv
best = cvalues[0]
for v in cvalues[1:]:
if v < 22 and v > best:
best = v
return best
def append(self, card):
self.cards.append(card)
class GameState(object):
def __init__(self):
self.state = BOTH
self.turn = PLAYER
def step(self, resign=False):
if self.turn == PLAYER:
if resign:
assert self.state in (BOTH, PLAYER)
if self.state == BOTH:
self.state = OP
else:
self.state = NEITHER
else:
if resign:
assert self.state in (BOTH, OP)
if self.state == BOTH:
self.state = PLAYER
else:
self.state = NEITHER
self.turn = (self.turn + 1) % 2
class OpponentStrategy(object):
def __init__(self):
pass
def action(self, op_score, player_score):
if player_score > op_score and player_score < 22:
return True
if player_score > 21:
return False
elif op_score > 21:
return False
elif op_score < 11:
return True
else:
return ri(0, 10) < 21 - op_score
class Game(object):
def __init__(self):
self.deck_state = DeckState()
self.player = PlayerState()
self.opponent = PlayerState()
self.game_state = GameState()
self.opponent_strategy = OpponentStrategy()
def iter(self):
state = self.game_state.state
turn = self.game_state.turn
if state == NEITHER:
ps = self.player.score
os = self.opponent.score
print "Your final score is %s and the opponent's final score is %s\n" % (ps, os)
if ps < 22 and (ps > os or os > 21):
print "You won\n"
else:
print "You lost\n"
return False
elif state == BOTH:
if turn == PLAYER:
if self.player.score > 21:
self.game_state.step(True)
else:
choice = raw_input("Would you like to draw a card? (Y/n)\n")
if choice in ("", "y", "Y"):
card = self.deck_state.next
print "You drew a %s\n" % card
self.player.append(card)
self.game_state.step()
else:
self.game_state.step(True)
if turn == OP:
if self.opponent_strategy.action(
self.opponent.score, self.player.score):
card = self.deck_state.next
print "The opponent drew a %s\n" % card
self.opponent.append(card)
self.game_state.step()
else:
print "Your opponent resigned\n"
self.game_state.step(True)
elif state == PLAYER:
if turn == OP:
self.game_state.step()
else:
if self.player.score > 21:
self.game_state.step(True)
else:
choice = raw_input("Would you like to draw a card? (Y/n)\n")
if choice in ("", "y", "Y"):
card = self.deck_state.next
print "You drew a %s\n" % card
self.player.append(card)
self.game_state.step()
else:
self.game_state.step(True)
else:
if turn == PLAYER:
self.game_state.step()
else:
if self.opponent_strategy.action(
self.opponent.score, self.player.score):
card = self.deck_state.next
print "The opponent drew a %s\n" % card
self.opponent.append(card)
self.game_state.step()
else:
print "Your opponent resigned\n"
self.game_state.step(True)
return True
if __name__ == "__main__":
game = Game()
while game.iter():
pass
exit()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment