Решение на От ливадите до Лас Вегас (и назад) от Харут Партамиан

Обратно към всички решения

Към профила на Харут Партамиан

Резултати

  • 8 точки от тестове
  • 0 бонус точки
  • 8 точки общо
  • 12 успешни тест(а)
  • 3 неуспешни тест(а)

Код

from random import randint, shuffle
FACES = ('2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A')
SUITS = ("clubs", "diamonds", "hearts", "spades")
BELOT_FACES = ('7', '8', '9', '10', 'J', 'Q', 'K', 'A')
class Card:
def __init__(self, suit: str, face: str):
assert suit in SUITS, f"Suit {suit} is not in allowed suites"
assert face in FACES, f"Face {face} is not in allowed faces"
self.__suit = suit

Идеята зад __ в Python, и причина да се прилага name mangling, е да се предотврати конфликт на имена при наследяване. Ти едва ли ще наследиш този клас, а дори да го направиш, едва ли ще имаш проблем с имената на атрибутите. В по-голямата часъ от случаите, една долна черта е достатъчно, за да покажеш на останалите, че това е атрибут/метод, който е само за вътрешно ползване.

self.__face = face
def get_suit(self) -> str:
return self.__suit
def get_face(self) -> str:
return self.__face
class Deck:
def __init__(self, face_filter=None):
self.__faces = face_filter if face_filter else FACES
self.__all_cards = self.__generate_cards()
def __generate_cards(self) -> list:
return [Card(suit, face) for suit in SUITS for face in self.__faces]
def cut(self):
cut_point = randint(1, len(self.__all_cards) - 1)
self.__all_cards = self.__all_cards[cut_point:] + self.__all_cards[:cut_point]
def shuffle(self):
shuffle(self.__all_cards)
def get_cards(self) -> list:
return self.__all_cards
class Player:
def __init__(self, player_id=None):
self.__player_id = player_id
self.__player_cards = []
def get_id(self) -> int:
return self.__player_id
def get_cards(self) -> list:
return self.__player_cards
def add_card(self, card):
self.__player_cards.append(card)
class Game:
def __init__(self, number_of_players: int, dealing_direction: str, dealing_instructions: tuple, face_filter=None):
assert dealing_direction in ("ltr", "rtl"), f"Dealing direction must be either rtl or ltr"
self.number_of_players = number_of_players
self.dealing_direction = dealing_direction
self.dealing_instructions = dealing_instructions
self._deck = Deck(face_filter)
self.players = self.__add_players()
def __add_players(self) -> list:
return [Player(player_id) for player_id in range(self.number_of_players)]
def get_players(self) -> list:
random_player_id = randint(0, self.number_of_players - 1)
return self.players[random_player_id:] + self.players[:random_player_id]
def prepare_deck(self):
for player in self.players:
if player.get_cards():
self._deck.get_cards().extend(player.get_cards())
self._deck.shuffle()
self._deck.cut()
def deal(self, start_player: Player):
right_part_players = self.players[start_player.get_id():]
left_part_players = self.players[:start_player.get_id()]
if self.dealing_direction == "rtl":
deal_order = left_part_players[::-1] + right_part_players[::-1]
else:
deal_order = right_part_players + left_part_players
for number_of_cards in self.dealing_instructions:
for player in deal_order:
for _ in range(number_of_cards):
if self._deck.get_cards():
top_card = self._deck.get_cards().pop(0)
player.add_card(top_card)
else:
break
def get_deck(self) -> Deck():
return self._deck
class Belot(Game):
def __init__(self):
super().__init__(number_of_players=4,
dealing_direction="ltr",
dealing_instructions=(2, 3, 3),
face_filter=BELOT_FACES)
class Poker(Game):
def __init__(self):
super().__init__(number_of_players=9,
dealing_direction="rtl",
dealing_instructions=(1, 1, 1, 1, 1))

Лог от изпълнението

........F.F...F
======================================================================
FAIL: test_collecting_cards_before_dealing (test.TestGame)
Test collecting the cards before a new deal.
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/storage/deedee/data/rails/pyfmi-2022/releases/20221115154139/lib/language/python/runner.py", line 67, in thread
    raise result
AssertionError: Lists differ: [<solution.Card object at 0xffff9b0c8a00>,[79 chars]3a0>] != []

First list contains 3 additional elements.
First extra element 0:
<solution.Card object at 0xffff9b0c8a00>

