© The Author(s), under exclusive license to APress Media, LLC, part of Springer Nature 2022
J. MeyerProgramming 101https://doi.org/10.1007/978-1-4842-8194-9_9

9. Word Guessing Game

Jeanine Meyer1  
(1)
Mt Kisco, NY, USA
 

Abstract

The focus for this chapter is a game of guessing a word one letter at a time. It resembles several such games. The computer program will take the role of the player that chooses the secret word. The number of guesses, or, as this version counts, the number of letters that are not in the secret word, can be fixed ahead of time and is hard-coded in my sketches. You can think of this as the number of allowed wrong moves. An alternative approach is to have the player propose the number of guesses, wrong guesses, or have a time limit. My programs demonstrate the allowed number of remaining using a circle that goes from green to red. This provides an excuse to explain two specific Processing features.

More on the Sketches

Typical practices in guessing letters are to either write out the letters guessed or write out the whole alphabet and cross out each letter as it is guessed. I decided to create two implementations to demonstrate different programming features. The first one, shown in Figure 9-1, represents an implementation of the game in which the player tries letters using the letters on the keyboard. Keeping track of letters guessed is left to the player. The figure shows that the player can make six more incorrect tries before losing the game. That is, when the display shows 0, the player can try one more letter. However, if that letter fails—is not in the secret wordthe player loses.

The image of a box with the number 6 written on it. There is a dashed line above the box. The text above the line reads Press a letter key to try that letter.

Figure 9-1

Window with secret word, using keyboard

In the second implementation, I supply buttons for each letter and remove the button once it has been used. To be fully accurate, my code covers up the button so it is not visible and sets a Boolean variable to indicate that this button has been removed.

Figure 9-2 shows the window of the implementation using buttons for each letter. Notice that the g button is missing and that is the button that I pressed. This implementation does not let the player make the mistake of trying a letter not in the secret word a second time, so this implementation changes the game. The existence of these two implementations gives you a chance to think about what is the same and what is different between the two implementations in terms of the user interface.

The image shows a box with the number 6 written on it. There is a dashed line above the box. The text above the line reads Press a letter key to try that letter. There are ovals below, each with the English alphabet written on them in order. The Oval for alphabet g is missing.

Figure 9-2

Window with letter keys

The implementation using Buttons uses the Button class that you saw in a previous chapter, with one modification. This demonstrates reusing code and is very, very common.

The secret words are chosen at random from a list contained in a CSV (comma-separated value) file in the data folder. My word list has only five words. They are carefully chosen to include words that check aspects of the programming and help me play the game while I am testing the program. It often makes sense to do the initial development with a smaller list. The word list can be replaced simply by changing the file in the data folder; no change is required in the code. This is called scaling up. Not all scaling up operations are that simple.

Programming Concepts

This section suggests things to think about when implementing familiar applications and issues in testing. I mention briefly the handling of strings of characters and producing a circle filled in with changing colors.

Implementing an Existing Application

Designing a known paper-and-pencil game can be more challenging than you might expect. Similarly, it can be challenging to build a new implementation of something that already exists in a computerized form. When you automate a manual task, or build a new version of something already computerized, you need to evaluate and, perhaps, trade off using the new capabilities vs. supplying your audience with what they expect. In Chapter 8, I provided a brief overview of an example for directions for an origami model making use of line drawings, images, and video. In this chapter, you will read about two implementations of a basic word guessing game. The fact that I came up with two implementations that produce games that are slightly different is not uncommon. It would be useful to perform testing to see how people, including young children and parents, react.

Testing and Scaling Up

Building a computer application involves testing! For games and related activities, you do not want to struggle with playing the game while building the game. My implementation of each implementation made use of a word list supplied as a file in the data folder. I did not need to wait to put together a final list while testing the logic of either sketch. Instead, I made a list of just five words. The number 5 does not appear in my code. Instead, my code reads in the Table and constructs an array of String objects. Besides being words that I like, the words I used are of different lengths so I know immediately or after guessing one letter what the word is without modifying the code that makes a random choice. Some of the words have letters that appear more than once, so I could verify that my code does the correct thing. I can be confident that my sketches will work with the longer lists.

