A-level Computing/AQA/Problem Solving, Programming, Data Representation and Practical Exercise/Skeleton code/2012 Exam/Section D

When you first run your code you will probably find that everything appears to work. Don't be deceived, try and put incorrect menu choices in, try and move your character outside the map. We have a lot to fix and any errors are very likely to come up as questions in the exam, where you have to fix them!

Miscellaneous
There are 3 steps of resuming in the game.

1. This is the code to be created:

Function gameinprogress(ByVal MonsterPosition As CellReference) As Boolean ' using monsterposition as a test to see if game in progress If MonsterPosition.NoOfCellsEast <> 0 Then gameinprogress = True Else gameinprogress = False End If End Function

You need to create this code[ABOVE CODE AS SHOWN] under the code BELOW:

Module Module1 Const NoOfTraps = 2 Const NSDistance = 5 Const WEDistance = 7

2. Then change from this:

Sub DisplayMenu Console.WriteLine("MAIN MENU") Console.WriteLine Console.WriteLine("1. Start new game") Console.WriteLine("2. Load game") Console.WriteLine("3. Save game") Console.WriteLine("4. Play training game") Console.WriteLine("9. Quit") Console.WriteLine Console.Write("Please enter your choice: ") End Sub

To this:

Sub DisplayMenu(ByVal MonsterPosition as cellreference) Console.WriteLine("MAIN MENU") Console.WriteLine Console.WriteLine("1. Start new game") Console.WriteLine("2. Load game") Console.WriteLine("3. Save game") Console.WriteLine("4. Play training game") If gameinprogress(monsterposition) then console.writeline(“5. Resume game”) Console.WriteLine("9. Quit") Console.WriteLine Console.Write("Please enter your choice: ") End Sub

3. After, create a case 5:

DisplayMenu Choice = GetMainMenuChoice Select Case Choice Case 1 SetUpGame(Cavern, TrapPositions, MonsterPosition, PlayerPosition, FlaskPosition, MonsterAwake, True) PlayGame(Cavern, TrapPositions, MonsterPosition, PlayerPosition, FlaskPosition, MonsterAwake) Case 2 LoadGame(TrapPositions, MonsterPosition, PlayerPosition, FlaskPosition, MonsterAwake) SetUpGame(Cavern, TrapPositions, MonsterPosition, PlayerPosition, FlaskPosition, MonsterAwake, False) PlayGame(Cavern, TrapPositions, MonsterPosition, PlayerPosition, FlaskPosition, MonsterAwake) Case 3 : SaveGame(TrapPositions, MonsterPosition, PlayerPosition, FlaskPosition, MonsterAwake) Case 4 SetUpTrainingGame(Cavern, TrapPositions, MonsterPosition, PlayerPosition, FlaskPosition, MonsterAwake) PlayGame(Cavern, TrapPositions, MonsterPosition, PlayerPosition, FlaskPosition, MonsterAwake) End Select Loop Until Choice = 9 End Sub

This is what you put in case 5:

Case 5 If gameinprogress(MonsterPosition) Then PlayGame(Cavern, TrapPositions, MonsterPosition, PlayerPosition, FlaskPosition, MonsterAwake) Else Console.WriteLine("no game currently in progress") End If

First, you need to declare a boolean variable to the code to allow it to have an enable function. We then need to allow the an input to take place so we add it to sub makemove. We then need to allow the input to be valid.(Section is Sub CheckValidMove)

Finally, we need to make it when cheat = true, then it will display all the cavern items. This is added to the sub DisplayCavern.

Movement
There are limits to where the player can move, on the x axis, it is all spaces above and including 1, and all spaces below and including NoOfCellsEast: 1 =< x =< NoOfCellsEast on the y axis, it is all spaces above and including 1, and all spaces below and including NoOfCellsSouth 1 =< y =< NoOfCellsSouth Using this knowledge we need to stop the  subroutine allowing the user to move outside these bounds.

Think about why  has been passed to   sub, and that it isn't currently being used. Could the check be done there? At the moment to check that it is a valid move it uses: But this doesn't take into account the times when an attempted move is not valid, for example when the player chooses N (UP) when they are in the first row (row 1): Direction = "N" And PlayerPosition.NoOfCellsSouth = 1 We need to update the IF STATEMENT above that sets ValidMove = False, to: Also we might want to add a little feedback to  sub, highlighting when moves are not valid. We need to add the following code above the line that says:

For Pascal

Remove the 3 lines from: And replace them with: If this question is going to be asked it is very unlikely that you'll be asked to remember the sleep command, and you'll probably be given it

First you'll need to add the case for the new commands to be recognised in the MakeMove sub-routine: But this doesn't work! Can you spot why? It is because the variables MoveDirection, Move and the GetMove Function have been declared as a Char (accepting only ONE character) and each time 'Direction' has been passed, it has passed as a Char also. They all need to be changed (inefficiently in terms of memory) to the String data type to allow the user to type more than one character to move the position of the player (i.e. "NE", "SE", "SW", "NW"). Use 'Ctrl + F' (Find and Replace box should appear) to find and replace all of the Char datatypes to String for ONLY the following variables or Function: Of course you must also update the move options here:
 * Replace 'GetMove As Char' to 'GetMove As String'
 * Replace 'Dim Move As Char' to 'Dim Move As String'
 * Replace 'Dim MoveDirection As Char' to 'Dim MoveDirection As String' in the PlayGame sub-routine
 * Replace 'Direction As Char' to 'Direction As String' in the MakeMove procedure and the CheckValidMove function.