+ []
- [<solution.Card object at 0xffff9b0c8a00>,
-  <solution.Card object at 0xffff9b0c8940>,
-  <solution.Card object at 0xffff9b0c83a0>]

======================================================================
FAIL: test_dealing_rtl (test.TestGame)
Test dealing the cards right to left.
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/storage/deedee/data/rails/pyfmi-2022/releases/20221115154139/lib/language/python/runner.py", line 67, in thread
    raise result
AssertionError: {('clubs', '9'), ('clubs', 'K'), ('clubs', '8')} not found in ({('clubs', '3'), ('clubs', '10'), ('clubs', '2')}, {('spades', 'K'), ('spades', '6'), ('spades', 'A')})

======================================================================
FAIL: test_correct_direction_and_players_deal (test.TestPoker)
Test dealing with correct direction and players.
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/storage/deedee/data/rails/pyfmi-2022/releases/20221115154139/lib/language/python/runner.py", line 67, in thread
    raise result
AssertionError: {('hearts', 'J'), ('clubs', '10'), ('diamonds', '6'), ('hearts', '2'), ('spades', '7')} not found in ({('hearts', 'Q'), ('clubs', 'J'), ('hearts', '3'), ('clubs', '2'), ('diamonds', '7')}, {('diamonds', 'K'), ('diamonds', '4'), ('hearts', '9'), ('spades', '5'), ('spades', 'A')})

----------------------------------------------------------------------
Ran 15 tests in 0.177s

FAILED (failures=3)

История (3 версии и 5 коментара)

Харут обнови решението на 09.11.2022 14:03 (преди над 1 година)

+from random import randint, shuffle
+
+FACES = ('2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A')
+SUITS = ("clubs", "diamonds", "hearts", "spades")
+BELOT_FACES = ('7', '8', '9', '10', 'J', 'Q', 'K', 'A')
+
+
+class Card:
+ def __init__(self, suit: str, face: str):
+ assert suit in SUITS, f"Suit {suit} is not in allowed suites"
+ assert face in FACES, f"Face {face} is not in allowed faces"
+
+ self.__suit = suit
+ self.__face = face
+
+ def get_suit(self) -> str:
+ return self.__suit
+
+ def get_face(self) -> str:
+ return self.__face
+
+
+class Deck:
+ def __init__(self, face_filter=None):
+ self.__faces = face_filter if face_filter else FACES
+ self.__all_cards = self.__generate_cards()
+
+ def __generate_cards(self) -> list:
+ return [Card(suit, face) for suit in SUITS for face in self.__faces]
+
+ def cut(self):
+ cut_point = randint(1, len(self.__all_cards) - 1)
+ self.__all_cards = self.__all_cards[cut_point:] + self.__all_cards[:cut_point]
+
+ def shuffle(self):
+ shuffle(self.__all_cards)
+
+ def get_cards(self) -> list:
+ return self.__all_cards
+
+
+class Player:
+ def __init__(self, player_id=None):
+ self.__player_id = player_id
+ self.__player_cards = []
+
+ def get_id(self) -> int:
+ return self.__player_id
+
+ def get_cards(self) -> list:
+ return self.__player_cards
+
+ def add_card(self, card):
+ self.__player_cards.append(card)
+
+
+class Game:
+ def __init__(self, number_of_players: int, dealing_direction: str, dealing_instructions: tuple,
+ player_max_cards=None, deck=Deck()):

deck = Deck() ще се евалюира само веднъж - при дефинирането на класа ти. Т.е този клас ще работи само при една инстанция. Повече инстанции ще го счупят, защото ще споделят едно и също тесте.

class Deck:
    pass

class Game:
    def __init__(self, deck=Deck()):
        self.deck = deck

