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

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

Към профила на Виктор Христов

Резултати

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

Код

import random
from itertools import repeat
DEFAULT_FACE_FILTER = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A']
BELOT_FACE_FILTER = ['7', '8', '9', '10', 'J', 'Q', 'K', 'A']
SUITS = ["clubs", "diamonds", "hearts", "spades"]
class Card:
def __init__(self, face, suit):
self.face = face
self.suit = suit
def get_face(self):
return self.face
def get_suit(self):
return self.suit
class Deck:
def __init__(self, face_filter = DEFAULT_FACE_FILTER):
def deck_generator(faces, suits):

Супер е, че виждам генератор! Но не мисля, че е добра идея той да бъде дефиниран в __init__ - по-добре е да се метод на класа, защото:
1) По-четимо е;
2) Достъпен е и за други потенциални клиенти;

Можеш да го дефинираш като staticmethod, тъй като той не изисква инстанция.

Освен това би си спестил цикъла по-долу, ако го преправиш да инстанцира карти:

@staticmethod
def deck_generator(faces, suits):
    for face in faces:
        for suit in suits:
            yield Card(face, suit)

def __init__(self, face_filter=DEFAULT_FACE_FILTER):
    self.cards = list(self.deck_generator(face_filter, SUITS))

ПП: не съм го тествал, пиша наизуст, но е нещо такова...

for face in faces:
for suit in suits:
yield face, suit
self.cards = []
for face, suit in list(deck_generator(face_filter, SUITS)):
self.cards.append(Card(face, suit))
def cut(self):
middle = len(self.cards) / 2

Бих използвал някакъв случаен елемент при цепене, а не винаги средата, но това не е нещо, за което ще тестваме, така че и това е валидно. Просто е предвидимо, ако говорим за истинска игра.

first_half = self.cards[:middle]
second_half = self.cards[middle:]
self.cards = second_half + first_half
def shuffle(self):
random.shuffle(self.cards)
def get_cards(self):
return self.cards
def draw_card(self):

Не трябва да раздаваш случайни карти, а карти, които са най-отгоре на тестето.

ПП: Никъде не е казано кое е отгоре, и кое е отдолу, така че просто и двете интерпретации са валидни, но трябва да взимаш карти само от единия края.

card = random.choise(self.cards)
self.cards.remove(card)
return card
def draw_cards(self, card_count):
cards = []
for _ in itertools.repeat(None, card_count):
cards = draw_card()
return cards
class Player:
def __init__(self):
self.cards = []
def give_cards(self, cards):
self.cards += cards
def clear_cards(self):
self.cards = []
def get_cards(self):
return self.cards
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 = []
self.players = []
def set_deck(self, deck = Deck()):

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

class Deck:
    pass

class Game:

    def set_deck(self, deck=Deck()):
        self.deck = deck

game1 = Game()
game1.set_deck()
game2 = Game()
game2.set_deck()
print(game1.deck is game2.deck) # True
self.deck = deck
def get_deck(self):
return deck
def prepare_deck(self):
for player in players:
self.deck += player.get_cards()
player.clear_cards()
self.deck.shuffle()
self.deck.cut()
def get_players(self):
return players
def order_players(self, player):
#Попринцип трябва тук да направя проверка, ако player е в players, но приемам, че ми подавате верен input в deal(player)
while players[0] != player:
players.append(players.pop(0))
def deal(self, player):
order_players(player)
if dealing_direction == "rtl":
players.reverse()
for card_count in dealing_instructions:
for player in players:
player.give_cards(self.deck.draw_cards(card_count))
class Belot(Game):
def __init__(self):
super().__init__(4, "ltr", (2, 3, 3))
super().set_deck(Deck(BELOT_FACE_FILTER))
class Poker(Game):
def __init__(self):
super().__init__(9, "rtl", (1, 1, 1, 1, 1))
super().set_deck()

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

EEFFE...EEEEEEE
======================================================================
ERROR: test_correct_deck_init (test.TestBelot)
Test initialization with correct deck.
----------------------------------------------------------------------
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
NameError: name 'deck' is not defined

======================================================================
ERROR: test_correct_direction_and_players_deal (test.TestBelot)
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
NameError: name 'deck' is not defined

======================================================================
ERROR: test_cutting_deck (test.TestDeck)
Test cutting a deck.
----------------------------------------------------------------------
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
TypeError: slice indices must be integers or None or have an __index__ method

