Moonlander is a small game where the player enters commands tomove an astronaut around the moon to c

Overview

Moonlander is a small game where the player enters commands tomove an astronaut around the moon to collect moon cheese.without running out of oxygen. The aim of the game is to collect some target amount of cheeseand make it back to the lander to export the moon cheese back toEarth! Movement has an oxygen cost and to collect the cheese wemay have to navigate around rocks and avoid running out ofoxygen completely (a player can drop off cheese and refill theiroxygen tank at the lander). We will begin by setting up the board, then add the ability to movearound it to play the game and in the final few stages we will alsoimplement moonguakes and some more interesting methods oftravel but we will leave that as a surprise for the moment…

The starter code for this assignment includes some functions and defined types:
 A print_board()function:
 This prints out the current state of the board, which ensures that your board printing matches the autotest exactly for a given board.
 An init_board()function:
 This stores a default value in each of the tiles in the provided board.
 A struct tile struct:
 Each square of the board (i.e. the 2D array) holds a struct tile, containing the information about what that tile contains.
 The player’s row and col values are stored seperately to the contents of the board.
 An enum entity enum:
 This is used in the struct tile struct to represent what is on each tile.

Let us look at an example output from the print board()function.

Here, we have tiles containing:
 the lander /|
 a rock ^^^
 a cheese <(]
 a hole down \0/
 two portals ~~~
 the player 0.0

Where do we store the player?
The player is not stored in the board , instead the print_board() function takes the player’s rowand column as arguments whenever we print the board.
 for the above example: print board(board,4,6);
So you can store the player however you like! (e.g. variables for the row/col, or perhaps a struct thatcontains both the row and the col!)
Stages
W’e have broken the assignment spec down into incremental stages:
 Stage 1: Place the lander, add cheese & rocks to the board.
 Stage 2: Setup the player, add player movement, pick up and drop off cheese, keep oxygen levelscorrectly updated, refill oxygen at the lander.
 Stage 3: Check for a win or lose condition, add a command to quit the program early, addmoonquake mechanics.
 Stage 4: Make the board 3D, add commands to create holes and jump between levels, add portals,implement travelling through portals.
 Extension (no marks): Add a graphical user interface

Stage 1
In stage 1, you will scan and store values to set up the map, including the lander, rock obstaclesand collectible cheese.
There is a reference implementation that you can play by running the command 1511cs_moonlander in the terminal.
Here is an example of input for a finished stage 1 that you can try within the referenceimplementation.
$ 1511 cs moonlander
1 5
c 1 2
c 3 1
r 3 5
r 3 7
R 5 4 8 6
[ctrl+d]

Stage 1.1: Placing the Lander
We will begin by scanning in and storing some values from the terminal. We will also need toassert that the values are valid.
In this substage, you will need to do the following:

  1. Print the prompt Please enter the [row] [col] of the lander:
  2. Scan in the lander’s position as row and col.
  3. Check that the row and col values correspond to a valid tile:
     lf the requested tile is not on the board, place the lander at board[4][4]
     Otherwise, add the lander to the board at the requested tile.
  4. Call the provided print board()function with these arguments:
     INVALID INDEx as the arguments for player row and player_col
     BASE XY RATE as the argument foroxy_rate
     0 or 0.0 for all other arguments.

Stage 1.2: Add cheese and rocks
So far we have only added the lander to the board, that is pretty boring so let us add some mooncheese collectibles and rock obstacles to spice it up!
To do this we will create a setup loop that scans in commands to let the user add cHEEsE andRock s to the board. Allow the user to add cHEEsE using the command in the form c int intand add a Rock using the command in the formr int int until [ctrl+d] is pressed.
In this substage, you will need to do the following:

  1. Print the prompt please enter cheese and rock locations:\n .
  2. Allow the user to input commands in a loop until [ctrl+d] is pressed.
    3.Given the command: c [row] [col], add a CHEESE to that tile.
  3. Given the command: r [row] [col] ,add a ROCK to that tile.
  4. After the user enters [ctrl+d] , call the provided print board() function with these arguments:
     INVALID INDEX as the arguments for player_row and player_col
     BASE_OXY_RATE as the argument for oxy_rate.
     0 or o.e for all other arguments.

Clarifications
 Each command provided will be of the form char int int
 You can not assume that the only the c or r command will be entered.