Testing might not be so easy; code might need to be modified. For example, in more complex applications, I might want to replace a random choice to test specific logical paths through the code. This is something to think about on a case-by-case basis. Bigger and more complex systems, especially systems that change frequently, could require the development of a testing suite or an automated system for testing, not requiring human interaction.

I did not include a final word list in the code available with the source code, but I can tell you my approach. I searched and found online lists that were supplied for spelling bees for different grades. It was easy to download and convert such a list to a CSV file. For each case, you might need to think about what is an appropriate source for the data. It probably is not a list of your favorite words. You also should consider the alternative of going to the Web for a new list each time you run the program. For this game, the list of words does not have to be complete in any sense. However, for a game in which the player gets to pick, the list should be large.

For the Word Game sketches, my code extracts the words and prepares a String array. The code does a lot of work at the start, when users generally are relatively patient as opposed to taking a small amount of time for each game. If what you determine to be the appropriate data source is very large, this might not be the proper decision.

Most, if not all, programming languages provide functions for examining and manipulating strings of characters. You do need to check on what is available. You also need to be careful about strings of characters vs. single characters.

Displaying the State of the Game

The reader may have guessed, or knew from the game has it appeared in the first edition, that my original word game showed the state of the game by a sequence of pictures. My approach for this edition was motivated by my wish to show off certain features of Processing. I decided to go from green light to red light (without going to yellow in-between. I leave that to the reader). My implementation made use of the map and lerpColor functions.

The map function is used with any two ranges of numbers plus a number representing something in the first range. The function returns the corresponding number in the second range. Suppose you are a teacher and gave a quiz of 30 problems, with 1 point apiece. Suppose the number of problems correct was held in the variable score. You could use
   grade = map (score,0,30,0,100);

to get a grade out of 100.

The lerpColor function (LERP stands for linearly interpolate) uses two colors and a number (float) and calculates an integer that can be interpreted as a color between the two colors. The code
  float inter = map(wrongs,0,maxTries,0,1);
  color c = lerpColor(greenC, redC, inter);
  fill(c);

is used to set the fill value for a circle to be displayed. The variables greenC and redC have been set to be green and red. The variable wrongs holds the number of wrong guesses at letters in the secret word, and the variable maxTries holds the number of wrong guesses allowed. The number of wrong guesses to go is shown against the specified color background. The player is allowed one more guess after the number reaches 0.

Displaying Text

Displaying text over and over on a static background can produce degraded text. One fix is to use a call to background, and this often is required. An alternative approach is to draw a rectangle first and put the text on top of it. The fill for the rectangle can be what would have been used in background so it does not appear. I wrote a function displayTextsBackground to be invoked when needed.

Processing Programming Features

The treatment of the word list is essentially the same as the data file kept and updated in the image test sketch described in Chapter 5. One key difference is that the file is not modified. My code brings in the file as a Table and then sets (populates) an array of String objects in the setup function. My code also sets a variable, numwords, to hold the number of words. Doing this once at the start saves a small amount of time later when making the choice. The choice of word to be the secret word is done in the keyPressed function and uses the random function.

Note

The number of elements in an array named myArray is myArray.length. The number of characters in a string named myString is myString.length(). The first length is a variable; the second is a method. To use entities in this example, the number of words in the array wordlist is wordlist.length. Because I set the variable numwords in setup, you won’t see this in the program. The number of letters in the secret word, held in the variable secret, is secret.length(). I set wlen to this value. Processing will catch errors you might make regarding length, and you will catch on. It is not something you would be expected to work out for yourself.

Examination and manipulation of the secret word are done using built-in String methods. The length method returns the length of the secret word, required to set the variable blanks to a combination of the underline (_) and the blank characters. When the player has made a guess, the method charAt is used within a for-loop that iterates through each of the characters in the secret word. In one implementation, the for-loop is in the keyPressed function; in the other, it is in the mousePressed function.

