代做CSCI1120 Introduction to Computing Using C++, Fall 2024/25 Assignment 4: Mathable代做C/C++编程

- 首页 >> Database

CSCI1120 Introduction to Computing Using C++, Fall 2024/25

Assignment 4: Mathable

Due: 23:59, Sat 2 Nov 2024

File name:                 mathable.cpp

                                mathable-game.cpp

                                  mathable.h

Full marks: 100

Introduction

The objective of this assignment is to practice (1) the use of 1-D and 2-D arrays, and (2) the use of pointers for passing 1-D arrays as arguments between functions.

You will write a program to simulate a boardgame called Mathable, which is commonly described as being like playing Scrabble but using numbers instead of letters. Its detailed game rules can be found on websites like [1] [2] [3]. An iPad or iPhone app of this game is available on App Storeif you have interest to try it for better ideas on how to play the game. Here we give a brief introduction.

The boardgame consists of:

•   Gameboard: a square gameboard of N × N cells or squares where players place their tiles.

•   Tokens (or tiles): each tile or numbered token displays a 1-digit or 2-digit number.

•   Racks (or token holders): each player owns a rack for privately holding a handful (R) of tokens.

•   Bag: a bag contains all the rest of the tokens. A player can draw tokens from it to refill their rack after a turn or can swap (some of) the tokens on their rack with the ones in the bag randomly if they find it hard to forman equation on the board using their current tokens.

•   Score pad: used to track players' scores throughout the game.

Note that a variant of the game tailored to younger children, known as Mathable Junior, consists of a smaller gameboard and fewer tokens. SeeTable 1below for their differences.



Game Board Representation

As we implement this game as a console application, the game board is represented by a text-based grid formed from characters  | and _ as shown and compared in Figure 1 below.

Figure 1: A GUI screenshot of the Mathable app versus our text-based game board representation

Each cell in the grid is addressed by an Excel-like addressing scheme, e.g., the cell located at row 2 and column 3 is referred to by a cell address C2. The initial configuration of the game board has fixed four tokens, valued 1, 2, 3, 4, in the center of the board. Token 1 is located at G7, token 2 at H7, token 3 at G8, and token 4 at H8. In the program, we use a 2-D int array called board to store the tokens placed on the game board. Corresponding to these initial 4 tokens, we have:

board[6][6] = 1; board[6][7] = 2; board[7][6] = 3; board[7][7] = 4;

Game Logic

The game supports 2 to 4 players, who take turns to put their tokens onto the board to form. valid math equations and score the points indicated by the tokens. The one who attains the highest total score at the end of the game is the winner.

In each turn, the player can make a series of moves (at most R moves, where R is the rack size). In each move, the player chooses one token,c, from their rack and places it onto the board to form. a simple math equation with two adjacent tokens, a and b, already existent on the board:

a  ?  b = c

where? is one of the four arithmetic operators (+, −, ×, or ÷).

Recap  the  official  game  instruction:  “A  math  equation  is  completed  by  adding,  subtracting, multiplying or dividing  two adjacent numbers putting a  token  with  the  result  on  the  next  empty square, be it to the right or left, below or above the two original tokens. Equations may be made horizontally or vertically, but never diagonally.



For example, for the initial game board, if your rack has token 7, you can play it at cell F8 or cell I8 (refer toFigure 1) to form. the equation 3 + 4 = 7. If you don’thave token 7 but token 1, you can also put it at cell F8 or cell I8 because this can form. the equation 4 – 3 = 1. You can put it next to token 4 or token 3, on either side of the two tokens, it doesn't matter. Similarly, you may also put token 12 at these two cells to form. the equation 3 × 4 = 12. An equation can also be formed vertically. See

Figure 2 for more examples of valid positions for placing a token onto the board.

Figure 2: Example valid token placements

Remember that the token you are going to place is always the  result of the math operation. It is illegal to place it between the two adjacent tokens (operands) as we can see in Figure 3. Equations are also  never formed  diagonally. A token  placement  is valid  as  long  as  it  can form. at least one equation with two consecutively adjacent tokens in any of the 4 directions (left, right, above, below). See Figure 4. Now, placing token 7 between 3 and 4 is valid because it can forman equation with 2 and 5 vertically.  For the example on the  right, although 7 cannot form. an equation with  1 and 2 vertically, it does with 3 and 4 horizontally. So, it is valid to place token 7 there.

 

Figure 3: Example invalid token placements

 

Figure 4: More examples of valid token placements



Once a move is made, the player scores the points indicated on the token they just placed on the board. So, you can score higher points if you can find locations to place a larger token (usually the result of multiplication of two existing tokens) on the board.

