1
0
Fork 0
sushi-go-variant/docs/SPECIFICATION.md

9.0 KiB

Assignment Specification

Below is the assignment specification, in full, slightly edited for context and appearence.


Part 1 - Valid table

Write a function comp10001huxxy_valid_table() which takes a single argument:

  • groups, a list of lists of cards (each a 2-element string, where the first letter is the card value and the second letter is the card suit, e.g. '3H' for the 3 of Hearts), where each list of cards represents a single group on the table, and the combined list of lists represents the combined groups played to the table.

Your function should return a bool, which evaluates whether the table state is valid or not. Recall from the rules of the game that the table is valid if all groups are valid, where a group can take one of the following two forms:

  • an N-of-a-kind (i.e. three or more cards of the same value), noting that in the case of a 3-of-a-kind, each card must have a unique suit (e.g. ['2S', '2S', '2C'] is not a valid 3-of-a-kind, as the Two of Spades has been played twice), and if there are 4 or more cards, all suits must be present.
  • a run (i.e. a group of 3 or more cards, starting from the lowest-valued card, and ending with the highest-valued card, forming a continuous sequence in terms of value, and alternating in colour; note that the specific ordering of cards in the list is not significant, i.e. ['2C', '3D', '4S'] and ['4S', '2C', '3D'] both make up the same run.

Example function calls are as follows:

>>> comp10001huxxy_valid_table([])

True

>>> comp10001huxxy_valid_table([['AC']])

False

>>> # run too short
>>> comp10001huxxy_valid_table([['AC', '2S']])

False

>>> # run doesn't alternate in colour
>>> comp10001huxxy_valid_table([['AC', '2S', '3H']])

False

>>> # values not adjacent
>>> comp10001huxxy_valid_table([['AC', '2S', '4H']]) 

False

>>> comp10001huxxy_valid_table([['AC', '2H', '3S']])

True

>>> # test unsorted run
>>> comp10001huxxy_valid_table([['3C', 'AS', '2H']])

True

>>> comp10001huxxy_valid_table([['0C', 'JH', 'QS', 'KH', '9D']])

True

>>> # n-of-kind too short
>>> comp10001huxxy_valid_table([['2C', '2H']])

False

>>> # same suit twice for 3-of-kind
>>> comp10001huxxy_valid_table([['2C', '2H', '2C']])

False

>>> # same suit twice for 4-of-kind
>>> comp10001huxxy_valid_table([['2C', '2H', '2S', '2C']])

False

>>> comp10001huxxy_valid_table([['2C', '2H', '2S']])

True

>>> comp10001huxxy_valid_table([['2C', '2H', '2S', '2D']])

True

>>> comp10001huxxy_valid_table([['2C', '2H', '2S', '2D', '2S']])

True

>>> comp10001huxxy_valid_table([['2C', '2H', '2S', '2D', '2S'], ['0D', '9C', '8H']])

True

Part 2 - Group validation

Write a function comp10001go_valid_groups() which takes a single argument:

  • groups, a list of groups, each of which is a list of cards (following the same definition as Part 1)

Your function should return a Boolean indicating whether all groups are valid or not (i.e. a singleton card, a valid N-of-a-kind or a valid run). Note that the function may be used to validate a grouping of partial discards or the full set of discards, i.e. the total number of cards in groups will be between 0 and 10.

Example function calls are as follows:

>>> comp10001go_valid_groups([['KC', 'KH', 'KS', 'KD'], ['2C']])

True

>>> comp10001go_valid_groups([['KC', 'KH', 'KS', 'AD'], ['2C']])

False

>>> comp10001go_valid_groups([['KC', 'KH', 'KS', 'KD'], ['2C', '3H']])

False

>>> comp10001go_valid_groups([])

True

Part 3 - Play and Group

The third question requires that you implement the two functions that are called in the tournament: (1) comp10001_play, which is used to select a discard over the 10 turns of a game; and (2) comp10001_group, which is used to group the discards into groups for scoring. We combine these together into a single question in Grok as a means of validating that you have a complete player that is qualified to enter the tournament. Note that in each case, we provide only a single test case (and no hidden test cases) for two reasons: (1) there are very few game states where there is a single possible option to either play a discard or group the discards, and testing relies on there only being one possible output; and (2) the real testing occurs in simulation mode in the actual tournament, in the form of random games against other players. On validation of implementations of each of the two functions, you will be given the option to submit your player to the tournament.

First, write a function comp10001go_play() which takes three arguments:

  • discard_history, a list of lists of four cards, each representing the discards from each of the four players in preceding turns (up to 9 turns) in sequence of player number (i.e. the first element in each list of four cards is for Player 0, the second is for Player 1, etc.). Note that the list is sequenced based on the turns, i.e. the first list of four cards corresponds to the first turn, and the last list of four cards corresponds to the last turn.
  • player_no, an integer between 0 and 3 inclusive, indicating which player is being asked to play. player_no can also be used to determine the discards for that player from discard_history by indexing within each list of four cards.
  • hand, a list of cards held by the player.

Your function should return a single card to discard from hand.

An example function call is as follows:

>>> comp10001go_play([['0S', 'KH', 'AC', '3C'], ['JH', 'AD', 'QS', '5H'], ['9C', '8S', 'QH', '9S'], ['8C', '9D', '0D', 'JS'], ['5C', 'AH', '5S', '4C'], ['8H', '2D', '6C', '2C'], ['8D', '4D', 'JD', 'AS'], ['0H', '6S', '2H', 'KC'], ['KS', 'KD', '7S', '6H']], 3, ['QC'])

'QC'

Second, write a function comp10001go_group() which takes two arguments:

  • discard_history, a list of lists of four cards, each representing the discards from each of the four players in preceding turns in sequence of player number (i.e., the first element in each list of four cards is for Player 0, the second is for Player 1, etc.). Note that the list is sequenced based on the turns, i.e. the first list of four cards corresponds to the first turn, and the last list of four cards corresponds to the last turn. Additionally note that the number of turns contained in discard_history will always be 10.
  • player_no, an integer between 0 and 3 inclusive, indicating which player is being asked to play. player_no can also be used to determine the discards for that player from discard_history by indexing within each list of four cards.

Your function should return a list of lists of cards based on the discard history of player_no, to use in scoring the player. Note that the grouping of cards represented by the output must be valid (i.e. each list of cards must be a singleton card, or a valid N-of-a-kind or run), but that the ordering of cards within groups, and the ordering of groups is not significant.

An example function call is as follows:

>>> comp10001go_group([['0S', 'KH', 'AC', '3C'], ['JH', 'AD', 'QS', '5H'], ['9C', '8S', 'QH', '9S'], ['8C', '9D', '0D', 'JS'], ['5C', 'AH', '5S', '4C'], ['8H', '2D', '6C', '2C'], ['8D', '4D', 'JD', 'AS'], ['0H', '6S', '2H', 'KC'], ['KS', 'KD', '7S', '6H'], ['JC', 'QD', '4H', 'QC']], 3)

[['3C'], ['5H'], ['9S'], ['JS'], ['4C'], ['2C'], ['AS'], ['KC'], ['6H'], ['QC']]

Part 4 - Optimal grouping

The final question is for bonus marks, and is deliberately quite a bit harder than the four basic questions (and the number of marks on offer is, as always, deliberately not commensurate with the amount of effort required). Only attempt this is you have completed the earlier questions, and are up for a challenge!

Write a function comp10001go_best_partitions() which takes a single argument:

  • cards, a list of up to 10 cards

Your function should return a list of list of lists of cards, representing the groupings of cards that score the most points from cards. Note that the ordering of the groupings is not significant, and neither is the ordering of the groups within a grouping, nor the order of cards within a group.

One area of particular focus with this question is efficiency: there are strict time limits associated with running your code over each example, that you must work within, or you will fail the test. Good luck!

Example function calls are as follows:

>>> comp10001go_best_partitions(['0H', '8S', '6H', 'AC', '0S', 'JS', '8C', '7C', '6D', 'QS'])

[[['AC'], ['0H', '0S'], ['JS'], ['8S', '8C'], ['7C'], ['6H', '6D'], ['QS']]]

>>> comp10001go_best_partitions(['9D', '2S', '4D', '4H', '6D', 'AH', '2C', 'JH', '3C', '9H'])

[[['4D', '4H'], ['6D'], ['AH'], ['2S', '2C'], ['JH'], ['3C'], ['9D', '9H']]]

>>> comp10001go_best_partitions(['3C', '5H', '9S', 'JS', '4C', '2C', 'AS', 'KC', '6H', 'QC'])

[[['3C'], ['5H'], ['9S'], ['JS'], ['4C'], ['2C'], ['AS'], ['KC'], ['6H'], ['QC']]]

>>> comp10001go_best_partitions(['0D', 'AS', '5C', '8H', 'KS', 'AH', 'QH', 'AC'])

[[['AS', '5C', '8H', 'AH'], ['0D', 'KS', 'QH', 'AC']], [['0D', 'AS', 'KS', 'QH'], ['5C', '8H', 'AH', 'AC']]]