Homework 4 is due Monday, October 30, 2017 at 11:59pm.

This week, your source code should appear in four separate files in a directory hw4 with the names world1.rkt, world2.rkt, world3.rkt, and world4.rkt.

Start by downloading two additional files that support universes. Save them in your include directory in your repository. You need both of these files even though cs151-big-bang stays behind the scenes and you don't explicitly require it.

(This piazza post gives similar instructions and links to the same files to be downloaded. If you've already downloaded them from there, you don't need to do it again.)

Your files should begin with these lines:

#lang typed/racket

(require typed/test-engine/racket-tests)

(require "../include/cs151-core.rkt")
(require "../include/cs151-image.rkt")
(require "../include/cs151-universe.rkt")
You should write (test) to run tests, but rather than putting this at the bottom of each file as usual, put it just above the final big-bang so the tests run before the big bang happens and the universe is created.

Homework Problems

For every function you write, you must preface the function definition with a contract (i.e., a type ascription) and a purpose, and you must follow it with tests with check testers (check-expect, check-within, etc.). For functions that produce images, check tests are not necessary.

Do write helper functions where it seems like a good idea to do so. As a programmer, you will be richly rewarded by choosing helper functions well. All functions need contracts, purposes and tests, even if they are "only" helper functions.

Universe Basics

A universe is created with big-bang.

The syntax of big-bang is as follows. Only the to-draw clause is required, and the clauses may appear in any order.

(big-bang <initial-world> : World
  [to-draw <World -> Image>]
  [on-mouse <World Integer Integer Mouse-Event -> World>]
  [on-key <World String -> World>]
  [on-tick <World -> World> <optional-tick-rate>]
  [stop-when <World -> Boolean>]
  [name <U Symbol String>])
where each thing in <angle brackets> is actually a value of that type; for instance:
[to-draw draw]
where draw is a function of the type World -> Image.

There is more to big-bang then this; you can read DrRacket's documentation for more information.

Note that World does not to be the name of the world type, although, in practice, it often is. You could use String or (Listof Real) or Triangle or anything other type for your world type if you chose. The only constraint is that the world type is consistent throughout the whole big-bang.

For on-tick, if you provide an optional tick rate t, ticks occur every t seconds. Exact rationals work well here; if you want 10 ticks per second, use 1/10. If no tick rate is provided, the default is 1/28.

We have not specified how large the window area should be for each of these worlds, or whether they should be square or rectangular. Just choose a size and shape that seems reasonable to you. Make sure you always return the same size image from your drawing function; universe does not behave well if the image size changes from call to call of this function. We are not, for the time being, concerned what happens when the user "misuses" the software, such as, for example, making gigantic circles in world 3 that go entirely off the screen, etc.

World 1: Twenty Clicks

The "twenty clicks" world should display a number of clicks, initially 0, and a running timer (in seconds). You can display the time at whatever granularity you like; for example, you might want to display seconds with tenths, for more detail. The goal of playing twenty clicks is to click on the world twenty times as fast as possible. (Please don't destroy your devices, everyone.) The world should stop as soon as the mouse has been clicked twenty times.

World 2: Type the Alphabet

In world 2, the goal is to type the alphabet, first in uppercase and then in lowercase, as fast as you can and without making any mistakes. This world should display the last character typed, the number of characters left to type (initially 52), and the time elapsed in seconds. Again, tenths or hundredths of seconds are fine if you wish to display them. If at any point the player strikes the wrong key, the player has to go back to capital A and type all 52 characters again. The world should stop exactly when the player has typed all 52 characters correctly.

World 3: Following Circles

In this world, circles must follow the mouse around the window. Your world should contain a list of circles, each with its own radius. At the start of the program, the world should contain a list of one circle of radius 2. Every time the mouse is clicked, another circle of radius 2 should be added to the list. When the user strikes "+", the radius of each circle must get larger by 1. When the user strikes "-", the radius of each circle must get smaller by 1, but never become any smaller than 1. The circles must all appear with their centers at the point of the mouse cursor. The world should shut down when all circles shrink to radius 1. Please look in the documentation for an operation called overlay/xy to place the circles properly.

Draw circles with mode "outline", as opposed to "solid", so players are able to see several circles at once.

The value of the Mouse-Event parameter that is passed to your mouse handler function every time the mouse is moved is "move". When the mouse is clicked, the value is "button-down". (Note that if you are in Matthew Wachs's lecture, he may have given a slightly incorrect name for this latter case.)

World 4: _

Design a world of your own. The only requirements are that the world responds to mouse events, key events, and tick events.

World 4 is a wildcard, get it? :-)

Submit Your Work

Submit your work by committing all four files to your subversion repository by Monday, October 30 at 11:59pm.