Section D: Basic Worksheet

SPA4321
Introduction to C++
Section D: Basic Worksheet
This worksheet is the “basic” level option for SectionD. You will use what
you have learnt about basic variables, loops, branches, functions as well as
basic input and output operations using cin and cout in completing this
worksheet. You should attempt this worksheet if you found the SectionC
worksheet very challenging.
The deadline for submission of both worksheets is 12 noon on Monday
3rd April 2017 (this is the Monday after the end of the semester).
2016-17
The assessed components are
marked clearly below. In addition to
being granted marks for completing
the tasks, you will also get 1 mark in
each assessed exercise for getting
the structure of the project and the
name correct and a reasonable use
of comments to explain your code.
Total marks: 37
The grade for this worksheet is capped at 50%
To submit your work you need to ensure you have used the correct project names – as listed in each
exercise – and then apply a tag to your repository:
SectionDCompleted
If you find you have made a mistake or need to update your work before the deadline you can make
additional tags with the form:
SectionDCompletedX
where X is a number. So for example, the first extra tag would be: SectionDCompleted1, the second:
SectionDCompleted2 etc. Whichever is last tag made before the deadline will be the one used in the
assessment.
1
SPA4321
Introduction to C++
2016-17
Exercise 1: Ex3.1 [ 36 marks]
In this exercise, you will build a simulation of the outcomes of a fairground game.
In the game the player fires a ball from a small cannon towards a hole a certain distance from the
cannon. The player can adjust the angle of the cannon and the speed at which the ball is fired. The
player must attempt to shoot the ball so it lands in the hole.
Part A [5 marks]
Assuming the mouth of the cannon is level with the top of the hole then the angle 𝜃 and velocity v
that the player has to choose to have the ball land in the centre of the hole are related by the
following equation:
sin 2𝜃 =
𝑑𝑔
,
𝑣2
Where g is the acceleration due to gravity and d is the distance from the mouth of the cannon to the
middle of the hole. In this question, we’ll assume g=10ms-2
•
Create a new source code file – functions.cpp
o Make sure you tick the box to create the corresponding header file
o Make sure the tick the box to add it to the targets (otherwise you’ll need to edit
your CMakeLists.txt file yourself)
•
Now you should write a function with the following signature:
•
•
Put the declaration in functions.h and the definition in functions.cpp
Now write the body of the function in functions.cpp to carry out the following steps:
2
SPA4321
Introduction to C++
2016-17
o
o
•
•
Create a new double variable called g and initialise it to 10.0
Calculate the value of sin 2𝜃 and store it in a double variable called sin2theta.
Use the equation given above.
o Some combinations of distance and speed will give a value for sin2theta that is
outside the valid range for a sine (valid range is -1 < sin2theta < 1). Check that
the value is within the valid range using an if statement and carry out the
following steps if the value is valid:
▪ Calculate the value of 𝜃 and return it as the value of the function (hint
use the return statement to return a value)
o If the value is not in the valid range carry out the following steps:
▪ Return a value of -1
You should now have a function that can calculate the angle in radians at which the
cannon needs to be set given a set distance between the cannon and the wall and a
specific velocity for the ball.
Push and commit your work now!
Part B [10 marks]
It is always important to test your code as you go along. Continuing in the same project you will now
start writing some code to help you carry out tests of your function.
When comparing real numbers (ie those with decimal places) in code it is always important to realise
that there is no perfect representation of every possible number and so although the results of two
different calculations might be the same mathematically, depending on the exact calculations they
might not be exactly the same in computer code. This can make it difficult to test if tow floating
point numbers are actually the same. To make this easier you will now write a little helper function:
•
In functions.h write a function declaration for the following function:
•
In functions.cpp write the appropriate function definition. The function body should carry
out the following steps:
o Calculate the difference between value and test and store this in a double called diff
o Using an if statement test that the absolute value (ie ignoring the sign) of diff is less
than p
o Return a value of true if this is the case
o Return a value of false if it is not
Hint: remember a default value should only appear in the declaration – you will get an error
if it appears in the definition as well.
•
Now you will write a test function that makes use of this together with your original angle function:
3
SPA4321
Introduction to C++
2016-17
•
In functions.h write a function declaration for the following function:
•
In functions.cpp write the appropriate function definition with a function body that carries
out the following actions:
o Call your function angle to calculate the angle for distance=2.5 and speed=6.0
o Store the result in a double called ang
o Call your function testFloat with the following parameters in order:
▪ ang
▪ 0.383823
▪ 0.000001
o Store the result in a bool called test
o Return the value of test as the return value of your function.
Now it’s time to put this together to do a full test of your code.
•
In main.cpp write code to carry out the following steps:
o Call the function test1() and store the return value in a bool called t1
o Using an if statement test the value of t1 and carry out the following actions if it is
true:
▪ Print the string “Test 1 SUCCESS” to the console
o else carry out the following steps if it is false:
▪ print the string “Test 1 FAILED” to the console
Now compile and test all your code. Make sure that your test code is correct and then run it. If you
don’t see “Test 1 SUCCESS” go back and see if you can figure out where the code is going wrong.
Adding extra cout statements to your code is a good way to check what values are being calculated
at different steps of the program.
•
Commit and push your code now
Part C [3 marks]
•
The point at which the ball enters the hole relative to the centre given a particular launch
angle, speed and the distance to the hole is given by:
𝑤=
𝑣2
𝑠𝑖𝑛2𝜃 − 𝑑
𝑔
(the symbols have the same meaning as in Part A)
•
Add a function declaration to functions.h and a function definition to function.cpp for a
function with the following properties:
o Function name: impact
o Return type: double
o 3 Parameters:
▪ double angle
4
SPA4321
•
•
•
Introduction to C++
2016-17
▪ double speed
▪ double distance
In the function body write code to evaluate the value of w given by the equation above
where 𝜃=angle, v=speed and d=distance. As with the previous exercise assume g=10.0
The function should return the value of w
Hint: sometimes it easier to break a big calculation up into smaller intermediate steps.
Part D [5 marks]
Time for some more test code.
•
•
Write a new function called test2 taking no arguments and returning a bool. Put the
declaration in functions.h and the definition in functions.cpp
The function body of test2 should carry out the following steps:
o Call your angle function with distance=2.5 and speed=6.0 to calculate the angle
required to hit the centre of the hole. Store the result in a double called ang
o Now call your impact function with angle=ang, speed=6.0 and distance=2.5, and
store the result in a double called position. Hint: make sure you get the order of the
parameters correct.
o If the calculations are correct then the calculated value of w should be 0
o Call your testFloat function with parameters: position, 0 and 0.0001
o store the result in a bool.
o If the result is true return a value of true from your test2 function
o Else return a value of false.
Now to add the new test to the main function:
In main.cpp:
•
•
Add code to call test2 and store the result in a bool called t2.
If t2 is true print the following string to the console “Test 2 SUCCESS” otherwise print the
following string to the console: “Test 2 FAILED”
Build and run your code. Does it print both tests as succeeding?
Double check your test code to be sure it is correct before moving!
Commit and push your code!
Part D [ 7 marks]
Now to turn this into a proper simulation with some random numbers.
•
•
•
Download the code: random.h and random.cpp from QMPlus.
Add the files to your project.
To get things to compile you’ll need to edit the CMakeLists.txt file as follows:
Currently it should look something like this:
5
SPA4321
Introduction to C++
2016-17
The line you need to edit is highlighted in the snapshot above.
Add the files random.h and random.cpp after functions.cpp and functions.h inside the bracket.
It should then look like this:
You should then be able to reload the project, add the files to git and then commit and push.
Now you can use the random number generator provided to build a simulation of attempts at the
fairground game.
The idea is that a real device will never aim quite perfectly with each shot, nor will the speed be
perfectly reproducible. You can use random numbers to simulate the effect of imperfections in the
system.
Add the following code to your main function (after the test code) to simulate a single random shot:
•
•
•
•
Create a new double called speed and initialise it to 7.5
Create a new double called distance and initialise it to 5.0
Create a new double called g and initialise it to 10.0
Calculate the nominal angle for a shot to hit the centre of the hole using these parameters
and your angle function from above. Store the result in a double called nominalAngle
You can generate a normally distributed random number using the function provided in
random.cpp/.h.
This function is called: Random::randomNorm(double mu, double sigma) and it generates random
number according to a normal distribution with mean mu and standard deviation sigma.
6
SPA4321
•
Introduction to C++
2016-17
Add a call to this function to generate a random number with a mean of 0 and standard
𝜋
deviation of 2∘ × 180.0 (ie a 2 degree variation expressed in radians) – store the result in a
•
•
new double called deltaAngle
Create a new double called actualAngle and initialise it to the sum of nominalAngle and
deltaAngle
Don’t forget the correct #include statements!
This simulates a random variation in the angle.
Now to simulate a random variation in the speed:
•
•
Add another call to the random number function to generate a random number with a mean
of 1 and a standard deviation of 0.1. Store the result in a double.
Create a new double called actualSpeed and initialise it with the product of the speed
defined above and the result of calling the random number generator.
This will simulate a 10% variation in the actual speed.
•
•
•
Add code to calculate the point of impact relative to the hole using your impact function
from above. The parameters should be: actualAngle, actualSpeed and distance.
Store the result in a double called height
Now put this code inside a loop – all the random variations and the calculation of the height
to simulate 10000 shots of cannon.
If the hole has width h and the ball has radius r then, to a reasonable approximation, the ball will
enter the hole if the impact position w is within:
𝑤
𝑟
𝑤
−( −
)<ℎ < −𝑟
2 𝑠𝑖𝑛𝜃
2
•
•
•
Add an integer counter before the loop called hits
Using the above equation - inside the loop, after the impact calculation, add an if statement
to test if the ball would have gone in the hole or not. If it would have gone in the hole
increment the counter.
Set the radius r=1 and the width w=4
Commit and push your code!
Part E [5 marks]
In this part you’ll modify the code to count the number of wins out of 10000 attempts, where a win
is defined as three hits in a row.
•
•
•
•
Add an integer before the loop called wins and initialise it to 0.
Add another integer before the loop called hitsInARow and initialise it to 0.
Modify your code so that if the ball goes in the hole you increment the value of hitsInARow
but if the ball misses you set hitsInARow to 0
Add code inside the loop to test if hitsInARow has reached 3. If so, increment the counter
wins and set hitsInARow to 0.
7
SPA4321
Introduction to C++
2016-17
Part F [ 3 marks]
•
•
If the cost of a prize is £1 to the operator of the stall, add code to calculate the amount
that would have to be charged per attempt in order to break even.
Print the break-even price to the console.
8