======================================================================
ERROR: 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
NameError: name 'players' is not defined

======================================================================
ERROR: test_dealing_ltr (test.TestGame)
Test dealing the cards left to right.
----------------------------------------------------------------------
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
NameError: name 'players' is not defined

======================================================================
ERROR: 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
NameError: name 'players' is not defined

======================================================================
ERROR: test_players_creation (test.TestGame)
Test creation and retrieval of 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
NameError: name 'players' is not defined

======================================================================
ERROR: test_prepare_deck (test.TestGame)
Test preparing the deck for dealing.
----------------------------------------------------------------------
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
NameError: name 'players' is not defined

======================================================================
ERROR: test_correct_deck_init (test.TestPoker)
Test initialization with correct deck.
----------------------------------------------------------------------
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
NameError: name 'deck' is not defined

======================================================================
ERROR: 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
NameError: name 'deck' is not defined

======================================================================
FAIL: test_get_face (test.TestCard)
Test the get_face method.
----------------------------------------------------------------------
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: 'spades' != 'A'
- spades
+ A


======================================================================
FAIL: test_get_suit (test.TestCard)
Test the get_suit method.
----------------------------------------------------------------------
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: 'A' != 'spades'
- A
+ spades


----------------------------------------------------------------------
Ran 15 tests in 0.199s

FAILED (failures=2, errors=10)

История (2 версии и 11 коментара)

Виктор обнови решението на 10.11.2022 16:16 (преди около 2 години)

+import random
+from itertools import repeat
+
+DEFAULT_FACE_FILTER = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A']
+BELOT_FACE_FILTER = ['7', '8', '9', '10', 'J', 'Q', 'K', 'A']
+SUITS = ["clubs", "diamonds", "hearts", "spades"]
+
+class Card:
+ def __init__(self, face, suit):
+ self.face = face
+ self.suit = suit
+
+ def get_face(self):
+ return self.face
+
+ def get_suit(self):
+ return self.suit
+
+
+class Deck:
+ def __init__(self, face_filter = DEFAULT_FACE_FILTER):
+ def deck_generator(faces, suits):
+ for face in faces:
+ for suit in suits:
+ yield face, suit
+
+ self.cards = []
+
+ for face, suit in list(deck_generator(face_filter, SUITS)):
+ self.cards.append(Card(face, suit))
+
+ def cut(self):
+ middle = len(self.cards) / 2
+
+ first_half = self.cards[:middle]
+ second_half = self.cards[middle:]
+
+ self.cards = second_half + first_half
+
+ def shuffle(self):
+ random.shuffle(self.cards)
+
+ def get_cards(self):
+ return self.cards
+
+ def draw_card(self):
+ card = random.choise(self.cards)
+
+ self.cards.remove(card)
+
+ return card
+
+ def draw_cards(self, card_count):
+ cards = []
+
+ for _ in itertools.repeat(None, card_count):
+ cards = draw_card()
+
+ return cards
+
+
+class Player:
+ def __init__(self):
+ self.cards = []
+
+ def give_cards(self, cards):
+ self.cards += cards
+
+ def clear_cards(self):
+ self.cards = []
+
+ def get_cards(self):
+ return self.cards
+
+
+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 = []
+ self.players = []
+
+ def set_deck(self, deck = Deck()):
+ self.deck = deck
+
+ def get_deck(self):
+ return deck
+
+ def prepare_deck(self):
+ for player in players:
+ self.deck += player.get_cards()
+ player.clear_cards()
+
+ self.deck.shuffle()
+ self.deck.cut()
+
+ def get_players(self):
+ return players
+
+ def order_players(self, player):
+ #Попринцип трябва тук да направя проверка, ако player е в players, но приемам, че ми подавате верен input в deal(player)
+ while players[0] != player:
+ players.append(players.pop(0))
+
+ def deal(self, player):
+ order_players(player)
+
+ if dealing_direction == "rtl":
+ players.reverse()
+
+ for card_count in dealing_instructions:
+ for player in players:
+ player.give_cards(self.deck.draw_cards(card_count))
+
+
+class Belot(Game):
+ def __init__(self):
+ super().__init__(4, "ltr", (2, 3, 3))
+ super().set_deck(Deck(BELOT_FACE_FILTER))
+
+
+class Poker(Game):
+ def __init__(self):
+ super().__init__(9, "rtl", (1, 1, 1, 1, 1))
+ super().set_deck()

