CS 136 Assignment 2

Due Wednesday, Sept. 26 at 11:59am sharp. Late submissions will receive half marks if submitted before Dec. 3 at 11:59 AM sharp.

All work must be submitted to the Marmoset submission system. See the preamble of assignment 1 for more information.

The specification of this assignment includes a few examples of interaction using the Read-Evaluate-Print-Loop (REPL) of DrRacket to help explain the required behaviour of your assignment code. DrRacket is sometimes handy for testing and debugging modules because it allows you to type in function calls and immediately see their results. You do not need to test in this way, but if you want to, ensure that DrRacket will "Determine language from source." This option is found in a drop-down list in the lower-left corner of the DrRacket window. Note that, as for other assignments, Marmoset will test your assignment using runC.

Assignment 2 Problem 1. 15 Marks. File: simon.rkt

Modify the implementation of simon.rkt (the "Simple Simon" game developed in lecture) to compute a score for each game, defined as follows: We define correct_presses to be the number of correct calls to (press) made by the player, and maximum_presses to be the number of calls to (press) needed to win the game. For Simple Simon (but not the full Simon game in later problems), maximum_presses = n, the size of the game.

Your module simon.rkt should provide (in addition to simple-simon and press) a function (score) which produces the score of the immediately previous completed game. If no game has been completed, it should produce 'undefined. For example, you might test your implementation with the following interaction:

Welcome to DrRacket, version 5.1.3 [3m].
Language: racket; memory limit: 128 MB.
   > (simple-simon 3)
   (green yellow red)
   > (press 'green)
   ok
   > (press 'yellow)
   ok
   > (press 'blue)
   lose
   > (score)
   1
You should submit only simon.rkt. However, it is strongly recommended that you create a module testsimon.rkt that you use to test your solution before submitting it to Marmoset.

Assignment 2 Problem 2. 15 Marks. File: simon.rkt

Enhance your solution for problem 1 to provide
   ;; (best-score) -- the highest score of any 
   ;;     game completed so far.  'undefined if no games have been completed.
Your program should not remove any features of your solution to problem 1; your solution here should work for problem 1 as well.
Here's a sample interaction:
Welcome to DrRacket, version 5.1.3 [3m].
Language: racket; memory limit: 128 MB.
   > (simple-simon 3)
   (green yellow red)
   > (press 'green)
   ok
   > (press 'yellow)
   ok
   > (press 'blue)
   lose
   > (score)
   1
   (best-score)
   1
   > (simple-simon 2)
   (red blue)
   > (press 'red)
   ok
   > (press 'blue)
   win
   (score)
   2
   (best-score)
   2

Assignment 2 Problem 3. 30 Marks. File: full-simon.rkt

Create a module full-simon.rkt that implements the logic of the full Simon game. The interface to your module should be as follows:

   ;; full-simon.rkt plays a simon game consisting of n rounds.
   ;;   The first round requires that the user press a sequence
   ;;   of length 1, the next round a sequence of length 2, and
   ;;   so on to the final round which requires that the user
   ;;   press a sequence of length n.   The sequence in each
   ;;   round is a prefix of the same random sequence of colors,
   ;;   each of which is one of ('red, 'blue, 'green, 'yellow)

   ;; the following functions are provided:
   ;;   (full-simon n)   Starts a new game with n rounds and produces
   ;;                    a list with one random color -- the sequence
   ;;                    that must be pressed in the first round

   ;;   (press c)   Consumes a color c (which must be one of 'red,
   ;;               'blue, 'green, 'yellow) and produces one of the
   ;;                following results:
   ;;
   ;;               'win -- the game is complete, and every round
   ;;                       has been played correctly
   ;;               'lose -- c is not the correct color
   ;;               'ok   -- c is the correct color, and the round is
   ;;                        not yet complete
   ;;                a list of colors -- c is the correct color, and
   ;;                        the round is complete, but the game
   ;;                        is not complete.  The list of colors
   ;;                        produced is the sequence that must 
   ;;                        be pressed in the next round.

   ;;   (score)  Produces the score for the most recently completed game,
   ;;            as defined by the formula given in problem 1.  Note
   ;;            that for this game  maximum_presses is not equal to n

   ;;   (best-score) -- the highest score of any
   ;;            game completed so far.  'undefined if no games have been completed.

You might test your implemenation with the following interaction:
Welcome to DrRacket, version 5.1.3 [3m].
Language: racket; memory limit: 128 MB.
   > (full-simon 3)
   (red)
   > (press 'red)
   (red red)
   > (press 'red)
   ok
   > (press 'red)
   (red red green)
   > (press 'red)
   ok
   > (press 'red)
   ok
   > (press 'green)
   win
   > (score)
   6
   > (best-score)
   6
As always, you are advised to write your own module testfull-simon.rkt and use it to test your solution thoroughly.

Assignment 2 Problem 4. 10 Marks. Hand-Marking. File: a2p1test.txt

Write a test suite for Problem 1. The test suite should include 10 different tests and should be in the form of the example shown in Problem 1. Also, clearly number each test and give a 1 line description of the test. Separate each test with a line of asterisk characters ("*").

Assignment 2 Problem 5 (Bonus). 5 Marks. File: simon.rkt

Courtesy Prof. P. L. Ragde.

Implement simon.rkt as an immutable abstract data type. Your implementation must not use mutation -- set!, mutable structs, and library functions that allow you to write memory are not allowed. Marmoset will do some cursory checks to enforce this rule, but markers will also check manually and cancel the Marmoset score if mutation is used.

Your simon.rkt module should implement the following interface, which is slightly different from that used for problem 2:

   ;; simon.rkt plays a single round of the "Simon" game
   ;; provides:
   ;;   (simple-simon n)  consumes a positive integer n
   ;;                     produces (list seq press-fn)
   ;;                     where seq is a length-n sequence of colors
   ;;                       from {red, blue, green, yellow}
   ;;                     and press-fn is a `press' function
   ;; ----------------------
   ;;   A `press' function  consumes a color c
   ;;                       produces (list 'win score) if c is correct and game done
   ;;                       another `press' function if correct and game not done
   ;;                       (list 'lose score) if c is incorrect