forked from pgwhalen/euchre_sim
-
Notifications
You must be signed in to change notification settings - Fork 0
/
utils.py
131 lines (98 loc) · 3.54 KB
/
utils.py
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
VALUE_MAP = {'9': 1, 'T': 2, 'J': 3, 'Q': 4, 'K': 5, 'A': 6}
# Jd beats Jh with h trump and Jd lead.
def best_card(cards, trump=None, lead=None):
""" Calculate winning card from list of cards
Trump suit and lead card must be specified, otherwise normal order is assumed.
"""
val_map = {}
leftbower = 'J' + same_color(trump)
# determine suit to follow
suit_to_follow = lead[1]
if lead == leftbower:
suit_to_follow = trump
for c in cards:
# standard value
val = VALUE_MAP[c[0]]
# right bower
if c[0] == 'J' and c[1] == trump:
val *= 1000 + 5
# left bower
elif c[0] == 'J' and c[1] == same_color(trump):
val *= 1000 + 3
# any other trump
elif c[1] == trump:
val *= 100
# any non-trump that followed the lead suit
elif suit_to_follow == c[1]:
val *= 10
val_map[c] = val
return sorted(val_map.items(), key=lambda x: x[1], reverse=True)[0][0]
def same_color(suit):
""" Return other suit of the same same color
I'm embarrased I had to write this function.
"""
if suit == 's':
return 'c'
elif suit == 'c':
return 's'
elif suit == 'd':
return 'h'
elif suit == 'h':
return 'd'
def follow_suit_priority(card, trump, lead):
""" Calculate priority order of "follow suit" rule.
Trump suit and lead card must be specified.
priority order of "follow suit" rules:
1) must match suit of lead card
- if suit of lead card is trump, then either trump or left bower is acceptable
2) must match suit of trump
- if suit of lead card is trump, then either trump or left bower is acceptable
3) anything else
"""
leftbower = 'J' + same_color(trump)
# Determine the suit of the lead card. This considers the left bower as trump.
suit_to_follow = lead[1]
if lead == leftbower:
suit_to_follow = trump
# Determine the priority of the card that was played. Note that this
# is slightly different than the logic in best_card.
if suit_to_follow == card[1]:
val = 1
elif suit_to_follow == trump and card == leftbower:
val = 1
elif trump == card[1]:
val = 2
elif trump == card[1] and card == leftbower:
val = 2
else:
val = 3
return val
def did_follow_suit(cards, card, trump, lead):
""" Calculate if card followed suit given the cards in the hand
Trump suit and lead card must be specified.
"""
# Determine the priority of the card played
card_pri = follow_suit_priority(card, trump, lead)
# Determine the priorities of all other cards in the hand
cards_pri = {}
for c in cards:
cards_pri[c] = follow_suit_priority(c, trump, lead)
best_pri = sorted(cards_pri.items(), key=lambda x: x[1])[0][1]
# If the card played has the same priority as the best priority,
# then the follow suit rules were followed. (Otherwise, there
# was a card that had higher priority ==> should have been played.)
if card_pri == best_pri:
return True
return False
# Should be unit tests
# print best_card(['Qs', 'As']) # As
# print best_card(['As', 'Jh'], 'h') # Jh
# print best_card(['Jc', 'Js'], 'h', 's') # Js
# print best_card(['Jc', 'Js', 'Jh'], 'h', 's') # Js
# print best_card(['Jc', 'Js', 'Jh', 'Jd'], 'h', 's') # Js
# print best_card(['Jc', 'Js', 'Ah', 'Jd'], 'h', 's') # Js
# print did_follow_suit(['Jc', 'Js', Kc'], 'Jc', 's', 's') # false, 'Js'
# print did_follow_suit(['Jc', 'As', Kc'], 'Jc', 's', 's') # false, 'Jc'
# print did_follow_suit(['Jc', 'Js', Kc'], 'Jc', 's', 'c') # true, 'Jc'
# print did_follow_suit(['Jc', 'As', Kc'], 'Jc', 's', 'c') # true, 'Jc'
# print did_follow_suit(['Td', '9s', 'Ts', '9c', 'Ah'], 'Ah', 'h', 'h') # true, 'Ah'