This assignment has been closed on October 02, 2023.
You must be authenticated to submit your files

CSE 201 - Tutorial 1 - First C++ program (compiling and running) and Control Flow

Programming a simple shooting game

You will program a simple shooting game in C++ where the player has to hit a target with a projectile.

The game is played in the 2 dimensions (on the horizontal axes \(x\) and the vertical axes \(y\)), the projectile is always shoot from the origin \((x=0, y=0)\) specifying the projectile shooting angle and velocity and the target is always to the right and above the origin (\(x\ge0\) and \(y\ge0\)). The player wins the game if one of the projectiles hits the target.

Examples of a trajectory (without target).

In the figure above you see a graphical representation of a trajectory: the projectile starts from position \((0,0)\) and then follows a parabolic motion until it eventually hits the ground.

From the figure above, note that:

Examples of different sampling times

Note that you will not be able to check when a trajectory exactly reach the groud (i.e., exactly when \(y=0\)).

You will program the game gradually through a series of exercises.

Setting up the tutorial.

  1. Download the handin of the tutorial CSE201-td1-1-handin.zip.
  2. Extract the handin of the tutorial. This will create the folder CSE201-td1-1-handin.
  3. Open QT Creator, then go on the menu “File”, then select “Open File or Project…”. Navigate to the CSE201-td1-1-handin folder and select the file td1.pro.

At this point you should be able to:

You will only edit the file td1.cpp: the file already contains the declarations of the functions you will have to implement during the tutorial.

Evaluation.

You will be evaluated on all the exercises, for a total of 100 points. The different exercises gives at most the following amount of points:

Note that each exercise usually extends the previous ones. So, work on the exercises in order.

Rules for the evaluation:

Running the automatic grader.

You can execute your evaluation directly from QT Creator running the main grading program, you should get an output like:

--------------------------------------------------------------------------------
START TEST - max

[FAILURE] max(0, 1): got -1 expected 1
[FAILURE] max(20, 1): got -1 expected 20
[FAILURE] max(-2, 1): got -1 expected 1
[FAILURE] max(-3, -4): got -1 expected -3
[FAILURE] max(0, 0): got -1 expected 0
[FAILURE] max(1, 1): got -1 expected 1

END TEST - max: [FAILURE] (0 correct test cases out of 6)
--------------------------------------------------------------------------------


... you will see more output here ...

--------------------------------------------------------------------------------
Scores summary:
--------------------------------------------------------------------------------
1 max: 0
2 max_io: 0
3 read_doubles: 0
4 simulate_projectiles: 0
5 compute_min_distance: 0
6 multiple_projectile: 0
7 play_game: 0

Total: 0
--------------------------------------------------------------------------------

The first section shows the results of grading a particular function you have to implement (in the example the function is max). You see that several tests failed, for example:

[FAILURE] max(0, 1): got -1 expected 1

Is telling you that your implementation of the function max called with the paremters 0 and 1 returned -1 as result, while the correct result is 1.

The line:

END TEST - max: [FAILURE] (0 correct test cases out of 6)

tells that your implementation is not correct and it did not pass any test case. To get the points, you need to pass all the test cases.

The last section shows a summary of the scores for all the exercises and all the tutorial.

Here’s some tips:

Submitting your Work

You will submit your work, the file td1.cpp here:

Upload form is only available when connected

You will only have to send the td1.cpp file. The server will automatically run the automatic grader and give you feedback on your submission:

Useful Resources.

There are different resources you can use to get started on your exercises:

Use the above resource for the rest of the course and for your project.

1. Find the maximum of two numbers

Write a function that computes the maximum among two floating point numbers. You will write the implementation of the max function in the td1.cpp file:

double max(double first, double second) {
  // IMPLEMENT YOUR CODE HERE

  return -1.0;
}

While we will learn more about functions in C++ next week, in this tutorial you will just need to know that a function takes some parameters as input (in the example above, first and second of type double), and returns a value (in the example a value of type double). You can use the input parameters in the body of the function (as in Python). Note an important difference between C++ and Python: in C++ you have to explicitly declare the type of all the variables (and parameters) you use.

In this function you will use the double primitive type to store your floating point number (another primitive type is float, which is less precise but also uses less space than a double number, see the IEE754 standard if you’re curious).

Finally, you’ll need to use an if statement to compare the two numbers:

if (<boolean condition>) {
  ... code for the if branch ...
} else {
  ... code for the else branch ...
}

