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.
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
-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.
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:
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
?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.
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:
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.
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.