Question 1
40 marks
1(a) 3 marks
A game is being written that makes use of object-oriented programming. A prototype for one part of the game is being designed that includes a character, a road and a prize to collect.
The road will have 50 spaces that a character can move along. Each space on the road will store a null value or a prize object for the user to collect. Each space is numbered sequentially from the first space (position 0) to the last space (position 49) and will not change during the game. As the player travels down the road, the position the player is on the road will be output.
The road is designed to be a 1-dimensional array with the identifier road.
Explain why an array is a suitable data structure to represent the road.
Mark scheme 1(a)
Tick each point your answer makes. Your mark is worked out from your ticks, and you can change it.
1 mark each to max 3. Max 2 for generic answers with no relation to scenario. e.g.
-
Has a set/fixed number of values
-
…and the number of spaces in the road will not change
-
Stores data of one type
-
… as the array is only made up of prize objects
-
Stores data linearly
-
… match the linear nature of the road
-
Array contents are mutable
-
… so prizes can be added/removed from the road
-
A single indentifier is used to directly index
-
… any position in the road
-
Can be iterated by index
-
… to perform an operation on all road positions
Guidance
Examiner’s Comments
Many responses were too vague, showing little knowledge of the properties of arrays. Relatively few candidates appeared to be able to make explicit links to the scenario to achieve full marks.
1(b)
The characters and prizes are designed as separate classes. 10 of the spaces on the road will contain an instance of the class Prize. The other spaces will be empty.
The class design for Prize is here.
class: Prize
attributes:
private name : string
private type : string
private value : integer
methods:
new()
getName()
getType()
getValue()
new() is the constructor method. The name, type and value are passed to the constructor as parameters which then assigns these to the attributes.
1(b)(i) 2 marks
The method getName() returns the data in the attribute name.
Write the method getName() using pseudocode or program code.
Mark scheme 1(b)(i)
Tick each point your answer makes. Your mark is worked out from your ticks, and you can change it.
1 mark each
-
Function/subroutine with identifier
getNametaking no parameters -
Returning
name
e.g.
public function
def getName(self):
getName()
return name return self.__name
endfunction
public getName(){ function getName() {
return name return this.name
} }
Guidance
BP1 Do not award procedure or method
BP1 Allow self as an additional parameter if Python is used.
BP1 If an access modifier is given for the method, it must be public and not private.
BP2 Do not allow any modified name attribute to be returned.
Examiner’s Comments
While many candidates had little difficulty giving code for a getter() there were a number of common errors. Some candidates used a private access modifier when a getter() needs to be public. There was often erroneous use of ‘procedure’ whereas a getter() is a function that must return a value.
Some candidates tried to set values within the getter() function when it should only have returned the class attribute value.
1(b)(ii) 3 marks
A global 1-dimensional array, allPrizes, stores 10 objects of type Prize.
The prize in index 3 has the name “Box”, the type is “money” and the value is 25.
Write pseudocode or program code to create a new object for this prize and store it in index 3 of
allPrizes.
Mark scheme 1(b)(ii)
Tick each point your answer makes. Your mark is worked out from your ticks, and you can change it.
1 mark each
-
New instance of
prize… -
… with “Box”, “money” and 25 as parameters
-
Assigned to
allPrizesindex 3
e.g.
allPrizes[3] = new prize("Box", "money",
25)
allPrizes[3] = prize.new("Box", "money",
25)
allPrizes[3] = prize("Box", "money", 25)
Guidance
MP2 allow any order of parameters
"Box" and "Money" must be strings and 25 must be an integer
Allow prize.new() as new is given as the constructor method in the class diagram
Examiner’s Comments
Many candidates struggled with the instantiation of an object. Where candidates made an attempt to instantiate some did not use a string for “box” and “money” or did not give 25 as an integer but instead gave the string “25”.
1(b)(iii) 3 marks
The game starts with 10 prizes. Each prize is allocated to one space on the road.
An algorithm needs designing that will generate a random space on the road for each prize. Each road space can only store one prize.
Describe the decisions that will need to be made in this algorithm and how these will affect the program flow.
Mark scheme 1(b)(iii)
Tick each point your answer makes. Your mark is worked out from your ticks, and you can change it.
1 mark for each bullet to maximum 3 e.g.
-
Decision - check whether the space already has a prize allocated …
-
Action if true - another space/number will need to be generated
-
Action if false - the prize will be stored here
-
Decision - check if all 10 prizes have been allocated …
-
Action if true - the algorithm needs to stop generating numbers
-
Action if false - a new number/space needs to be generated and checked
Guidance
Give:
- 1 mark for stating a decision
- 1 mark for the action required if true
- 1 mark for the action required if false
Examiner’s Comments
There were only two reasonable decisions that could be given from the scenario details. Candidates needed to make it clear that a decision with a Boolean output was present that would dictate two potential outcomes. Some candidates quoted actions such as ‘randomly assign space for prize’ which did not represent a decision. Many responses described the mechanics of setting up the game and the random spaces but did not highlight the program conditions/decisions as required.
1(c)
The class design for Character is here.
class: Character
attributes:
private name : string
private money : integer
private experience : integer
private roadPosition : integer
methods:
new()
getName()
getMoney()
getExperience()
getRoadPosition()
changePosition()
updateValues()
The four get methods return the associated attribute.
The number of moves is passed to changePosition() as a parameter. The method adds this value to the character’s position on the road.
The type and value of an object are passed to updateValues() as parameters. If the object is money the value is added to the character’s money. If the type is experience the value is added to experience. If the type is neither money or experience no changes are made.
1(c)(i) 5 marks
new() is the constructor method. The name of the character is passed into the constructor as a parameter. The constructor then initialises both the experience and road position of the character to 0 and initialises the amount of money to 5.
Write the constructor method for Character using either pseudocode or program code.
You do not need to declare the class, the attributes or any other methods.
Mark scheme 1(c)(i)
Tick each point your answer makes. Your mark is worked out from your ticks, and you can change it.
1 mark each
-
Constructor header (any suitable name e.g. new, constructor, create, init)
-
…taking one parameter only
-
Initialising name to the parameter
-
Initialising money to 5
-
Initialising experience to 0 and roadPosition to 0
e.g.
public procedure new(pName)
name = pName
Pseudocode experience = 0
example: roadPosition = 0
money = 5
endprocedure
def __init__(self, pName):
self.__name = pName
Python
self.__experience = 0
Example:
self.__roadPosition = 0
self.__money = 5
public Character(string
pName) {
string name = pName;
C# Example: int experience = 0;
int roadPosition = 0;
int money = 5;
}
Guidance
Allow minor changes to identifiers as long as purpose is clear.
Allow
procedure new(pName)
this.name = pName
…
(or similar e.g. self.name)
Allow two parameters if one is self and the response is clearly in Python.
The parameter name should be different to the attribute name.
Examiner’s Comments
It was clear that those candidates with limited OOP programming knowledge found the writing of a relatively simple constructor method difficult. Those with relevant programming experience often found this to be a very straightforward question. Common errors included passing additional values to set the experience, roadPosition and money attributes rather than setting them to the constant values indicated in the question.
1(c)(ii) 5 marks
The type and value of a prize are passed as parameters to the method updateValues. If the type is money the value is added to the character’s money. If the type is experience then the value is added to the experience. If the type is neither money or experience no changes are made.
For example, for the Character player1:
player1.updateValues("money",10) updates player1’s money by 10
player1.updateValues("experience",5) updates player1’s experience by 5
player1.updateValues("foo",9) has no effect on player1.
Write pseudocode or program code for the method updateValues().
Mark scheme 1(c)(ii)
Tick each point your answer makes. Your mark is worked out from your ticks, and you can change it.
1 mark each
-
Procedure/method header …
-
… taking two parameters, type (or similar) followed by value (or similar) …
-
… compare type parameter with "
money" -
… compare type parameter with "
experience" -
… both attributes updated correctly and nothing else modified
e.g.
public procedure updateValues(pType,
pValue)
if pType == "money" then
money = money + pValue
elseif pType == "experience"
experience = experience + pValue
endif
endprocedure
def updateValues(self, pType, pValue):
if pType == "money":
money += pValue
elif pType == "experience":
experience += pValue
Guidance
Do not allow Function for BP1
BP2 parameters must be given in the correct order to match the calls to updateValues() in the question.
“money” and “experience” must be string values
Examiner’s Comments
The updateValues procedure again proved problematic for candidates with limited OOP experience. No marks were given for the first mark point if a function was declared as there was no return value. Parameter names needed to be fit for purpose, understandable,
and had to match the order given in the question scenario to work for the given example calls.
1(d) 6 marks
This incomplete pseudocode algorithm:
- creates a new character with the name Jamal
- loops until the character reaches the end of the road
- generates a random number of spaces to move between 1 and 4 (including 1 and 4)
- moves the character and checks if the new space has a prize
- updates the character attributes if there is a prize
- outputs the character’s new attribute values.
Complete the pseudocode algorithm.
character1 = new …… ("Jamal")
newPosition = 0
while newPosition < ……
move = random(1, 4) /this will generate a random number between 1 and 4
character1.changePosition(move)
newPosition = character1.getRoadPosition()
if newPosition < 50 and road[……] != null then
prizeType = road[newPosition].getType()
valueAmount = road[newPosition].getValue()
character1.updateValues(……, valueAmount)
print("Congratulations you are in position", newPosition, "and found",
road[newPosition].getName())
print("Money =", character1.getMoney(), "and experience =",
character1. …… ())
endif
……
print("You reached the end of the road")
Mark scheme 1(d)
Tick each point your answer makes. Your mark is worked out from your ticks, and you can change it.
1 mark for each completed space
character1 = new Character("Jamal")
newPosition = 0
while newPosition < 50
move = random(1, 4)
character1.changePosition(move)
newPosition =
character1.getRoadPosition()
if newPosition < 50 and
road[newPosition] != null
then
prizeType = road[newPosition].getType()
valueAmount =
road[newPosition].getValue()
character1.updateValues(prizeType,
valueAmount)
print("Congratulations you are in
position",
newPosition, "and found",
road[newPosition].getName())
print("Money", character1.getMoney(),
"and
experience", character1.getExperience())
endif
endwhile
print("You reached the end of the road")
Guidance
Allow road.length / len(road) instead of 50
Allow <=49 instead of < 50
Examiner’s Comments
Nearly all candidates achieved some marks, and a majority scored five or six marks.
1(e) 4 marks
The procedure displayRoad() outputs the contents of each space in the road. The number of each space is output with either:
- the word “empty” if there is no prize
- the name of the prize if there is a prize.
01 procedure displayRoad()
02 for x = 0 to 60
03 print("Space", y)
04 if road[x] == null then
05 print("empty")
06 elseif
07 print(road[x].getValue())
08 endif
09 next x
10 endprocedure
The algorithm contains errors.
Give the line number of four different errors and write the corrected line for each error.
Error 1
Error line 1
Correction
Error 2
Error line 2
Correction
Error 3
Error line 3
Correction
Error 4
Error line 4
Correction
Mark scheme 1(e)
Tick each point your answer makes. Your mark is worked out from your ticks, and you can change it.
1 mark each
-
(Line 02)
for x = 0 to 49 -
(Line 03)
print("Space", x) -
(Line 06)
else / elseif road[x] <>
null
-
(Line 07)
print(road[x].getName())
Guidance
Line 07 allow print(road[x].name)
Examiner’s Comments
Many candidates scored three or four marks but in general candidates found it harder to identify errors in the code than to complete code in the previous question. Some candidates didn’t give the line number but rewrote the incorrect line before giving the corrected line, which was acceptable, although not ideal given the scaffolding.
1(f) 9 marks
A programmer is going to create a prototype for one small part of the game. Both road and allPrizes will be needed throughout the whole prototype. The programmer is considering making these global arrays as she thinks it will reduce the development time. Another programmer has suggested that doing this may create some problems when the rest of the game is created at a later stage.
Compare the use of global and local variables in this program.
You should include the following in your answer:
- the use of local and global variables
- alternative methods to using global variables
- the appropriateness of each to this program design.
Mark scheme 1(f)
Tick each point your answer makes. Your mark is worked out from your ticks, and you can change it.
Mark Band 3 – High level (7-9 marks)
The candidate demonstrates a thorough knowledge and understanding of global variables and the alternatives; the material is generally accurate and detailed.
The candidate is able to apply their knowledge and understanding directly and consistently to the context provided. Evidence/examples will be explicitly relevant to the explanation. There is a well-developed line of reasoning which is clear and logically structured. The information presented is relevant and substantiated.
Mark Band 2 – Mid level (4-6 marks)
The candidate demonstrates reasonable knowledge and understanding of global variables and the alternatives; the material is generally accurate but at times underdeveloped.
The candidate is able to apply their knowledge and understanding directly to the context provided although one or two opportunities are missed.
Evidence/examples are for the most part implicitly relevant to the explanation.
The candidate provides a reasonable discussion, the majority of which is focused. Evaluative comments are, for the most part appropriate, although one or two opportunities for development are missed.
There is a line of reasoning presented with some structure. The information presented is in the most part relevant and supported by some evidence.
Mark Band 1 – Low Level (1-3 marks)
The candidate demonstrates a basic knowledge of global variables and the alternatives with limited understanding shown; the material is basic and contains some inaccuracies. The candidates makes a limited attempt to apply acquired knowledge and understanding to the context provided. The candidate provides a limited discussion which is narrow in focus. Judgements if made are weak and unsubstantiated.
The information is basic and comunicated in an unstructured way. The information is supported by limited evidence and the relationship to the evidence
may not be clear.
0 mark
No attempt to answer the question or response is not worthy of credit.
Guidance
AO1: Knowledge and Understanding
Indicative content
-
Global variables are created when the program starts, all subroutines can access/update the contents
-
Local variables are created in the subroutine they are created in, they are not accessible directly from any other subroutine
-
Local variables are removed from memory when the subroutine ends.
-
Local variables can be passed as parameters to a function to be updated, and then returned to override the original local variable
-
Local variables can be passed by reference to a subroutine to allow the content of the variable to be updated
AO2: Application
- The variables will be stored in memory throughout the whole code execution. However, the amount of data they are storing is relatively low so would not use a lot of memory.
- When the game is expanded, the amount of data may increase so it could be memory intensive, especially if graphics are used in the game.
- Both arrays are needed throughout the whole game so keeping them as global will make writing the code easier as the programmer will not need to keep passing them as parameters and setting return values.
- Only one part of the game is being created initially and therefore the use of global variables would not affect the efficiency greatly. However, when the program expands, it could cause accuracy / testing / debugging and maintenance problems.
AO3: Evaluation
- As this is only a prototype, the use of global variables would be beneficial.
- However, when the game expands, the use of global variables could create issues such as running out of memory, coupling, testing & debugging problems and maintenance problems.
- The programmer may be best to keep the variables as local and then pass them between the different subroutines as parameters byVal and byRef.
Examiner’s Comments
Most responses were Level 2 for definitions and some expansion to passing parameters. Very few candidates were able to go into depth about alternatives to global variables such as passing by value and passing by reference in detail or extending to issues such as scalability within a larger more extended game. Few candidates picked up on the fact that this was a more limited prototype that was likely to be expanded on which would require more consideration to be given to variable scope.