Bonus  for  multiple  equations:  Another  strategy  to  score  higher  is  to  gain  bonus  points  due to simultaneously forming multiple equations by one move. If a token, when being placed, completes more than one equation, the points are gained for each equation completed. See an example  in Figure 5, which is actually the first move (placing token 4 at cell H4) in Round 13 Player 1’sturn in the Mathable Junior sample run 1 logged on macOS (mathable-jr-run1-mac.txt).

Figure 5: One move completing 3 equations, scoring 12 points (3 times 4 points)

Total Score: The total amount of points earned per turn is the total sum of the points scored by all moves made (i.e., all tokens placed plus bonuses) in that turn.

Rack Refill: At the end of his turn, each player draws tokens randomly from the bag, to bring the number of tokens on their rack back toR (e.g., 7 in classical Mathable). If there are fewer tokens left in the bag than the empty slots on the rack to fill up, the player will take all the remaining tokens and the bag becomes empty. The next player cannot refill (or swap) tokens anymore.

Game-over Conditions: The game continues until (1) there are no tokens left in the bag, and one of the players has used up all the tokens on his rack, or until (2) no more equations can be made. Since detecting condition (2) is a bit clunky, our program design will give players an option (T) to terminate the game anytime they want to. When players see no more possible moves, one of them will select this option to determine the game winner. A draw game can happen if more than one players attain the same highest score.

Simplifying the Game

The  original  Mathable  game  board  has  two  special  types  of  cells  called  restriction  squares  and  award squares. Restriction squares are those blue squares (inFigure 1GUI) marked with an addition, subtraction, multiplication or division sign. To occupy a square of this kind, the player must make an  equation that corresponds to the sign of that square.  For award squares,a purple square marked 2x  doubles the amount of point of the token on that square, an orange square marked 3x triples the  number of points. In this assignment, we will skip their implementation. So, there are no special cells  in our program. Some tedious game rules below are also cancelled:

•   “Extra Bonus. If a player manages to place all the tokens he has on his holder in one turn, he earns an extra bonus of 50 points.

•   “At the end of the game, each player deducts the value of the tokens still on his holder from the total amount of points accumulated during the game.


Program Specification

This section describes the basic requirements, starter code, player actions, some necessary functions, and program flow.

Basic Requirements

•    Apart from our given global constants  in the mathable.h header file, you cannot declare any global variables in all files.

•    Your program is scalable to board size (8 ≤ N  ≤  14, even number only), player size (2  ≤ P  ≤ 4), rack  size  (4 ≤ R ≤ 8),  token  amount  (either T  = 60 or T  = 106),  which  could  be  changed  at compile time (not hardcoded in the program code).

•    You cannot use any vectors or self-defined classes (they will be used in later assignments).

Starter Code

•    To help you get started, you are provided with all the required source files:

Filename

What’s inside

mathable.h

Several global constants defining the board size, rack size, player count, total number of tokens and the function prototypes of the functions

required by the client’s main() function.

mathable.cpp

The source file implementing all the functions needed by the game,e.g., printing the game board, rack, drawing tokens from bag, validating and   making moves on the board.

mathable-game.cpp

The client source file implementing the main() function which contains the main game loop for alternating turns across players. It includes the    header file and calls the functions provided by the above source file.

•    Basically,  you  need   not  change  the  header  file  unless  you  need  to  add  extra  functions  to mathable.cpp and their function prototypes to the header file.

•    To achieve the second  requirement mentioned above, the header file has defined some global constant integers for scaling board size, player count, rack size and token count easily.

o We may grade your program with them changed to a different value within their valid range specified. When you test your program against smaller or bigger boards, you can change N to other values but remember to reset it to its original value before your submission.

o To  make  the  program  scalable,  whenever  you  have  need  to  use  the  board  size, say, you should use the named constant N instead of hardcoded values throughout every source file. For simulating empty cells on the board, we can’t use 0 for the board array elements since token 0 may be placed on the board. A possible choice is to initialize the elements to -1. But instead of hardcoding -1 throughout the program, a more scalable implementation should use the global constant BLANK which is set to -1 in mathable.h.

o You  may change the preprocessor flag  JUNIOR on line 7 in mathable.h from 0 to 1 if you want to compile the program as the Mathable Junior variant, which uses a smaller board size and rack size, etc. This can already help testifyour program is scalable.

•    The  source files  have organized the entire  program  into different functions with well-defined parameter lists. Your main task in this assignment is to search for all “TODO” comments and fill in the missing parts of code.

Player Actions:

There are 4 options of game actions that a player can choose in each turn:

1.     Play (P): play a move, i.e., select a token on the rack to place at a specified cell on the board.

2.     Swap (S): select some or all tokens from the rack to swap with random tokens in the bag.

3.     End (E): end the current turn (if the player can’t see any more moves to make).

4.     Terminate  (T):  terminate  the  game   (prematurely).  Then   players’   current  total  scores   are compared to see who wins the game.

