Project 1: Plotting the Unity Fractal

How many digits does the number \(\pi\) have? An infinite number. How do we represent it on a computer then? Usually by chopping it off at some specific precision, but another way to represent it is to write a program that emits more and more digits, the longer you run it (i.e., the longer it runs, the more accurate a version of \(\pi\) you get). That way, you can choose how much precision you want, by just running your program longer.

This project is based on a similar idea, but for the number 1. We write a program that takes two inputs, x and y and runs a scheme to “approximate” (get close to) the number 1. Eventually, it will get “close enough” and we stop; we count the number of steps that it took to to get there and call that the iteration count.

The first stage of this project just asks you to do that much: input x andy, run the process, and then print out the iteration count. The second stage asks you to treat x and y as coordinates in the plane, and to treat the iteration count as colors, and use this to “plot” the results as an image, called the Unity fractal. The third (advanced) stage asks you to generalize your program so that it could be extended to other kinds of fractals.

Project 2: Interactive fiction

(Show demo)

First stage: one room, one object that you can manipulate in some way. Note that the “game” accepts commands until you type QUIT, so it will need to run in a loop. For example, maybe the object is a computer which you can TURN ON and TURN OFF, and which prints something different in each case. Maybe you can GET (pick up) and DROP it.

The second stage asks you to add multiple rooms and objects, together with movement commands (NORTH, EAST, UP, etc).

The third stage asks you to add the ability to save and load your game.

Project 3: Cellular Automtaton

An “automaton” is a simple machine, one that has some current state (i.e., “what am I doing right now”) and responds to input. In this project, you’ll implement a simple 1D cellular automaton. These automatons live on a 1-dimensional world, and can only see their neighbors directly to the left and right. Thus, each automaton changes its state in response to the combination of the state it’s in now, plus the states of its left and right neighbors. (All automatons in the world use the same “rules” for changing states.) For simplicity, the state of each automaton can be only one of two things: alive (indicated by a 1) or dead (0).

Here’s an example world, with one living automaton in the middle and everyone else dead:

0000000000100000000

Because each automaton only cares about three inputs, and those inputs have only two values, there are 8 (\(= 2^3\)) possible input-combinations to consider when determining how the automaton will response. We put these into a table like this:

111 110 101 100 011 010 001 000
0 1 1 1 1 1 1 0

The headings across the top are patterns that we look for in the world (left-self-right automaton states); when we find a particular pattern we change the automaton’s state to the value in the bottom row. For example, running this set of rules (which says that an automaton lives if there is at least one living automaton near it, and dies if there are 0 or 3) on the above world produces the new world

0000000001110000000

The two cells next to the middle cell came alive (because of the rules 001 → 1 and 100 → 1), and the cell itself stayed alive (010 → 1). All other cells stayed dead (000 → 0).

If we continue to run this set of rules, the world evolves as automatons come to life and die:

00000000001000000000
00000000011100000000
00000000110110000000
00000001111111000000
00000011000001100000
00000111100011110000
00001100110110011000
00011111111111111100

The first part of this project is simple: we want to encode the set of eight rules above as a single number, so that we can easily talk about particular sets of rules without having to give the entire table. We do this by treating the second row of the table (the first row is always the same) as a binary number, a number base-2. This means that instead of the digits running 0..9, they are just 0,1. Similarly, instead of talking about the ones, tens, hundreds, etc. digits, we talk about the ones, twos, fours, etc. digits. The “value” of a digit is a power of two, instead of a power of 10.

To encode the above ruleset as a number, we work from right-to-left (least to most significant digits), multiplying by powers of two:

$$0 \times 2^7 + 1 \times 2^6 + 1 \times 2^5 + 1 \times 2^4 + 1 \times 2^3 + 1 \times 2^2 + 1 \times 2^1 + 0 \times 2^0 = 126$$

So we would describe the above set of rules as “rule 126”.

Project 4: Building a calendar

In this project, you’ll gradually build a more and more advanced calendar tool.

