Кристиан обнови решението на 12.11.2022 15:53 (преди около 2 години)
+import random
+
+all_faces = ["2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"]
+all_suits = ["clubs", "diamonds", "hearts", "spades"]
+belot_num_players = 4
+poker_num_players = 9
+left_to_right = "ltr"
+right_to_left = "rtl"
+belot_dealing_instructions = (2, 3, 3)
+poker_dealing_instructions = (1, 1, 1, 1, 1)
+
+
+class Card:
+ def __init__(self, suit, face):
+ self.suit = suit
Бих използвал protected имена на атрибути като тези, които не използваш извън класа - self._suit
+ self.face = face
+
+ def get_suit(self):
+ return self.suit
+
+ def get_face(self):
+ return self.face
+
+
+class Deck:
+ def __init__(self, face_filter=all_faces):
+ self.face_filter = face_filter
+ self.cards = self.generate_deck()
+
+ def generate_deck(self):
+ cards = []
+ for face in self.face_filter:
+ for suit in all_suits:
+ cards.append(Card(suit, face))
+ return cards
+
+ def get_cards(self):
+ return self.cards
+
+ def shuffle(self):
+ random.shuffle(self.cards)
+
+ def cut(self):
+ cut = random.randrange(1, len(self.cards))
+ first_half = self.cards[:cut]
Принципно можеш да минеш без тези променливи, а направо да изпълниш:
self.cards = self.cards[cut:] + self.cards[:cut]
+ second_half = self.cards[cut:]
+ self.cards = second_half + first_half
+
+ def add_cards(self, cards):
+ self.cards += cards
+
+ def get_card(self):
+ return self.cards.pop(0)
+
+
+class Player:
+ def __init__(self):
+ self.cards = []
+
+ def get_cards(self):
+ return self.cards
+
+ def clear_cards(self):
+ self.cards = []
+
+ def add_card(self, card):
+ self.cards.append(card)
+
+
+class Game:
+ def __init__(self, number_of_players, dealing_direction, dealing_instructions):
+ self.number_of_players = number_of_players
+ self.dealing_direction = dealing_direction
+ self.dealing_instructions = dealing_instructions
+ self.deck = Deck()
+ self.players = [Player() for i in range(number_of_players)]
Когато не плануваш да използваш променлива, именувай я _
, както е по конвенция.
+
+ def get_players(self):
+ return self.players
+
+ def get_deck(self):
+ return self.deck
+
+ def prepare_deck(self):
+ for player in self.players:
+ self.deck.add_cards(player.get_cards())
+ player.clear_cards()
+ self.deck.shuffle()
+ self.deck.cut()
+
+ def deal(self, player):
+ order = self.get_order_of_deal(player)
+ for deal in range(len(self.dealing_instructions)):
Препоръчително е да обхождаш елементите, а не техните индекси. По-кратко, по-лесно.
for num_of_card_per_deal in self.dealing_instructions
+ num_of_card_per_deal = self.dealing_instructions[deal]
+ for player in range(self.number_of_players):
+ for _ in range(num_of_card_per_deal):
+ order[player].add_card(self.deck.get_card())
+
+ def get_order_of_deal(self, player):
+ index_of_player = self.players.index(player)
+ order = self.players[index_of_player:]
+ order += self.players[:index_of_player]
+ if self.dealing_direction == right_to_left:
+ order.reverse()
+ return order
+
+
+class Belot(Game):
+ def __init__(self, number_of_players=belot_num_players, dealing_direction=left_to_right,
+ dealing_instructions=belot_dealing_instructions):
+ super().__init__(number_of_players, dealing_direction, dealing_instructions)
+ self.deck = Deck(all_faces[5:])
Не съм почитател на хардкоуднати магически числа. Не е ясно защо точно 5 и кога би се наложило да го сменя. Бих го дефинирал като константа, или бих дефинирал отделен списък за белот, или поне бих сложил коментар...
+
+
+class Poker(Game):
+ def __init__(self, number_of_players=poker_num_players, dealing_direction=right_to_left,
+ dealing_instructions=poker_dealing_instructions):
+ super().__init__(number_of_players, dealing_direction, dealing_instructions)