Computer Algebra With Mathematica
UMass Lowell / CyberEd /  Fall 1998
Final Project  Dec 27,  1998
Jill Garland   Good Doggie Software   GoodDoggie@pobox.com

Intro

This is Math-terMind, a Mathematica version of the game WebMind, which is a web version of the classic "code guessing" game, MasterMind.    WebMind can be found at: http://www.math.niu.edu/~rusin/uses-math/games/mastermind/
and in particlar http://einstein.et.tudelft.nl/~mvdlaan/WebMind/WM_intro.html.

Jump to the Game

Game Instructions

This is a Mathamatica version (based on the WebMind, the Web version ) of the old 
MasterMind game, where the objective is to find right combination of colors. 

Description

The game contains a grid of Color Selection buttons,  n rows by  m columns 
(positions),  each row a different color.   

Below this grid is a single row of m buttons which are initially blank,
called the guess buttons.

For each position in the game, the player guesses a color by clicking on the 
Color Selection button in the grid above.  The guessed color is reflected in
 the corresponding guess button below.

After guessing the color of each  position in the guess row, the player
submits the entire set for evaluation using the "Submit Guess" button.

The computer will respond by displaying the guesses, and next
to them the results which show which positions were exact matches, 
plus some hints about the unmatched positions which the player can review
to help improve the next guess.

The player continues the guess/submit/review cycle unitl  all positions are matched.

Output/Results:  

The results given are for each position:

●  For an exact match (you guessed the right color and right position).
	⟹ a solid color button the same color as the guess.
      			
●  For partial or no match,  hints  are given as follows:

     	◆  for partial match  (color you guessed exists in the solution but not 
     	in the position you guessed),
      	⟹ a gray button with a circle the color of your guess at that position,
      		
    	◆ for no match (color you guessed at that position doesn't exist 
      	     anywhere in the solution),
      	⟹ a solid gray button.
      		
For the basic level of play, the hints are shown in the correct postions. This version 	 
has only a basic level of play.

Solution   
A game solution is randomly generated based on the number of colors and number of 
positions.   The solution consists of a random selection, not a permutation. Therefore
 the solution for any given game may 
   a) drop colors (fail to include all available colors) 
   b) repeat colors (use the same color in more than one position)

Options    
The game options are
	n,  the number of colors:  from 3 to 8
	m, the number of positions:  from 3 to 8
	Level of Play:  basic (only)

                                              Jump to Game

Programming Notes

Programming Notes  

Debugging

Two global variables, Icheat, and Idebug, are available for debugging and are 
normally set to zero.  Create a new input cell to assign a different value to either 
of these.   For normal operation, reset the value to zero:

◆  Icheat
	Setting  Icheat=1 will cause a graphic of the game solution to be displayed 
	at the start of each new game.  These graphics must be deleted manually.
	
◆  Idebug
	Idebug will cause details of the "guess processing"  to be printed as
	each guess is processed.  Setting Idebug=1  generates one message
	at the end of the processing.  Setting Idebug>1  generates several
	messages before, during, and after the processing.   These  messages 
	must be deleted manually.  


Known Bugs  (or, as Microsoft calls it, the "Knowledge Base" )