game1 = Game()
game2 = Game()
print(game1.deck is game2.deck) # True
+ assert dealing_direction in ("ltr", "rtl"), f"Dealing direction must be either rtl or ltr"
+
+ self.number_of_players = number_of_players
+ self.dealing_direction = dealing_direction
+ self.dealing_instructions = dealing_instructions
+ self._deck = deck
+ self.players = self.__add_players()
+ self.player_max_cards = player_max_cards
+
+ def __add_players(self) -> list:
+ return [Player(player_id) for player_id in range(self.number_of_players)]
+
+ def get_players(self) -> list:
+ random_player_id = randint(0, self.number_of_players - 1)
+ return self.players[random_player_id:] + self.players[:random_player_id]
+
+ def prepare_deck(self):
+ for player in self.players:
+ if player.get_cards():
+ self._deck.get_cards().extend(player.get_cards())
+ self._deck.shuffle()
+ self._deck.cut()
+
+ def deal(self, start_player: Player):
+ right_part_players = self.players[start_player.get_id():]
+ left_part_players = self.players[:start_player.get_id()]
+
+ if self.dealing_direction == "ltr":
+ deal_order = left_part_players + right_part_players
+ else:
+ deal_order = right_part_players + left_part_players
+
+ for number_of_cards in self.dealing_instructions:
+ for player in deal_order:
+ for _ in range(number_of_cards):
+ if self._deck.get_cards():
+ top_card = self._deck.get_cards().pop(0)
+ player.add_card(top_card)
+ else:
+ break
+
+ def get_deck(self) -> Deck():
+ return self._deck
+
+
+class Belot(Game):
+ def __init__(self):
+ super().__init__(number_of_players=4,
+ dealing_direction="ltr",
+ dealing_instructions=(2, 3, 3),
+ deck=Deck(BELOT_FACES))
+
+
+class Poker(Game):
+ def __init__(self):
+ super().__init__(number_of_players=9,
+ dealing_direction="rtl",
+ dealing_instructions=(1, 1, 1, 1, 1))

Харут обнови решението на 12.11.2022 15:02 (преди над 1 година)

from random import randint, shuffle
FACES = ('2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A')
SUITS = ("clubs", "diamonds", "hearts", "spades")
BELOT_FACES = ('7', '8', '9', '10', 'J', 'Q', 'K', 'A')
class Card:
def __init__(self, suit: str, face: str):
assert suit in SUITS, f"Suit {suit} is not in allowed suites"
assert face in FACES, f"Face {face} is not in allowed faces"
-
self.__suit = suit

Идеята зад __ в Python, и причина да се прилага name mangling, е да се предотврати конфликт на имена при наследяване. Ти едва ли ще наследиш този клас, а дори да го направиш, едва ли ще имаш проблем с имената на атрибутите. В по-голямата часъ от случаите, една долна черта е достатъчно, за да покажеш на останалите, че това е атрибут/метод, който е само за вътрешно ползване.

self.__face = face
def get_suit(self) -> str:
return self.__suit
def get_face(self) -> str:
return self.__face
class Deck:
def __init__(self, face_filter=None):
self.__faces = face_filter if face_filter else FACES
self.__all_cards = self.__generate_cards()
def __generate_cards(self) -> list:
return [Card(suit, face) for suit in SUITS for face in self.__faces]
def cut(self):
cut_point = randint(1, len(self.__all_cards) - 1)
self.__all_cards = self.__all_cards[cut_point:] + self.__all_cards[:cut_point]
def shuffle(self):
shuffle(self.__all_cards)
def get_cards(self) -> list:
return self.__all_cards
class Player:
def __init__(self, player_id=None):
self.__player_id = player_id
self.__player_cards = []
def get_id(self) -> int:
return self.__player_id
def get_cards(self) -> list:
return self.__player_cards
def add_card(self, card):
self.__player_cards.append(card)
class Game:
- def __init__(self, number_of_players: int, dealing_direction: str, dealing_instructions: tuple,
- player_max_cards=None, deck=Deck()):
+ def __init__(self, number_of_players: int, dealing_direction: str, dealing_instructions: tuple, face_filter=None):
assert dealing_direction in ("ltr", "rtl"), f"Dealing direction must be either rtl or ltr"
-
self.number_of_players = number_of_players
self.dealing_direction = dealing_direction
self.dealing_instructions = dealing_instructions
- self._deck = deck
+ self._deck = Deck(face_filter)
self.players = self.__add_players()
- self.player_max_cards = player_max_cards
def __add_players(self) -> list:
return [Player(player_id) for player_id in range(self.number_of_players)]
def get_players(self) -> list:
random_player_id = randint(0, self.number_of_players - 1)
return self.players[random_player_id:] + self.players[:random_player_id]
def prepare_deck(self):
for player in self.players:
if player.get_cards():
self._deck.get_cards().extend(player.get_cards())
self._deck.shuffle()
self._deck.cut()
def deal(self, start_player: Player):
right_part_players = self.players[start_player.get_id():]
left_part_players = self.players[:start_player.get_id()]
if self.dealing_direction == "ltr":
deal_order = left_part_players + right_part_players
else:
deal_order = right_part_players + left_part_players
for number_of_cards in self.dealing_instructions:
for player in deal_order:
for _ in range(number_of_cards):
if self._deck.get_cards():
top_card = self._deck.get_cards().pop(0)
player.add_card(top_card)
else:
break
def get_deck(self) -> Deck():
return self._deck
class Belot(Game):
def __init__(self):
super().__init__(number_of_players=4,
dealing_direction="ltr",
dealing_instructions=(2, 3, 3),
- deck=Deck(BELOT_FACES))
+ face_filter=BELOT_FACES)
class Poker(Game):
def __init__(self):
super().__init__(number_of_players=9,
dealing_direction="rtl",
- dealing_instructions=(1, 1, 1, 1, 1))
+ dealing_instructions=(1, 1, 1, 1, 1))

