A trick game is a card game played by four players seated around a table. They are designated, in a clockwise direction, by the letters N (north), E (east), S (south) and W (west).

The number of cards used in the game is a multiple of four. One of the players is the dealer. At the start of the game, the dealer deals the cards one by one in a clockwise direction to the players, starting with himself. He then chooses one of the four suits as trumps, or decides to play without trumps.
The cards a player is holding at any given moment are referred to as the player's hand. The game is played in rounds known as tricks. With each trick, the players take turns clockwise, each playing one card from their hand onto the table: in the first trick, the dealer plays a card first, and in each subsequent trick, the winner of the previous trick plays a card first.
To determine the winning card in a trick, you need to know that a standard deck of cards consists of 52 different cards. They are divided into four suits, each containing 13 cards: 13 spades (♠), 13 hearts (♥), 13 diamonds (♦) and 13 clubs (♣). Each suit contains cards ranked from 2 to 10, a jack, a queen, a king and an ace. This is also the order of the cards within each suit: a 2 is the lowest card and an ace is the highest card.
If trump cards are played in a trick, the highest trump card wins the trick. If the trick is played without trumps, or if no trump cards are played, the highest card in the suit of the first card played wins the trick. For example, suppose player N plays the ten of spades (♠10), player E the king of spades (♠K), player S the jack of diamonds (♦J) and player W the seven of hearts (♥7). If the game is played without trumps, or if spades or clubs are trumps, player E wins with the king of spades (♠K). If diamonds are trumps, player S wins with the jack of diamonds (♦J). If hearts are trumps, player W wins with the seven of hearts (♥7).

