YCP Logo Assignment 7: Mini Golf

Due: Tuesday, April 14th by 11:59 PM

Getting Started

Start by downloading CS101_Assign7.zip, saving it in the directory H:\CS101.

Start a Cygwin Bash Shell and run the following commands:

cd h:
cd CS101
unzip CS101_Assign7.zip
cd CS101_Assign7

Using Notepad++, open the file

H:\CS101\CS101_Assign7\MiniGolf.cpp

You will add your code to this file.

Run the command

make

when you are ready to compile the program. To run the program, run the command

./MiniGolf.exe

Your Task

Complete the program so that the user can play a game of "Mini Golf". The game works as follows:

  • Game play occurs on a rectangular field the size of the output window (80 columns by 25 rows)
  • The field contains a number of rectangular obstacles:
    • four barriers on the top, right, bottom, and left of the field, preventing the ball from moving out of the field
    • eight randomly placed rectangular obstacles somewhere to the right of the left quarter of the field, each random obstacle having a width between 3 and 14 characters, and a height between 3 and 6 characters
  • A 2x2 cup is placed in the middle of the right half of the field
  • The game starts by allowing the user to move the ball up and down by pressing the up and down arrow keys
  • After the user has positioned the ball to his or her satisfaction, pressing the 'j' key launches the ball towards the upper right of the screen, and the 'k' key launches the ball towards the lower right of the screen
  • The player may press 'q' at any time to quit the game.
  • The ball then moves, bouncing off obstacles. If the ball enters the cup, the player wins, and a congratulatory message is displayed.

You can run the sample implementation to get a sense of how the program should work:

MiniGolf.zip [Fixed version]

Unpack the zip file, and then run MiniGolf.exe in a cygwin bash shell.

Screenshots:

  • Placing the ball

    images/positionBall.png
  • Ball moving on the playing field

    images/moveOnField.png
  • Hole in one!

    images/holeInOne.png

Hints

This will be a complex program. You will need to think carefully about how to organize the program, and work on the features incrementally.

Don't panic!: Substantial credit is available for implementing a subset of the features. See Grading Criteria below.

The code is structured in the same way as Lab 18: the init_scene, render_scene, and update_scene functions all take a pointer to the Scene data structure.

Suggested implementation approach:

Define a Rectangle struct type to represent the rectangular barriers and obstacles.

Define a function to initilize a rectangle by the x and y coordinates of its upper-left corner and its width and height:

void init_rect(Rectangle *r, int x, int y, int width, int height);

Define a function to draw a given rectangle on the screen:

void draw_rect(Rectangle *r);

Add a Rectangle field to the Scene data type to represent the cup.

Add code to the init_scene function to initialize the field representing the cup.

Add a field to your Scene data type which is an array or vector of 12 Rectangle elements. These will represent the barriers and obstacles.

Add code to the init_scene function to initialize elements of the rectangle array/vector to represent the barriers at the edge of the window.

Add code to the init_scene function to initialize elements of the rectangle array/vector to represent the internal obstacles. (You will need to think carefully about how to ensure that they don't overlap the cup.)

Add code to the render_scene function to draw the field and all obstacles.

Running the program at this point should show the playing field and the obstacles and barriers. Continuing...

Define a Ball struct type to represent the position (x, y) and motion (dx, dy) of the ball. In the Mini Golf game, dx and dy should be restricted to the values 1 and -1, so make the dx and dy fields int.

Add code to init_scene to set the initial position and motion of the ball. The initial position of the ball should be on the left hand side of the playing field. For now, set the motion as dx = 1 and dy = 1.

Add code to render_scene to draw the ball.

At this point, when you run the program, you should see the the ball, but the ball won't move. Continuing...

Add code to the update_scene function to move the ball, using an approach similar to Lab 16 and Lab 18.

Running the program again, the ball should move, but it will not bounce off any of the barriers or obstacles. Continuing...

Add code to the update_scene function that will check for collisions between the ball and each obstacle. If the ball hits any obstacle, deflect the ball away from the obstacle. See the short document about detecting and handling collisions for a suggested approach.

Running the program again, the ball should bounce off obstacles, but if the ball hits the cup, nothing will happen. Continuing...

In update_scene, add code to detect when the ball has hit the cup. When this happens, the player wins and the game should end by displaying a congratulatory message.

Add code to update_scene that allows the player to change the initial position of the ball by pressing the up and down arrow keys, and launch the ball by pressing the 'j' or 'k' keys:

int key = cons_get_keypress();
if (key == UP_ARROW) {
        // move the ball up
} else if (key == DOWN_ARROW) {
        // move the ball down
} else if (key == 'j') {
        // launch to upper right
} else if (key == 'k') {
        // launch to lower right
}

Note that the code above should only be checked when the game is in "ball positioning mode": after the ball is launched, these keys should have no effect.

Finally, add code to update_scene so that when 'q' is pressed, the game will exit. You will also need to modify the game_is_finished function.

Note: in the main function, the while loop which displays the frames of the animation has the following structure:

while (!game_is_finished(&scene)) {
        // update scene, render scene, delay
}

If you would like, you may change the loop condition to

while (game_is_finished(&scene) != 0) {

In either case, the game_is_finished function should return a value of 0 to indicate that the game is finished (because the user pressed 'q'), or a non-zero value if the game should continue.

Now you're done!

Grading Criteria

For up to 70% credit, implement the creation and rendering of the playing field with randomly-placed obstacles and fixed-position cup.

For up to 75% credit, implement a moving ball without collisions.

For up to 80% credit, implement a moving ball with collisions with the barriers at the four edges of the playing field, but no collisions with internal obstacles.

For up to 85% credit, implement a moving ball with collisions with internal obstacles.

For up to 90% credit, detect when the ball hits the cup, displaying a congratulatory message.

For up to 100% credit, allow the user to position and launch the ball.

For up to 110% credit, implement a moving obstacle in addition to the fixed obstacles.

As always, make sure you use correct indentation, choose meaningful names for variables and functions, and add comments to describe what your code is doing. Points may be deducted for poor coding style.

Submitting

To submit your work, make sure your MiniGolf.cpp file is saved, and type the command

make submit

Enter your Marmoset username and password (which you should have received by email.) Note that your password will not be echoed to the screen. Make sure that after you enter your username and password, you see a message indicating that the submission was successful.

Important: Make sure that you check the file(s) you submitted to ensure that they are correct. Log into the server using the following URL:

https://camel.ycp.edu:8443/view/course.jsp?coursePK=54

You should see a list of labs and assignments. In the row for assign7, click the link labeled view. You will see a list of your submissions. Download the most recent one (which should be listed first). Verify that it contains the correct files.

You are responsible for making sure that your submission contains the correct file(s).