Виктор обнови решението на 10.11.2022 20:05 (преди около 2 години)

import random
from itertools import repeat
DEFAULT_FACE_FILTER = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A']
BELOT_FACE_FILTER = ['7', '8', '9', '10', 'J', 'Q', 'K', 'A']
SUITS = ["clubs", "diamonds", "hearts", "spades"]
class Card:
+
def __init__(self, face, suit):
self.face = face
self.suit = suit
-
+
def get_face(self):
return self.face
-
+
def get_suit(self):
return self.suit
class Deck:
+
def __init__(self, face_filter = DEFAULT_FACE_FILTER):
def deck_generator(faces, suits):

Супер е, че виждам генератор! Но не мисля, че е добра идея той да бъде дефиниран в __init__ - по-добре е да се метод на класа, защото:
1) По-четимо е;
2) Достъпен е и за други потенциални клиенти;

Можеш да го дефинираш като staticmethod, тъй като той не изисква инстанция.

Освен това би си спестил цикъла по-долу, ако го преправиш да инстанцира карти:

@staticmethod
def deck_generator(faces, suits):
    for face in faces:
        for suit in suits:
            yield Card(face, suit)

def __init__(self, face_filter=DEFAULT_FACE_FILTER):
    self.cards = list(self.deck_generator(face_filter, SUITS))

ПП: не съм го тествал, пиша наизуст, но е нещо такова...

for face in faces:
for suit in suits:
yield face, suit
-
+
self.cards = []
-
+
for face, suit in list(deck_generator(face_filter, SUITS)):
self.cards.append(Card(face, suit))
-
+
def cut(self):
middle = len(self.cards) / 2

Бих използвал някакъв случаен елемент при цепене, а не винаги средата, но това не е нещо, за което ще тестваме, така че и това е валидно. Просто е предвидимо, ако говорим за истинска игра.

-
+
first_half = self.cards[:middle]
second_half = self.cards[middle:]
-
+
self.cards = second_half + first_half
-
+
def shuffle(self):
random.shuffle(self.cards)
-
+
def get_cards(self):
return self.cards
-
+
def draw_card(self):

Не трябва да раздаваш случайни карти, а карти, които са най-отгоре на тестето.

ПП: Никъде не е казано кое е отгоре, и кое е отдолу, така че просто и двете интерпретации са валидни, но трябва да взимаш карти само от единия края.

card = random.choise(self.cards)
-
+
self.cards.remove(card)
return card
-
+
def draw_cards(self, card_count):
cards = []
-
+
for _ in itertools.repeat(None, card_count):
cards = draw_card()
-
+
return cards
class Player:
+
def __init__(self):
self.cards = []
-
+
def give_cards(self, cards):
self.cards += cards
-
+
def clear_cards(self):
self.cards = []
-
+
def get_cards(self):
return self.cards
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 = []
self.players = []
-
+
def set_deck(self, deck = Deck()):

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

class Deck:
    pass

class Game:

    def set_deck(self, deck=Deck()):
        self.deck = deck

game1 = Game()
game1.set_deck()
game2 = Game()
game2.set_deck()
print(game1.deck is game2.deck) # True
self.deck = deck
-
+
def get_deck(self):
return deck
-
+
def prepare_deck(self):
for player in players:
self.deck += player.get_cards()
player.clear_cards()
-
+
self.deck.shuffle()
self.deck.cut()
-
+
def get_players(self):
return players
-
+
def order_players(self, player):
#Попринцип трябва тук да направя проверка, ако player е в players, но приемам, че ми подавате верен input в deal(player)
while players[0] != player:
players.append(players.pop(0))
-
+
def deal(self, player):
order_players(player)
-
+
if dealing_direction == "rtl":
players.reverse()
-
+
for card_count in dealing_instructions:
for player in players:
player.give_cards(self.deck.draw_cards(card_count))
class Belot(Game):
+
def __init__(self):
super().__init__(4, "ltr", (2, 3, 3))
super().set_deck(Deck(BELOT_FACE_FILTER))
class Poker(Game):
+
def __init__(self):
super().__init__(9, "rtl", (1, 1, 1, 1, 1))
super().set_deck()