Main content

### Course: AP®︎/College Computer Science Principles > Unit 6

Lesson 3: Creating simulations# Programming a simple simulation

Ever heard the fable about the tortoise and the hare?

A hare makes fun of a tortoise for moving so slowly and challenges the tortoise to a race. The hare speeds ahead in the race, but then seeing that he's so far ahead, he takes a nap. The hare wakes up to discover that the tortoise had slowly but surely overcome him. 🐢> 🐇 !

The fable has inspired people to run actual races between tortoises and hares. I don't have any such animals handy, but I am curious to see if it's really possible: can a tortoise beat a sleepy hare? How fast must the tortoise be and how sleepy must the hare be?

Let's investigate the questions by programming a simulation.

## Starting simple

We'll begin by simulating a race between a tortoise and a hare that

*doesn't*take naps. I think we both know the results of that race, but when we're programming, it helps to start with a simpler problem and then add complexity after.First we need to establish some initial conditions:

- The length of the race
- The average speed of the tortoise
- The average speed of the hare

We also need to keep track of some values that vary during the race:

- The current position of the tortoise
- The current position of the hare

We can store both the initial conditions and the varying values in variables.

Here's JavaScript code that initializes those variables:

```
var tortoiseSpeed = 1;
var hareSpeed = 2;
var raceDistance = 350;
var tortoisePos = 0;
var harePos = 0;
```

Then we can use a loop that updates the position of the tortoise and the hare and only stops once one of them reaches the finish line.

```
while (tortoisePos < raceDistance && harePos < raceDistance) {
tortoisePos += tortoiseSpeed;
harePos += hareSpeed;
}
```

Here's the running simulation with that code:

As long as the hare is faster than the tortoise, it

*will*win that race. Now that we've got that working, it's time to make it more interesting.## Adding complexity

Our simulation needs to model the behavior of a lazy hare. We can start by establishing some initial properties about his laziness:

- How long is he typically awake between naps?
- When he does nap, how long are the naps?

Here's JavaScript code that stores those properties as variables:

```
var minsBetweenNaps = 30;
var napLength = 20;
```

To figure out when to stop the hare for naptime, we need to also keep track of some values:

- How long has it been since the last nap?
- If he's currently napping, how long has it been since the nap started?

This code stores initial values for those variables:

```
var minsSinceLastNap = 0;
var minsSinceNapStart = 0;
```

The hare starts off awake and running, so both variables start at 0.

Finally, we need to add logic inside the loop to make the hare take naps.

If the hare doesn't need to nap yet, the code updates the hare position (like before) and increments

`minsSinceLastNap`

:```
if (minsSinceLastNap <= minsBetweenNaps) {
harePos += hareSpeed;
minsSinceLastNap++;
}
```

If the hare should be napping, the code increments

`minsSinceNapStart`

, and once the hare has finished napping, the code resets `minsSinceLastNap`

and `minsSinceNapStart`

to 0:```
else {
if (minsSinceNapStart < napLength) {
minsSinceNapStart++;
} else {
minsSinceLastNap = 0;
minsSinceNapStart = 0;
}
}
```

## Visualizing the changes

A simulation does

*not*have to have a visual output; it may just have a textual or numeric output like the simulations above. However, a visualization can help the users of a simulation gain a more intuitive understanding of the output.The way in which we add a visual component to a computer simulation depends on the language we're using and what libraries we have available. In the Khan Academy coding environment, we can use the ProcessingJS library to draw and animate shapes onto the screen, so that's a great fit for visualizing this simulation.

This simulation runs the same logic as before but adds a visualization:

## Adding variability

The real world is full of variation. Tortoises and hares vary in their speeds; the slowest tortoise moves at 0.3 km/hr while the fastest moves at 5 km/hr. Plus, within a race, the tortoise and hare won't move at exactly the same speed the whole time; they'll have their fast moments and slow moments.

One way to add variation to a simulation is to generate random numbers. We can find out the expected ranges of a value in the real world and generate values within those ranges.

Try to find all the places that use randomly generated numbers in this version of the simulation, and then restart to see what changes:

Note that this simulation uses more realistic numbers for the speed of the hare versus the tortoise, so you might be a bit shocked by the results. Play around with the nap parameters to see if you can give the tortoise a shot at winning the race.