Stage 1.3: Add Large Rocks and check Scan Positioning
Adding rocks one by one can get quite repetitive, so here we will introduce the new R commandto our handy setup loop from stage 1.2. This will allow us to add large rectangular rocks to theboard. We will also print an error message if the cheese and rocks we scan in would be placed on asquare that already contains something.
In this substage, you will need to do the following:

  1. for our cheese input from stage 1.2, if the requested tile is occupied or not on the board,instead of adding the cheese to the board print That is not a valid cheese placement!\n
  2. for our single rock input from stage 1.2, if the requested tile is occupied or not on the board,instead of adding the rock to the board print That is not a valid rock placement!\n
  3. Given the command R [start_row] [start_col] [end_row] [end_col] , place a large rock withtop left corner at [start_row] [start_col] and bottom right corner at [end_row][end col] .A large rock is represented by placing a Rock on every tile in it’s area.
     lf any of the following error conditons are true, print That is not a valid rockplacement!\n and do not add the large rock to the board.
     Any tile enclosed in the requested rectangle does not lie on the board.
     Any tile enclosed in the requested rectangle is occupied.
     Start_row is greater than end_row, or start_col is greater than end_col
    Clarifications
     A tile is occupied If its entity field is not EMPTY

Stage 2
In stage 2, you will setup the player, implement player movement, the oxygen consumption (turn) system and picking up and dropping off cheese at the lander.
We implement the beginnings of the turn system in this stage. When the player moves, they use up a certain amount of oxygen, decreasing their tank level by that much. That amount starts as 1.0but may change in later stages. lf a player attempts an action that would decrease their oxygen amount, but they cannot complete that action, no oxygen decrement occurs for that turn (i.e. attempting to move onto a rock).
When we implement winning or losing the game and lander interactions (refill oxygen, drop off cheese), the order of operations for any single turn becomes important. They are as follows, in order:

  1. Any preconditions for the action are checked
     lf the action cannot be performed (i.e. moving onto a rock), it does not count as a turn andnothing else happens this turn except printing the board.
  2. The action is taken and any effects are carried out
     l.e. player moves, picks up cheese and decreases oxygen level
  3. Check for and execute lander interactions if available
     Lander interactions happen when the player is on one of the 8 tiles that surround the lander
     Lander interactions will consist of refilling the oxygen level, repairing suit leaks anddropping off held cheese
  4. Check for win/lose conditions
     Including printing win/lose message and exiting the program (stage 3.1)
  5. lf the command was not recognised you should print command not recognised!\n (stage 2.2), otherwise call the print_board() function.

Here is an example of input for a finished stage 2 that you can try on the reference implementation.
3 3
c 3 4
c 2 8
q
3
20
2 9
x
a
a
a
s
a
a
a
[ctr1+d]

Stage 2.1: Setting up the player
The last bit of initialisation is to scan in the target amount of cheese, the player’s oxygen tank capacity, and the player’s starting tile.
In this substage, you will need to do the following:

  1. Edit the setup command loop to end when COMAND_QUIT is entered, rather than [ctrl+d]. This means that after the player has placed all the cheese and rocks, they will have to enter COMMAND_QUIT in order to enter the player setup phase below.
     The reason for this change is that once [ctrl+d] is entered, C will not scan any further inputs, meaning we can not play the game.
  2. Ask for a target quantity of cheese.
     Use the prompt please enter the target gty of cheese:
     Scan in the target quantity of cheese to collect as an int.
     lf the target quantity of cheese is less than 0, print The target qty of cheese must be >0l\n and scan again, repeating until a valid input is entered.
  3. Ask for the oxygen tank capacity of the player.
     Use the prompt please enter the player’s oxygen tank capacity:
     Scan in the player’s tank capacity as a double.
     lf the scanned tank capacity is less than 0, print The oxygen tank capacity must be >el’n and scan again, repeating until a valid input is entered.
  4. Ask for the player’s starting position.
     Use the prompt please enter the [row] [col] of the player:
     Scan in the [row] [col] of the player as ints.
     lf the requested tile is not in bounds of the map or is occupied, print That is not a validplayer placementl\n , repeating until a valid starting position is entered.
    5.Print the message <->STARTING MOONLANDER<->\n
  5. Print the board using the provided print board() function.
     From now on, instead of using default values in the print board() function, use thecurrent values of:
    the player’s row and column
    amount of cheese the player and lander hold (starts at 0)
     oxygen capacity
     oxygen level (starts at capacity)
     oxygen rate (starts as BASE_OXY_RATE )