There are 3 sub-routines that need to be edited for this. First the sub-routine that writes out move options on the screen for the user:

Second, the MakeMove sub-routine which actually processes the movement of the player when a key is pressed:

Lastly, the CheckValidMove which simply checks if the key they have pressed is a valid choice:

First we need to create a subroutine to teleport the user. This will need access to the  so we can update it, and the   function so we can randomly assign a new position: But this won't let the player teleport to position[1,1]?! Now we have declared the sub routine we must create an option in the  subroutine to to handle pressing "T": We must add the "T" option to the  sub routine: And finally we must allow the "T" option to be a  sub routine: '''With this code the player can teleport as many times as they like. An additional boolean variable is needed if the player is only going to be allowed to teleport once. The record structure will also need changing. Possibly too many changes for the exam?'''

Alternative way and to allow to ONLY teleport once:

We need to make a boolean variable to see if we used teleport or if we didnt, true or false: Then we need to add a menu option here:

Then we Have to add a code to allow to teleport to a new random position

Now we need to update the code that checks if its a valid move. IT has to be "T" and teleport has to be = "True"

Next we need to fix a small problem to allow user to go back to the main menu, start a new game and BE ABLE to teleport once again since its a new game.

Function CheckValidMove(ByVal PlayerPosition As CellReference, ByVal Direction As Char) As Boolean Dim ValidMove As Boolean ValidMove = True If Not (Direction = "N" Or Direction = "S" Or Direction = "W" Or Direction = "E" Or Direction = "M") Then ValidMove = False End If       If Direction = "N" And PlayerPosition.NoOfCellsSouth = 1 Then ValidMove = False End If   CheckValidMove = ValidMove End Function
 * OR*** (Visual Basic)

Input Validation
In the  function change the line: to: This converts whatever the input is into an Upper Case letter

To stop the menu breaking on you typing in "g" or "one" we have to change the code in several places:

We then need to catch any errors when the program converts the input into an Integer by adjusting the  function: This should work. But to make it even better we should probably give an error message to tell them when they have typed in an incorrect menu choice if the number is incorrect. Take a look at the  function again and at the case statement. We are going to add an else case that will handle any incorrect input:

Change the  function to:

For Pascal

Adding a TYPE Check validation (try/catch) to GetMenuChoice will stop runtime exceptions being thrown

Change the  function to:

We might want to add a little feedback to  sub, highlighting when moves are not valid

Loading and Saving
A simple solution:

In playGame method

//add to top { int moveCounter = 0; } add in if statement

if (moveDirection != 'M' && validMovement(moveDirection, playerPosition)==true) {  moveCounter++; makeMove(cavern, moveDirection, playerPosition); displayCavern(cavern, monsterAwake); ... }

add in the if Statement for flaskfound

if (flaskfound) {    displayWonGameMessage; console.println("You completed the game in "+moveCounter+" moves); }

How to do for VB.net

Then we add the score to the win message '''Another thought - what about if the game is saved. Wouldn't we also need to save the number of moves?? If so, this makes the problem considerably more difficult as it involves changing the record structure.'''

Sub SaveGame(ByVal TrapPositions As CellReference, ByVal MonsterPosition As CellReference, ByVal PlayerPosition As CellReference, ByVal FlaskPosition As CellReference, ByVal MonsterAwake As Boolean) Dim Filename As String Dim FileCheck As Integer Dim CurrentGameData As GameData CurrentGameData.TrapPositions = TrapPositions CurrentGameData.MonsterPosition = MonsterPosition CurrentGameData.PlayerPosition = PlayerPosition CurrentGameData.FlaskPosition = FlaskPosition CurrentGameData.MonsterAwake = MonsterAwake

Do While FileCheck < 4 Console.Write("Enter new file name: ") Filename = Console.ReadLine FileCheck = Len(Filename) If FileCheck > 4 Then Console.WriteLine FileOpen(1, Filename, OpenMode.Binary, OpenAccess.Write) FilePut(1, CurrentGameData) FileClose(1) Else Console.WriteLine Console.WriteLine("You need a save name of at least four characters!") Console.WriteLine End If       Loop End Sub

Menu Additions
You must add the option to the main menu:

We must create a sub routine to display the story:

We must add the option to display the story to the main menu system in the  subroutine:

Other
the number of traps is hard coded in: But later it is not used when cycling through the traps, this means that if you adjust the number of traps then the code will not include any more than two and break on any less than two.  However the number of traps must remain a constant and not changed at runtime as it is used to create the  array.

REMOVE:

AND MAKE THE CHANGES IN HERE:

Final Question
The final question of the exam is usually an extend and stretch question. It won't require you to code anything, but to discuss how you would code the solution to the problem if you had the time:

In order to make the game more playable, it has been decided to make the cavern have different levels. This means that the player will be able to move up or down in some parts on the cavern. This means that the player will be offered the choices Enter N to move NORTH Enter E to move EAST Enter S to move SOUTH Enter W to move WEST Enter U to move UP Enter D to move DOWN Enter M to return to the Main Menu

Describe the changes necessary to the following data structures in order to make this possible.
 * TCellReference
 * TCavern
 * TGameData