Cards that have been played are no longer in the game: the player who has won a trick takes the played cards from the table, places them face down in front of him, and is the first to play a card from his hand in the next trick. The game ends when all cards have been played.
We represent each of the 52 cards in a standard deck as a string (str) consisting of the card's suit
| name | spades | hearts | diamonds | clubs |
|---|---|---|---|---|
| suit | ♠ | ♥ | ♦ | ♣ |
followed by the card's rank
| name | two | three | four | five | six | seven | eight | nine | ten | jack | queen | king | ace |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| rank | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | J | Q | K | A |
Note that a card's suit is always represented by a single character. For example, ♠A represents the ace of spades, ♥10 the ten of hearts and ♣K the king of clubs. A card's suit by itself is represented by its corresponding character (str; ♠, ♥, ♦ or ♣). A player is represented by his corresponding letter (str; N, S, E or W).
The order in which we have listed suits and ranks above also determines the canonical order in which the cards in a player's hand are listed. Spades are listed first, followed by hearts, diamonds and clubs. Cards of the same suit are listed in descending order of rank: first the ace, followed by the king, queen, jack, 10, 9, …, 2.
Define a class TrickGame that can be used to simulate the play of a trick game. When creating a new game (TrickGame), the dealer is determined, the cards are dealt amongst the players, trumps are determined and each player starts with zero tricks. The first parameter takes the location (str) of a text file containing the order in which the cards are dealt, one card per line. The second parameter dealer takes the dealer (str). There is also an optional third parameter trump that takes trumps (str). If no trumps are explicitly specified, the game is played without trumps.
A game $$t$$ (TrickGame) must support at least the following methods:
A method first_player that takes no arguments. The method must return the first player (str) to play a card in the next trick of game $$t$$.
A method order_of_play that takes no arguments. The method must return a string (str) consisting of four letters, indicating the order in which the players must play a card during the next trick of game $$t$$.
A method hand that takes a player (str). The method must return a list (list) containing the cards (str) the player currently holds in his hand in game $$t$$, listed in their canonical order.
A method tricks that takes a player (str). The method must return the number of tricks (int) the player has already won in game $$t$$.
Use the above methods to make the built-in function str return a string representation (str) describing the state of game $$t$$ (TrickGame), when game $$t$$ is passed. For each player, this representation has (in the fixed order N, E, S, W), a line containing three information fields separated by a vertical bar (|):
the letter representing the player, followed by an asterisk (*) for the player who must play a card first in the next trick of game $$t$$, or a space for the other players
the number of tricks the player has already won in game $$t$$, displayed as a two-digit number by adding leading zeros where necessary
the cards in the player's hand in game $$t$$, listed in their canonical order and separated by commas
To simulate playing a trick in game $$t$$ (TrickGame), the following methods must also be supported:
A method has_card that takes two arguments: i) a player (str) and ii) a card (str). The method must return a Boolean value (bool) that indicates whether the player currently holds the card in his hand in game $$t$$.
A method highest_card that takes two arguments: i) a suit (str) and ii) a collection (list, tuple or set) of cards (str). If the collection does not contain any cards of the given suit, the value None must be returned. Otherwise, the highest card (str) of the given suit from the collection must be returned.
A method winning_card that takes a sequence (list or tuple) of four cards (str) that could be played in the next trick of game $$t$$ (listed in the order in which they would be played). The method must return the card (str) that would win the trick (without playing the trick itself).
A method winning_player that takes a sequence (list or tuple) of four cards (str) that could be played in the next trick of game $$t$$ (listed in the order in which they would be played). The method must return the player (str) who would win the trick (without playing the trick itself).
A method trick that takes a sequence (list or tuple) of four cards (str) that are played in the next trick of game $$t$$ (listed in the order in which they are played). The method must play the trick in game $$t$$: the players play the cards from their hands, the winning player wins the trick and is first to play a card in the next trick. The method must return a reference to game $$t$$.
If the methods winning_card, winning_player or trick take four cards that cannot be played in that order in the next trick in game $$t$$ — because the player who must play a card does not have that card in his hand — an AssertionError must be raised with the message invalid trick. In that case, the method trick must not change the state of game $$t$$ at all.
In this interactive session, we assume the current directory contains the text file cards.txt.
>>> game = TrickGame('cards.txt', dealer='W', trump='♠')
>>> game.first_player()
'W'
>>> game.order_of_play()
'WNES'
>>> game.hand('N')
['♠K', '♠9', '♠3', '♥6', '♥2', '♦K', '♦J', '♦9', '♦8', '♦6', '♦3', '♣9', '♣5']
>>> game.hand('E')
['♠10', '♠8', '♠6', '♥A', '♥K', '♥Q', '♥9', '♥7', '♥5', '♦A', '♣A', '♣K', '♣4']
>>> game.hand('S')
['♠A', '♠Q', '♠J', '♠7', '♠4', '♥10', '♦Q', '♦7', '♦2', '♣J', '♣8', '♣3', '♣2']
>>> game.hand('W')
['♠5', '♠2', '♥J', '♥8', '♥4', '♥3', '♦10', '♦5', '♦4', '♣Q', '♣10', '♣7', '♣6']
>>> game.tricks('N')
0
>>> game.tricks('E')
0
>>> game.tricks('S')
0
>>> game.tricks('W')
0
>>> print(game)
N |00|♠K,♠9,♠3,♥6,♥2,♦K,♦J,♦9,♦8,♦6,♦3,♣9,♣5
E |00|♠10,♠8,♠6,♥A,♥K,♥Q,♥9,♥7,♥5,♦A,♣A,♣K,♣4
S |00|♠A,♠Q,♠J,♠7,♠4,♥10,♦Q,♦7,♦2,♣J,♣8,♣3,♣2
W*|00|♠5,♠2,♥J,♥8,♥4,♥3,♦10,♦5,♦4,♣Q,♣10,♣7,♣6
>>> game.has_card('W', '♥4')
True
>>> game.has_card('N', '♥2')
True
>>> game.has_card('E', '♥Q')
True
>>> game.has_card('S', '♥10')
True
>>> game.highest_card('♥', {'♠6', '♣6', '♦7', '♦9', '♣7', '♣3', '♣K', '♥9', '♥6', '♣9', '♠Q', '♦Q', '♥A'})
'♥A'
>>> game.highest_card('♦', {'♠6', '♣6', '♦7', '♦9', '♣7', '♣3', '♣K', '♥9', '♥6', '♣9', '♠Q', '♦Q', '♥A'})
'♦Q'
>>> game.winning_card(['♥4', '♥2', '♥Q', '♥10'])
'♥Q'
>>> game.winning_player(['♥4', '♥2', '♥Q', '♥10'])
'E'
>>> print(game.trick(['♥4', '♥2', '♥Q', '♥10']))
N |00|♠K,♠9,♠3,♥6,♦K,♦J,♦9,♦8,♦6,♦3,♣9,♣5
E*|01|♠10,♠8,♠6,♥A,♥K,♥9,♥7,♥5,♦A,♣A,♣K,♣4
S |00|♠A,♠Q,♠J,♠7,♠4,♦Q,♦7,♦2,♣J,♣8,♣3,♣2
W |00|♠5,♠2,♥J,♥8,♥3,♦10,♦5,♦4,♣Q,♣10,♣7,♣6
>>> game.order_of_play()
'ESWN'
>>> game.has_card('W', '♥4')
False
>>> game.has_card('N', '♥2')
False
>>> game.has_card('E', '♥Q')
False
>>> game.has_card('S', '♥10')
False
>>> game.hand('N')
['♠K', '♠9', '♠3', '♥6', '♦K', '♦J', '♦9', '♦8', '♦6', '♦3', '♣9', '♣5']
>>> game.hand('E')
['♠10', '♠8', '♠6', '♥A', '♥K', '♥9', '♥7', '♥5', '♦A', '♣A', '♣K', '♣4']
>>> game.hand('S')
['♠A', '♠Q', '♠J', '♠7', '♠4', '♦Q', '♦7', '♦2', '♣J', '♣8', '♣3', '♣2']
>>> game.hand('W')
['♠5', '♠2', '♥J', '♥8', '♥3', '♦10', '♦5', '♦4', '♣Q', '♣10', '♣7', '♣6']
>>> game.tricks('N')
0
>>> game.tricks('E')
1
>>> game.tricks('S')
0
>>> game.tricks('W')
0
>>> game.trick(['♥4', '♥2', '♥Q', '♥10'])
Traceback (most recent call last):
AssertionError: invalid trick
>>> print(game.trick(['♣A', '♣2', '♣7', '♣5']))
N |00|♠K,♠9,♠3,♥6,♦K,♦J,♦9,♦8,♦6,♦3,♣9
E*|02|♠10,♠8,♠6,♥A,♥K,♥9,♥7,♥5,♦A,♣K,♣4
S |00|♠A,♠Q,♠J,♠7,♠4,♦Q,♦7,♦2,♣J,♣8,♣3
W |00|♠5,♠2,♥J,♥8,♥3,♦10,♦5,♦4,♣Q,♣10,♣6
>>> print(game.trick(['♦A', '♦2', '♦4', '♦3']))
N |00|♠K,♠9,♠3,♥6,♦K,♦J,♦9,♦8,♦6,♣9
E*|03|♠10,♠8,♠6,♥A,♥K,♥9,♥7,♥5,♣K,♣4
S |00|♠A,♠Q,♠J,♠7,♠4,♦Q,♦7,♣J,♣8,♣3
W |00|♠5,♠2,♥J,♥8,♥3,♦10,♦5,♣Q,♣10,♣6
>>> print(game.trick(['♣K', '♣3', '♣6', '♣9']))
N |00|♠K,♠9,♠3,♥6,♦K,♦J,♦9,♦8,♦6
E*|04|♠10,♠8,♠6,♥A,♥K,♥9,♥7,♥5,♣4
S |00|♠A,♠Q,♠J,♠7,♠4,♦Q,♦7,♣J,♣8
W |00|♠5,♠2,♥J,♥8,♥3,♦10,♦5,♣Q,♣10
>>> print(game.trick(['♥A', '♠4', '♥3', '♥6']))
N |00|♠K,♠9,♠3,♦K,♦J,♦9,♦8,♦6
E |04|♠10,♠8,♠6,♥K,♥9,♥7,♥5,♣4
S*|01|♠A,♠Q,♠J,♠7,♦Q,♦7,♣J,♣8
W |00|♠5,♠2,♥J,♥8,♦10,♦5,♣Q,♣10
>>> print(game.trick(['♠7', '♠5', '♠K', '♠6']))
N*|01|♠9,♠3,♦K,♦J,♦9,♦8,♦6
E |04|♠10,♠8,♥K,♥9,♥7,♥5,♣4
S |01|♠A,♠Q,♠J,♦Q,♦7,♣J,♣8
W |00|♠2,♥J,♥8,♦10,♦5,♣Q,♣10
>>> print(game.trick(['♠3', '♠8', '♠A', '♠2']))
N |01|♠9,♦K,♦J,♦9,♦8,♦6
E |04|♠10,♥K,♥9,♥7,♥5,♣4
S*|02|♠Q,♠J,♦Q,♦7,♣J,♣8
W |00|♥J,♥8,♦10,♦5,♣Q,♣10
>>> print(game.trick(['♠Q', '♥8', '♠9', '♠10']))
N |01|♦K,♦J,♦9,♦8,♦6
E |04|♥K,♥9,♥7,♥5,♣4
S*|03|♠J,♦Q,♦7,♣J,♣8
W |00|♥J,♦10,♦5,♣Q,♣10
>>> print(game.trick(['♦Q', '♦5', '♦6', '♥5']))
N |01|♦K,♦J,♦9,♦8
E |04|♥K,♥9,♥7,♣4
S*|04|♠J,♦7,♣J,♣8
W |00|♥J,♦10,♣Q,♣10
>>> print(game.trick(['♦7', '♦10', '♦J', '♥7']))
N*|02|♦K,♦9,♦8
E |04|♥K,♥9,♣4
S |04|♠J,♣J,♣8
W |00|♥J,♣Q,♣10
>>> print(game.trick(['♦K', '♥9', '♣8', '♣10']))
N*|03|♦9,♦8
E |04|♥K,♣4
S |04|♠J,♣J
W |00|♥J,♣Q
>>> print(game.trick(['♦9', '♣4', '♣J', '♣Q']))
N*|04|♦8
E |04|♥K
S |04|♠J
W |00|♥J
>>> print(game.trick(['♦8', '♥K', '♠J', '♥J']))
N |04|
E |04|
S*|05|
W |00|