Clarifications
 The target quantity of cheese, player row and col, will always be ints.
 The tank capacity will always be a double.
 When using the reference solution, after the board prints, enter [ctrl+d] to match what your program should do.

Stage 2.2: Command loop, Player movement
This substage sets up the gameplay command loop for the rest of the game, after this most of what we will be doing is extending it to cover more user commands.
We will also implement the first set of commands here, those used to move the player around the board.
In this substage, you will need to do the following:

  1. Construct a main command loop that scans commands ( char followed by optional otherinputs depending on the command) and executes them.
     When a unknown command character is entered, print Command not recognised!\n
  2. When the commands w, a,s, d are entered, move the player onto the square above.left, below or right respectively, of their current position.
     Call the print board()function after each command
     Each time the player moves, their oxygen level should be decreased by the oxygen rate(starts at BASE_OXY_RATE )
  3. When [ctrl+d] is pressed, exit the program without any further scanning or printing
    Clarifications
    The first input of every command will be either [ctrl+d] or a char

Stage 2.3: Movement Collision and Refilling oxygen
Now when we move the player, we will have to assert that the target tile can be moved onto. A tile can be moved onto if it is on the board and there is not a rock or the lander on it already.
We will also add the ability to refill the player’s oxygen level back to the full tank capacity at the lander. The tank is refilled if the player ends their turn in one of the 8 tiles adjacent to the lander
In this substage, you will need to do the following:

  1. Check whether the tile in the corresponding direction is free to walk on before moving.
     Tiles off the board, tiles containing the lander or tiles with rocks cannot be moved onto.
     lf they can, the player moves to the target tile.
  2. lf the player moved, decrement their oxygen tank level by the current oxygen rate (starts at BASE_OXY_RATE ).
  3. lf the player is within 1 tile of the lander in both the vertical and horizontal directions (i.e. in one of the eight tiles directly surrounding the lander), their oxygen level is refilled to the tank capacity.
    Clarifications
    We will handle the case when the player has no oxygen in stage 3.1 when win/lose conditions are implemented, this case will not be tested until then.

Stage 2.4: Pick up and drop off cheese
In this substage, you will need to do the following:

  1. Whenever the player moves onto a tile containing a piece of cheese:
     Add a unit of cheese to the player’s total.
     Remove the cheese from the tile.
  2. lf the player is in one of the eight tiles directly surrounding the lander, transfer all cheese they are holding onto the lander (at the same time as refilling their oxygen).

Stage 3
In stage 3, you will check for win and lose conditions, allow the user to quit early and implement moonquake mechanics.
Stage 3.1: Win and Lose, Quit Early
Our game is starting to come together, we can control the player, pick up and drop off collectibles and manage our oxygen resources.
There is one thing missing though, there is no way to win! The next thing we will do is rectify this by checking and acting upon winning and losing conditions after each player action.
In this substage, you will need to do the following:

  1. lf the player ends their turn within range of the lander (in any of the 8 tiles adjacent to the lander):
     After transferring the cheese to the lander, if the amount of cheese on the lander meets or exceeds the target value we scanned back in substage 2.1, print congratulations, you won!\n and return from the program.
  2. lf the player ends their turn with less than or equal to e.0 oxygen they lose.
     lf the player uses their last unit of oxygen to get into range of the lander they should endtheir turn with a full tank and not lose.
     When the player loses, print Sorry, you ran out of oxygen and lost!\n and return fromthe program.
  3. Add a new command COMMAND_QUIT to the main command loop.
     When entered, exit the program without printing anything.
    Clarifications
     You should not print the board after a win or loss message.