## What's excluded?

This simulation is an abstraction of a real world scenario. It attempts to include the most significant parameters about the scenario, but it cannot include everything.

Here are some ideas for excluded details that might affect the race:

- whether each racer moves in a straight path or meanders
- whether each racer has the calories necessary to keep racing
- whether either racer risks overheating during the race

🤔 What else is the simulation missing? How could the simulation be more realistic? What parameters would let us investigate more possibilities?

🙋🏽🙋🏻♀️🙋🏿♂️Do you have any questions about this topic? We'd love to answer—just ask in the questions area below!

## Want to join the conversation?

- what does it mean to add variation to a simulation(4 votes)
- We can use randomness to change aspects of the simulation and add some variation. For example, we could randomize the color of a flower or the path of a ball. This can make the simulation more interesting as it would change every time we would run it.(6 votes)

- QUESTION ABOUT : The code just before "Visualizing the changes". Is my reasoning below correct? Tortoise is making one extra step per each Hare nap, Hare is sleeping for 20 minutes, so the tortoise must make 20 more steps while the Hare is sleeping, but we can see that it makes 21 steps. The hare is resting one minute after he is done having a nap, which was not nebtioned in the description, therefore was not the original intension. You can also see it in the Simulation if you make the framerate 1 and count, tortoise is making one extra step per each Hare nap.

I counted the total time the Hare slept with "var count = 0". I put "count++" here "if (minsSinceNapStart < napLength)" and "println(count)" after the whole code, so that it shows me the total time the hare was sleeping. The results were as follows: Total nap time = 100; Hare position = 350; Tortoise position = 280. So we could say that the whole race took 280 minutes, since tortoise is constantly moving at a rate 1 step per minute. However when we calculate the time of the race with HARE it does not coincide: 350/2 = 175 minutes the hare was running, and the rest amount of time he was having a nap 100 minutes, which gives us 175+100=275 minutes. The race took 280 minutes if we calculate with tortoise and 275 minutes if we do the same with the Hare. I found that the problem was as follows: the loop runs updating the var minsSinceNapStart 20 times, each time it updates the tortoisePos. so far so good. But after the variable napLength stores 20, next time the loop runs it updates tortoisePos, but does not update the harePos, because the loop checks the condition it sees that minsSinceNapStart is equal to naplength so it moves forward to the last else condition that updates the variables minsSinceLastNap = 0; minsSinceNapStart = 0. So it appears that after having slept for 20 minutes not moving, the Hare is also not moving for one extra minute after he wakes up, while the tortoise does make a step. So we must add an extraline to the last ELSE condition of the loop "harePos += hareSpeed". If we do so the results are as follows: Total nap time = 100; Hare position = 350 ; Tortoise position = 275! If we calculate now we will see that there are no mismatches this time: 350/2=175. 175+100=275, which is equal to the time tortoise was moving. You can also see it in the Simulation, tortoise is making one extra step per each Hare nap.

The edited code:

var tortoiseSpeed = 1;

var hareSpeed = 2;

var raceDistance = 350;

var minsBetweenNaps = 30;

var napLength = 20;

var tortoisePos = 0;

var harePos = 0;

var minsSinceLastNap = 0;

var minsSinceNapStart = 0;

var count = 0;

while (tortoisePos < raceDistance && harePos < raceDistance) {

tortoisePos += tortoiseSpeed;

if (minsSinceLastNap <= minsBetweenNaps) {

harePos += hareSpeed;

minsSinceLastNap++;

} else {

if (minsSinceNapStart < napLength) {

minsSinceNapStart++;

count++;

} else {

minsSinceLastNap = 0;

minsSinceNapStart = 0;

harePos += hareSpeed;

}

}

}

println("The total time the hare was having a nap is " + count + " minutes");

println("Tortoise position: " + tortoisePos);

println("Hare position: " + harePos);(3 votes) - one racer could have an emergency and have to forfeit the race.

whether there is a tornado that destroys the finish line. no finish line, no end to the race.

whether there is a referee who can say who won the race.

whether or not the race is actually just a simulation that has bias input. Maybe the code is not precise.(1 vote)