Casper — the house ghost — found an old camera in the castle cellar. Immediately he photographed everything that he loves to make disappear when he is haunting … inclusing himself, of course. Unfortunately, the enchanted camera takes many photos in the wrong colors. Sometimes the green bottle is white, other times it's blue. Looking at the photos, Casper doesn't really remember any more what he wanted to make disappear next. Can you help him with his haunting and quickly name the right item, or even make it disappear yourself? If you grab the right items quickly, you have good chances to win …
Ghost blitz is a reaction game as fast as lightning for 2 to 8 bright minds (8 years and up). It is played with 5 physical items and 60 cards (representing photos of the items). Each item has two unique properties: a unique color and a unique shape. There is a red chair, a blue book, a green bottle, a gray mouse and a white ghost.
Each card depicts two items. An item depicted on a card does not necessarily have the same color as the corresponding physical item of the same shape.
The game is set up by placing the 5 physical items on the table so that all players have easy access to them. The cards are shuffled and placed on the table as a deck. The starting player (whoever was the last person in a cellar) turns over the top card in such a way that all players can see it at the same time. Now, using one hand, all players try as fast as lightning to grab the desired physical item that is depicted on the card in the matching color. For the cards below, these are the blue book (left), the gray mouse (center) and the green bottle (right), respectively.
And if neither of the two items on the card is depicted in its original color? Then the players must grab the physical item from the table whose shape is not depicted on the card and whose original color is not shown on the card. For example, the left card below shows a blue ghost and a gray chair. These physical items are not as such on the table. Therefore, players must grab the green bottle because both the bottle and the color green are not shown on the card. For the same reason, players must also grab the green bottle for the right card below.
Whoever grabs the correct physical item from the table, lays down the turned-over card in front of him as a reward, and then turns over the next card from the deck.
A player may not grab more than one physical item per round. Whoever grabs an incorrect item must give up one of his cards (provided he has any) to the winner of the round. Thus, the winner of the round may win more cards in addition to the turned-over card.
The game ends when the deck of cards has been used up. Whoever possesses the most cards wins.
We represent an item as a tuple (tuple) with two strings (str) each describing one property of the item: the first property describes the color of the item, and the second describes its shape.
We represent a collection of items as a list (list), a tuple (tuple), or a set (set) of unique items. This uniqueness must apply both to the items as a whole and to their individual properties. Thus, the collection may not contain two identical items, or two items with the same property (same color or same shape). The collection must also not contain objects that do not represent items.
For the ghost blitz game, we represent the physical items on the table as a collection with 5 items. These items may be different from the original items in the ghost blitz game: for example, there may be a blue ghost or a pink flamingo on the table.
We represent a card from the ghost blitz game as a collection with 2 items. The shape of each item on a card must correspond to the shape of a physical item on the table, and its color must also correspond to the color of a physical item on the table. However, it does not have to be the same physical item for those two properties. So an item on a card may combine the shape and color of two physical items on the table. But if there is a pink flamingo on a card, then there must be a pink item on the table, and there must also be a flamingo on the table. In addition, exactly one of the following conditions must be satisfied:
exactly one physical item on the table corresponds in shape and color to an item on the card
exactly one physical item on the table has a shape and a color that is not found on the card
The correct physical item to grab from the table for a given card according to the rules of the ghost blitz game is that physical item from the above condition that is satisfied.
Your task:
Write a function isitem that takes a single argument. The function must return a Boolean value (bool) that indicates whether the argument represents an item.
Write a function iscollection that takes a single argument. The function must return a Boolean value (bool) that indicates whether the argument represents a collection of items.
Write a function istable that takes a single argument. The function must return a Boolean value (bool) that indicates whether the argument represents items that can be physically on the table in a ghost blitz game. This is the case if the argument is a collection with 5 items.
Write a function iscard that takes two arguments. These arguments must represent a card and the items on the table in a ghost blitz game, respectively. If the second argument does not represents items that can be physically on the table in a ghost blitz game, an AssertionError must be raised with the message invalid table. Otherwise, the function must return a Boolean value (bool) that indicates whether the first argument represents a card in the ghost blitz game. This is the case if the argument satisfies these conditions:
a card is a collection with 2 items
the shape of each item on a card corresponds to the shape of a physical item on the table
the color of each item on a card corresponds to the color of a physical item on the table
exactly one of the following conditions must be satisfied
exactly one physical item on the table corresponds in shape and color to an item on the card
exactly one physical item on the table has a shape and a color that is not found on the card
Write a function grab that takes two arguments. These arguments must represent the items on the table and a card in a ghost blitz game, respectively. If the first argument does not represents items that can be physically on the table in a ghost blitz game, an AssertionError must be raised with the message invalid table. Otherwise, an AssertionError must be raised with the message invalid card if the first argument does not represent a card in the ghost blitz game. Otherwise, the function must return the correct item to grab from the table for the given card according to the rules of the ghost blitz game.
>>> table = [('red', 'chair'), ('blue', 'book'), ('green', 'bottle'), ('gray', 'mouse'), ('white', 'ghost')]
>>> card1 = [('blue', 'book'), ('green', 'chair')]
>>> card2 = (('white', 'bottle'), ('gray', 'mouse'))
>>> card3 = {('red', 'ghost'), ('green', 'bottle')}
>>> card4 = [('blue', 'ghost'), ('gray', 'chair')]
>>> card5 = (('white', 'mouse'), ('red', 'book'))
>>> isitem(('blue', 'book'))
True
>>> isitem(['green', 'ghost'])
False
>>> isitem(('white', 'lang', 'bottle'))
False
>>> isitem((666, 'chair'))
False
>>> iscollection(table)
True
>>> iscollection(card1)
True
>>> iscollection(card2)
True
>>> iscollection(frozenset(table))
False
>>> iscollection([666] + table)
False
>>> iscollection([('white', 'ghost'), ('white', 'ghost')])
False
>>> iscollection([('white', 'ghost'), ('white', 'chair')])
False
>>> iscollection([('white', 'chair'), ('red', 'chair')])
False
>>> istable(table)
True
>>> istable(card1)
False
>>> iscard(card1, table)
True
>>> iscard(card2, table)
True
>>> iscard([('blue', 'book'), ('green', 'chair'), ('white', 'bottle')], table)
False
>>> iscard([('blue', 'book'), ('green', 'kikker')], table)
False
>>> iscard(table, card1)
Traceback (most recent call last):
AssertionError: invalid table
>>> grab(table, card1)
('blue', 'book')
>>> grab(table, card2)
('gray', 'mouse')
>>> grab(table, card3)
('green', 'bottle')
>>> grab(table, card4)
('green', 'bottle')
>>> grab(table, card5)
('green', 'bottle')
>>> grab(card1, table)
Traceback (most recent call last):
AssertionError: invalid table
>>> grab(table, [('blue', 'book'), ('green', 'kikker')])
Traceback (most recent call last):
AssertionError: invalid card