Project 04: Turtle race

In this project, you will practice creating objects that have unique roles and properties. You will be making a scene where two turtles are racing each other in a race course that you design. Aside from the Screen object, you will create different Turtle objects, each of whom perform different roles:

Extension points are awarded for complex scenes, especially those that show me that you can integrate concepts from lecture into making your scenes and take things to the next level!


Tasks

0. Design your race course

Decide on the shape of your race course. It doesn't need to be fancy. Keep in mind that your turtles will need to be able to go around the race course multiple times (i.e. to complete "laps"). Some ideas are:

1. Create object_shapelib.py

Just like better_shapelib from last week, object_shapelib.py will contain all your functions that draw shapes and the race scene. You're welcome to add as much complexity as you would like, but minimally it should contain the following functions.

For full credit, all these functions should only use a Turtle object to do the drawing. Only import the Turtle and Screen classes from turtle. I should not see turtle.<blah> anywhere!

1a. goto function

Copy-and-paste the goto function that you have from better_shapelib, and update it to have the function signature:

def goto(turt, x, y, heading=0):

Do the following:

Note: Assume that when a Turtle object like turt is passed in as a parameter that it already exists. That is, you should not create a new Turtle object in your goto function.

1b. Create functions that you need to draw your race track scene

The ones you need depend on your race track design and your concept for your race scene. For example, if you were using a circular track, you might use a circle function to draw the racing lanes (e.g. their outlines, fill, inner and outer lane dividers, road markers, etc.):

def circle(turt, x, y, radius, penWidth=3, fill=True, fillColor='brown'):

Keep it simple! You can always add complexity later. At minimum, each of your shape functions should have:

Feel free to copy-and-paste and adapt code from previous projects!

1c. draw_race_scene

This is the function that should draw your race track scene. It does NOT need to have (x, y, scale) parameters — I suggest only putting in the work to do this if you plan to take advantage of repositioning and scaling your scene as part of a larger extension.

Here is an overview of what the draw_race_scene function should do:

Notes:

1d. Test your race track scene

Add main code to if __name__ == '__main__': in object_shapelib.py to test out your race scene. It should make a Screen object and draw your race scene.

Run object_shapelib.py to produce your race scene. Take a screenshot — this is Required Image 1 in your project report.

Tired of waiting for your scene to draw? You can turn off animations using tracer, which is a Screen method.


2. Create race.py

This file will place your turtles in their racing lanes and have them race. The following subtasks walk you through the general setup.

2a. Copy over make_turtle from lab into race.py

Call this function when you need to create a Turtle object.

2b. Make a main function

Your function should:

Important notes:

Add a if __name__ == '__main__': statement in race.py that calls your main function.

If you run your code now, you should see your racing scene drawn on the screen and your two racing turtles should show up at the starting line in their respective lanes.

2c. Create the move_turtle function

Each racing turtle will move at a different speed, which means that you move them speed units on each time step of your simulation (e.g. in a loop coming up later). The move_turtle function should have one of your turtles (turt) take one "step" (the size of step is speed) and should have a signature that looks like:

def move_turtle(turt, speed):
    '''Moves the `Turtle` object `turt` `speed` units
    '''

Feel free to customize the parameters to suit your race course concept.

Note: speed here refers to the distance a turtle moves forward per iteration of your loop. It is NOT the same as the speed turtle function used to speed up the animations.

Hint (if using a circular course): The turtle circle method has a keyword argument that allows you to specify how much of a circle (angle) that you want to move around.

2d. Move your racing turtles around the track

After the code that you have already written in main, move each of the racing turtles 1000 times. Give Turtle 1 a speed of 4 and Turtle 2 a speed of 3.9. Note: speed here refers to the distance a turtle moves forward per iteration of your loop. This is not the same as using turt1.speed(4) and turt2.speed(3.9).

If you run your code, you should see each turtle move around the track (not deviating from it). Turtle 1 should complete laps faster than Turtle 2.

Hint: If your race course requires the turtles or go back-and-forth or turn corners, you will need to change their heading after they move a certain distance or reach the end of the screen.


3. Race!

Make the race more interesting by adding the following elements.

3a. Randomly jitter each racing turtle's speed

Every time that you move one of the turtles, randomly shift its speed by 0-2.0 units. In your report, comment on whether this affects which turtle complete laps faster.

3b. Keep score

Create variables to keep track of each turtle's "score": how many laps each turtle has completed.

Detect when a turtle completes a lap, increment the appropriate turtle's score, and display the updated score on the screen (somewhere in your scene). You may repurpose any relevant code from lab.

3c. Declare a winner!

Update your code to use a while loop instead of a for loop to move your turtles. Have the race stop after one turtle completes 5 laps. Have a turtle write on the screen which racing turtle won.

Take a screenshot of your final race scene in action (showing two turtles racing on your track with their scores shown). This is Required Image 2 to be included in your report.


Check reproducibility

In order to grade your project, we need to be able to run your code and get the same results as you do! Here is a summary of the expected outputs from each of the source code files that you created:


Extensions

Congratulations on completing the core tasks! Between the code that you’ve already written and the report that you write, you’ve already earned up to 26/30 points for this project. If you turn it in by the first deadline that's 27/30 points.

The remaining 3/30 are a chance for you to earn credit for exploring parts of this project and digging deeper to express your creativity! This is entirely optional; 27/30 is an A- and is a perfectly respectable place to stop. Extensions are open-ended and exist to compliment the structured core project. Explore and learn something new that interests you! Concentrating your energy on 2 "deep" extensions that challenge you will earn you more points than many small, "shallow" extensions.

You can pick your own topics that interest you. Here are a few examples:

  1. Make the animation of your turtles making the collage from lab look more like code rain. Some ideas are to draw letters and numbers rather than turtle shapes, randomize which letters or numbers are drawn, have the "stamps" disappear after each the turtle has moved a certain number of times.
  2. Learn about lists and use them to improve the conciseness of your code. (1-1.5pt dependent on extent)
  3. Add additional racing turtles. (.5-1.5pt dependent on number)
  4. Design a more complex race track shape (e.g. a spiral, maze, etc.) (1-1.5pt dependent on complexity)
  5. Analyze how differences in the turtle speeds and the amount of randomness influences the chance that they win. (.5-1pt)
  6. Related to the previous extension, jitter the one or both turtle's speed using an asymmetric window. For example, randomly adjust the speed to be between [-1, +2] the regular speed. How does this affect how often the turtle with the slower regular speed wins? Analyze how the imbalanced jitter influences wins with different window endpoints.
  7. Learn about and use command line arguments control a number of different aspects of the scene (for example, number of turtles racing). (.5-1pt)
  8. Make it so that you can position and scale your race scene. Do something interesting that takes advantage of this. (1-1.5pt)
  9. Create a new scene and/or scenario that involves multiple Turtle objects in an interesting way. (1-1.5pt)

To get credit for your extensions, you must document them in your report. For each extension this includes:

  1. A description of your extension and how it fulfills one of the above tasks.
  2. A screen shot (or multiple) of your extension.
  3. An explanation of how you implemented your extension.

Submission checklist

To turn in your project, make sure you do all of the following:

Link to detailed turn in instructions and more information about what should be contained in the report. This week's report does not require an Art Statement.


© 2021 Oliver Layton