In the first stage of the project, you’re job is just to translate a year, month, and day of the month into a day of the week. For example, 8/28/2017 was a Monday. You can assume that users won’t ask about years prior to 1980, and you can ignore leap years for simplicity if you want.

In the second stage, your task is to print out an entire month, looking something like this:

    August 2017       
Su Mo Tu We Th Fr Sa  
       1  2  3  4  5  
 6  7  8  9 10 11 12  
13 14 15 16 17 18 19  
20 21 22 23 24 25 26  
27 28 29 30 31 

One way to accomplish this would be to use your code from the fundamental project to figure out what day of the week the first day of the month falls on (e.g., here 8/1/2017 is a Tuesday). From there, you simply count from 1 to the number of days in the month, printing a newline when you get to Saturday.

To get the numbers to line up, you’ll have to use cout.width(w) to set the field width. When printing the next number, it will be padded with extra spaces to make sure that it takes up at least w columns.

In the advanced stage, you will try to print an entire year, like this:

      January               February               March          
Su Mo Tu We Th Fr Sa  Su Mo Tu We Th Fr Sa  Su Mo Tu We Th Fr Sa  
 1  2  3  4  5  6  7            1  2  3  4            1  2  3  4  
 8  9 10 11 12 13 14   5  6  7  8  9 10 11   5  6  7  8  9 10 11  
15 16 17 18 19 20 21  12 13 14 15 16 17 18  12 13 14 15 16 17 18  
22 23 24 25 26 27 28  19 20 21 22 23 24 25  19 20 21 22 23 24 25  
29 30 31              26 27 28              26 27 28 29 30 31     


       April                  May                   June          
Su Mo Tu We Th Fr Sa  Su Mo Tu We Th Fr Sa  Su Mo Tu We Th Fr Sa  
                   1      1  2  3  4  5  6               1  2  3  
 2  3  4  5  6  7  8   7  8  9 10 11 12 13   4  5  6  7  8  9 10  
 9 10 11 12 13 14 15  14 15 16 17 18 19 20  11 12 13 14 15 16 17  
16 17 18 19 20 21 22  21 22 23 24 25 26 27  18 19 20 21 22 23 24  
23 24 25 26 27 28 29  28 29 30 31           25 26 27 28 29 30     
30                                                                

        July                 August              September        
Su Mo Tu We Th Fr Sa  Su Mo Tu We Th Fr Sa  Su Mo Tu We Th Fr Sa  
                   1         1  2  3  4  5                  1  2  
 2  3  4  5  6  7  8   6  7  8  9 10 11 12   3  4  5  6  7  8  9  
 9 10 11 12 13 14 15  13 14 15 16 17 18 19  10 11 12 13 14 15 16  
16 17 18 19 20 21 22  20 21 22 23 24 25 26  17 18 19 20 21 22 23  
23 24 25 26 27 28 29  27 28 29 30 31        24 25 26 27 28 29 30  
30 31                                                             

      October               November              December        
Su Mo Tu We Th Fr Sa  Su Mo Tu We Th Fr Sa  Su Mo Tu We Th Fr Sa  
 1  2  3  4  5  6  7            1  2  3  4                  1  2  
 8  9 10 11 12 13 14   5  6  7  8  9 10 11   3  4  5  6  7  8  9  
15 16 17 18 19 20 21  12 13 14 15 16 17 18  10 11 12 13 14 15 16  
22 23 24 25 26 27 28  19 20 21 22 23 24 25  17 18 19 20 21 22 23  
29 30 31              26 27 28 29 30        24 25 26 27 28 29 30  
                                            31                    

You can start by using your code from the fundamental project to figure out what day of the week January 1 of the desired year was.

The tricky thing here is that the months are horizontally adjacent to each other, so you cannot directly reuse your printing code from the previous stage. You might start by modifying it so that instead of directly printing the month, it writes each line of the month into a different string. E.g., the first line of the first month would be the string " January ". The second line would be stored in a separate string. You can then append these strings together to get the text to display for a complete horizontal row of text.