Харут обнови решението на 15.11.2022 12:42 (преди над 1 година)

from random import randint, shuffle
FACES = ('2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A')
SUITS = ("clubs", "diamonds", "hearts", "spades")
BELOT_FACES = ('7', '8', '9', '10', 'J', 'Q', 'K', 'A')
class Card:
def __init__(self, suit: str, face: str):
assert suit in SUITS, f"Suit {suit} is not in allowed suites"
assert face in FACES, f"Face {face} is not in allowed faces"
self.__suit = suit
self.__face = face
def get_suit(self) -> str:
return self.__suit
def get_face(self) -> str:
return self.__face
class Deck:
def __init__(self, face_filter=None):
self.__faces = face_filter if face_filter else FACES
self.__all_cards = self.__generate_cards()
def __generate_cards(self) -> list:
return [Card(suit, face) for suit in SUITS for face in self.__faces]
def cut(self):
cut_point = randint(1, len(self.__all_cards) - 1)
self.__all_cards = self.__all_cards[cut_point:] + self.__all_cards[:cut_point]
def shuffle(self):
shuffle(self.__all_cards)
def get_cards(self) -> list:
return self.__all_cards
class Player:
def __init__(self, player_id=None):
self.__player_id = player_id
self.__player_cards = []
def get_id(self) -> int:
return self.__player_id
def get_cards(self) -> list:
return self.__player_cards
def add_card(self, card):
self.__player_cards.append(card)
class Game:
def __init__(self, number_of_players: int, dealing_direction: str, dealing_instructions: tuple, face_filter=None):
assert dealing_direction in ("ltr", "rtl"), f"Dealing direction must be either rtl or ltr"
self.number_of_players = number_of_players
self.dealing_direction = dealing_direction
self.dealing_instructions = dealing_instructions
self._deck = Deck(face_filter)
self.players = self.__add_players()
def __add_players(self) -> list:
return [Player(player_id) for player_id in range(self.number_of_players)]
def get_players(self) -> list:
random_player_id = randint(0, self.number_of_players - 1)
return self.players[random_player_id:] + self.players[:random_player_id]
def prepare_deck(self):
for player in self.players:
if player.get_cards():
self._deck.get_cards().extend(player.get_cards())
self._deck.shuffle()
self._deck.cut()
def deal(self, start_player: Player):
right_part_players = self.players[start_player.get_id():]
left_part_players = self.players[:start_player.get_id()]
- if self.dealing_direction == "ltr":
- deal_order = left_part_players + right_part_players
+ if self.dealing_direction == "rtl":
+ deal_order = left_part_players[::-1] + right_part_players[::-1]
else:
deal_order = right_part_players + left_part_players
for number_of_cards in self.dealing_instructions:
for player in deal_order:
for _ in range(number_of_cards):
if self._deck.get_cards():
top_card = self._deck.get_cards().pop(0)
player.add_card(top_card)
else:
break
def get_deck(self) -> Deck():
return self._deck
class Belot(Game):
def __init__(self):
super().__init__(number_of_players=4,
dealing_direction="ltr",
dealing_instructions=(2, 3, 3),
face_filter=BELOT_FACES)
class Poker(Game):
def __init__(self):
super().__init__(number_of_players=9,
dealing_direction="rtl",
- dealing_instructions=(1, 1, 1, 1, 1))
+ dealing_instructions=(1, 1, 1, 1, 1))