●  At the start of each new game, the program searches for output from the 
previous game and deletes it.  This includes result cells, guess
buttons, and color selector buttons.   If it can't find these output cells from 
a previous game, Mathematica  may display an error message, ("Mathematica 
did not understand...."), which can safely be ignored.

●  Initialization takes a long time.

●  The screen flashes and jumps when new buttons are drawn.  

●  The window may need to be resized when larger # postions  is used 
(e.g., 7 or 8), otherwise the buttons in the resullt cell may wrap to the next line.

Play The Game

1.      Evaluate Initialization Cells   (first time only) .                                                           READY

2.   Choose game options using the buttons below

# Positions                                                  # Colors                    3 4 5 6 7 8                   3 4 5 6 7 8

5                                                                         6

3.     ({{  New Game }})

6.   Review your Guesses and Hints

4.     Make a guess:   Select a color from each column

5.   ({{  Submit Guess }})                                                     Help

The Code

Notebook object and color definitions,  game Color Generator, etc

DoNothing[x_] := xx = x;

NB = InputNotebook[];

\(ShowStatus[stat_String, \ fcolor_] := 
      Module[{oldcell, newcell, a}, 
		
        NotebookFind[NB, "DoInit", All, CellTags, 
          AutoScroll -> False]; 
		
        SelectionMove[NB, All, CellContents, AutoScroll -> False]; \ 

        		oldcell = NotebookRead[NB]; 
		
        newcell = 
          oldcell /. {
              TagBox[a___, "status"] -> 
                TagBox[StyleBox[ToString[stat], 
                    \((FontColor)\) -> \((fcolor)\)], "status"]}; 

        		NotebookWrite[NB, newcell]; 
]\)

ShowStatus["Please wait.",  RGBColor[1., 0.85, 0.]];

Off[General::"spell1"]

\(AvailableColorNames
       = {"Redish", "Bluish", "Greenish", "Yellowish", 
        "Orangeish", "Fuscia", "Purplish", "Aqua"}; 

    AvailableColors = 
      \({Redish, Bluish, Greenish, Yellowish, Orangeish, Fuscia, Purplish, 
          Aqua} = {RGBColor[1., 0., 0.], RGBColor[0., 0., 1.], 
          RGBColor[0., 1., 0.], RGBColor[1., 1., 0.], RGBColor[1., 0.75, 0.], 
          RGBColor[1., 0.412, 0.706], RGBColor[0.75, 0.35, 0.83], 
          RGBColor[0.2, 0.89, 0.89]}\); \)

\(Icheat = \(Idebug = 0\); 
offwhite = RGBColor[.996, .98, .95]; 

    igame = 0; \)

\(SolutionGraphic[ColorList_List] := 
      Module[{is, lcl = Length[ColorList]}, 
		
        Show[Graphics[{Thickness[0.001], 
              Table[{ColorList[[is]], 
                  Rectangle[{.1\ \((is - 1)\), 0}, {.1\ is, .1}], 
                  GrayLevel[0], 
                  Line[{{.1\ \((is - 1)\), 0}, {.1\ \((is - 1)\), .1}}]}, {
                  is, 1, lcl}], Line[{{0, 0}, {.1\ lcl, 0}}], 
              Line[{{0, .1}, {.1\ lcl, .1}}], 
              Line[{{.1\ lcl, 0}, {.1\ lcl, .1}}]}, 
            AspectRatio -> Automatic, Axes -> False, 
            PlotRange -> All]]]\)

?SolutionGraphic

GenGameColors[nGS_, nGC_, DoPlot_:  0] := 
      (GC = Table[
            AvailableColorNames
              [[Random[Integer, {1, nGC}]
                ]], {nGS}]; 
        If[DoPlot == 1, SolutionGraphic[ToExpression[GC]]; GC, GC]; )

?GenGameColors

Functions for refreshing the Guess Buttons

\(TBox[pos_] := 
      \((\ Module[	

          			{bnote = "slot"<>ToString[pos], 
            btag = "G"<>ToString[pos]}, 
\ 
          TagBox[ButtonBox[" ", \((Background)\) -> \((offwhite)\), 
              \((ButtonNote)\) -> \((bnote)\)], \((btag)\)]])\)\)

?TBox

\(RegenGuessButtons[nnGS_] := 
      \((Module[

          			{i, \ rdatg = RowBox[\ Table[\ TBox[i], {i, 1, nnGS}]\ ]}, 
          		
			
          Cell[BoxData[
              StyleBox[\ rdatg, 
                ButtonBoxOptions -> {Active -> False, ButtonStyle -> None}]], 
            "Input", \ \ 
				
            CellFrame -> {{0, \ 0}, \ {0.25, \ 0}}, 
				
            CellMargins -> {{20, \ 0}, \ {0, \ 0}}, 
				
            CellBracketOptions -> {"Color" -> RGBColor[0, \ 0, \ 0.1]}, 

            				Evaluatable -> False, 
				GeneratedCell -> True, 

            				ShowCellLabel -> False, 
				
            CellFrameMargins -> {{0, \ 0}, \ {1, \ 0}}, 
				
            CellFrameColor -> GrayLevel[0], 
				
            TextAlignment -> Center, 
				LineSpacing -> {0.5, 0}, 

            				FontFamily -> "Courier", 
				FontSize -> 9, 

            				FontWeight -> "Plain", 
				
            Background -> GrayLevel[0.45], 
				Magnification -> 1, 

            				ButtonBoxOptions -> {ButtonMargins -> 7}, 
            CellTags -> "guess"]
		])\)\)

?RegenGuessButtons

WriteGuessButtons[numGS_]:=(
		NotebookFind[NB, "guess", All, CellTags, 
              AutoScroll -> False];
	  NotebookDelete[NB];  
		NotebookFind[NB, "GameControls", All, CellTags, 
                AutoScroll -> False];
SelectionMove[NB, Before, Cell, AutoScroll -> False];
		NotebookWrite[NB,RegenGuessButtons[numGS],AutoScroll -> False];
		NotebookFind[NB, "Review", All, CellTags, 
              AutoScroll -> False];SelectionMove[NB, After, Cell, AutoScroll -> False]; 
			)

?WriteGuessButtons

\(RefreshGuessButtons[numGS_] := 
      \((\ Module[{bnote, \ btag, \ i}, 
	
          For[\ i = 1, \ i <= numGS, \ \(i++\), 
	\ 
            btnote = "slot"<>ToString[i]; \ 
	\ 
            bttag = "G"<>ToString[i]; 
	\ 
            SetGuess[offwhite, btnote, bttag]]
])\)\)

?RefreshGuessButtons

Funtions for processing the player's guesses

\(MakeOutputCell[celldata_] := 
	
      \((Cell[BoxData[RowBox[celldata]], "Input", 
		
          Editable -> True, 
		CellFrame -> False, 
		
          CellMargins -> {{20, 0}, {0, 0}}, 
\ 	\ 
          CellBracketOptions
             -> {"Color" -> RGBColor[0, \ 0, \ 0.100008]}, 
		
          Evaluatable -> False, 
		GeneratedCell -> False, 
		
          CellAutoOverwrite -> False, 
		ShowCellLabel -> False, 
          
		CellLabelMargins -> {{0, 0}, {0, 0}}, 
		
          CellFrameMargins -> False, 
		
          CellFrameLabelMargins -> False, 
		TextAlignment -> Center, 
          
		LineSpacing -> {0.5, 0}, 
		
          FontFamily -> "Arial", 
		FontSize -> 9, 
          FontWeight -> "Bold", 
		
          FontColor -> GrayLevel[1], 
		
          Background -> GrayLevel[0.45], 
		
          Magnification -> 1.0, CellTags -> "ResultCell"])\)\)

?MakeOutputCell

OutputResults[cdat_]:=( 
		NotebookFind[NB,"Selections",Next,CellTags,AutoScroll -> False];
		SelectionMove[NB,Before,Cell,AutoScroll -> False];
		NotebookWrite[NB,MakeOutputCell[cdat],AutoScroll -> False];)

?OutputResults

BBox[fcolor_, bgcolor_] := 
      ButtonBox[
        StyleBox["●", FontSize -> 16, 
          FontWeight -> "Bold", FontColor -> fcolor], 
        ButtonMargins -> 5, Background -> bgcolor, 
        ButtonStyle -> None, Active -> False];

?BBox

\(HintColrs[s_String] := 
      Module[{fc, bgc}, 
		
        If[StringMatchQ[s, "X*"], fc = ToExpression[StringDrop[s, 1]]; 
          bgc = GrayLevel[0.8], 
          If[StringMatchQ[s, "Wrong"], fc = \(bgc = GrayLevel[0.8]\), 
            fc = \(bgc = ToExpression[s]\)]]; {fc, bgc}]\)

?HintColrs

\(GenHints[ig_] := 
      Module[{guesses2E}, guesses2E = ToExpression[guesses]; 
        GuessButtns = MapThread[BBox[#1, #2]&, {guesses2E, guesses2E}]; 
        HintText = 
          "⟵ Guess  ("<>ToString[ig]<>
            ")  Hint ⟶ "; \ \ \ 
		
        HintButtns = 
          MapThread[BBox[#1, #2]&, Transpose[\((HintColrs[#1]&)\)/@Hints]]; 
        OutputResults[Join[GuessButtns, {HintText}, HintButtns]]; ]\)

?GenHints

GenWinnerMessage[] := 
      Module[{celdat2}, 
        celdat2 = {
            StyleBox["Congratulations, ", 
              FontColor -> RGBColor[1, .95, .01], FontSize -> 14, 
              FontFamily -> "Arial"], 
            StyleBox[ToString[$UserName], 
              FontColor ->  RGBColor[0, 1, .34], FontSize -> 14, 
              FontFamily -> "Arial"], 
            StyleBox[", you win!!          ", 
              FontColor -> RGBColor[1, .95, .01], FontSize -> 14, 
              FontFamily -> "Arial"]}; OutputResults[celdat2]; ]

?GenWinnerMessage

Printdebug[igu_, Act_, Gu_, Hi_, nM_] := 
      Print[" iguess=", igu, "\nActual= ", Act, "\nGuess= ", Gu, 
        "\nHints= ", Hi, "\nnMatched=", nM];

GetGuesses[nGSlot_]:=Module[{celldat, rowdat, i},ClearAll[guesses];NotebookFind[NB, "guess", All, CellTags, 
              AutoScroll -> False]; 
		SelectionMove[NB,All,CellContents,AutoScroll -> False];  
		celldat = NotebookRead[NB]; 
		rowdat = 
              celldat /. {
                  BoxData[StyleBox[RowBox[{a___, b_, c___}], d_]] 
                    -> {a, b, c}};NotebookFind[NB, "GameControls", All, CellTags, 
              AutoScroll -> False];SelectionMove[NB,After,Cell,AutoScroll -> False]; guesses = 
              Table[rowdat
                   /. {a___, 
                      TagBox[ButtonBox[b___, 
                          ButtonNote -> "slot"<>ToString[i]], y_], 
                      c___} -> y, {i, 1, nGSlot}];guesses]

?GetGuesses

\(ProcessGuess[nGS_] := 
      Module[{i, p, guessi, Actual, Guess, celdat, nMatched}, \ 
		
        \(iguess++\); 
		Guess = GetGuesses[nGS]; 
		Actual = GC; 
		
        Hints = Table["Wrong", {nGS}]; 
		nMatched = 0; \ 
		
		
        If[Idebug > 1, Printdebug[iguess, Actual, Guess, Hints, nMatched]]; 

        		
		
        For[i = 1, i ≤ nGS, \(i++\), 
          guessi = Guess[[i]]; 
			
          If[guessi == Actual[[i]], 
            Hints[[i]] = guessi; \ 
            Actual[[i]] = "Closed"; 
            Guess[[i]] = 
              ToString[guessi]<>"X"; \(nMatched++\); ]; ]; 
        If[Idebug > 1, Printdebug[iguess, Actual, Guess, Hints, nMatched]]; 

        		
		
        For[i = 1, i ≤ nGS, \(i++\), 
          guessi = Guess[[i]]; 
          If[MemberQ[Actual, guessi], 
            Hints[[i]] = 
              "X"<>ToString[guessi]; 
            p = Flatten[Position[Actual, guessi, 1, 1]]; 
				
            Actual[[p]] = "Closed"; 
            \ \ 
				
            Guess[[i]] = 
              ToString[guessi]<>"X"; ]; ]; 
		
		
        If[Idebug ≥ 1, 
          Printdebug[iguess, Actual, Guess, Hints, nMatched]]; 
		
		
        GenHints[iguess]; \ 
		
        If[nMatched == nGS, GenWinnerMessage[]; GameOver = 1, 	
          RefreshGuessButtons[nGS]]; \ 
	]\)

?ProcessGuess

Function for updating a Guess Button when Color-Selector clicked

SetGuess[newcolor_, bnote_String, cname_String]:=
	Module[{oldcell, newcell, a, b, c, d},NotebookFind[NB, "guess", All, CellTags, 
              AutoScroll -> False];
		SelectionMove[NB,All,CellContents,AutoScroll -> False];  
		oldcell = NotebookRead[NB];
		newcell = 
              oldcell /. {
                  TagBox[ButtonBox[a___, b_, ButtonNote -> bnote, c___], 
                      d_] -> 
                    TagBox[ButtonBox[a, Background -> newcolor, 
                        ButtonNote -> bnote, c], cname]};NotebookWrite[NB, newcell];]

?SetGuess

Functions for generating Color-Selector Buttons

\(CBBox[pos_, col_, colnam_] := 
      \((
ButtonBox[" ", 
          ButtonFunction :> 
            SetGuess[col, \(("slot"<>ToString[pos])\), colnam]]\ )\)\)

?BBox

\(SetColorCell[colr_, colrname_String, nS_] := 
      Module[
		{i, \ 
          rdat = RowBox[\ Table[CBBox[i, colr, colrname], {i, 1, nS}]\ ]}, 

        		Cell[
          BoxData[StyleBox[rdat, 
              ButtonBoxOptions 
                -> {ButtonEvaluator -> "Local", 
                  Active -> True, ButtonStyle -> None, 
                  Background -> colr, 
                  ButtonNote -> ToString[colrname]}]], "Input", 
          Editable -> False, CellFrame -> False, 
          CellMargins -> {{20, 0}, {0, 0}}, 
			\ 
          CellBracketOptions
             -> {"Color" -> RGBColor[0, \ 0, \ 0.100008]}, 
			
          Evaluatable -> False, GeneratedCell -> False, 
          CellAutoOverwrite -> True, ShowCellLabel -> False, 
          CellLabelMargins -> {{0, 0}, {0, 0}}, 
          CellFrameMargins -> False, 
          CellFrameLabelMargins -> False, \ TextAlignment -> Center, 
          LineSpacing -> {0.5, 0}, FontFamily -> "Courier", 
          FontSize -> 9, FontWeight -> "Plain", 
          Background -> GrayLevel[0], Magnification -> 1., 
          ButtonBoxOptions -> {ButtonMargins -> 7}, 
          CellTags -> "AColorCell"]]\)

?SetColorCell

CreateGameButtons[nS_, nC_]:=(
    NotebookFind[NB, "Selections", After, CellTags, 
            AutoScroll -> False]; 
		NotebookFind[NB, "AColorCell", All, CellTags, 
            AutoScroll -> False];  
		NotebookWrite[NB,SetColorCell[Greenish, "Greenish", nS],AutoScroll -> False]; 
		If[nC ≥ 8,NotebookWrite[NB,SetColorCell[Aqua, "Aqua", nS],AutoScroll -> False]];  NotebookWrite[NB,SetColorCell[Bluish, "Bluish", nS],AutoScroll -> False];  
		If[nC ≥ 7,NotebookWrite[NB,SetColorCell[Purplish, "Purplish", nS],AutoScroll -> False]];If[nC ≥ 6,NotebookWrite[NB,SetColorCell[Fuscia, "Fuscia", nS],AutoScroll -> False]];NotebookWrite[NB, SetColorCell[Redish, "Redish", nS]];
		If[nC ≥ 5,NotebookWrite[NB,SetColorCell[Orangeish, "Orangeish", nS],AutoScroll -> False]];If[nC ≥ 4,NotebookWrite[NB,SetColorCell[Yellowish, "Yellowish", nS],AutoScroll -> False]];	
		WriteGuessButtons[nS]; 
)

?CreateGameButtons

Function for initializing a new game

\(NewGame[ns_:  6, nc_:  8, \ cheat_:  0] := 
      \((
		numslots = Min[ns, \ 8]; 
		numcolors = Min[nc, 8]; 
		
        iguess = 0; 
		\(igame++\); 
		
        If[igame == 1, ShowStatus["READY", \ GrayLevel[0]]]; 
		
        NotebookFind[NB, "ResultCell", All, CellTags, 
          AutoScroll -> False]; 
		NotebookDelete[NB]; 
		
        CreateGameButtons[numslots, numcolors]; 
		
        NewColors = GenGameColors[numslots, numcolors, cheat]; )\)\)

?NewGame

ButtonFunctions for updating the Game Options cell

\(\(SetNS[x_] := 
      Module[{oldcell, newcell, a}, 
		NS = x; 
		
        NotebookFind[NB, "GameOptions", All, CellTags, 
          AutoScroll -> False]; 
		
        SelectionMove[NB, All, CellContents, AutoScroll -> False]; 
		
        oldcell = NotebookRead[NB]; 
		
        newcell = 
          oldcell /. {
              TagBox[a___, "NSTag2"] -> 
                TagBox[
\ \ \ \ \ \ \ \ \ \ \ \ 
                  StyleBox[\ 
                    FrameBox[\ 
                      StyleBox[ToString[x], \ FontSlant -> "Italic", \ 
                        FontColor -> RGBColor[0, \ 0, \ .1]]], 

                    \ \ \ \ \ \ \ \ \ \ \ \ \ \ 
                    FrameBoxOptions
                       -> {BoxMargins -> {{0.6, \ 0.5}, \ {0.7, \ 0.5}}}], 

                  \ \ \ \ \ \ \ \ \ \ \ \ "NSTag2"]}; 
		
        NotebookWrite[NB, newcell]]; \)\)

\(SetNC[y_] := 
      Module[{oldcell, newcell, a}, 
		NC = y; 
		
        NotebookFind[NB, "GameOptions", All, CellTags, 
          AutoScroll -> False]; 
		
        SelectionMove[NB, All, CellContents, AutoScroll -> False]; 
		
        oldcell = NotebookRead[NB]; 
		
        newcell = 
          oldcell /. {
              TagBox[a___, "NCTag2"] -> 
                TagBox[
\ \ \ \ \ \ \ \ \ \ \ \ 
                  StyleBox[\ 
                    FrameBox[\ 
                      StyleBox[ToString[y], \ FontSlant -> "Italic", \ 
                        FontColor -> RGBColor[0, \ 0, \ .1]]], 

                    \ \ \ \ \ \ \ \ \ \ \ \ \ \ 
                    FrameBoxOptions
                       -> {BoxMargins -> {{0.6, \ 0.5}, \ {0.7, \ 0.5}}}], 

                  \ \ \ \ \ \ \ \ \ \ \ \ "NCTag2"]}; 
		
        NotebookWrite[NB, newcell, AutoScroll -> False]; ]\)

End-of-Initialization Code (Set-up after all other initialization)

Create dummy 'previous output' cells so NotebookDelete doesn't fail.

\(NotebookFind[NB, "Review", All, CellTags, 
      AutoScroll -> False]; 

    SelectionMove[NB, After, Cell, AutoScroll -> False]; 
    NotebookWrite[NB, 
      \((Cell[TextData["DummyResultCell"], \ "Text", 
\ \ 
          CellBracketOptions -> {"Color" -> GrayLevel[0.1]}, \ 
          Background -> GrayLevel[.1], 
\ \ CellTags -> "ResultCell"])
        \), \ AutoScroll -> False]; 


    NotebookFind[NB, "GameControls", All, CellTags, 
      AutoScroll -> False]; 

    SelectionMove[NB, Before, Cell, AutoScroll -> False]; 

    NotebookWrite[NB, 
      \((Cell[TextData["DummyColorCell"], \ "Text", 
\ \ 
          CellBracketOptions -> {"Color" -> GrayLevel[0.1]}, \ 
          Background -> GrayLevel[.1], 
\ \ CellTags -> "AColorCell"])
        \), \ AutoScroll -> False]; 

    NotebookWrite[NB, 
      \((Cell[TextData["DummyguessCell"], \ "Text", 
\ \ 
          CellBracketOptions -> {"Color" -> GrayLevel[0.1]}, \ 
          Background -> GrayLevel[.1], 
\ \ CellTags -> "guess"])\), \ 
      AutoScroll -> False]; \)

\(SetNS["?"]; 
SetNC["?"]; \)

ShowStatus["READY",  Greenish];

Function usage/descriptions

BBox::usage="Generates the ButtonBox spec for a single hint or result button, given the font color and background color.  Called by GenHints";

CreateGameButtons::usage="Outputs a new set of color selector cells at the start of each game.  Called by NewGame";

GenHints::usage="Generates the hints/results output after a submitted guess has been evaluated. Called by ProcessGuess.  It's only arg is the guess number, which it prints in the output cell.  The remaining parameters (Hints, Level or Play, number of colors, number of slots, etc) are global. It also (in future) will scramble the order of the hints for higher levels of play. ";

GenWinnerMessage::usage="Generates the cell data for a 'congratulations' message for when the player wins a game.  Called by ProcessGuess.";

GetGuesses::usage="Called by ProcessGuess. Reads the cell containing the row of guesses and assigns this list of guessed colors to the global variable, 'guesses'.";

GenGameColors::usage="Generates a random solution color set for the game, of nGC (# of colors) arranged in nGS (# of positions).  This is not a permutation but a random selection from a set of nGC colors. Therefore it's possible for a color to be used in more than one position, or not to be used at all.";

SetNC::usage="Button function used in Game Option selector cell to update the #Colors box with the number selected.";

SetNS::usage="Button function used in Game Option selector cell to update the #Positions box with the number selected.";

SolutionGraphic::usage="Generates and displays a graphic
of the game solution, for debugging purposes";

RegenGuessButtons::usage="Generates the cell specification for a fresh (blank) set of guess buttons.  Called by WriteGuessButtons.";

Scramble::usage="Generic function which, given a list, returns a randmom permutation of the list";

MakeOutputCell::usage="Generic function for creating this game's output cells, given the RowBox data.  This is used for hints and results output, and for the winner's 'congratulations' message.  Called by OutputResults";

NewGame::usage="Function invoked when user clicks on 'New Game' button. Launches a new game.";

OutputResults::usage="Generic function printing this game's output cells, given the Cell specification.  This is used for hints and results output, and for the winner's 'congratulations' message.  Called by GenHints and GenWinnerMessage.";

TBox::usage="Generates the spec for a TagBox wrapped around a ButtonBox, for the given postion. The tag string is formed by appending the given 
position to the letter 'G' (for 'guess').  Called by RegenGuessButtons.";

HintColrs::usage="Calculate the font and background colors for a hint/result button, based on the 'modified' color name, s.  Called by GenHints.  The 'modified' color name is generated by ProcessGuess function and indicates the type of hint to produce:  For a full match, the modified color name for that postion = the real color name.  For a partial match, an 'X' is prepended to the real color name for that position.  For a completely wrong guess, the modified color name = 'Wrong' for that position.";

ProcessGuess::usage="The main loop for evaluating and processing each guess, given the number of positions in the game. Invoked when player clicks 'Submit Guess' button.  For each position, it determines whether the guessed color is a complete match, a partial match, or a 'no match'.  If all are a complete match, the game is won and a 'congratulations' message is printed ";

RefreshGuessButtons::usage="Refreshes (clears) an existing set of guess buttons.  Called by ProcessGuess.";

SetGuess::usage="Function invoked when user clicks on a color selector button to guess the color of a single position.  It changes the corresponding button in the guess row to the selected color.";

SetColorCell::usage="Generates a cell containing a single row of nS 'Color Selector' buttons (where nS = #positions) for the given color.  CreateGameButtons calls this function once for each color in the game.";

ShowStatus::usage="Displays status message during/after initialization process.";

WriteGuessButtons::usage="Writes a new set of guess buttons.  Called by NewGame.  Calls RegenGuessButtons.";

On[General::"spell1"]