Recall the color-guessing game from exercise~#excheckguess#46160>. One
player picks two colors for two squares; we call those ``targets''. The
other one tries to guess which color is assigned to which square; they are
guesses. The first player's response to a guess is to compare the colors
and to produce one of the following answers:
- <#68390#><#46162#>'<#46162#><#46163#>perfect!<#46163#><#68390#>, if the first target is equal to the first
guess and the second target is equal to the second guess;
- <#68391#><#46164#>'<#46164#><#46165#>OneColorAtCorrectPosition<#46165#><#68391#>, if the first guess is equal to
the first target or the second guess is equal to the second target;
- <#68392#><#46166#>'<#46166#><#46167#>OneColorOccurs<#46167#><#68392#>, if either of the guesses is one of the two
targets;
- and <#68393#><#46168#>'<#46168#><#46169#>NothingCorrect<#46169#><#68393#>, otherwise.
These four answers are the only answers that the first player gives. The
second player is to guess the two chosen target colors with as few guesses
as possible.
To simplify the game, the choice of colors is limited: see the top of
figure~#figmaster#46171>. Our goal is to develop a program that plays the
role of the master player. That is, we want a program that picks the colors
and checks the guesses of the second player.
<#68394#>;; <#46176#>Constants<#46176#>:<#68394#>
<#46177#>;; the legitimate colors <#46177#>
<#46178#>(d<#46178#><#46179#>efine<#46179#> <#46180#>COLORS<#46180#>
<#46181#>(list<#46181#> <#46182#>'<#46182#><#46183#>black<#46183#> <#46184#>'<#46184#><#46185#>white<#46185#> <#46186#>'<#46186#><#46187#>red<#46187#> <#46188#>'<#46188#><#46189#>blue<#46189#> <#46190#>'<#46190#><#46191#>green<#46191#> <#46192#>'<#46192#><#46193#>gold<#46193#> <#46194#>'<#46194#><#46195#>pink<#46195#> <#46196#>'<#46196#><#46197#>orange<#46197#> <#46198#>'<#46198#><#46199#>purple<#46199#> <#46200#>'<#46200#><#46201#>navy))<#46201#>
<#46202#>;; the number of colors<#46202#>
<#46203#>(define<#46203#> <#46204#>COL#<#46204#> <#46205#>(length<#46205#> <#46206#>COLORS))<#46206#>
<#68395#>;; <#46207#>Data Definition<#46207#>:<#68395#>
<#71767#>;; A <#68396#><#46208#>color<#46208#><#68396#> is a symbol on COLORS. <#71767#>
<#46212#>Figure: Guessing colors<#46212#>
The game description suggests that the program must offer two services: one
for setting up two target colors and another one for checking the
guesses. Naturally, each service corresponds to a function. Let's call the
first <#68397#><#46214#>master<#46214#><#68397#> and the second one <#68398#><#46215#>master-check<#46215#><#68398#>.
Here is a possible dialogue, based on the two functions:
<#46220#>;SPMgt;<#46220#> <#46221#>(master)<#46221#>
<#46222#>;SPMgt;<#46222#> <#46223#>(master-check<#46223#> <#46224#>'<#46224#><#46225#>red<#46225#> <#46226#>'<#46226#><#46227#>red)<#46227#>
<#46228#>'<#46228#><#46229#>NothingCorrect<#46229#>
<#46230#>;SPMgt;<#46230#> <#46231#>(master-check<#46231#> <#46232#>'<#46232#><#46233#>black<#46233#> <#46234#>'<#46234#><#46235#>pink)<#46235#>
<#46236#>'<#46236#><#46237#>OneColorOccurs<#46237#>
<#46238#>...<#46238#>
<#46246#>;SPMgt;<#46246#> <#46247#>(master)<#46247#>
<#46248#>;SPMgt;<#46248#> <#46249#>(master-check<#46249#> <#46250#>'<#46250#><#46251#>red<#46251#> <#46252#>'<#46252#><#46253#>red)<#46253#>
<#46254#>'<#46254#><#46255#>perfect!<#46255#>
The <#68399#><#46259#>master<#46259#><#68399#> function consumes nothing and produces the invisible
value; its effect is to initialize the two targets. Depending on what the
chosen colors are, checking the two same guesses may produce
<#68400#><#46260#>'<#46260#><#46261#>perfect!<#46261#><#68400#> or <#68401#><#46262#>'<#46262#><#46263#>NothingCorrect<#46263#><#68401#>. In other words,
<#68402#><#46264#>master<#46264#><#68402#> sets up some memory that <#68403#><#46265#>master-check<#46265#><#68403#> uses.
Let us now study how the design recipe applies to the development of the
program. The first step is to define the state variables and to specify the
purpose of each variable. Our analysis suggests that we need two state
variables, one per target:
<#71768#>;; <#68404#><#46270#>target1,<#46270#> <#46271#>target2<#46271#> <#46272#>:<#46272#> <#46273#>color<#46273#><#68404#><#71768#>
<#46274#>;; the variables represent the two colors that the first player chooses<#46274#>
<#46275#>(define<#46275#> <#46276#>target1<#46276#> <#46277#>(first<#46277#> <#46278#>COLORS))<#46278#>
<#46279#>(define<#46279#> <#46280#>target2<#46280#> <#46281#>(first<#46281#> <#46282#>COLORS))<#46282#>
Both variables are set to the first item from <#68405#><#46286#>COLORS<#46286#><#68405#>, just so that
they stand for some color.
The second step is to develop an initializer for the two state variables. A
single initializer is enough because the two variables go together. Indeed,
the initializer is the desired <#68406#><#46287#>master<#46287#><#68406#> function:
<#71769#>;; <#68407#><#46292#>master<#46292#> <#46293#>:<#46293#> <#46294#><#46294#><#46295#>-;SPMgt;<#46295#><#46296#><#46296#> <#46297#>void<#46297#><#68407#><#71769#>
<#71770#>;; effect: set <#68408#><#46298#>target1<#46298#><#68408#> and <#68409#><#46299#>target2<#46299#><#68409#> to randomly chosen items in <#68410#><#46300#>COLORS<#46300#><#68410#><#71770#>
<#46301#>(d<#46301#><#46302#>efine<#46302#> <#46303#>(master)<#46303#>
<#46304#>(b<#46304#><#46305#>egin<#46305#>
<#46306#>(set!<#46306#> <#46307#>target1<#46307#> <#46308#>(list-ref<#46308#> <#46309#>COLORS<#46309#> <#46310#>(random<#46310#> <#46311#>COL#<#46311#><#46312#>)))<#46312#>
<#46313#>(set!<#46313#> <#46314#>target2<#46314#> <#46315#>(list-ref<#46315#> <#46316#>COLORS<#46316#> <#46317#>(random<#46317#> <#46318#>COL#<#46318#><#46319#>)))))<#46319#>
The effect comment explains how <#68411#><#46323#>master<#46323#><#68411#> changes the two state
variables by picking an item from <#68412#><#46324#>COLORS<#46324#><#68412#> based on a random number
between 0 and the length of <#68413#><#46325#>COLORS<#46325#><#68413#>.
Finally, we can turn to the functions that modify and utilize the program's
memory. As it turns out, the memory isn't modified after the two target
variables are initialized; it is only used to compare to the two guesses of
the player. The only other service we need is <#68414#><#46326#>master-check<#46326#><#68414#>. It
uses <#68415#><#46327#>check-guess<#46327#><#68415#>, the solution of exercise~#excheckguess#46328>,
to conduct the comparison. For a summary, see figure~#figmaster2#46329>,
which contains the variable and function definitions that we just
discussed.
<#71771#>;; <#68416#><#46334#>target1,<#46334#> <#46335#>target2<#46335#> <#46336#>:<#46336#> <#46337#>color<#46337#> <#68416#><#71771#>
<#46338#>;; the two variables represent the two colors that the first player chose<#46338#>
<#46339#>(define<#46339#> <#46340#>target1<#46340#> <#46341#>(first<#46341#> <#46342#>COLORS))<#46342#>
<#46343#>(define<#46343#> <#46344#>target2<#46344#> <#46345#>(first<#46345#> <#46346#>COLORS))<#46346#>
<#71772#>;; <#68417#><#46347#>master<#46347#> <#46348#>:<#46348#> <#46349#><#46349#><#46350#>-;SPMgt;<#46350#><#46351#><#46351#> <#46352#>void<#46352#><#68417#><#71772#>
<#71773#>;; effect: set <#68418#><#46353#>target1<#46353#><#68418#> and <#68419#><#46354#>target2<#46354#><#68419#> to two randomly chosen items from <#68420#><#46355#>COLORS<#46355#><#68420#><#71773#>
<#46356#>(d<#46356#><#46357#>efine<#46357#> <#46358#>(master)<#46358#>
<#46359#>(b<#46359#><#46360#>egin<#46360#>
<#46361#>(set!<#46361#> <#46362#>target1<#46362#> <#46363#>(list-ref<#46363#> <#46364#>COLORS<#46364#> <#46365#>(random<#46365#> <#46366#>COL#<#46366#><#46367#>)))<#46367#>
<#46368#>(set!<#46368#> <#46369#>target2<#46369#> <#46370#>(list-ref<#46370#> <#46371#>COLORS<#46371#> <#46372#>(random<#46372#> <#46373#>COL#<#46373#><#46374#>)))))<#46374#>
<#71774#>;; <#68421#><#46375#>master-check<#46375#> <#46376#>:<#46376#> <#46377#>color<#46377#> <#46378#>color<#46378#> <#46379#><#46379#><#46380#>-;SPMgt;<#46380#><#46381#><#46381#> <#46382#>symbol<#46382#><#68421#><#71774#>
<#46383#>;; to determine how many colors at how many positions are guessed correctly<#46383#>
<#71775#>;; The function defers to <#68422#><#46384#>check-guess<#46384#><#68422#>, the solution of exercise~#excheckguess#46385>.<#71775#>
<#46386#>(d<#46386#><#46387#>efine<#46387#> <#46388#>(master-check<#46388#> <#46389#>guess1<#46389#> <#46390#>guess2)<#46390#>
<#46391#>(check-guess<#46391#> <#46392#>guess1<#46392#> <#46393#>guess2<#46393#> <#46394#>target1<#46394#> <#46395#>target2))<#46395#>
<#46399#>Figure: Guessing colors (Part 2)<#46399#>
<#46403#>Exercise 37.1.1<#46403#>
Draw a diagram that shows how <#68423#><#46405#>master<#46405#><#68423#> and <#68424#><#46406#>master-check<#46406#><#68424#>
interact with memory.~ Solution<#68425#><#68425#>
<#46412#>Exercise 37.1.2<#46412#>
Abstract the repeated expressions in <#68426#><#46414#>master<#46414#><#68426#> into the function
<#68427#><#46415#>random-pick<#46415#><#68427#>. It consumes a list and chooses a random item from
that list. Then use the function to eliminate the repeated expressions in
<#68428#><#46416#>master<#46416#><#68428#>.~ Solution<#68429#><#68429#>
<#46422#>Exercise 37.1.3<#46422#>
Modify the color guessing program so that its final answer isn't just
<#68430#><#46424#>'<#46424#><#46425#>perfect!<#46425#><#68430#> but a list of two items: the symbol <#68431#><#46426#>perfect!<#46426#><#68431#>
and the number of guesses that the second player made. Start by modifying
the diagram of exercise~#exmasterdiagram#46427>.~ Solution<#68432#><#68432#>
<#46433#>Exercise 37.1.4<#46433#>
Modify the color guessing program so that it automatically re-starts the
game when a player has guessed the correct target colors.~ Solution<#68433#><#68433#>
<#46440#>Exercise 37.1.5<#46440#>
Develop a graphical user interface, similar to that of the teachpack
<#46442#>master.ss<#46442#>. Instead of colored buttons, use buttons labeled with the
color. Show the current selection in message fields.~ Solution<#68434#><#68434#>