Isolation is a 2 player strategy game, played on a 6 8 grid of removable squares. An illustration of the board appears in Figure 1. On your turn, you move your pawn one space, then remove a board square (meaning that square can no longer be occupied). The object is to isolate your opponent so they cannot move. A more detailed description of the game is as follows:

The Board: You play the game on a board of 6 8 squares. The two starting squares have fixed platforms that cannot be removed from the board, all other squares have removable platforms. Each player is represented by a pawn (a moveable piece) that occupies exactly one platform at any one time.

The Object: To isolate your opponents pawn so that it is impossible for it to move.

To Start: Begin so that all the platforms are in place (i.e. all squares can be occupied). Place each pawn on its starting location.

To Play:

1. On each turn, Move your pawn one space in any direction (left, right, forward, back, or diagonally). You cannot occupy a location where the platform has been removed, or the same square as another pawn.

2. After moving your pawn remove one platform from the board. You cannot choose a starting square or a square occupied by a pawn.

The player who cannot legally move his/her pawn on his/her turn loses.

Your Task

You have been provided some code that partially implements the Isolation game described above. Your job is to complete it, by completing the implementation of two classes: Position and Board as described in the following sections. The code is provided in a single file, and contains three classes Problem, Position and Board. All three classes appear in the same file.

  • Position must be a simple immutable class, and you are advised to implement this first.
  • Board is a slightly more complex class that utilises Position objects, and you are advised to implement this second.
Position
-NODIRECTION: int
-NORTH: int
-NORTHEAST: int
-EAST: int
-SOUTHEAST: int
-SOUTH: int
-SOUTHWEST: int
-WEST: int
-NORTHWEST: int
...
Position(row: int, col: int)
+getRow() : int
+getCol() : int +isValidDirection(direction: int) : boolean
+getNeighbour(direction: int) : Position
? equals? ? ?
+stringToDirection(str: String) : int
+getAllDirections() : int[]
+getDirectionAbbreviations() : String
+toString() : String

Figure 2: A UML description of the Position class.

  • You should not edit the Problem class. This has been provided so that when you have finished you can play the isolation game, and test your implementation.
  • The Problem class is public and the Position & Board classes are package visible. You should not change the visibility of the classes.
  • You should compile and test your changes regularly on your local machine.
  • When you are satisfied that you have done as much as you can, you should go to the link in the TestDome email and submit the code there. A description of how to do so appears in Section 3.

2.1 Implementing Position

Your first task is to implement the Position class. This is a simple immutable class representing possible positions on a grid. Every Position object has a row and a column value which are accessed by the getRow and getCol methods respectively. For example, the position in row 1 and column 4 of the grid, would be represented by the Position (1, 4).

Calling getRow and getCol on this position would give 1 and 4 respectively. However, Position objects need to be protected from changes of state.

A UML description of the Position class is shown in Figure 2. The attributes and methods that are provided for you are in grey text. The methods in blue text are not fully implemented; you will need to provide an implementation for these methods. For the equals method you will need to provide a signature and an implementation. Some static attributes have been provided for you, but you may also need to add attributes of your own to this class. The methods you need to provide are defined as follows:

  • Position A constructor for a Position, taking a row and column as input. In general, there are no restrictions on the values row and column can take.
  • getRow A straightforward getter method for the row
  • getCol A straightforward getter method for the column
  • equals A conventional equals method. This is an instance method that takes another Position as input and should return true if the other Position has the same row and column as this object, and false otherwise. You will need to provide the signature for this method.
  • isValidDirection This method should return true if the input is a valid direction and false otherwise. All valid directions are provided for you as static attributes: NORTH, NORTHEAST, EAST etc. Variable NODIRECTION represents an invalid direction.
  • getNeighbour If the input is a valid direction, this method returns the appropriate Position object; otherwise it should return null. For instance if the direction is NORTH the neighbour is the position one row up in the same column; if the direction is NORTHEAST the neighbour is the position one up & one right; and so on. Row number increases as we move down (SOUTH). Column number increases as we move right (EAST).

The positions extend in all directions without end; there will always be a position above, below, left and right of any other, even if the row or column numbers are negative.

