forked from siddhi/python-functional
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathblackjack_solution.py
More file actions
94 lines (79 loc) · 2.75 KB
/
Copy pathblackjack_solution.py
File metadata and controls
94 lines (79 loc) · 2.75 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
import random
from itertools import product, starmap, cycle
from monads import MultiValue
from utils import compose2, update_dict, stream_logs
from card_games import Card, Deck, Hand, draw_to_hand
BUST_LIMIT = 22
def new_deck() -> Deck:
return list(starmap(Card, product(range(1, 14), "SHDC")))
def shuffle(deck: Deck) -> Deck:
return random.sample(deck, len(deck))
new_shuffled_deck = compose2(new_deck, shuffle)
def get_points_for_card(card: Card):
match card.rank:
case 10 | 11 | 12 | 13:
return MultiValue({10})
case 1:
return MultiValue({1, 11})
case _:
return MultiValue({card.rank})
def get_points(hand: Hand) -> MultiValue:
return sum((get_points_for_card(card) for card in hand), MultiValue({0}))
def score_hand(hand: Hand):
total = get_points(hand)
allowed_values = (value for value in total.values if value < BUST_LIMIT)
return max(allowed_values)
def get_player_action(hand):
while (action := input('(H)it or (S)tay: ').lower()) not in {'h', 's'}:
print("Only enter H or S")
return action
def get_dealer_action(hand):
total_points = score_hand(hand)
if total_points >= 17:
return 's'
return 'h'
def initial_state():
deck = new_shuffled_deck()
players = ['Player', 'Dealer']
hands = {player: [] for player in players}
actions = {'Player': get_player_action, 'Dealer': get_dealer_action}
return deck, players, hands, actions
def process_game():
update_hands = update_dict
deck, players, hands, actions = initial_state()
turns = cycle(players)
while players:
turn = next(turns)
hand = hands[turn]
print(f'\n> {turn} hand is: {" ".join(str(card) for card in hand)}')
action = actions[turn](hand)
match action:
case 'h':
print(f'Hit')
hand, deck = draw_to_hand(hand, deck)
hands = update_hands(hands, turn, hand)
print(f'Drawn {hand[-1]}')
try:
total = score_hand(hand)
print(f'Current score is {total}')
except ValueError:
print(f'BUSTED')
return hands
hands = update_dict(hands, turn, hand)
case 's':
print(f'Stay')
players = [player for player in players if player != turn]
turns = cycle(players)
return hands
def get_score(hand):
try:
total = score_hand(hand)
return total
except ValueError:
return 'BUSTED'
def end_game(hands):
print(f'\n*** Game Over ***')
for player, hand in hands.items():
print(f'{player}:{get_score(hand)}')
run = compose2(process_game, end_game)
run()