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
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.
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.
to get a grade out of 100.
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);.
Notice that the replace function does not change the base but returns the new string.
Operation Overview
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.
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 |
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.
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.
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.