Stage 3.2: Moonquakes
Now we will implement moonquakes, via the m command in the main command loop.Moonquakes rotate the entire board clockwise by 90 degrees each time the command is input.There are also some detrimental effects to the players stats that can be rectified by visiting thelander again.
In this substage, you will need to do the following:

  1. Add the m command to the command loop.
  2. lmplement the rotation.
     Board rotated 90 degrees clockwise each m command.
     The player also rotates so that their relative distance to all objects on the board does not change.
    3.lmplement player state changes.
     Moonquakes decrement the player’s current oxygen tank level by 20% of the tank’smaximum capacity.
     Moonquakes cause the players suit to leak by multiplying whatever the current oxygen rateis by 1.2. This effect stacks, so after 2 moonquakes the rate will be 1.0 * 1.2 * 1.2 = 1.44
    4.lmplement player suit leak repair.
     Similar to the move command, if the player ends their turn within range of the lander, they refill their oxygen and drop off all held cheese
     In addition to dropping off their cheese and refilling their oxygen tanks when near the lander, a player will also have their suit repaired, resetting their oxygen rate to BASE_OXY_RATE .
  3. After all the previous effects have been completed, print the board.

Stage 4
In Stage 4, you will make the board 3-dimensional, implementing digging holes, making and travelling between portals.
Stage 4.1: Digging
Up until now we have only explored the surface of the moon. As we well know, much like an onion (mmmmm, cheese and onion), the moon is constructed of many layers, with rich veins of mooncheese running through them. Let us take advantage of this!
The first thing to do is add the ability to dig holes to travel to lower layers of the moon.
In this substage, you will need to do the following.

  1. Transform the board state to keep track of 32 levels with the same dimensions as the original board.
     When the user scans in the rocks and cheese at the start of each game, each rock and cheese appears at the same [row [col] on each layer.
     The lander only appears on the surface layer (layer 0).
     The player starts on the surface layer (layer 0).
    2.Add the command h [direction] to the command loop.
     Adds a hole HOLE_DOWN in the current layer and corresponding HOLE_UP at the same position in the layer below.
     direction must be either w,a,s or d and corresponds to the tile surrounding the player that the hole is placed.
     Holes can only be placed on tiles that have an EMPTY field for both the HOLE up and HOLE_DOWN tiles.
     The player is allowed to move onto a tile with a hole on it.
     Adding a hole counts as a turn, the player should lose oxygen if the hole is placed
     successfully.
     lf the player is standing on the lowest level of the moon, attempting to dig a hole does nothing.
     After the command, whether successful or not, print the board.
    3.Add the command j to the command loop.
     lf the tile the player is standing on is HOLE_UP, jump up one level, if it is a HOLE_DOWN, jump down one level, else no change.
     Jumping counts as a turn, the player should lose oxygen if and only if the jump was successful (player level changed).
     After the command, whether successful or not, print the board.

Stage 4.2: Portals
Moving and jumping are all good, but sometimes we need to move faster than that to collect enough cheese with our oxygen constraints.
Cue portals, we can now create portals between any two (valid) tiles on the board. Stepping onto one side of a portal results in stepping out of the other side of the linked portal in the samedirection the player stepped in.
Portal travel works in both directions, stepping into a portal and then directly back with the movecommand should land the player in their starting position with twice the oxygen rate less oxygenthen they started with.
In this substage, you will need to do the following:

  1. Add the portal command t [direction] [level] [row] [col] to the command loop.
     Creates a portal between the tile in direction directly next to the player and the tilereferenced by level,row ,col
     Direction is one of w, a,s,d , corresponding to the tile directly up, left, down or right of the player’s current position respectively.
     For a portal to be placed, both target tiles cannot be the same tile and must both be on the board and not occupied by a lander, rock, cheese, portal, hole or the player.
     Placing a portal counts as a turn, the player loses their oxygen rate from their tank after placing the portal (only if it was successfully placed).
     Tiles with portals on them should have their entity field set to PORTAL
     There is a limit of MAX_PORTALS at any one time.
  2. Update the move commands( w,a,s , d ) so that if the player steps onto a portal, theycome out the opposite side of the other portal.
     lf the square the player would end up on is not on the board, or has a rock or the lander on it, then the player should remain in their current position and no oxygen should be consumed.
     Moving still has the same oxygen cost. l.e. one times the current oxygen rate if successful, else no cost.
     lf moving through a portal would leave the player standing on a second portal, they travel through that portal also and so on. in this case, each portal traversed costs one oxygen but the player does not stop to do lander interactions until they land on a tile, they can however run out of oxygen and lose while in this state (if the player does run out of oxygen, place them on the final square in the portal chain before printing the board and exiting with the no oxygen losing message).
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值