The function asks you to return the maximum value between first and second. As in Python, the keyword return stops the execution of a function and returns the value of the expression written after return (e.g., return 1.0 returns the value 1.0, return first returns the value contained in the variables first).

2. Read two numbers and print the maximum

Implement the function:

void max_io(std::ostream &out, std::istream &in) {
  // IMPLEMENT YOUR CODE HERE

}

that reads two floating point numbers (of type double) from the user and print the maximum of the two.

To read an input from the user you will need to use the input stream in and the extraction operator >> as follows:

double number;
in >> number;

Note how in C++ you have to declare the variable number with its type double before being able to use it. The code above reads a number from the input in and stores it in the variable number. Don’t worry about understanding what is in in detail: while ususally is the input from the user (e.g., the user typing on a keyword), it can also be provided programmaticaly (e.g., when reading a file). The automatic tester will produce the two numbers to be read as input for you. Also, in the slides you saw std::cin and std::cout are the standard instances of input and output streams (the keyboard input and the output on the screen). Here, just use the variables in and out declared in the function.

To output the number you will use the output stream out. Recall that you can print using the << operator (this syntax will become clearer later in the following lectures). The operator << is the insertion operator and it inserts a number into an output stream. For example:

out << number;

outputs number on the output stream out. You will see this output on the screen, but in general the output stream could be a file or a network socket. You can append multiple outputs in a single statement as cout << "My number is: " << number;.

IMPORTANT: We expect you to output the string ‘The maximum number is:’ followed the maximum number (please pay attention to use exactly that string, strings like “the maximum number is:” will be considered differently because the automatic grader is case sensitive). The automatic grader will report an error if you do not output the string ‘The maximum number is:’.

You will see the following output running the automatic grader for max_io (this is the output with an empty implementation):


--------------------------------------------------------------------------------
START TEST - max_io

[FAILURE] max_io called with inputs: 0.0 1.0
          We did not find this string in the output: "The maximum number is:1"
          Your implementation returned the following (wrong) output:
--------------------------------------------------------------------------------

--------------------------------------------------------------------------------
...

You can interpret the above output as follows:

A correct implementation would look like this:

[SUCCESS] max_io called with inputs: 0.0 1.0
          Correctly found this string in the output: "The maximum number is:1"

Note that the return value of the function is void. In this context, void tells that the function does not return a value (so you don’t need to write return value;).

Also, ignore the & symbol used in the parameter declaration of the function (e.g., std::ostream &out). You’ll learn what that symbol later in the course.

3. Read and print 5 numbers

Implement the function:

void read_doubles(std::ostream &out, std::istream &in) {
    // IMPLEMENT YOUR CODE HERE

}

that reads a 5 numbers, stores them, and prints them back. To store the numbers you need to declare an array variable of type double and of size 5:

double numbers[5];

Recall that you can access the element of the array by index (e.g., numbers[0] accesses the first element of the array, numbers[4] accesses the last element of the array).

Here you will also need a loop to read all the numbers. For example, the following loop iterates for 5 times (look back at the slides to see how the different loop statements work):

for (int i = 0; i < 5; i++) {
    std::cout << "Loop iteration " << i << std::endl;
}

IMPORTANT: We expect you to output the list of numbers you read as input.

For example, if you input the numbers 0.0 1.0 2.0 3.0 4.0, the output will be 0 1 2 3 4. The automatic grader would report something like this:

[SUCCESS] read_doubles called with inputs: 0.0 1.0 2.0 3.0 4.0
          Correctly found this string in the output: "0 1 2 3 4"

4. Simulates the projectile trajectory

Implement the function:

double simulate_projectile(const double magnitude,
                           const double angle,
                           const double simulation_interval) {
    double PI = 3.14159265; // use these variables for PI and g
    double g = 9.8;

    // IMPLEMENT YOUR CODE HERE

    return -1.0;
}

that simulates the motion of a projectile in 2 dimensions. Your projectile is always shot from the origin position (the point with coordinates \(x=0\) and \(y=0\)) with an initial velocity took as input. The input to the function are the components of the velocity vector, that is:

and the sampling time of the simulation ‘simulation_interval’ (in seconds).

The function simulates the trajectory of the projectile every simulation_interval seconds until it hits the ground (coordinate \(y = 0\)) and returns the last computed value for the coordinate x before hitting the ground (\(y = 0\)).

