Day 22: Crab Combat¶
Classes:
|
Represent a deck of cards. |
|
Represent a split of one big deck of cards into two sub-decks. |
Functions:
|
Play a round of the game given the current |
|
Parse the input lines into two decks, as list of cards. |
|
Compute the score for the given deck based on its cards. |
|
Play the game starting with the |
- class Deck(cards: Sequence[int])[source]¶
Represent a deck of cards.
Please make sure that you transfer the “ownership” immediately to
Deck
and don’t modify the original list of strings any more:## # OK ## deck = Deck([1, 2, 3]) ## # Not OK ## cards = [1, 2, 3] deck = Deck(cards) # ... do something assuming ``deck`` is immutable ... cards[0] = 2 # ERROR! cards[0] now breaks the invariant!
Methods:
__init__
(cards)Initialize with the given values.
Get the card(s) at the given index.
__len__
()Return the number of the cards in the deck.
__iter__
()Iterate through the cards in the deck.
__add__
(other)Join two decks together.
__repr__
()Represent the deck for easier debugging.
__eq__
(other)Compare with
other
bycards
.Attributes:
Cards in the deck
- __init__(cards: Sequence[int]) None [source]¶
Initialize with the given values.
- Requires
len(set(cards)) == len(cards)
(Unique cards)
all(card >= 0 for card in cards)
- cards: Final[Sequence[int]]¶
Cards in the deck
- __getitem__(index: int) int [source]¶
- __getitem__(index: slice) Deck
Get the card(s) at the given index.
- class Split(deck1: Deck, deck2: Deck)[source]¶
Represent a split of one big deck of cards into two sub-decks.
Methods:
__init__
(deck1, deck2)Initialize with the given values.
Attributes:
The deck for the player 1
The deck for the player 2
- play_a_round(split: Split) Split [source]¶
Play a round of the game given the current
split
.- Returns
A new split after the round
- Requires
len(split.deck2) > 0
(Not game over for player 2)
len(split.deck1) > 0
(Not game over for player 1)
- Ensures
( len(split.deck1) == len(result.deck1) + 1 and len(split.deck2) == len(result.deck2) - 1) or ( len(split.deck1) == len(result.deck1) - 1 and len(split.deck2) == len(result.deck2) + 1)
(Either lost or won two cards)
split.deck2[1:] == result.deck2[0:len(split.deck2) - 1]
(Only the prefix and the suffix of the deck 2 change)
split.deck1[1:] == result.deck1[0:len(split.deck1) - 1]
(Only the prefix and the suffix of the deck 1 change)
set(split.deck1).union(split.deck2) == set(result.deck1).union(result.deck2)
(No new cards)
- parse_lines(lines: List[str]) Tuple[List[int], List[int]] [source]¶
Parse the input lines into two decks, as list of cards.
- Requires
len(lines) > 3
lines[0] == 'Player 1:'
'Player 2:' in lines[1:]
all( re.match(r'^(Player 1:|Player 2:|0|[1-9][0-9]*|)\Z', line) for line in lines )
- compute_score(deck: Deck) int [source]¶
Compute the score for the given deck based on its cards.
- Ensures
result >= 0
- play(split: Split) Split [source]¶
Play the game starting with the
split
until one of the players wins.- Requires
len(split.deck2) > 0
(Not game over for player 2)
len(split.deck1) > 0
(Not game over for player 1)
- Ensures
set(split.deck1).union(split.deck2) == set(result.deck1).union(result.deck2)
( len(split.deck1) + len(split.deck2) == len(result.deck1) and len(result.deck2) == 0 ) or ( len(result.deck1) == 0 and len(split.deck1) + len(split.deck2) == len(result.deck2) )