-
Notifications
You must be signed in to change notification settings - Fork 6
/
human_player.py
239 lines (211 loc) · 7.45 KB
/
human_player.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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
from i_player import IPlayer
from card_set import CardSet
class HumanPlayer(IPlayer):
def __init__(self):
IPlayer.__init__(self)
self.player_id = 0
self.teammate_id = 2
self.team_id = 0
self.score = None
self.bids = None
self.trick_count = {i: 0 for i in range(4)}
def give_hand(self, cards):
"""
Give a hand of cards to this player, by passing a list of cards.
cards: a list of 13 Card objects.
"""
# Make sure to reset the trick counter
self.trick_count = {i: 0 for i in range(4)}
self.hand = CardSet(cards)
print("You have received the following hand:")
print(self.hand)
print()
def print_bids(self, final=False):
assert not final or len(self.bids) == 4
for i in range(4):
if i not in self.bids:
self.bids.add_bid('?', i)
team0_sum = ""
team1_sum = ""
if final:
print("The bids for this round:")
team0_sum = " = " + "+".join([str(bid) for bid in self.bids.get_team_bid(0)])
team1_sum = " = " + "+".join([str(bid) for bid in self.bids.get_team_bid(1)])
else:
print("Bids so far:")
print("\tteam 0: " + str(self.bids[0]) + " + " + str(self.bids[2]) + team0_sum)
print("\tteam 1: " + str(self.bids[1]) + " + " + str(self.bids[3]) + team1_sum)
def make_bid(self, bids):
""""
Ask this player to make a bid at the start of a round.
bids: a dict containing all bids so far, with keys 0-3 (player_id) and values 0-13 or "B" for Blind Nill.
return value: An integer between 0 (a Nill bid) and 13 minus the teammate's bid (inclusive).
"""
teammate_bid = 0
if 2 in bids:
pass
if self.teammate_id in bids:
teammate_bid = bids[self.teammate_id]
max_bid = 13 - teammate_bid
self.bids = bids
print("Please make a bid for this round")
self.print_bids()
print(bids)
answer = -1
while not (0 <= answer <= max_bid):
try:
answer = int(input("Please enter a number between 0 and " + str(13-teammate_bid) + "\n"))
except ValueError:
answer = -1
print()
return answer
def play_card(self, trick, valid_cards):
"""
Ask this player to play a card, given the trick so far.
trick: a Trick object with the cards played so far.
valid_cards: a list of Card objects present in your hand that are valid to play for this trick.
Intended purely to assist in choosing a card.
return value: a Card object present in your hand.
"""
print("It's your turn to play a card!")
print("The trick so far:", str(trick))
print("Your hand:")
print(self.hand.to_string(True))
valid_ids = [int(card) for card in valid_cards]
chosen_card_nr = ""
while chosen_card_nr not in valid_ids:
if not isinstance(chosen_card_nr, int):
try:
chosen_card_nr = int(input("Please enter the value of the card you wish to play (shown in parenthesis)\n"))
except ValueError:
chosen_card_nr = -1
if chosen_card_nr not in valid_ids:
try:
chosen_card_nr = int(input("That card is not valid for this trick, please choose another\n"))
except ValueError:
chosen_card_nr = ""
chosen_card = None
for card in valid_cards:
if int(card) == chosen_card_nr:
chosen_card = card
break
self.hand.remove(chosen_card)
print("You have played " + str(chosen_card))
print()
return chosen_card
def offer_blind_nill(self, bids):
""""
Ask this player if they want to bid a Blind Nill.
bids: a dict containing all bids so far, with keys 0-3 (player_id) and values 0-13
return value: True or False
"""
print("You are allowed to bid a Blind Nill this round.")
print("Bids so far are: " + str(bids))
answer = input("Bid Blind Nill? (y/n)\n")
while answer not in ["y", "Y", "n", "N"]:
answer = input("Please answer y or n\n")
return answer in ["y", "Y"]
def receive_blind_nill_cards(self, cards):
""""
Receive 2 cards from your teammate in case of a Blind Nill.
cards: a list of 2 Card objects.
"""
for card in cards:
self.hand.append(card)
print("Your teammate has given you the following cards:", cards[0], cards[1])
print()
def request_blind_nill_cards(self):
""""
Donate 2 cards to your teammate in case of a Blind Nill.
return value: a list of 2 Card objects present in your hand.
"""
print("Please select 2 cards to give to your teammate")
print("Your hand:")
print(self.hand.to_string(True))
hand_card_ids = [int(card) for card in self.hand]
chosen_card_numbers = []
chosen_card_nr = ""
ordinals = ["first", "second"]
while chosen_card_nr not in hand_card_ids and len(chosen_card_numbers) < 2:
if not isinstance(chosen_card_nr, int):
try:
chosen_card_nr = int(input("Please enter the value of the {} card you wish to give (shown in parenthesis)\n".format(ordinals[len(chosen_card_numbers)])))
except ValueError:
print("Invalid card value given. Card values must be integers")
chosen_card_nr = ""
continue
if chosen_card_nr not in hand_card_ids:
try:
if len(chosen_card_numbers) == 1 and chosen_card_nr == chosen_card_numbers[0]:
chosen_card_nr = int(input("You have already picked that card, please choose another\n"))
else:
chosen_card_nr = int(input("That card is not in your hand, please choose another\n"))
except ValueError:
print("Invalid card value given. Card values must be integers")
chosen_card_nr = ""
continue
else:
chosen_card_numbers.append(chosen_card_nr)
hand_card_ids.remove(chosen_card_nr)
chosen_card_nr = ""
chosen_cards = []
for chosen_card_nr in chosen_card_numbers:
for card in self.hand:
if int(card) == chosen_card_nr:
chosen_cards.append(card)
self.hand.remove(card)
break
print("You have given your teammate", str(chosen_cards[0]), "and", str(chosen_cards[1]))
print()
return chosen_cards
def announce_bids(self, bids):
""""
Tell the player about the bids that have been made.
bids: a dict containing all bids, with keys 0-3 (player_id) and values 0-13 or "B" for Blind Nill.
"""
self.bids = bids
self.print_bids(final=True)
print()
def announce_trick(self, trick):
""""
Tell the player about a completed trick.
trick: a Trick object with the cards played.
"""
self.trick_count[trick.get_winner()] += 1
print("Result:", str(trick))
winner = trick.get_winner()
if winner == self.player_id:
print("Congratulations! The trick is yours!")
elif winner == self.teammate_id:
print("Well done, the trick goes to your teammate")
else:
print("Alas, the trick has gone to your opponent")
progress_strings = []
for team_id in range(2):
res = "Team " + str(team_id) + ": "
if self.bids.team_has_nill(team_id):
res += str(self.trick_count[0 + team_id]) + "/" + str(self.bids[0 + team_id])
res += " + "
res += str(self.trick_count[2 + team_id]) + "/" + str(self.bids[2 + team_id])
else:
trick_sum = self.trick_count[0 + team_id] + self.trick_count[2 + team_id]
res += str(trick_sum) + "/" + str(self.bids.get_team_bid(team_id)[0])
progress_strings.append(res)
print("Current trick count:", self.trick_count, "Progress:", ", ".join(progress_strings))
print()
def announce_score(self, score):
""""
Tell the player about the new scores for each team.
score: a dict containing the scores of each team (keys 0 and 1).
"""
if self.score is None:
self.announce_start()
self.score = score
else:
self.score = score
print("The new scores are " + str(score))
print()
def announce_start(self):
print("Welcome, player " + str(self.player_id) + "!")
print("You are on team " + str(self.team_id) + " together with player " + str(self.teammate_id))
print()