-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathplayers.py
114 lines (89 loc) · 3.38 KB
/
players.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
import copy
import cards
import random
class Player:
def __init__(self, name, score = 0, decks = {"hand": cards.CardDeck(name="Hand")}):
self.name = name
self._decks = decks
self._score = score
def __repr__(self):
decks_string = '\n'.join(map(lambda x: str(x), self._decks.values()))
return(f"Player: {self.name}\n{decks_string}")
def draw_from(self, deck, draw_to_deck = "hand"):
if not draw_to_deck in self._decks:
self._decks[draw_to_deck] = cards.CardDeck(name = draw_to_deck)
self._decks[draw_to_deck].add_card(deck.draw())
def play_from_deck(self, index, deck = "hand"):
return(self._decks[deck].play(index))
def read_from_deck(self, index, deck = "hand"):
return(self._decks[deck].read_card(index))
def add_to_score(self, add):
self._score += add
if self._score < 0:
self.score = 0
def get_score(self):
return(self._score)
class PlayerGroup:
def __init__(self, players, first_player = 0, default_decks = {"hand": cards.CardDeck(name="Hand")}):
self._players = list(map(lambda x: Player(x, decks = copy.deepcopy(default_decks)), players))
self._current_player = 0
if 0 <= first_player and first_player < len(self._players):
self._current_player = first_player
else:
raise PlayerGroup.OutOfRange(f"{first_player} is not a valid index for first player; must be between zero and {len(self._players) -1}.")
self._index = -1
self._direction = 1
def __repr__(self):
return_string = []
for i in range(len(self._players)):
return_string.append(f"{i}: {self._players[i].name}")
return("\n".join(return_string))
def __iter__(self):
return PlayerGroupIter(group = self)
def __getitem__(self, item):
return(self._players[item])
def set_random_starting_player(self):
self._current_player = random.randint(0,len(self._players) - 1)
def deal_cards_from(self, deck, hand_size, to_deck = "hand"):
if deck.get_card_count() < (len(self._players) * hand_size):
raise PlayerGroup.OutOfRange(f"Not enough cards in deck to deal {hand_size} cards to each player.")
for i in range(hand_size):
for player in self._players:
player.draw_from(deck, draw_to_deck = to_deck)
def get_player_count(self):
return(len(self._players))
def get_player_names(self):
return(list(map(lambda x: x.name, self._players)))
def pass_turn(self):
self._current_player += self._direction
self._current_player %= len(self._players)
def change_direction(self):
self._direction *= -1
def get_current_player(self):
return(self._players[self._current_player])
def get_player_by_name(self, name):
for p in self._players:
if p.name == name:
return(p)
def get_player_by_index(self, index):
return(self._players[index])
def get_offset_player(self, offset):
return(self._players[(self._current_player + offset) % len(self._players)])
class OutOfRange(Exception):
def __init__(self, message):
self.message = message
def __str__(self):
return(self.message)
class PlayerGroupIter:
def __init__(self, group, start = 0):
self._index = start
self._player_group = group
def __next__(self):
index = self._index
group = self._player_group
self._index += 1
if self._index > group.get_player_count():
self._index = 0
raise StopIteration
else:
return group.get_player_by_index(index)