-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcoat_piece.py
320 lines (254 loc) · 11.5 KB
/
coat_piece.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
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
#import numpy as np
import random
SUITS = ['H', 'S', 'D', 'C'] # H-Hearts, S-Spades, D-Diamond, C-Clubs
NUMBER_OF_PLAYERS = 4
NUMBER_OF_HANDS = 13
SPADES = u"\u2660"
DIAMONDS = u"\u2666"
HEARTS = u"\u2665"
CLUBS = u"\u2663"
SYMBOLS = {'H': HEARTS, 'S': SPADES, 'D': DIAMONDS, 'C': CLUBS}
CHARACTERS = {1:1, 2:2, 3:3, 4:4, 5:5, 6:6, 7:7, 8:8, 9:9, 10:10, 11:'J', 12:'Q', 13:'K', 14:'A'}
class Card:
def __init__(self, num, suit):
self.number = num # The number on the card (2 - 14) [11-Jack, 12-Queen, 13-King, 14-Ace]
self.suit = suit
class Player:
def __init__(self, num):
self.number = num
self.card_list = []
self.discard_pile = [] # Knowledge of
def define_trump(self, manual):
max_suit = None
if manual and self.number == 0:
first_five = ""
for card in self.card_list[0:5]:
first_five = first_five + " ({}{}) ".format(CHARACTERS[card.number], SYMBOLS[card.suit])
print("Choose Trump from : {}".format(first_five))
while max_suit not in ['H', 'S', 'D', 'C']:
max_suit = input("Enter (H/S/D/C) :").upper()
else:
suit_count = {"H": 0, "S": 0, "D": 0, "C": 0}
for card in self.card_list[0:5]: # Select the highest sum of suit in first 5 cards
suit_count[card.suit] += card.number
max_num = 0
for suit in suit_count:
if suit_count[suit] >= max_num:
max_num = suit_count[suit]
max_suit = suit
return max_suit
def print_card_list(self, card_list):
print_card_list = ""
for i, card in enumerate(card_list):
print_card_list = print_card_list + " {}:({}{}) ".format(i, CHARACTERS[card.number], SYMBOLS[card.suit])
return print_card_list
def get_suited_card_list(self, suits):
card_list = []
for card in self.card_list:
if card.suit in suits:
card_list.append(card)
return card_list
def play_manual(self, active_pile, player_order):
if not active_pile:
legal_card_list = self.get_suited_card_list(SUITS)
else:
active_suit = active_pile[player_order[0]].suit
legal_suits = [active_suit]
legal_card_list = self.get_suited_card_list(legal_suits)
if not legal_card_list:
legal_card_list = self.get_suited_card_list(SUITS)
print("CARDS PLAYED: ")
for playa in player_order[:-1]: # Do not print cards of the latest added player
print("Player {}: ({}{})".format(playa, CHARACTERS[active_pile[playa].number], SYMBOLS[active_pile[playa].suit]))
c_list = self.print_card_list(legal_card_list)
print("YOUR HAND: {}".format(c_list))
idx = len(legal_card_list)
legal_move = [x for x in range(len(legal_card_list))]
while idx not in legal_move:
idx = int(input("Enter the index of the legal playable card list: "))
selected_card = legal_card_list[idx]
active_pile[self.number] = selected_card
self.card_list.pop(self.card_list.index(selected_card))
# This function defines the rules of playing coat piece
def play_legal_card_random(self, active_pile, trump, first_player):
selected_card = None
if not active_pile:
card_num = random.randint(0, len(self.card_list) - 1) # random card selector
selected_card = self.card_list[card_num]
else:
active_suit = active_pile[first_player].suit
legal_suits = [active_suit]
legal_card_list = self.get_suited_card_list(legal_suits)
if legal_card_list:
card_num = random.randint(0, len(legal_card_list) - 1) # random card selector from active suit
selected_card = legal_card_list[card_num]
else:
legal_suits.append(trump)
legal_card_list = self.get_suited_card_list(legal_suits)
if legal_card_list:
card_num = random.randint(0, len(legal_card_list) - 1) # random card selector from trump
selected_card = legal_card_list[card_num]
else:
card_num = random.randint(0, len(self.card_list) - 1) # random card selector from whole list
selected_card = self.card_list[card_num]
active_pile[self.number] = selected_card
self.card_list.pop(self.card_list.index(selected_card))
class Team:
def __init__(self):
self.player_list = [] # Will contain the list of player numbers
self.hands_made = 0
def add_player(self, player_num):
self.player_list.append(player_num)
def check_player(self, player_num):
return player_num in self.player_list
class Board:
def __init__(self):
self.trump = None
self.discard_pile = []
self.active_pile = {}
self.deck = []
self.current_player = None
self.player_order = []
def shuffle(self):
random.shuffle(self.deck)
def generate_cards(self):
self.deck = []
for suit in SUITS:
for rank in range(2, 15, 1):
card = Card(rank, suit)
self.deck.append(card)
def reset(self):
self.trump = None
self.discard_pile = []
self.active_pile = {}
self.player_order = []
self.generate_cards()
def distribute(self, players, trump_player, teams):
current_player = trump_player
# Distributing the cards in order (with trump_player being first)
for i in range(4):
# Adding trump_player and the next to next player in team_a or teams[0] (even)
# Adding rest of the players or teams[1] (odd)
if i % 2 == 0:
teams[0].add_player(players[current_player].number)
else:
teams[1].add_player(players[current_player].number)
players[current_player].card_list = self.dealer(current_player)
current_player = self.next_player(current_player)
self.deck = []
def dealer(self, player):
# Switch case for distributing the cards according to 5, 4 , 4 rule
dealer = {
0: self.deck[0:5] + self.deck[20:24] + self.deck[36:40],
1: self.deck[5:10] + self.deck[24:28] + self.deck[40:44],
2: self.deck[10:15] + self.deck[28:32] + self.deck[44:48],
3: self.deck[15:20] + self.deck[32:36] + self.deck[48:52]
}
return dealer.get(player, "Invalid player number")
def next_player(self, current_player):
if current_player == 3:
return 0
else:
return current_player + 1
def check_hand_winner(self):
high_card = self.active_pile[self.player_order[0]] # This will store the highest card of active suit
high_player = self.player_order[0]
active_suit = self.active_pile[0].suit
high_card_trump = None
high_player_trump = None
if active_suit == self.trump:
high_player_trump = self.current_player
high_card_trump = high_card # This will store highest trump card if trump is played
for playa, card in self.active_pile.items():
if card.suit == self.trump:
if high_card_trump is None or card.number > high_card_trump.number:
high_card_trump = card
high_player_trump = playa
elif card.suit == active_suit:
if card.number > high_card.number:
high_card = card
high_player = playa
if high_card_trump is None:
return high_player
else:
return high_player_trump
def clear_board(self):
self.discard_pile = self.discard_pile + [card for key, card in self.active_pile.items()]
self.active_pile = {}
self.player_order = []
class Game:
def __init__(self):
self.winner = None
self.manual = False
self.manual_player = None
def set_manual(self):
manual = input("Do you want to play the game? (Y/N)")
if manual.upper() == 'Y':
self.manual = True
self.manual_player = 0
print("You are assigned - Player 0")
def check_winner(self, teams):
if teams[0].hands_made > teams[1].hands_made:
self.winner = "Team A"
else:
self.winner = "Team B"
def game_init(self, players, board, teams):
board.reset()
board.shuffle()
# Who will play first and define trump
trump_player = random.randint(0, 3)
board.distribute(players, trump_player, teams)
board.current_player = trump_player
print("Player {} will play first".format(trump_player))
# Check for trump
# for card in players[trump_player].card_list[0:5]:
# print("card: {},{} ,Player-{}".format(card.number, card.suit, card.player))
board.trump = players[trump_player].define_trump(self.manual)
# Check distribution in teams
# for team in teams:
# for player in team.player_list:
# for card in player.card_list[0:5]:
# print("card: {},{} ,Player-{}".format(card.number, card.suit, card.player))
print("TRUMP : {}".format(board.trump))
def play_game(self, players, board, teams):
# Game play 13 hands
for hand in range(NUMBER_OF_HANDS):
for turn in range(NUMBER_OF_PLAYERS):
board.player_order.append(board.current_player)
if self.manual and board.current_player == 0:
players[board.current_player].play_manual(board.active_pile, board.player_order)
else:
players[board.current_player].play_legal_card_random(board.active_pile, board.trump, board.player_order[0]) # Player will select a card from his card list
board.current_player = board.next_player(board.current_player)
""" ############ PRINT STATEMENTS ################ """
print("Hand {}:".format(hand+1))
for i in range(NUMBER_OF_PLAYERS):
card = board.active_pile[board.player_order[i]]
print("Player {}: Card ({}{})".format(board.player_order[i], CHARACTERS[card.number], SYMBOLS[card.suit]))
""" ############################################## """
winner_player = board.check_hand_winner() # check hand winner
board.current_player = winner_player # The winner will play the first turn in next hand
if teams[0].check_player(winner_player): # Adding score to the winning team
teams[0].hands_made += 1
else:
teams[1].hands_made += 1
board.clear_board() # Clearing the active game pile for next hand
print("Winner: Player {}, Team A: {}, Team B: {}".format(winner_player, teams[0].hands_made, teams[1].hands_made))
print("==============================================")
self.check_winner(teams)
print("Winning Team: {}".format(game.winner))
if __name__ == '__main__':
game = Game()
players = []
for i in range(4):
player = Player(i)
players.append(player)
board = Board()
teams = []
team_a = Team() # Trump team
team_b = Team() # Opposing team
teams.append(team_a)
teams.append(team_b)
game.set_manual()
game.game_init(players, board, teams)
game.play_game(players, board, teams)