The greyed out methods are already implemented and are described in the code. You can add any other helper methods you think appropriate.

[hint] You may find getAllDirections useful when implementing part of the Board class.

2.2 Implementing Board

Your second task is to implement the Board class. This is a more complex class representing a board state for the game of Isolation. We can refer to particular locations on the Board with a Position object; these are valid Positions, all other positions are invalid.

A UML description of the Board class is shown in Figure 3. You will see a number of attributes in red. These have been partially defined for you, but you will need to decide their visibility and whether they should be class or instance attributes. You do not need to add any other attributes, but you may choose to.

As before, the methods that are provided for you are in grey text. The methods in blue text are not fully implemented; you will need to provide an implementation for these methods. The methods provided for you are as follows:

  • Board() A constructor taking zero arguments has been provided, this creates a 2- dimensional array of ints one for each location on the board. Each locations int gives the state of the platform at that location. A value of Board.FIXED represents a fixed platform that cannot be removed. A value of Board.PRESENT represents a non-fixed platform. And value of Board.REMOVED represents a platform that has been removed. Attributes p1Pawn and p2Pawn respectively hold player 1 and 2 pawn positions. The P1START and P2START attributes hold the initial pawn positions.
  • Board(Position, Position) A second constructor has been provided that allows the start- ing pawn positions to be specified. This constructor is for testing purposes, and must not be removed or edited.
Board
?NUMROWS: int ?NUMCOLS: int ?FIXED: int ?REMOVED: int ?PRESENT: int ?P1START: Position ?P2START: Position
?p1Pawn: Position ?p2Pawn: Position ?locations: Position[][]
+Board()
+getPlatformAt(pos: Position)
+toString() : String
+getPawnPosition(player: int) : Position +isValidLocation(pos: Position) : boolean +hasPlatform(testId: String) : boolean
+isValidMove(player: int, move: int) : boolean +tryToMovePawn(player: int, move: int) : boolean +playerCanMove(player: int)
: boolean +tryToRemovePlatform(row: int, col: int) : boolean

Figure 3: A UML description of the Board class.

|0|1|2|3|4|5|6|7|
-----------------
1. 0 |x| | | | |x|x|x|
2. 1 | | |x|x|x|2|x| |
3. 2 |#| | | |x| |x|x|
4. 3 | |x|x|x|x| | |#|
5. 4 | | |x|1|x| |x| |
6. 5 |x| |x|x| |x| | |

Figure 4: Desired representation of a game state in Isolation.

  • getPlatformAt Gets the platform state at a given position. Input positions must be valid.
  • toString Gets a String representation of the board.

When implemented correctly, the board position shown in Figure 1 should output as seen in Figure 4.

The methods you need to provide are defined as follows:

  • getPawnPosition Takes a player id as input and returns the Position of that players pawn.
  • isValidLocation Takes any Position object and returns true if it is a location on the board, and false otherwise.
  • tryToRemovePlatform Takes a row and column as input and attempts to remove the plat- form at that location. If this is a valid choice, it should remove the platform and return true; otherwise it should return false.
  • isValidMove Takes a player id (int) and move (int) as input, and returns true if it is a 5

valid move for that players pawn. Remember: the move must be valid, and a player cannot move to a location outside of the board, onto a location with the platform removed or onto another players pawn. You can assume that the player id is okay.

  • tryToMovePawn Takes a player and move as input, and if these are valid update the state of the board to reflect this and return true. Otherwise return false
  • playerCanMove Required to test whether the game is finished. This takes a players id as input, and checks whether any move is possible for the pawn; it returns true if so, and false otherwise.

Some of these methods build on the functionality of earlier methods, so you are advised to implement them in order. When you have finished implementing all methods in Position and Board, you should be able compile and play the Problem class.

Academic Honesty!
It is not our intention to break the school's academic policy. Posted solutions are meant to be used as a reference and should not be submitted as is. We are not held liable for any misuse of the solutions. Please see the frequently asked questions page for further questions and inquiries.
Kindly complete the form. Please provide a valid email address and we will get back to you within 24 hours. Payment is through PayPal, Buy me a Coffee or Cryptocurrency. We are a nonprofit organization however we need funds to keep this organization operating and to be able to complete our research and development projects.