To solve your problem, you’ll need to compute the coordinates of the projectiles \(x\) and \(y\) given a time \(t\) (i.e., the coordinate of the projectile \(t\) seconds after the shooting). The equations you will need to use are:

\(x(t) = v_x t\)

\(y(t) = v_y t - 0.5 g t^2\)

where \(g = 9.81\) is the gravitational constant, \(v_x\) is the component of the velocity vector on the \(x\) axes, and \(v_y\) is the component of the velocity vector on the \(y\) axes (use the variable g that we already defined in the function to get our same numerical results).

To compute the components \(v_x\) and \(v_y\) you will need to compute the cosine and sine of \(\theta\). The library math.h declares the functions sin and cos, which compute the sine and cosine of an angle expressed in radians. For example:

cos(30 * (3.14159265 / 180))

computes the cosine of the 30 degrees angle (you can convert from degrees to radians multiplying the angle by (3.14159265 / 180). Use the variable PI already declared in the function). We already added the include directive #include 'math.h' at the top of the td1.cpp file: this directive tells the compiler (or better, the preprocessor) to include the functions defined in math.h (try to remove the directive and see what happens).

WARNING: since you simulate the trajectory in time-steps, you will rarely compute a point where \(y = 0\) (also because of numerical inaccuracies). So, in your function:

5. Minimum distance from a target:

Implement the function:

double compute_min_distance(const double magnitude,
                            const double angle,
                            const double simulation_interval,
                            const double x_target,
                            const double y_target) {
    // IMPLEMENT YOUR CODE HERE

    return -1.0;
}

that simulates the projectile trajectory, as you did in the previous exercise, and that computes the minimum distance of the projectile from the target, during the whole projectile’s trajectory.

The function takes as input the initial velocity of the projectile (magnitude and angle) and the simulation interval (as before). Additionally, the function takes as input the coordinate of the target (x_target, y_target). The function must return the minimum distance.

Computing the distance of the projectile from the target. Suppose that \(x\) and \(y\) are the current position of the projectile, and \(x_t\) and \(y_t\) are the position of the target. The distance between the projectile and the target is:

\[ \sqrt{ (x - x_t)^2 + (y-y_t)^2 } \]

6. Multiple projectiles

Implement the function

double simulate_multiple_projectiles(const double proj_magnitude[],
                                     const double proj_angle[],
                                     const int total_projectile,
                                     const double simulation_interval,
                                     const double x_target,
                                     const double y_target) {
    // IMPLEMENT YOUR CODE HERE

    return -1.0;
}

that computes the minimum distance between multiple projectiles and a target.

The function takes as input an array of velocities (proj_magnitude), an array of angles (proj_angle), the number of elements in each array (total_projectile), a simulation interval and the coordinates of the target. You can also assume that total_projectile is greater than 0.

You can interpret an element of the arrays as the initial velocity (e.g., proj_magnitude[0] and proj_angle[0] are the initial velocity and angle of of a projectile).

The function computes the trajectory of each projectile and computes the minimum distance between all the projectiles and the target, returning it as value from the function.

HINT: can call the function compute_min_distance you implemented in the previous exercise on each projectile (for now, you can use your function “as in Python” — there will be more to it next week).

7. Shooting game

Now we should have all the ingredients to program the shooting game.

Implement your game in the:

void play_game(std::ostream &out, std::istream &in) {
    double simulation_interval = 0.05;

    // IMPLEMENT YOUR CODE HERE

    // WARNING -- remember to output
    // "You hit the target" if a projectile hit target
    // "You did not hit the target" if it didn't
}

function.

The game will read from the user (in this order!):

You will use a simulation interval of 0.05 (please use the variable simulation_interval already defined in the function) to compute the trajectories of each projectile.

The function will compute the minimum distance between a projectile and the target (sounds familiar?). A projectile hits the target if the minimum distance is less than or equal to 1.

The game will output the string

PLAYING THE GAME:

You can play the game yourself instead of running the automatic grader. The execution of all C++ programs starts from the int main function. The main function in the main.cpp file executes bt default the automatic grader. You can change this file to execute the play_game function instead:

If you run the program now you will run the game, instead of the automatic grader.

The preprocessor runs before the compilation of your program and process all the “directives” in the file, which start with a hashtag symbol # (e.g., #include, #define). You can read more information about the preprocessor if you want to, e.g., here. Using the preprocessor could be helpful for the class project.