When the player guesses a letter that is in the secret word, the blanks String is changed to show the guessed letter. My function is more general than it needs to be, accepting as parameters a base String, parameter name base; a String representing that to be inserted, parameter name sub; an integer indicating the place of the insertion, parameter place; and an integer indicating the number of characters removed, parameter remove. The function makes use of the substring String method. This method provides a way to extract a piece of a string using index values. A call of substring(myString,a,b) extracts the string from position a, with 0 corresponding to the first character, up to, but not including, b. This is another programming feature that you can and will get accustomed to if you give yourself time. It also is helpful to try small examples.

Note also that the base here will be the blanks String, which has two characters for every character in the secret word. The call of replace is blanks = replace(blanks,letterpicked+" ",i*2,2);.

The function is
String replace(String base,String sub,int place,int remove){
    String prior = base.substring(0,place); //before insert
    String after = base.substring(place+remove); //after
    return prior+sub+after;
}

Notice that the replace function does not change the base but returns the new string.

Operation Overview

Both sketches start with what is termed a splash window or screen, shown in Figure 9-3. Having this extra window made it easier to program restarting with a new secret word. Of course, an improved splash window could be more interesting.

In this image there is a text that reads press any key to start.

Figure 9-3

Opening window for both implementations

You have seen what the next windows look like for the two implementations in Figure 9-1 and Figure 9-2. Figure 9-4 shows another game in process. The player has correctly guessed an m but tried three other letters, resulting in the murky color that is a specific point between green and red.

The image shows a box with the numerical zero written on it. There are two lines of text. Line one reads press a letter key to try that letter. Line 2 reads, underscore underscore i g underscore t.

Figure 9-4

Word Game with buttons after several moves

Switching to the game without buttons, the player has used the keyboard, correctly picked three letters, but picked several wrong letters, as shown in Figure 9-5.

The image shows a box with the numerical zero written on it. There are two lines of text. Line one reads press a letter key to try that letter. Line 2 reads underscore underscore I G underscore t.

Figure 9-5

Word Game, keyboard version, close, but not yet a loss

Figure 9-6 shows a winning game.

The image has a text that reads, you won! press any key for new game. It has 26 ovals below, each representing 26 English alphabets in lowercase and in order.

Figure 9-6

A win in the Word Game with buttons

Pressing any key starts a new game. I have nothing in the code that prevents the same word from being selected during a session. It is something to consider adding to the sketches. The longer the word list, though, the less likely that secret words will be repeated often.

If you have multiple windows open on your desktop and you move among the different programs, you could have the experience of pressing a key for a program such as these with no response. There are a lot of possibilities, but there is a good chance that the operating system is not sending the key event information to the program you want to use. Your program needs to have the focus, and some other program has it instead. The focus will go to a program by clicking its window. This is common when users have numerous applications open.

Implementing the Word Game Sketches

The examples for this chapter do not require me to design an application, but instead to think about how to represent the features of guess-a-word games. I decided to produce the two implementations to demonstrate that there can be multiple possibilities in such situations and to demonstrate different ways of obtaining input from a player.

Planning

It was clear to me that I should make use of a file for the word list to make it independent of the code and, therefore, easily changeable. For the Word Game sketches, my code loads the file as a Table and then extracts the words to populate a String array.

The letter Button class for this chapter is a modification of the Button classes used earlier in the text. I could have used the same Button class and defined a parallel structure to hold the removed attribute but decided that a better approach was to add to the object variables and change the isOver method. I also changed the display method because I liked my rectangular design for the single-character letter buttons better than the ovals for longer labels. Note: I did not include a check of removed in the display method because this method is only invoked when all alphabet buttons are present. This decision can be debated.

For the changing presentation of the secret word, I started off with a String variable, named blanks, that consists of underlines and blanks. Using just blanks would not work because they all run together. String methods are used both for examining the secret word, held in the variable secret, and modifying the variable blanks.