Your program is to prompt the user to enter one of the four letters: P, S, E, or T  (case-insensitive) to perform. one of the above actions for the current turn.

Playing a Token : If the player chooses P, the program prompts the player to enter a move, which consists of the target cell address, followed by the value of a token on his rack. The following shows an example where the player places token 4 at cell G9, and then places token 8 at cell H6. He may enter as many valid moves as possible based on the available tokens on his rack. The player then enters E to end the current turn and pass the turn to the next player.

Action (P/S/E/T): P Enter move: G9 4

...

Action (P/E/T): p Enter move: h6 8

Swapping Tokens: Note that the program implements the option S (Swap) is to support this feature

in the game rules: “A player may make use of his turn to exchange one or more tokens on his holder for new ones … To play, he must await his next turn.” So, a player who wants to swap for new tokens from the bag must choose S at the beginning of the turn. If the player has chosen P (Play), he cannot choose S anymore, and this option should be hidden throughout the current turn. See below for an example  prompt  for  swapping  tokens.  It  first  asks  for  how  many  tokens  on  the  rack  are to  be swapped out. Then the program loops that many times to prompt for each token and replace it on the rack with a randomly drawn token from the bag.

Player 2's turn

Bag (83 tokens)

...

Rack: [ 9 14 1 5 10 10 2 ]

Action (P/S/E/T): S

How many to swap? 4

1st token to swap: 14 2nd token to swap: 10 3rd token to swap: 5   4th token to swap: 10

Swapped 14 -> 32, 10 -> 13, 5 -> 19, 10 -> 60 Rack swapped: [ 9 32 1 19 13 60 2 ]

Provided and Required Functions (mathable.cpp and mathable.h)

Your program must contain the following functions. Most of them have been written for you already (Provided) and you shall not modify their contents. The others shall be written by you (Required). These functions shall be implemented in the source file mathable.cpp with their prototypes in the header file mathable.h. These functions shall be called somewhere in your program. You must not modify the prototypes of all these functions. You can design extra functions if you find necessary.

Besides, all the required functions below will be graded individually. That is, we shall connect your mathable.cpp with another source file with our testing code to call the functions one by one for grading. So, your code for each function shall implement the description of that function only. You shall not write any code in a function that is beyond that function’sdescription.

Provided Functions:

void shuffleTokens(int* bag)

Shuffle the tokens in the bag (elements in the bag array) using theFisher-Yates algorithm.

void fillBag(int* bag)

Fill up the bag with shuffled tokens based on official game's token listing.

int bagSize(int* bag)

Return the number of tokens in the bag.

int drawTokens(int* bag, int* rack)

Draw tokens from bag to fill up all empty slots in the specified rack as far as possible and return the count of tokens drawn.

void printBag(int* bag)

Print the content (tokens and empty slots) of the bag (to ease debugging if needed).

int rackSize(int* rack)

Return the number of tokens on the rack.

void printRack(int* rack)

Print the tokens on the rack of a player. All elements equal to BLANK are skipped from printing.

int tokenInRack(int* rack, int token)

Return the position or indexof token in the 1-D array pointed by rack if it exists and -1 otherwise.

void setupBoard(int board[][N])

Set  up the game board with all elements of  board set to  BLANK except for the 4 central tokens which are set to 1, 2, 3, and 4.

void printBoard(int board[][N])

Print the gameboard in the format illustrated in Figure 1.

bool isValidCell(int y, int x)

Return true if the cell at row y and column x is within the board dimensions, and false otherwise (i.e., outside the board).

Required Functions with TODO Tasks

void swapTokens(int* bag, int* rack, int pos)

Swap the token indexed by pos in rack with a random token in bag.

bool isValidMove(int board[][N], int token, int y, int x, int& points)

Return true if putting the token on an empty cell at row y and column x can form. a valid equation with the token being the result of adding, subtracting, multiplying or dividing two adjacent tokens next to it, be they to the right or left, below or above the token, and false otherwise.

The function also accumulates the points gained by possible multiple equations formed by this move and passes it back to the caller via the points reference parameter.

A move placing token at board[y][x] is valid only if:

1.  Location y, x lies within the board.

2.  The cell at y, x is empty (not yet occupied by an existing token).

3.  For 2 consecutive cells a and b adjacent to cell at y, x in any of the left, right, up, down directions, it is true that token equals a op b, or token equals b op a (where opis +, −, ×, or ÷).

Hint: the provided isValidCell() function is useful for saving some effort here.

bool possibleMoveExists(int board[][N], int* rack)

Return true if at least one possible valid move can be found on the game board using the tokens on the specified rack and false otherwise. Note: It always returns false if the rack has no tokens left.

Hint: one way to implement this function is to scan the entire board array and if any valid move is found on any of the empty cells on the board.

Hint: reuse the isValidMove() function to save effort here.



站长地图