Part 2 – Moving Around the World (20 Points)
In this section, we will implement the Player class. At the end of this section, our player should be able to navigate freely around our grid world by receiving certain integer action codes corresponding to their ability to move up, right, down or left as well as update the visibility of individual tiles in the grid based on what the player can and can’t see.
The compiled Grid and Tile classes have been supplied for you in this section so there is no need to bring across your solution. All of the same methods that you were required to implement in the previous section are included. So, if you are not sure what methods are available to you, look back at the previous section description (or look through the Assignment Reference material).
The following functionality that needs to be implemented in this section is described below. You are free to add any data member variables or your own helper methods that you feel you need in order to accomplish the task. The testing will only care about being able to call the methods described below and receive the expected output based on the functionality descriptions. Remember that if you do add data members to your class they should be private, and the member methods that you are required to implement should be public.
The Player Class Setup (1 Point):
Create the Player class from scratch and add the required boilerplate code required for all java classes.
Implement the Player constructor that has one parameter which is a Grid object.
If the Grid object passed into the constructor does not currently have a tile on it with a “Player” item, then you need to add a “Player” item to the tile in the bottom left of the grid (take a look at the 2D coordinate system explanation in the previous section to understand the coordinate for that position).
If there is already a “Player” item on one of the tiles in the grid, then this Player object should assume control of that “Player” item location. As in, the position of this Player should match the position of the tile that has the “Player” item on it.
Implement the getXPosition and getYPosition methods that return the x and y coordinate of this current player’s position on the grid.
You can assume there is only ever zero or one tile with a “Player” item in the Grid.
The foundExit Method (1 Point):
Implement the foundExit method which should return true if this player is located on a tile with an “Exit” item and false otherwise.
The getValidMoves Method (6 Points): – Difficult!
Implement the getValidMoves method that returns an array of integers which hold the action codes for the possible moves that the player can make. It doesn’t matter what order the integers are in the array but they should only hold valid move action codes and action codes should not be repeated.
The integer action codes are as follows:
0: Do Nothing
1: Move Up
2: Move Right
3: Move Down
4: Move Left
For example: If the player is able to only Move Up and Move Left then your function should return an array holding [0, 1, 4] in any order (a player can always Do Nothing).
A players movement is restricted by two things:
The boundary of the map. E.g. a player can’t move left if they are on a tile on the left boundary (i.e. when their x coordinate is 0).
A tile with an “Obstacle” item on it. E.g. if the tile above the player has an “Obstacle” item on it, then the player cannot Move Up.
The takeAction Method (6 Points):
The takeAction method should take one parameter being the action code of the action you want the player to take and should return nothing.
You can assume that the action code entered as a parameter is a valid action.
In this method, you will be required to update the grid to reflect the move that was made.
This will involve removing the “Player” item from the tile the player is currently on and adding a “Player” item to the tile the player has moved to, as well as making sure your getXPosition and getYPosition methods will return the correct new position of this player.
The possible action codes are the same as in the previous method:
0: Do Nothing
1: Move Up
2: Move Right
3: Move Down
4: Move Left
The display of the test results are a bit hard to interpret for this part. It is easiest to use the Runner class to test this updateVisibility method if you are failing the tests. You can create your own grid objects, add items to different positions on the grid and updateVisibility on the player then print the grid to see what the grid looks like and compare that with what you expect it to look like. An example of how to do this are provided for you in the Runner class.
The updateVisibility Method(6 Points): – Difficult!
In the previous part, in your implementation of the Tile class, you provided an ability for the tile to be toggled between visible and not visible. If a tile is visible, then whatever item is on that tile is displayed on the grid. If that tile was not visible, then the tile is depicted with a “~” symbol. In this updateVisibility method on the player, you will need to determine which of the tiles in the grid are visible to the player and which are not.
Create and implement the updateVisibility method which does not return anything and has a single int parameter. This parameter will be the players view distance.
This method should do the following:
Set the visibility of every tile based on the three following rules:
A player can see up to the view distance (the parameter passed into this method) tiles away from the player in each of the four directions (up, right, down and left) but can’t see tiles on their diagonal.
The player can’t see passed a tile with an “Obstacle” on it, even if the tiles beyond the obstacle are within the view distance, but they can see the tile with the obstructing “Obstacle” item on it.
The tile that the Player is on is always visible.
A Few Examples:
You have the following Grid arrangement with all tiles visible:
+-+-+-+-+-+-+
| | | | | |X| // X: Exit
+-+-+-+-+-+-+ // #: Obstacle
| | |#| | | | // P: Player
+-+-+-+-+-+-+ // ?: Some Unknown Item
| | |P| |?| |
+-+-+-+-+-+-+
| | | | | | |
+-+-+-+-+-+-+
After calling updateVisibility(2) on the player, the printed grid would look like:
+-+-+-+-+-+-+
|~|~|~|~|~|~|
+-+-+-+-+-+-+
|~|~|#|~|~|~|
+-+-+-+-+-+-+
| | |P| |?|~|
+-+-+-+-+-+-+
|~|~| |~|~|~|
+-+-+-+-+-+-+
The int parameter 2 passed into the method means that in the case of tiles to the right
in this example, the player can see the tile directly to the right (1 tile away)
and the tile to the right of that (2 tiles away) but not the far right tile
(which would be 3 tiles away).
A bigger example:
+-+-+-+-+-+-+-+-+-+-+-+-+
| | | | | | | | | | | | |
+-+-+-+-+-+-+-+-+-+-+-+-+
| | |?| | | | | | | | | |
+-+-+-+-+-+-+-+-+-+-+-+-+
| | | | | | |X| | | | | |
+-+-+-+-+-+-+-+-+-+-+-+-+
| | |#| | | | | | | | | |
+-+-+-+-+-+-+-+-+-+-+-+-+
| | | | | | | | | | | | |
+-+-+-+-+-+-+-+-+-+-+-+-+
| | | |#| | |P| | | | | |
+-+-+-+-+-+-+-+-+-+-+-+-+
| | | | | | | | | | | | |
+-+-+-+-+-+-+-+-+-+-+-+-+
After calling updateVisibility(4)
+-+-+-+-+-+-+-+-+-+-+-+-+
|~|~|~|~|~|~|~|~|~|~|~|~|
+-+-+-+-+-+-+-+-+-+-+-+-+
|~|~|~|~|~|~| |~|~|~|~|~|
+-+-+-+-+-+-+-+-+-+-+-+-+
|~|~|~|~|~|~|X|~|~|~|~|~|
+-+-+-+-+-+-+-+-+-+-+-+-+
|~|~|~|~|~|~| |~|~|~|~|~|
+-+-+-+-+-+-+-+-+-+-+-+-+
|~|~|~|~|~|~| |~|~|~|~|~|
+-+-+-+-+-+-+-+-+-+-+-+-+
|~|~|~|#| | |P| | | | |~|
+-+-+-+-+-+-+-+-+-+-+-+-+
|~|~|~|~|~|~| |~|~|~|~|~|
+-+-+-+-+-+-+-+-+-+-+-+-+
The boundary at the bottom limits the players visibility, the obstacle to the left
limits the visibility but the player can see the obstacle, the “Exit” does not block
the player from seeing beyond it.
The Runner class has been provided for you for testing purposes with an example set of input provided in order to create the grid, create the player, test the players position, the getValidMoves method, the takeAction method and the updateVisibility method. Feel free to edit any of this code for your own testing and debugging purposes. Nothing you write in the Runner class will be sent to the automated testing