Python代写:CS1210 Ruba Mazzetto

代写一个叫Ruba Mazzetto的扑克牌游戏,玩法比较独特,需要跑过所有测试。

Introduction

In Homework 4, you completed the simple implementation of the Italian children’s card game called Ruba Mazzetto. In this homework, we’ll finally finish the complete version of the game that pits you against any number of other players, and includes provisions for taking more than one card each turn. In the interest of brevity, you can refer to the descriptions of Homework 3 and Homework 4 for more information about the game.

Background

For this assignment, we’ll start with a refactored version of the Homework 4 solution, that incorporates one small change to the rules of the game 1 and significantly revamps the structure of the play() function.

Your job is to complete this refactored version to support taking more than one card per turn, where the cards matched must sum to the value of the card played. So, for example, the solution to Homework 5 will behave as follows (excerpt taken from the middle of a 3-player game):

Player0:
Stash: [Player1] 7♠ (*3), [Player2] 6♥ (*2)
Table: [3] 10♦, [4] 3♦
My hand: [0] 10♣, [1] 10♠
Play which card? 0
Select matching indeces separated by spaces (blank to discard): 1 4
Player0 plays 10♣ and...
...takes 3♦ from table
...steals player1 stash 7♠

=========
Player1:
Stash: [Player 0] 10♣ (*5), [Player2] 6♥ (*2)
Table: [3] 10♦
Player1 plays 6♦ and...
...steals player2 stash 6♥

=========
Player2:
Stash: [Player0] 10♣ (*5), [Player1] 6♦ (*3)
Table: [3] 10♦
Player2 adds 1♦ to table

Note how Player 0 uses the 10♣ to match a 3♦ from the table and the 7♣ from Player 1’s stash (because 10 = 3 + 7).

As for HW4, to make this homework feasible, you will be provided a code skeleton containing nearly all of the code you will need for the solution. Your assignment is to complete the functions getMove() and pickMove(), but you should begin by studying the code skeleton file carefully.

def play(N=2, K=10)

The play() function has undergone the most significant reworking since the previous assignment. Aside from an additional variable, which changes the parameters of the deck you play with, the big change is in the main iteration that continues until the deck is exhausted. Previously, this loop was divided into two sections: one for the human player and one for everyone else. The new structure merges these two sections into a single loop and relegates the differentiation of the human player from the computer player(s) to getMove(). The last change to play() involves assignment of any cards remaining on the table to the last player who successfully matched, a job handled by the addition of a variable, last, that is reset each time a player makes a match.

def getMove(i, N, H, T, P)

The purpose of getMove() has changed significantly from HW4. In HW4, getMove() was to return a single “best” move for a given (automated) player, where each move consisted only of matching a single card from the player’s hand with a single card from the table or the top card from an opposing player’s stash. But now that we permit matching a single card from the player’s hand with the sum of multiple cards from the table or from the top of each opposing player’s stash, we need to generate and then consider the space of all possible legal moves. Each move is represented as (c, M), where c is the index into the player’s hand correspond to the card they will play and M is a list of indeces selected from the table and/or the opposing player’s stashes such that sum(M) ≡ H[i][c][0]. If (c, M) is (c, []), then the move corresponds to discarding c to the table.

Your job is to implement helper(c, v, j, M, L) to generate all legal moves, from which one will be selected and returned as the value of getMove(). Let’s examine getMove() more closely:

  1. The first step is to determine if the argument i relates to the human player (i ≡ 0). If so, then move selection is relegated to pickMove().

  2. The second step invokes the as-yet-unwritten helper function helper(c, v, j, M, L) repeatedly (once for each card held by the current player) to generate the list L of all legal moves.

  3. The third step returns a random card to discard if no legal moves were found.

  4. The final step returns the legal move that maximizes the number of cards captured by the current player (note that other heuristics might be used to make a ‘’best’’ move selection from the list L of legal moves).

The helper() function is a recursive function that constructs the set of legal moves. If you think of the len(T) cards on the table and the up to N-1 player stashes (excluding the current player’s stash) as defining a space of size 2^(len(T)+N-1) , you will need to enumerate the up to this many card combinations by considering possible inclusion or exclusion of each successive card. The arguments to helper(c, v, j, M, L) are designed to help you do so.

  1. The first argument, c, is the index of the card you are trying to match from player i’s hand.

  2. The second argument, v, initially the value of the card from the player’s hand that you are trying to match, represents how many “points” remain to match with the addition of each successive card. When this number reaches 0, you know the cards you’ve selected so far sum to the original value you were trying to match.

  3. The third argument, j, initially 0, is the index of the card you are currently considering adding to the legal move you are construction. On each successive recursive call, you’ll increase j by 1 to indicate you are going to consider the next card, from 0 through N up to N+len(T)-1. At each recursive step, you will want to explore both adding the jth card to the current legal move or not adding it.

  4. The fourth argument, M, initially[], is the legal move under construction. Each time you elect to include an additional card, you will need to extend M to include that card’s index.

  5. The last argument, L, initially[], is the list of legal moves you have found so far. Each new legal move you discover should be added to L, and the updated L should be the value returned from helper().

def pickMove(i, N, H, T, P)

pickMove() is called by getMove() when the first argument i to getMove() corresponds to the human player. pickMove() interacts with the user to obtain a legal move (c, M). Note that pickMove() must guarantee that the move is both legal in every sense and that the cards selected from the table and the top of any opposing player’s stash do, in fact, sum to the value of the card selected from the player’s hand.