The tables showing the functions and their relationships show the main differences between the two implementations. Table 9-1 shows the functions and relationships for the Word Game using the keyboard. It is, as you should expect, simpler. The main action is in keyPressed. Actually, keyPressed is invoked for the key press that starts off the application plus the game play.
Table 9-1

Function Table for the Word Game Using the Keyboard

Function

Invoked by

Invokes

setup

Java program

 

draw

Java program

displayTextwBackground

keyPressed

Java program

advance, replace, displayTextwBackground

replace

keyPressed

 

advance

keyPressed

displayTextwBackground

displayTextwBackground

draw,keyPressed, advance

 
The functions table for the Word Game using letter buttons is shown in Table 9-2. You will see that several functions are invoked in only one place. Here, keyPressed is used for starting the application. The mousePressed function does the work during the playing of the game.
Table 9-2

Functions Table for the Word Game with Buttons

Function

Invoked by

Invokes

setup

Java program

 

draw

Java program

displayTextwBackground

keyPressed

Java program

advance, showButtons, keyPressed

mousePressed

Java program

whichLetter, replace, advance, resetAlphabetButtons,

showButtons, drawTextwBackground

replace

mousePressed

 

advance

mousePressed

resetAlphabetButtons, displayTextwBackground

setupAlphabetButtons

setup

Button

resetAlphabetButtons

mousePressed, advance

Directly changes removed

showButtons

keyPressed, mousePressed

Button.display

whichLetter

mousePressed

Button.isOver

Button

setupAlphabetButtons

 

isOver

whichLetter

 

display

showButtons

 

displayTextwBackground

draw, mousePressed,advance, keyPressed

 

Programming the Word Game Sketches

The two sketches are essentially the same, differing mainly in the treatment of the letter buttons. However, one issue did arise and was pointed out to me by the technical review. The Buttons version of the game did not allow the player to guess the same letter more than one time. The keyboard version did. My original implementation could be tricked by a sly player selecting the same correct letter over and over. The keyboard version required an extra check to determine if the player truly had guessed all the letters.

The code for the Word Game using the keyboard is shown in Table 9-3. It is long, but as I have written before, do not read it from start to finish. Use the functions table and examine individual lines of code.
Table 9-3

Word Game Using Keyboard Program

String[] wordlist;

Will hold all the words

Table words;

Table for loading in words

int numWords;

Set to be number of words

Boolean chosen = false;

Will change when secret word is selected

String secret;

Current secret word

String blanks = "";

Will hold blanks and the guessed letters

int wlen;

Length of secret word

int wrongs;

Number of wrong guesses

int nGuessed;

Number of guesses

String msg = "Press any key to start";

Starting message

color bgcolor = 200;

Background color

int msgstart = 50;

Horizontal start of messages

int maxTries = 7;

Number of wrong answers allowed. Can still win on the 8th try

color greenC = color(0,255,0);

Green color

color redC = color(255,0,0);

Red color

void setup() {

Header for setup

  size(1050,800);

Set the dimensions of window

  textSize(30);

Set text size

  words = loadTable("words.csv");

Bring in word file

  numWords = words.getRowCount();

Set the number of words

  wordlist = new String[numWords];

Create array of appropriate size

  for (int i = 0;i<numWords;i++) {

For loop to populate the array

    wordlist[i] = words.getString(i,0);

Extract word from table

  }

Close for-loop

  background(bgcolor);

Set the color of window

}

Close setup

void draw() {

Header for draw

   if (!chosen) {

If secret word is not chosen

    displayTextwBackground();

Display msg

   }

Close if

  }

Close draw

void displayTextwBackground() {

Header for displayTextwBackground

  fill(bgcolor);

Prepare to draw invisible rectangle

  noStroke();

No stroke

  rect(0,0,width, 60);

Draw rectangle to be under msg

 fill(0);

Set text color to black

 text(msg,msgstart,30);

Display text

}

Close displayTextwBackground

