CTEC1903 Computer Programming II Coursework  
Additional explanation sheet  
The coursework is about writing a simple game. This explanation sheet will help you to better  
understand the required functionality. Some features are more advanced, and it is expected you will  
attempt to complete as much of the game as possible. The mark you receive will be based upon how  
many unit tests you pass - the tests are designed to assess that the features work correctly.  
You have been given a class Game, which consists of a field of size 10x10. The field is numbered  
as follows: 
The grid above should help you to visualise this scenario, and we have used p to show the current  
player position and w to show a wall. Coordinates are given as pairs in the form (x,y). Although  
different conventions can be used, here we define the origin as being in the upper left corner (which  
is common in computer graphics). Moving in the x direction would go right (or left) and moving in  
the y direction would go down (or up).  
Therefore, in the snapshot shown above, the player is positioned in (0,0) at the origin. In the Game  
class you have been provided, the current position of the player is stored in playerX and  
playerY.  
The use of “left”, “right”, “up”, and “down” allows the player to be moved around in the field. You  
cannot move diagonally.  
You will note the variable called field which is of type Array[Array[Boolean]] - this  
represents the grid shown above, where each cell is either empty (false) or a wall (true). In the above  
example, there are walls in (2,0), (2,1), and (2,2). The player can move within the field. If the player  
tries moving into a wall or off the field, nothing happens. So, in the example above, the player could  
move right or down, but not up or left. If the player has moved right once, it cannot move right again  
(because of the wall).  
There are also bounties to collect, which are held in a separate 10x10 field of functions called  
bounties. If the player moves onto a bounty, the function of the bounty is applied to the overall  
score and the bounty is erased. This is done by the checkBounty method. For example, if the  
score is 0 and the player moves onto position (1,3) – this contains a bounty in the field above.  
Suppose in bounties, at position (1,3) there is the function x => x+5 stored - the score would  
increase to 5. Any further moves onto (1,3) would not change the score, as the bounty would have  
been removed. Notice a position in bounties is null if there is no bounty in it.  
The player can also save the current position to saveX and saveY  by calling save(). If the player  
continues moving, the covered positions are evaluated by the checkBounties method. Covered  
positions are those inside a rectangle where the current position and the saved positions form two  
opposite corners of the rectangle. As soon as 9 or more positions are covered, the saved position is  
reset to -1, -1, indicating no saved position (these are the initial values of saveX and saveY as  
well) and all bounties in the covered positions are collected. For example, the player is in position  
(0,0), save is applied, and the player then moves right (parts of the field have been left out to save  
space, the same is true in other examples further down):  
x  
0 1 2 3 4 5 6 7 8 9  
Y 0 s p w . . . . . . .  
1 . . w . . . . . . .  
2 . b w . . . . . . .  
3 b . . . . . . . . .  
Here, the player (p) is in (1,0), the saved position (s) is in (0,0). There are two positions (grey)  
covered. The player moves down one position. There are now 4 positions covered. With a further  
move down, 6 positions are covered and the bounty at (1,2) will be collected. A further move down  
would result in 8 positions being covered. Nothing happens here. However, with a further move  
down, the situation is this (note the player is now at (1,4)):   
x  
0 1 2 3 4 5 6 7 8 9  
Y 0 s . w . . . . . . .  
1 . . w . . . . . . .  
2 . . w . . . . . . .  
3 b . . . . . . . . .  
4 . p . . . . . . . .  
5 . . . . . . . . . .  
There are now 10 positions covered. Since 9 or more are covered, we now collect all remaining  
bounties in here, which would include (0,1), (0,2), (0,3), and (0,4), even though these positions were  
not touched by the player – note (0,3) contains a bounty, which will therefore be collected. It would  
also reset the saved position to -1,-1, which indicates no saved position. Walls count as covered  
positions as well, if they are in the rectangle, however, you cannot move through them of course.  
The method move takes a string where left, right, up, and down are encoded as l, r, u, and d  
respectively. The moves are executed according to the string, so “llrru” would move to the left twice,  
to the right twice and up once. If there is a wall, an individual move (but not the complete string) is  
not executed. After each individual move a bounty is collected if moved onto and the saved position  
is evaluated to see if 9 or more positions have been covered. This is the same as happens after  
moving left, right, up, or down.  
The method suggestMove returns a string in the same format as noted for the move method,  
which moves the player from the current position to position (x,y). No specific requirements for the  
efficiency of the solution exist. The move cannot jump walls. The method is restricted to finding a  
path which follows two sides of a rectangle defined by the current position and the target. This  
means there is a given number of moves in one direction first, followed by a given number of moves  
in another direction. If the first move was horizontal, the second is vertical, and vice versa. If this is  
not possible due to walls, the method returns an empty string. If two paths are possible, any of them  
can be returned. No actual move is done. For example, below the two potential paths to get from  
(0,0) to (3,3) are indicated: 
Since the move “rrrddd” is blocked by a wall, it is not possible, so the method would return “dddrrr”.  
If this pathway would be blocked as well, an empty string would be returned.  
The maxBounty() function could give different values depending on which order the bounties are  
collected (as some bounties may increment whilst others may multiply). In the tests however, there  
are no such situations and there is always only one possible maxBounty result.  
The file Game.scala also contains an object GameProducer which allows the “production” of  
predefined game situations, such as those shown throughout this explanation. This object could go  
in its own file, but you should place it within the Game object as we want you to be able to submit a  
single file.