void keyPressed() {

Header for keyPressed

  if (!chosen) {

No word chosen

    msg =  "Press a letter key to try that letter";

Set msg

  displayTextwBackground();

Display text on top of invisible rectangle

    secret = wordlist[int(random(numWords))];

Choose random word from wordlist

    wlen = secret.length();

Set wlen with length

    chosen = true;

Set chosen Boolean

    blanks = "";

Start the preparation of blanks

    wrongs = 0;

Initialize wrongs

    nGuessed = 0;

Initialize nGuessed

    for (int i=0;i<wlen;i++) {

For loop to set blanks

      blanks = blanks + "_ ";

Two characters for each letter

    }

Close for-loop

    fill(0);

Set fill to black

    textAlign(LEFT);

Set alignment

    text(blanks,msgstart,100);

Display blanks

  }

Close if not chosen

  else  {

Else clause—secret has been set

     char letterpicked =  key;

Set letterpicked. Note: data type is char

     Boolean found = false;

The found variable starts as false

     for (int i=0;i<wlen;i++){

For loop going through secret

       if (secret.charAt(i)==letterpicked) {

If ith char is equal to letterpicked

         found = true;

Set found to true

       blanks =  replace(blanks,letterpicked+" ",i*2,2);

Modify blanks

         nGuessed++;

Increment nGuesses

        }

Close if clause

     }

Close loop through all letters in secret

     if (found) {

If letter is found (could be set multiple times)

       fill(bgcolor);

Set fill to background color

       noStroke();

No stroke

       rect(0,60,width,80);

Draw a rectangle to erase that section of the window

       fill(0);

Set fill now to black

       textAlign(LEFT);

Set alignment

       text(blanks,msgstart,100);

Display the modified blanks

     }

Close if found

     else {

Else bad guess

         wrongs++;

Not found means increment wrongs

         advance();

Show advanced color and count

       }

Close else

    if ( (nGuessed>=wlen)&&(checkIfDone() {

Check if all letters are guessed

        background(bgcolor);

Set background color

        textAlign(LEFT);

Set alignment

        msg =  "You won! Press any key for new game";

New message

        chosen = false;

Set chosen back to false

        displayTextwBackground();

Display msg

        nGuessed = 0;

Set nGuessed back to 0

        wrongs = 0;

Set wrongs back to 0

     }

Close if all letters are guessed

    }

Close else for not chosen

}

Close keyPressed

String replace (String base, String sub, int place, int remove) {

Header for replace

     String prior =  base.substring(0,place);

Extract substring before the insertion

     String after =  base.substring(place+remove);

Extract substring after the insertion

     return prior+sub+after;

Return new string

  }

Close replace

boolean checkIfDone() {

Header for checkIfDone

for (int i=0;i<blanks.length();i++) {

Iterate through the blanks string

   if (blanks.charAt(i)== '_') {

Check for the presence of a blank

      return false;

If found, return false: still work to do

   }

Close if true clause

  }

Close for-loop

  return true;

Return true: no blanks in the blanks string

}

Close checkIfDone

void advance() {

Header for advance

 if (wrongs>maxTries) {

Check if too many wrong guesses

      background(bgcolor);

Set background

      textAlign(LEFT);

Set alignment

      msg = "You lost! Press any key for new game";

Set msg to indicate loss

      chosen = false;

Reset chosen to false

     displayTextwBackground();

Display msg

      nGuessed = 0;

Reset nGuessed to 0

      wrongs = 0;

Reset wrongs to 0

  }

Close clause for end of game

  else {

Else game continues

   // update display

Make rectangle holding number of wrong guesses be a specific color in range from green to red

   float inter = map(wrongs,0,maxTries,0,1);

inter will be proportion from 0 to 1

   color c = lerpColor(greenC, redC, inter);

Use inter to get an intermediate color

   fill(c);

Set fill with that color

   rect(msgstart,200,100, 100, 20);

Draw rectangle

   fill(0);  //set color of text for the number be black

Set fill to black

   textAlign(LEFT,CENTER);

Set alignment

   text(str(maxTries-wrongs),msgstart+40,200+40);

Display the number of wrong answers allowed

  }

Close clause

} //ends advance

Close advance

The program and description for the Word Game main coding with letter buttons are shown in Table 9-4. I have included a modified version of the Button class shown earlier. The modification of the Button class from that used in the previous chapter was to add the removed variable. This variable is used only in the isOver method. The button is immediately erased (covered over). The display method is only invoked at the start of a round.

Please note the similarities between the keyboard and the buttons programs.
Table 9-4

Word Game with Buttons Program

String[] wordlist;

Will hold all the words

Table words;

Table for loading in words

int numWords;

Will be set to the number of words

Boolean chosen = false;

Will change when secret word is selected

String secret;

Current secret word

String blanks = "";

Will hold blanks and the guessed letters

int wlen;

Length of secret word

int wrongs;

Number of wrong guesses

int nGuessed;

Number of guesses

String msg = "Press any key to start";

Starting message

color bgcolor = 200;

Background color

int msgstart = 50;

Horizontal start of messages

int maxTries = 7;  //number of wrong answers allowed. Can still win on the 8th try.

Number of wrong answers allowed. Can still win on the 8th try

color greenC = color(0,255,0);

Green color

color redC = color(255,0,0);

Red color

Button[] buttons = {};

Sets buttons array

float padding = 8;

Padding for buttons

void setup() {

Header for setup

  size(1050,800);

Sets the dimensions of window

  textSize(30);

Sets text size

  words = loadTable("words.csv");

Brings in word file

  numWords = words.getRowCount();

Sets the number of words

  wordlist = new String[numWords];

Creates array of appropriate size

  for (int i = 0;i<numWords;i++) {

For loop to populate the array

    wordlist[i] = words.getString(i,0);

Extracts word from table

  }

Closes for-loop

  background(bgcolor);

Sets the color of window

  setupAlphabetButtons();

Sets alphabet buttons

}

Closes setup

void setupAlphabetButtons() {

Header for setupAlphabetButtons

  String alphabet =  "abcdefghijklmnopqrstuvwxyz";

Holds alphabet

  int startx = 20;

Starting horizontal position

  int starty = 680;

Vertical position

  int buttonwidth = 30;

Width of button

  int buttonheight = 40;

Height of button

  int margin = 10;

Space between buttons

  int spacing = margin + buttonwidth;

Total space

  for (int i=0;i<alphabet.length();i++) {

For loop for buttons

     Button b = new Button(startx+i*spacing, starty, buttonwidth, buttonheight, color(200,0,0), str(alphabet.charAt(i)));

Invokes Button constructor

     buttons =  (Button[]) append (buttons,b);

Adds new Button to buttons

  }

Closes for-loop

}

Closes setupAlphabetButtons

void resetAlphabetButtons() {

Header for resetAlphabetButtons

  for (int i=0;i<buttons.length;i++) {

For loop

    buttons[i].removed = false;

Resets removed object variable to false

  }

Closes for-loop

}

Closes function

void showButtons() {

Header for showButtons

  for (int i=0;i<buttons.length;i++) {

For loop

     buttons[i].display();

Invokes display method

  }

Closes for-loop

}

Closes function

char whichLetter (int x, int y) {

Header for whichLetter

     for (int i=0;i<buttons.length;i++) {

For loop checking buttons

         if (buttons[i].isOver(x,y)) {

Invokes isOver method

              return (buttons[i].label.charAt(0));

At a hit, returns the letter

         }

Closes if

     }

Closes for-loop

     return ('?');

Returns indication of not over any button

}

Closes function

void draw() {

Header for draw

  if (!chosen) {

If secret word is not chosen

    displayTextwBackground();

Displays msg

  }

Closes if

}

Closes draw

void displayTextwBackground() {

Header for displayTextwBackground

  fill(200);

Prepares to draw invisible rectangle

  noStroke();

No stroke

  rect(0,0,width, 60);

Draws rectangle to be under msg

 fill(0);

Sets text color to black

 text(msg,msgstart,30);

Displays text

}

Closes displayTextwBackground

void keyPressed() {

Header for keyPressed

if (!chosen) {

No word chosen

msg =  "Press a letter button to try that letter";

Sets msg

displayTextwBackground();

Displays text on top of invisible rectangle

secret = wordlist[int(random(numWords))];

Chooses random word from word list

    wlen = secret.length();

Sets wlen with length

    chosen = true;

Sets chosen Boolean

    blanks = "";

Starts the preparation of blanks

    wrongs = 0;

Initializes wrongs

    nGuessed = 0;

Initializes nGusses

    for (int i=0;i<wlen;i++) {

For loop to set blanks

      blanks = blanks + "_ ";

Two characters for each letter

     }

Closes for-loop

    fill(0);

Sets fill to black

    textAlign(LEFT);

Sets alignment

    text(blanks,msgstart,100);

Displays blanks

    advance();

Displays status

    showButtons();

Shows the alphabet buttons

  }

Closes if not chosen

}

Closes keyPressed

void mousePressed() {

Header for mousePressed

   char letterpicked = whichLetter(mouseX,mouseY);

Invokes whichLetter

   if (letterpicked=='?') { return;}

If no letter button was pressed, no action

     Boolean found = false;

Initializes found to false

     for (int i=0;i<wlen;i++){

For loop going through secret word

       if (secret.charAt(i)==letterpicked) {

Checks ith letter

         found = true;

Sets found to true

         blanks =  replace(blanks,letterpicked+" ",i*2,2);

Modifies blanks

         nGuessed++;

Increments nGuessed

       }

Closes if

     }

Closes for-loop

     if (found) {

If found in word at least once

       fill(bgcolor);

Erases old blanks, starting with fill

       noStroke();

No stroke

       rect(0,60,width,80);

Draws rectangle over area

       fill(0);

Now sets fill to black

       textAlign(LEFT);

Align

       text(blanks,msgstart,100);

Displays blanks

     }

Closes if

     else {

Else bad guess

       wrongs++;

Increments wrongs

       advance();

Change display

     }

Closes else

     if (nGuessed>=wlen) {

Checks if all letters are guessed

      background(bgcolor);

Erases whole window

      textAlign(LEFT);

Sets alignment

      msg =  "You won! Press any key for new game";

Sets msg

      resetAlphabetButtons();

Resets buttons (resets removed variables)

      showButtons();

Shows alphabet buttons

      chosen = false;

Resets chosen

      displayTextwBackground();

Displays the msg

      nGuessed = 0;

Resets nGuessed

      wrongs = 0;

Resets wrongs

     }

Closes clause checking if game won

  }

Closes mousePressed

String replace(String base, String sub,int place,int remove){

Header for replaced used to update blanks

   String prior =  base.substring(0,place);

Extracts part of string prior to change

   String after =  base.substring(place+remove);

Extracts part of string after the changed part

   return prior+sub+after;

Constructs new string

}

Closes replace

void advance() {

Header for advance

 if(wrongs>maxTries) {

Checks for loss

      background(bgcolor);

Erases whole windows

      textAlign(LEFT);

Sets alignment

      msg = "You lost! Press any key for new game";

Sets msg

      resetAlphabetButtons();

Resets buttons (resets removed variables)

      chosen = false;

Resets chosen

      displayTextwBackground();

Displays msg

      nGuessed = 0;

Resets nGuessed

      wrongs = 0;

Resets wrongs

  }

Closes clause determining loss

  else {

Starts else

   float inter = map(wrongs,0,maxTries,0,1);

inter will be proportion from 0 to 1

   color c = lerpColor(greenC, redC, inter);

Uses inter to get an intermediate color

    fill(c);

Sets fill with that color

    rect(msgstart,200,100, 100, 20);

Draws rectangle

    fill(0);

Sets fill to black

    textAlign(LEFT,CENTER);

Sets alignment

    text(str(maxTries-wrongs),msgstart+40,200+40);

Displays the number of wrong answers allowed

  }

Closes else clause

}

Closes advance

//Button class

 

class Button {

Header for Button class

  int cx,cy;

Horizontal and vertical positions

  int bw, bh, bwsq, bhsq;

Width, height, and calculated values used in isOver

  color col;

color

  String label;

Holds the letter of the alphabet

  boolean removed;

Will be set to true after letter is tried

  Button (int x,int y,int bwid, int bht, color c, String lab)  {

Button constructor

    cx = x;

Sets object variables, x position

    cy = y;

y position

    bw = bwid;

Width

    bh = bht;

Height

    bwsq = bw*bw;

Calculates for isOver

    bhsq = bh*bh;

Calculates for isOver

    col = c;

Sets color

    label = lab;

Sets label

    removed = false;

Initial value of removed

  }

Closes Button

boolean isOver(int x,int y)  {

Header for isOver method

    if (removed) return (false);

Returns false—can’t be over a removed button

    float disX = cx - x;

Start of calculation

    float disXsq = disX * disX;

Continues calculation

    float disY = cy - y;

Continues calculation

    float disYsq = disY * disY;

Continues calculation

    float v = (disXsq / bwsq) + (disYsq/bhsq);

Completes calculation

    if (v<1) {

isOver is true …

        removed = true;

Marks button as removed

        fill(bgcolor);

Sets fill to background color

        stroke(bgcolor);

Turns off stroke

        ellipse(cx,cy,bw+8,bh+8);

Draws ellipse to erase button

        return (true);

Returns true

    }

Closes check for isOver

    else {

else

        return (false);

Returns false

    }

Closes else clause

  }

Closes isOver method

  void display()  {

Header for display method

//display only invoked at start of a round

No need to check removed variable

     fill(col);

Sets fill

     ellipse(cx,cy,bw,bh);

Draws ellipse

     fill(0);

Sets fill to black

     textAlign(CENTER,CENTER);

Sets alignment

     text (label,cx,cy-2);

Draws text, positioned within ellipse

     textAlign(LEFT);

Resets alignment

  }

Close of display method

}

Close of Button class

Things to Look Up

Look up String methods.

Look up treatment of tables, formed from comma-separated values, and think about how you can use them with other applications.

Research how text is formed, including the use of transparent pixels to produce smooth borders on the letters.

Study methods for manipulating colors, such as filtering using TINT or GRAY.

How to Make This Your Own

Build on my green-to-red idea or do something different to indicate the state of the game. You may consider using images or making line drawings.

Do the research to find suitable word lists online. You might want to use the URL method of bringing in the file or files, though this can be problematic as well as unethical if it is using something without permission.

For the implementation using the keyboard, display the letters of the alphabet that have been played.

Change what happens with a loss by showing the whole secret word, with the guessed letters a different color than the unguessed letters. Similarly, you may give a winner the chance to see the complete word.

Keep score over one session using global variables, or update a CSV file kept in the data folder.

Define levels of play that access different word lists and have different displays.

Create or acquire suitable video clips or audio clips to play on a win or a loss.

Move on to other guessing games. Invent your own.

What You Learned

In this chapter, you saw another use of a CSV file and two different ways to support player input: the keyboard and letter buttons. The fact that how to implement a simple word guessing game is not obvious is more common than you might imagine. You read about the possibilities of developing and initial testing with a small data set. You saw manipulation of String objects and calculations involving colors. The letter Button class is similar, although not identical, to the Button class used in previous chapters. This can be termed partial reuse of programming.

What’s Next

The next and final chapter is an introduction to drawing in 3D. Working in 3D is a challenge. Doing your own experimenting will help your understanding. Both featured examples show the use of 2D images with 3D objects. One example shows a ball, wrapped in a 2D image, apparently rolling around in 3D. The other example will include an explanation of how to detect when a specified time has elapsed. The source code includes extra examples, introduced briefly in the text.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.161.228