Writing a hangman game by speaking

This shows to write 900 line program with minimal typing. It is a hangman game. The code entry will take about twice as long as compared with furious typing, but you may get to like this slow paced and relaxing way of programming. Moreover, one normally spends most of their time thinking and testing the program so the code entry is a small fraction of the time spend anyway. But programmers who edit their code with Happy Hands will hardly need to type at all, and go home with a healthier body and mind.

The hangman game we will program looks like this when it is running:

Player is loosing Player has won

The hangman demo consists of four source files.

The general procedure will be to first create the four files, and then define the functions and classes (by speaking) in an order that defines the elements that are used by other elements first. This makes the symbols names we create in the lower level declarations available for use by the higher level definitions. One does not normally write code from the top of the file down - instead one would normally write a very simple version of the program and gradually fill it out. The Happy Hands editor is normally used this way. However this demonstration simply shows how to get out the code, as if the programmer were some type of Mozart-like genius having the ability to just stream out the code because they know the whole program from front to back before they write a single line.

The beginning of the demonstration requires you to type in allot of field names. Don't be discouraged! The code is no more than 10% symbol name declarations! As the names get declared there will less and less typing. You're really going to be able to code mostly by waving the mouse around and speaking.

The demonstration has listings of the speech recognition results that were piped directly from Happy Hands during the course of the recopying of the code. The results were edited to remove any misrecognitions, but other than this these results are presented verbatim. If you have trained your recognition engine to your voice (which takes 15 minutes with Via Voice) you should get about an 80% recognition rate. If the recognizer cannot recognize a certain phrase after you have said it more than once, go ahead and just type this piece of code. Or, feel free to repeat your self many times in different tones of voice to learn how to talk to the computer. Try to use the same tone of voice you used when you training the recognizer.

Speech recognition results are joined by dashes to indicate they were spoken in one utterance. You may change the groupings to suit your tastes and skills. Some groupings are immutable: variable-X, field-X, type-X, append-X, add-argument-type-X. Generally in an expression, immutable groupings express a single value or a single operator. On the other side, some utterances will require a pause: after append-X, after chose-member. These pauses are required as the recognizer is reconfigured to listen for new grammars. Happy Hands is very fast at these changes, so the pause is usually less then a second. Also, incoming speech is buffered by the recognizer during reconfigurations, so you can speak at these times.

To create hangman project

Specifying the source directories

The project is all set up. Happy Hands assumes all source files under the source directories are part of the project, so we may now simply start making source files!

Create a new file by hitting the "New" graphical button or by saying "new unnamed file", or just use a blank file in the editor that may already be there.

HangmanGame.java - Import Statements:

append-package-declaration
hangman

append-import-statement
java-a-w-t

append-import-statement
java-applet

append-import-statement
java-a-w-t-event

append-import-statement
java-x-swing

append-import-statement
java-util

append-import-statement
java-io

append-import-statement
java-net

append-class-definition
public
extends-type-applet
Type: HangmanGame

package hangman;
import java.awt.*;
import java.applet.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
import java.io.*;
import java.net.*;

At this point, to be safe, it would be a good idea to save the file. Just say "save top file" or hit the "Save" button. The filename and directory is determined automatically based on the package and class of the java code within. Note, Happy Hands still adds the HangmanGame class to the speech recognition grammars whether or not you save it. It should be possible to do the entire demo without saving, but don't try this at home!

Create a new file.

HangmanCanvas.java - Import Statements:

append-package-declaration
hangman

append-import-statement
java-a-w-t

append-import-statement
java-x-swing

append-import-statement
Type (hard to recognize): java.awt.geom.*

append-import-statement
java-a-w-t-image

append-class-definition
public
extends-type-j-panel
Type: HangmanCanvas

We are going to declare a series of fields. For these you will need to type the field names. Symbol names need to by typed once. This the last time you will need to type them.

insert-in-block-field-declaration
type-hangman-game
type-hangman-game
Type: game

append-field-declaration
Type: topLevel

append-field-declaration
Type: groundLevel

append-field-declaration
Type: leftPole

append-field-declaration
Type: braceSize

append-field-declaration
Type: bodyCenter

append-field-declaration
Type: legTop

append-field-declaration
Type: legSize

append-field-declaration
Type: bodyTop

append-field-declaration
Type: armSize

append-field-declaration
Type: headSize

append-field-declaration
Type: neckSize

append-field-declaration
Type: eyeSize

append-field-declaration
type-one-dimensional-color-array
Type: colors
initialize
new-type-one-dimensional-color-array-integer-fifty

append-field-declaration
type-buffered-image
Type: offScreen

package hangman;
import java.awt.*;
import javax.swing.*;
import java.awt.geom.*;
import java.awt.image.*;

public class HangmanCanvas extends JPanel{
	HangmanGame game = null;
	int topLevel = 10;
	int groundLevel = 0;
	int leftPole = 0;
	int braceSize = 0;
	int bodyCenter = 0;
	int legTop = 0;
	int legSize = 0;
	int bodyTop = 0;
	int armSize = 0;
	int headSize = 0;
	int neckSize = 0;
	int eyeSize = 0;
	Color[] colors = new Color[50];
	int iColor = 0;
	BufferedImage offScreen = null;

HangmanGame.java - HangmanCanvas.makeColors:

append-method-definition
public
Type: makeColors

insert-in-block-for-loop
declare-initializer
enter-condition
variable-i-is-less-than-field-colors-length
enter-incrementer
variable-i-post-increment

insert-in-block-executable
field-colors-index-array
variable-i
Move mouse to select colors[i] assignment
new-type-color
three-arguments
type-math-choose-member
select-method-random
type-cast-type-floating-point
Copy this value and replace the next two arguments with this
copy-selection
Move mouse to select second argument
replace-with-copy
Move mouse to select third argument
replace-with-copy

	public void makeColors(){
		for (int i = 0; i < colors.length; i++){
			colors[i] = new Color((float)Math.random(), (float)Math.random(), (float)Math.random());
		}
	}

Create a new file

AnswerCanvas.java - Import Statements:

append-package-declaration
hangman

append-import-statement
java-a-w-t

append-import-statement
java-x-swing

append-class-definition
public
Type: AnswerCanvas
extends-type-j-panel

insert-in-block-field-declaration
type-hangman-game
Type: game

append-field-declaration
type-font
Type: font
initialize
new-type-font
three-arguments
string-constant
type-font-choose-member
select-field-bold
integer-twenty-four

append-field-declaration
type-font-metrics
Type: fm

To add the line:

Font font2 = new Font("Courier", Font.BOLD, 16);
just copy the similar line above by moving the mouse over the line so that the green rectangle selects the entire field declaration and say:
copy-selection
Then move the cursor to the last field declaration and say:
append-copy
and change the name to "font2"

Do the same for the line

FontMetrics fm = null;

And change the name to "fm2".
You can change the font size to 16 by moving selecting the expression 24 with the red box and saying:

integer-sixteen
Or you might just want to make this small change with the keyboard.

append-method-definition
public-constructor

insert-in-block-executable
field-f-m-assignment-method-get-font-metrics
field-font

append-executable
field-f-m-2-assignment-method-get-font-metrics
field-font-2


package hangman;
import java.awt.*;
import javax.swing.*;

public class AnswerCanvas extends JPanel{
	HangmanGame game = null;
	Font font = new Font("Courier", Font.BOLD, 24);
	FontMetrics fm = null;
	Font font2 = new Font("Courier", Font.PLAIN, 14);
	FontMetrics fm2 = null;

	public AnswerCanvas(){
		fm = getFontMetrics(font);
		fm2 = getFontMetrics(font2);
	}

Create a new file

LetterCanvas.java - Import Statements:

append-package-declaration
hangman

append-import-statement
java-a-w-t

append-import-statement
java-a-w-t-event

append-import-statement
java-x-swing

append-class-definition
public
Type: LetterCanvas
extends-type-j-panel

insert-in-block-field-declaration
type-font
Type: font
initialize
new-type-font-three-arguments
Type: "SansSerif"
type-font-choose-member
select-field-bold
integer-sixteen

append-field-declaration
type-font-metrics
Type: metrics

append-field-declaration
Type: letterHeight

append-field-declaration
Type: overLetterIndex
initialize
integer-negative-one

append-field-declaration
type-hangman-game
Type: game


package hangman;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class LetterCanvas extends JPanel{
	Font font = new Font("SansSerif", Font.BOLD, 16);
	FontMetrics metrics = null;
	int letterHeight = 0;
	int overLetterIndex = -1;
	HangmanGame game = null;

HangmanGame.java - WordEntry:

append-class-definition
Type: WordEntry
insert-in-block-field-declaration
type-string
Type: word

append-field-declaration
type-string
Type: definition

append-method-definition
public-constructor

append-method-definition
public-constructor
add-argument-type-string
insert-in-block-executable
variable-this-word-assignment-field-word

	class WordEntry{
		String word = null;
		String definition = null;

		public WordEntry(){
		}

		public WordEntry(String word){
			this.word = word;
		}
	}

We will continue filling the fields of HangmanGame.

HangmanGame.java - Field Declarations:

insert-in-block-field-declaration
type-hangman-canvas

append-field-declaration
type-letter-canvas
Type: hangmanCanvas

append-field-declaration
type-answer-canvas
Type: letterCanvas

append-field-declaration
type-j-button
Type: answerCanvas

append-field-declaration
type-j-button
Type: exitButton

append-field-declaration
Type: newWordButton

append-field-declaration
type-string
Type: mistakes

append-field-declaration
type-string
Type: letters

append-field-declaration
type-word-entry
Type: currentWord

append-field-declaration
type-vector
Type: wordList

append-field-declaration
Type: currentWordIndex

append-field-declaration
type-true-or-false
Type: bWinner

append-field-declaration
Type: penalty

append-field-declaration
Type: loadProgress

	HangmanCanvas hangmanCanvas = null;
	LetterCanvas letterCanvas = null;
	AnswerCanvas answerCanvas = null;
	JButton exitButton = null;
	JButton newWordButton = null;
	int mistakeCount = 0;
	String letters = null;
	WordEntry currentWord = null;
	StringBuffer partialWord = null;
	Vector wordList = null;
	int currentWordIndex = 0;
	boolean bWinner = false;
	int penalty = 0;
	int loadProgress = 0;

Lets move down to the function HangmanGame.setWord()

HangmanGame.java - HangmanGame.setWord():

append-method-definition
public
Type: setWord
add-argument-type-word-entry
Type: entry

insert-in-block-executable
variable-this-current-word-assignment-variable-entry

append-executable
variable-this-partial-word-assignment
new-type-string-buffer
one-arguments
string-constant
choose-member
select-method-substring
add-argument-integer-zero
add-argument-field-current-word-word
choose-member
select-method-length

append-executable
variable-this-letters-assignment
string-constant
Type: ABCDEFGHIJKLMNOPQRSTUVWXYZ-

append-executable
field-mistake-count-assignment-integer-zero

append-if-test
field-current-word-word-choose-member
select-method-length
is-greater-than-integer-eight

insert-in-block-executable
field-mistake-count-assignment-integer-one

The other two if blocks are similar. Copy them using:
copy-selection
append-copy
Change constants to match the example, and once more:
copy-selection
append-copy
And change constants

append-executable
field-mistake-count-addition-assign
field-penalty

append-executable
field-b-winner-assignment-false-constant

append-executable
field-hangman-canvas-make-colors

append-executable
method-repaint

	public void setWord(WordEntry entry){
		this.currentWord = entry;
		this.partialWord = new StringBuffer("                                     ".substring(0, currentWord.word.length()));
		this.letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ-";
		mistakeCount = 0;
		if(currentWord.word.length() > 8){
			mistakeCount = 1;
		}
		if(currentWord.word.length() > 11){
			mistakeCount = 2;
		}
		if(currentWord.word.length() > 14){
			mistakeCount = 3;
		}
		mistakeCount+= penalty;
		bWinner = false;
		hangmanCanvas.makeColors();
		repaint();
	}

Lets move to the function HangmanGame.tryLetter()

HangmanGame.java - HangmanGame.tryLetter():

append-method-definition
public
Type: tryLetter
add-argument-type-integer
Type: letterIndex

insert-in-block-variable-declaration
Type: letter
initialize
field-letters-char-at
variable-letter-index

append-variable-declaration
Type: inWord
initialize
integer-negative-one

append-variable-declaration
type-true-or-false
Type: mistake
initialize
true-constant

append-variable-declaration
type-string
Type: word
initialize
field-current-word-word

append-do-while-loop
variable-in-word-is-not-equal-to-integer-negative-one

insert-in-block-executable
variable-in-word-assignment-variable-word-index-of
two-arguments
variable-letter
next-argument
variable-in-word-addition-integer-one

append-if-test
variable-in-word
is-not-equal-to-integer-negative-one

insert-in-block-executable
field-partial-word-choose-member
select-method-set-char-at
variable-in-word
next-argument
field-letters-char-at
variable-in-word
type-cast-type-character

append-executable
variable-mistake-assignment-false-constant

append-if-test
variable-mistake

insert-in-block-executable
field-mistake-count-post-increment

append-line-comment
Type: the comment

append-if-test
field-mistake-count-is-greater-than-integer-nine
insert-in-block-executable
field-letters-assignment-string-constant

append-executable
field-partial-word-assignment-new-type-string-buffer
one-arguments-variable-word

append-executable
method-repaint

append-return
Note return statement has a default argument that you may fill in as
needed, but it is not needed in this case. Selecting another code element
will remove the default.

append-else-if-test
field-partial-word-to-string
choose-member
select-method-equals
variable-word

insert-in-block-executable
field-b-winner-assignment-true-constant

append-executable
field-letters-assignment-string-constant

append-executable
field-hangman-canvas-make-colors

append-executable
method-repaint

append-return

append-executable
field-letters-assignment-field-letters-substring
two-arguments
integer-zero
next-argument
variable-letter-index
Move selection to letters.substring(0, letterIndex)
addition
field-letters-substring
two-arguments
variable-letter-index-addition-integer-one
next-argument
field-letters-length

append-executable
method-repaint

	public void tryLetter(int letterIndex){
		int letter = letters.charAt(letterIndex);
		int inWord = -1;
		boolean mistake = true;
		String word = currentWord.word;
		do {
			inWord = word.indexOf(letter, inWord + 1);
			if(inWord != -1){
				partialWord.setCharAt(inWord, (char)letter);
				mistake = false;
			}
		}while (inWord != -1);
		if(mistake){
			mistakeCount++;

			//game is lost
			if(mistakeCount > 9){
				letters = "";
				partialWord = new StringBuffer(word);
				repaint();
				return;
			}
		}

		//game is won
		else if(partialWord.toString().equals(word)){
			bWinner = true;
			letters = "";
			hangmanCanvas.makeColors();
			repaint();
			return;
		}

		//progress or error: remove letter
		letters = letters.substring(0, letterIndex) + letters.substring(letterIndex + 1, letters.length());
		repaint();
	}

Lets move to the function HangmanGame.newWord()

HangmanGame.java - HangmanGame.newWord():

append-method-definition
Type: newWord

insert-in-block-variable-declaration
Type: i

append-variable-declaration
Type: tryCount

append-while-loop
variable-try-count post-increment is-less-than integer-three

insert-in-block-executable
variable-i-assignment
type-math-choose-member
select-method-random
multiplication-field-word-list-size
type-cast-type-integer

append-field-declaration
type-word-entry
initialize
field-word-list-element-at-variable-i
type-cast-type-word-entry

append-if-test
field-current-word-index
is-not-equal-to-variable-i

insert-in-block-if-test
variable-test-word
choose-member
select-method-length
is-greater-than
integer-four

insert-in-block-break

append-executable
field-current-word-index-assignment
variable-i

append-executable
field-current-word-assignment
field-word-list-element-at
field-current-word-index
type-cast-type-word-entry

append-executable
method-set-word
field-current-word

	void newWord(){
		int i = 0;
		int tryCount = 0;
		while (tryCount++ < 3){
			i = (int)(Math.random()*wordList.size());
			WordEntry test = (WordEntry)wordList.elementAt(i);
			if(currentWordIndex != i){
				if(test.word.length() > 4){
					break;
				}
			}
		}
		currentWordIndex = i;
		currentWord = (WordEntry)wordList.elementAt(currentWordIndex);
		setWord(currentWord);
	}

HangmanGame.java - HangmanGame.buildDefaultWordList():

append-method-definition
Type: buildDefaultWordList

insert-in-block-executable
field-word-list-assignment-new-type-vector

append-executable
field-word-list-add-new-type-word-entry
one-arguments-string-constant
Type: AARDVARK

append-executable
field-word-list-add-new-type-word-entry
one-arguments-string-constant
Type: TIGER

append-executable
field-word-list-add-new-type-word-entry
one-arguments-string-constant
Type: GIRAFFE
	void buildDefaultWordList(){
		wordList = new Vector();
		wordList.add(new WordEntry("AARDVARK"));
		wordList.add(new WordEntry("TIGER"));
		wordList.add(new WordEntry("GIRAFFE"));
	}

HangmanGame.java - HangmanGame.addEntry():

append-method-definition
Type: addEntry
add-argument-type-string

insert-in-block-if-test
variable-line-length
is-equal-to-integer-zero

insert-in-block-return

append-variable-declaration
type-word-entry
Type: entry
initialize
new-type-word-entry

append-variable-declaration
Type: iSpace
initialize
variable-line-index-of
Type: ' '

append-if-test
variable-i-space
is-not-equal-to-integer-negative-one

insert-in-block-executable
variable-entry-word-assignment
variable-line-substring-two-arguments
sequence-integer-zero-variable-i-space

append-executable
variable-entry-word
assignment-variable-entry-word
choose-member
select-method-to-upper-case

append-executable
variable-entry-definition
assignment
variable-line-substring-two-arguments
variable-i-space-addition-integer-one
next-argument
variable-line-length

append-executable
variable-entry-definition
assignment
variable-entry-definition
choose-member
select-method-trim

append-else-block

insert-in-block-executable
variable-entry-word-assignment
variable-line-to-upper-case

append-executable
field-word-list-add
variable-entry

append-executable
field-load-progress-post-increment

append-if-test
field-load-progress-modulus
integer-one-thousand
is-equal-to-integer-zero

insert-in-block-executable
field-answer-canavas-paint
field-answer-canavas-get-graphics

	void addEntry(String line){
		if(line.length() == 0){
			return;
		}
		WordEntry entry = new WordEntry();
		int iSpace = line.indexOf(' ');
		if(iSpace != -1){
			entry.word = line.substring(0, iSpace);
			entry.word = entry.word.toUpperCase();
			entry.definition = line.substring(iSpace + 1, line.length());
			entry.definition = entry.definition.trim();
		}
		else{
			entry.word = line.toUpperCase();
		}
		wordList.add(entry);
		loadProgress++;
		if(loadProgress%1000 == 0){
			//answerCanvas.repaint();
			//Thread.yield();
			answerCanvas.paint(answerCanvas.getGraphics());
		}
	}

HangmanGame.java - HangmanGame.readWordFile():

append-method-definition
public
Type: readWordFile
add-argument-type-input-stream

insert-in-block-executable
field-word-list-assignment-new-type-vector

append-variable-declaration
type-input-stream-reader
Type: reader
initialize
new-type-input-stream-reader-variable-input-stream

append-variable-declaration
type-one-dimensional-character-array
Type: buffer
initialize
new-type-one-dimensional-character-array

append-variable-declaration
Type: nRead

append-try-block
type-exception
Type: ex
Move selection to try block

insert-in-block-for-loop

insert-in-block-variable-declaration
type-character
Type: c
initialize
variable-reader-read
type-cast-type-character

append-switch-block
variable-c

insert-in-block-case-block
Type: '\r'

insert-case-label
Type: '\n'

insert-if-test
variable-n-read-is-greater-than-integer-zero

insert-in-block-executable
method-add-entry-new-type-string
three-arguments
sequence-variable-buffer-integer-zero-variable-n-read

append-executable
variable-n-read-assignment-integer-zero

append-default-block

insert-executable
variable-buffer
index-array
variable-n-read
post-increment
assignment-variable-c

insert-in-block-executable
variable-ex-print-stack-trace

append-executable
field-load-progress-assignment-integer-negative-one

append-executable
field-answer-canvas-repaint

	public void readWordFile(InputStream inputStream){
		wordList = new Vector();
		InputStreamReader reader = new InputStreamReader(inputStream);
		char[] buffer = new char[256];
		int nRead = 0;
		try {
			for (; ; ){
				char c = (char)reader.read();
				switch (c){
				case '\n':
				case '\r':{
					if(nRead > 0){
						addEntry(new String(buffer, 0, nRead));
					}
					nRead = 0;
					break;
				}
				default:{
					buffer[nRead++] = c;
					break;
				}
				}
			}
		}
		catch (Exception ex) {
			ex.printStackTrace();
		}
		loadProgress = -1;
		answerCanvas.repaint();
	}

HangmanGame.java - HangmanGame.setBounds():

append-method-definition
override-set-bounds
Add arguments by typing them, is the easiest way here.

insert-in-block-executable
variable-super-set-bounds
sequence-integer-zero-integer-zero-variable-w-variable-h

append-variable-declaration
Type: letterWidth
initialize
integer-fourty

append-variable-declaration
Type: answerHeight
initialize
integer-one-hundered

append-variable-declaration
Type: buttonHeight
initialize
integer-twenty-eight

append-variable-declaration
Type: buttonWidth
initialize
variable-w-subtraction-variable-letter-width
division-integer-two

append-executable
field-letter-canvas-set-bounds
four-arguments
sequence-integer-zero-integer-zero-variable-letter-width-variable-h

append-executable
field-hangman-canvas-set-bounds-four-arguments
variable-letter-width
integer-zero
variable-w-subtraction-variable-letter-width
variable-h
subtraction-variable-answer-height

append-executable
field-exit-button-set-bounds
four-arguments
variable-letter-width
variable-h-subtraction-variable-button-height
variable-button-width
variable-button-height

append-executable
field-new-word-button-set-bounds
four-arguments
variable-letter-width-addition-variable-button-width
variable-h-subtraction-variable-button-height
variable-button-width
variable-button-height

	public void setBounds(int x, int y, int w, int h){
		super.setBounds(0, 0, w, h);
		int letterWidth = 40;
		int answerHeight = 100;
		int buttonHeight = 28;
		int buttonWidth = (w - letterWidth)/2;
		letterCanvas.setBounds(0, 0, letterWidth, h);
		hangmanCanvas.setBounds(letterWidth, 0, w - letterWidth, h - answerHeight - buttonHeight);
		answerCanvas.setBounds(letterWidth, h - answerHeight - buttonHeight, w - letterWidth, answerHeight);
		exitButton.setBounds(letterWidth, h - buttonHeight, buttonWidth, buttonHeight);
		newWordButton.setBounds(letterWidth + buttonWidth, h - buttonHeight, buttonWidth, buttonHeight);
	}

HangmanGame.java - HangmanGame.ButtonHandler

append-class-definition
Type: ButtonHandler
implements-type-action-listener

insert-in-block-method-definition
override-action-performed

insert-in-block-if-test
variable-e-get-source
is-equal-to
field-exit-button

insert-in-block-executable
type-runtime-choose-member
select-method-get-runtime
choose-member
select-method-exit
integer-zero

append-if-test
variable-e-get-source-is-equal-to
field-new-word-button

insert-in-block-executable
method-new-word

	class ButtonHandler implements ActionListener{
		public void actionPerformed(ActionEvent e){
			if(e.getSource() == exitButton){
				Runtime.getRuntime().exit(0);
			}
			else if(e.getSource() == newWordButton){
				newWord();
			}
		}
	}

HangmanGame.java - HangmanGame.LoadThread:

append-class-definition
public
Type: LoadThread
extends-type-thread

insert-in-block-method-definition
override-run

insert-in-block-try-block
type-exception

insert-in-block-executable
field-penalty-assignment
type-capital-integer-choose-member
select-method-parse-int
one-arguments
method-get-parameter
one-arguments
Type: "penalty"

insert-in-block-executable
field-penalty-assignment-integer-zero

append-variable-declaration
type-string
Type: word_list_file
initialize
method-get-parameter-one-arguments
Type: "word_list"

append-try-block
type-exception

insert-in-block-variable-declaration
type-url
initialize
method-get-document-base

append-variable-declaration
type-url
initialize
new-type-url
two-arguments
variable-db-next-argument
variable-word-list-file

append-variable-declaration
type-input-stream
initialize
variable-url
choose-member
select-method-open-stream

append-executable
method-read-word-file
variable-input-stream

insert-in-block-executable
type-system-choose-member
choose-member

append-executable
variable-e-x-print-stack-trace

append-executable
method-new-word

append-executable
field-new-word-button-set-enabled-true-constant

	public class LoadThread extends Thread{
		public void run(){
			//constant penalty for this word group
			try {
				penalty = Integer.parseInt(getParameter("penalty"));
			}
			catch (Exception ex) {
				penalty = 0;
			}
			String word_list_file = getParameter("word_list");
			try {
				URL db = getDocumentBase();
				URL url = new URL(db, word_list_file);
				InputStream inputStream = url.openStream();
				readWordFile(inputStream);
			}
			catch (Exception ex) {
				System.err.println(ex);
				ex.printStackTrace();
			}
			newWord();
			newWordButton.setEnabled(true);
		}
	}

HangmanGame.java - HangmanGame.HangmanGame():

append-method-definition
public-constructor

insert-in-block-executable
method-set-layout-null-constant

append-executable
field-hangman-canvas-assignment-new-type-hangman-canvas

append-executable
field-hangman-canvas-game-assignment-this-object

append-executable
field-letter-canvas-assignment-new-type-letter-canvas

append-executable
field-letter-canvas-game-assignment-this-object

append-executable
field-answer-canvas-assignment-new-type-answer-canvas

append-executable
field-answer-canvas-game
assignment-this-object

append-executable
field-exit-button-assignment-new-type-j-button
one-arguments-string-constant
Type: Exit

append-executable
field-exit-button-add-action-listener
new-type-button-handler

append-executable
field-new-word-button-assignment-new-type-j-button
one-arguments-string-constant
Type: New Word append-executable
field-new-word-button-add-action-listener
new-type-button-handler

append-executable
field-new-word-button-set-enabled-false-constant

append-executable
method-add-field-hangman-canvas

append-executable
method-add-field-letter-canvas

append-executable
method-add-field-answer-canvas

append-executable
method-add-field-exit-button

append-executable
method-add-field-new-word-button

	public HangmanGame(){
		setLayout(null);
		hangmanCanvas = new HangmanCanvas();
		hangmanCanvas.game = this;
		letterCanvas = new LetterCanvas();
		letterCanvas.game = this;
		answerCanvas = new AnswerCanvas();
		answerCanvas.game = this;
		exitButton = new JButton("Exit");
		exitButton.addActionListener(new ButtonHandler());
		newWordButton = new JButton("New Word");
		newWordButton.addActionListener(new ButtonHandler());
		newWordButton.setEnabled(false);
		add(hangmanCanvas);
		add(letterCanvas);
		add(answerCanvas);
		add(exitButton);
		add(newWordButton);
	}

HangmanGame.java - HangmanGame.init():

append-method-definition
override-init

insert-in-block-executable
new-type-load-thread-choose-member
select-method-start

	public void init(){
		new LoadThread().start();
	}

HangmanGame.java - HangmanGame.main():

append-method-definition
public-static
Type: main
add-argument-type-one-dimensional-string-array
Type: argList

insert-in-block-variable-declaration
type-hangman-game
Type: game
initialize
new-type-hangman-game

append-if-test
variable-arg-list-length
is-greater-than-integer-zero

insert-in-block-variable-declaration
type-string
Type: filename
initialize
variable-arg-list-index-array
integer-zero

append-try-block
type-exception
Type: ex

insert-in-block-variable-declaration
type-input-stream
Type: reader
initialize
new-type-file-input-stream
variable-file-name

append-executable
type-variable-game
variable-game
choose-member
select-method-read-word-file
variable-reader

insert-in-block-executable
type-system-choose-member
Type: err
choose-member
select-method-print-line
string-constant
addition
variable-file-name

append-return

append-executable
variable-game
choose-member
select-method-new-word

append-variable-declaration
type-j-frame
Type: frame
initialize
new-type-j-frame

append-executable
variable-frame-set-content-pane
type-variable-game

append-executable
variable-frame-set-bounds
four-arguments
sequence-integer-one-hundered-integer-one-hundered
sequence-integer-six-hundered-integer-seven-hundered

append-executable
variable-frame-set-title
string-constant
Type: Hangman

append-executable
variable-frame-show

append-executable
type-system-choose-member
select-field-err
choose-member

	public static void main(String[] argList){
		HangmanGame game = new HangmanGame();

		//words from file
		if(argList.length > 0){
			String filename = argList[0];
			try {
				InputStream reader = new FileInputStream(filename);
				game.readWordFile(reader);
			}
			catch (Exception ex) {
				System.err.println("Bad word filename: " + filename);
				return;
			}
		}
		game.newWord();

		//frame it
		JFrame frame = new JFrame();
		frame.setContentPane(game);
		frame.setBounds(100, 100, 600, 700);
		frame.setTitle("Hangman");
		frame.show();
		System.err.println("Welcome to the hangman");
	}

That?s all of HangmanGame.java! Yeah! And our hands are doing fine! Now lets move on to finishing HangmanCanvas.java.

HangmanCanvas.java - HangmanCanvas.randomColor()

append-method-definition
add-argument-type-graphics-2-d
Type: graphics

insert-in-block-executable
variable-graphics-set-color
field-colors-index-array
field-i-color-post-increment

	void randomColor(Graphics2D graphics){
		graphics.setColor(colors[iColor++]);
	}

HangmanCanavs.java - HangmanCanvas.drawLine():

append-method-definition
Type: drawLine
add-argument-type-graphics-2-d
Type: graphics
add-argument-type-integer
Type: x0
add-argument-type-integer
Type: y0
add-argument-type-integer
Type: x1
add-argument-type-integer
Type: y1

insert-in-block-variable-declaration
type-double
Type: angle
initialize
type-math-choose-member
select-method-a-t-a-n-2
variable-y-1
subtraction-variable-y-0
variable-x-1-subtraction-variable-x-0

append-variable-declaration
Type: radius
initialize
integer-ten

append-variable-declaration
Type: nPoint
initialize
integer-twenty-four

append-variable-declaration
Type: len
initialize
type-math-choose-member
select-method-sqrt
variable-x-1-subtraction-variable-x-0
multiplication
variable-x-1-subtraction-variable-x-0
addition
variable-y-1
subtraction-variable-y-0
multiplication
variable-y-1-subtraction-variable-y-0
type-cast-type-integer

append-variable-declaration
Type: xArray
type-one-dimensional-integer-array
initialize
new-type-one-dimensional-integer-array
variable-n-point
addition-integer-two

append-variable-declaration
Type: yArray
type-one-dimensional-integer-array
initialize
new-type-one-dimensional-integer-array
variable-n-point-addition-integer-two

append-for-loop
declare-initializer
Type: i
enter-condition
variable-i
is-less-than-variable-n-point
division-integer-two
addition-integer-one
enter-incrementer
variable-i-post-increment

insert-in-block-variable-declaration
Type: a

type-double
initialize
variable-i-division-variable-n-point
type-cast-type-double
subtraction
double-float-zero-point-two-five
multiplication
double-float-three-point-one-four-one-five-nine
multiplication-double-float-two

append-executable
variable-x-array
index-array-variable-i
assignment
type-math-choose-member
select-method-c-o-s
variable-a
multiplication-variable-radius
type-cast-type-integer

Copy current line to below
copy-selection
append-copy
Change cos to sin

Copy for loop to below by selecting for loop with green box
copy-selection
append-copy
Copy i < nPoint/2 + 1 to initializer below
copy-selection
replace-with-copy
To change i to i-1, select the i and say:
subtraction-integer-one

Note- this was pretty rough! Very intricate code such as the above you may want to just type.

append-variable-declaration
type-polygon
initialize
new-type-polygon
three-arguments
sequence-variable-x-array-variable-y-array
next-argument
variable-x-array-length

append-variable-declaration
type-affine-transform
initialize
variable-graphics-get-transform

append-executable
variable-graphics-translate
sequence-variable-x-0-variable-y-0

append-executable
variable-graphics-rotate
variable-angle

append-executable
method-random-color-variable-graphics

append-executable
variable-graphics-fill-polygon
variable-polygon

append-executable
variable-graphics-set-transform
variable-old-t


	void drawLine(Graphics2D graphics, int x0, int y0, int x1, int y1){
		double angle = Math.atan2(y1 - y0, x1 - x0);
		int radius = 10;
		int nPoint = 24;
		int len = (int)Math.sqrt((x1 - x0)*(x1 - x0) + (y1 - y0)*(y1 - y0));
		int[] xArray = new int[nPoint + 2];
		int[] yArray = new int[nPoint + 2];
		for (int i = 0; i < nPoint/2 + 1; i++){
			double a = (i/(double)nPoint - 0.25)*3.14159*2.f;
			xArray[i] = (int)(Math.cos(a)*radius + len);
			yArray[i] = (int)(Math.sin(a)*radius);
		}
		for (int i = nPoint/2 + 1; i < nPoint + 2; i++){
			double a = ((i - 1)/(double)nPoint - 0.25)*3.14159*2.f;
			xArray[i] = (int)(Math.cos(a)*radius);
			yArray[i] = (int)(Math.sin(a)*radius);
		}
		Polygon polygon = new Polygon(xArray, yArray, xArray.length);
		AffineTransform oldT = graphics.getTransform();
		graphics.translate(x0, y0);
		graphics.rotate(angle);
		randomColor(graphics);
		graphics.fillPolygon(polygon);
		graphics.setTransform(oldT);
	}

HangmanCanavs.java - HangmanCanvas.drawHangman():

append-method-definition
Type: drawHangman
add-argument-type-graphics-2-d
Type: graphics

insert-in-block-variable-declaration
Type: mistakeCount
initialize
field-game-mistake-count

append-if-test
variable-mistake-count-is-greater-than-integer-zero

insert-in-block-executable
method-draw-line
variable-graphics
field-left-pole
field-top-level
field-left-pole
field-ground-level

append-if-test
variable-mistake-count-is-greater-than-integer-one

insert-in-block-executable
method-draw-line
sequence-variable-graphics-field-left-pole-field-top-level
next-argument
field-body-center-addition-integer-fourty
next-argument
field-top-level

append-if-test
variable-mistake-count-is-greater-than-integer-two

insert-in-block-executable
method-draw-line
sequence-variable-graphics-field-left-pole
field-top-level-addition-field-brace-size
field-left-pole-addition-field-brace-size
field-top-level

append-if-test
variable-mistake-count-is-greater-than-integer-three

insert-in-block-executable
method-draw-line
variable-graphics
field-body-center-subtraction-field-leg-size
field-leg-top-addition-field-leg-size
field-body-center
field-leg-top

append-if-test
variable-mistake-count
is-greater-than-integer-four

insert-in-block-executable
method-draw-line
variable-graphics
field-body-center-addition-field-leg-size
field-leg-top-addition-field-leg-size
field-body-center
field-leg-top

append-if-test
pre-decrement-is-greater-than-integer-five

variable-mistake-count
is-greater-than-integer-five
insert-in-block-executable
method-draw-line
variable-graphics
field-body-center
field-body-top-subtraction-field-neck-size
field-body-center
field-leg-top

append-if-test
variable-mistake-count-is-greater-than-integer-six

insert-in-block-executable
method-draw-line
variable-graphics
field-body-center
field-body-top
field-body-center-subtraction-field-arm-size
field-body-top-addition-integer-ten

append-executable
method-draw-line

variable-graphics
field-body-center-subtraction-field-arm-size
field-body-top-addition-integer-ten
field-body-center-subtraction-field-arm-size
subtraction-integer-ten
field-body-top

append-if-test
variable-mistake-count-is-greater-than-integer-seven

insert-in-block-executable
method-draw-line
variable-graphics
field-body-center
field-body-top
field-body-center-addition-field-arm-size
field-body-top-addition-integer-ten

append-executable
method-draw-line
variable-graphics
field-body-center-addition-field-arm-size
field-body-top-addition-integer-ten
field-body-center-addition-field-arm-size
addition-integer-ten
field-body-top

append-if-test
variable-mistake-count
is-greater-than-integer-eight-ten

insert-in-block-executable
method-random-color-variable-graphics
append-executable
variable-graphics-fill-oval
field-body-center-subtraction-field-head-size
division-integer-two
field-body-top-subtraction-field-head-size
subtraction-field-neck-size
next-argument
field-head-size
next-argument
field-head-size

append-if-test
variable-mistake-count-is-greater-than-integer-nine

insert-in-block-executable
method-draw-line
variable-graphics
field-body-center
field-top-level
field-body-center
field-body-top-subtraction-field-head-size-subtraction-field-neck-size

	void drawHangman(Graphics2D graphics){
		int mistakeCount = game.mistakeCount;

		//left pole
		if(mistakeCount > 0){
			drawLine(
				graphics, 
				leftPole, 
				topLevel, 
				leftPole, 
				groundLevel);
		}

		//top
		if(mistakeCount > 1){
			drawLine(
				graphics, 
				leftPole, 
				topLevel, 
				bodyCenter + 40, 
				topLevel);
		}

		//left brace
		if(mistakeCount > 2){
			drawLine(
				graphics, 
				leftPole, 
				topLevel + braceSize, 
				leftPole + braceSize, 
				topLevel);
		}

		//left leg
		if(mistakeCount > 3){
			drawLine(
				graphics, 
				bodyCenter - legSize, 
				legTop + legSize, 
				bodyCenter, 
				legTop);
		}

		//right leg
		if(mistakeCount > 4){
			drawLine(
				graphics, 
				bodyCenter + legSize, 
				legTop + legSize, 
				bodyCenter, 
				legTop);
		}

		//body
		if(mistakeCount > 5){
			drawLine(
				graphics, 
				bodyCenter, 
				bodyTop - neckSize, 
				bodyCenter, 
				legTop);
		}

		//left arm
		if(mistakeCount > 6){
			drawLine(
				graphics, 
				bodyCenter, 
				bodyTop, 
				bodyCenter - armSize, 
				bodyTop + 10);
			drawLine(
				graphics, 
				bodyCenter - armSize, 
				bodyTop + 10, 
				bodyCenter - armSize - 10, 
				bodyTop);
		}

		//right arm
		if(mistakeCount > 7){
			drawLine(
				graphics, 
				bodyCenter, 
				bodyTop, 
				bodyCenter + armSize, 
				bodyTop + 10);
			drawLine(
				graphics, 
				bodyCenter + armSize, 
				bodyTop + 10, 
				bodyCenter + armSize + 10, 
				bodyTop);
		}

		//head
		if(mistakeCount > 8){
			randomColor(g);
			graphics.fillOval(bodyCenter - headSize/2, bodyTop - headSize - neckSize, headSize, headSize);
		}

		//rope
		if(mistakeCount > 9){
			drawLine(
				graphics, 
				bodyCenter, 
				topLevel, 
				bodyCenter, 
				bodyTop - headSize - neckSize);
		}
	}

HangmanCanvas.java - HangmanCanvas.drawWinner():

append-method-definition
Type: drawWinner
add-argument-type-graphics-2-d
Type: graphics

insert-in-block-executable
variable-graphics-translate
integer-zero
field-ground-level-subtraction
field-leg-top-addition-field-leg-size

append-executable
method-draw-line-variable-graphics
field-body-center-subtraction-field-leg-size
field-leg-top-addition-field-leg-size
field-body-center
field-leg-top

append-executable
method-draw-line
variable-graphics
field-body-center-addition-field-leg-size
field-leg-top-addition-field-leg-size
field-body-center
field-leg-top

append-executable
method-draw-line
variable-graphics
field-body-center
field-body-top-subtraction-field-neck-size
field-body-center-next-argument-field-leg-top

append-executable
method-draw-line-variable-graphics
sequence-field-body-center-field-body-top
sequence-field-body-center-subtraction-field-arm-size
field-body-top-addition-integer-ten

append-executable
method-draw-line-variable-graphics
field-body-center-subtraction-field-arm-size
field-body-top-addition-integer-ten
field-body-center-subtraction-field-arm-size
subtraction-integer-ten
field-body-top-subtraction-field-arm-size

append-executable
method-draw-line
variable-graphics
field-body-center
field-body-top
field-body-center-addition-field-arm-size
field-body-top-addition-integer-ten

append-executable
method-draw-line
field-when-focused
variable-graphics
field-body-center-addition-field-arm-size
field-body-top-addition-integer-ten
field-body-center-addition-field-arm-size-addition
integer-ten
field-body-top-subtraction-field-arm-size

append-executable
variable-graphics-fill-oval
field-body-center-subtraction-field-head-size-division-integer-two
type
field-body-top
subtraction-field-head-size
subtraction-field-neck-size
field-head-size
field-head-size

append-executable
method-random-color
variable-graphics
append-executable
variable-graphics-fill-oval
field-body-center-subtraction-field-head-size-subtraction-integer-four
field-body-top-subtraction-field-head-size-division-integer-two
subtraction-field-neck-size-subtraction-field-eye-size
field-eye-size
field-eye-size

append-executable
method-random-color-variable-graphics
append-executable
variable-graphics-fill-oval
field-body-center-addition-integer-four
field-body-top-subtraction-field-head-size
division-integer-two
subtraction-field-neck-size
subtraction-field-eye-size
field-eye-size
next-argument
field-eye-size

append-executable
method-random-color-variable-graphics

append-executable
variable-graphics-draw-arc
field-body-center-subtraction-field-eye-size
field-body-top-subtraction-field-head-size-division-integer-two
subtraction-field-neck-size
addition-field-eye-size
division-integer-two
field-eye-size-multiplication-integer-three
field-eye-size
integer-negative-thirty
integer-negative-one-hundered-fifty

	void drawWinner(Graphics2D graphics){
		graphics.translate(0, groundLevel - (legTop + legSize));

		//legs, body
		drawLine(
			graphics, 
			bodyCenter - legSize, 
			legTop + legSize, 
			bodyCenter, 
			legTop);
		drawLine(
			graphics, 
			bodyCenter + legSize, 
			legTop + legSize, 
			bodyCenter, 
			legTop);
		drawLine(
			graphics, 
			bodyCenter, 
			bodyTop - neckSize, 
			bodyCenter, 
			legTop);

		//left arm
		drawLine(
			graphics, 
			bodyCenter, 
			bodyTop, 
			bodyCenter - armSize, 
			bodyTop + 10);
		drawLine(
			graphics, 
			bodyCenter - armSize, 
			bodyTop + 10, 
			bodyCenter - armSize - 10, 
			bodyTop - armSize);

		//right arm
		drawLine(
			graphics, 
			bodyCenter, 
			bodyTop, 
			bodyCenter + armSize, 
			bodyTop + 10);
		drawLine(
			graphics, 
			bodyCenter + armSize, 
			bodyTop + 10, 
			bodyCenter + armSize + 10, 
			bodyTop - armSize);

		//head
		graphics.fillOval(bodyCenter - headSize/2, bodyTop - headSize - neckSize, headSize, headSize);

		//face
		randomColor(graphics);
		graphics.fillOval(bodyCenter - eyeSize - 4, bodyTop - headSize/2 - neckSize - eyeSize, eyeSize, eyeSize);
		randomColor(graphics);
		graphics.fillOval(bodyCenter + 4, bodyTop - headSize/2 - neckSize - eyeSize, eyeSize, eyeSize);
		randomColor(graphics);
		graphics.drawArc(
			bodyCenter - eyeSize, 
			bodyTop - headSize/2 - neckSize + eyeSize/2, 
			eyeSize*3, 
			eyeSize, 
			-30, 
			-150);
	}

HangmanCanvas.java - HangmanCanvas.paint():

append-method-definition
public
Type: paint
add-argument-type-graphics
Type: _g

Instead of this, you could have said:
override-paint

insert-in-block-if-test
field-off-screen-is-equal-to-null-constant
select != group by moving mouse
logical-or
field-off-screen-get-width-is-not-equal-to-method-get-width
select != group by moving mouse
logical-or
field-off-screen-get-height-is-not-equal-to-method-get-height

insert-in-block-executable
field-off-screen-assignment
method-create-image
two-arguments
method-get-width-next-argument-method-get-height
select entire rhs by moving mouse
type-cast-type-buffered-image

insert-in-block-variable-declaration
type-graphics-2-d
Type: g
initialize
field-off-screen-get-graphics
type-cast-type-graphics-2-d

We are going to initialize the size parameters. Alot of these statements are rather long because the expert Happy Hands user tries to save time by saying as much as possible. You can insert pauses if you like.

append-executable
field-top-level-assignment-integer-fifteen

append-executable
field-ground-level-assignment-method-get-height-subtraction-integer-ten

append-executable
field-left-pole-assignment-integer-twenty

append-executable
field-brace-size-assignment-integer-sixty

append-executable
field-body-center-assignment-method-get-width-division-integer-two

append-executable
field-leg-top-assignment
method-get-height-multiplication
floating-point-zero-point-six
Move selection to contain getHeight()*0.6f
type-cast-type-integer

append-executable
field-leg-size-assignment-integer-one-hundred-and-twenty

append-executable
field-body-top-assignment
method-get-height
multiplication-floating-point-point-three
type-cast-type-integer

append-executable
field-arm-size-assignment-integer-one-hundred

append-executable
field-head-size-assignment-integer-eighty

append-executable
field-neck-size-assignment-integer-forty

append-executable
field-eye-size-assignment-integer-fifty

append-if-test
field-game-b-winner
insert-in-block-executable
variable-graphics-set-color
type-color-choose-member
select-field-white

append-else-if-test
field-game-mistake-count-is-greater-than
integer-nine

insert-in-block-executable
variable-graphics-set-color
new-type-color
three-arguments
sequence-integer-two-hundered-fifty-five-integer-one-hundered-ninety-five-integer-one-hundered-ninety-five

append-else-block
insert-in-block-executable
variable-graphics-set-color
new-type-color
three-arguments
sequence-integer-one-hundered-ninety-five-integer-one-hundered-ninety-five-integer-one-hundered-ninety-five

append-executable
variable-graphics-choose-member
select-method-fill-rectangle
four-arguments
integer-zero
integer-zero
method-get-width
method-get-height

append-executable
field-i-color-assignment-integer-zero

append-if-test
field-game-b-winner

insert-in-block-executable
method-draw-winner-variable-graphics

append-else-block

insert-in-block-executable
method-draw-hangman-variable-graphics

append-executable
variable-underscore-g
choose-member
select-method-draw-image
four-arguments
field-off-screen
integer-zero
integer-zero
this-object

	public void paint(Graphics _g){
		if(offScreen == null
		 || offScreen.getWidth() != getWidth()
		 || offScreen.getHeight() != getHeight()){
			offScreen = (BufferedImage)createImage(getWidth(), getHeight());
		}
		Graphics2D graphics = (Graphics2D)offScreen.getGraphics();
		topLevel = 15;
		groundLevel = getHeight() - 10;
		leftPole = 20;
		braceSize = 60;
		bodyCenter = getWidth()/2;
		legTop = (int)(getHeight()*0.6f);
		legSize = 120;
		bodyTop = (int)(getHeight()*0.3f);
		armSize = 100;
		headSize = 80;
		neckSize = 40;
		eyeSize = 15;

		//clear
		if(game.bWinner){
			graphics.setColor(Color.white);
		}
		else if(game.mistakeCount > 9){
			graphics.setColor(new Color(255, 195, 195));
		}
		else{
			graphics.setColor(new Color(195, 195, 195));
		}
		graphics.fillRect(0, 0, getWidth(), getHeight());
		iColor = 0;

		//ground
		if(game.bWinner){
			drawWinner(graphics);
		}
		else{
			drawHangman(graphics);
		}
		_g.drawImage(offScreen, 0, 0, this);
	}

AnswerCanvas.java - AnswerCanvas.paint():

append-method-definition
override-paint
Type: graphics

insert-in-block-if-test
field-game-partial-word
is-equal-to-null-constant

insert-in-block-return

append-variable-declaration
type-string
Type: partialWord
initialize
field-game-partial-word
choose-member
select-method-to-string

append-variable-declaration
Type: wordWidth
initialize
field-fm-string-width
variable-partial-word

append-variable-declaration
Type: x
initialize
method-get-width-type
subtraction-variable-word-width
division-integer-two

append-variable-declaration
Type: fontHeight
initialize
field-fm-get-height

append-variable-declaration
initialize
Type: wordY
variable-font-height-addition-integer-ten

append-executable
variable-graphics-set-color
new-type-color
three-arguments
integer-one-hundered-twenty-seven
integer-two-hundered-fifty-five
integer-one-hundered-twenty-seven

append-executable
variable-graphics-fill-rectangle
integer-zero-integer-zero
integer-zero
method-get-width
method-get-height

append-executable
variable-graphics-set-font
field-font

append-executable
variable-graphics-set-color
type-color-choose-member
select-field-black

append-if-test
field-game-load-progress
is-not-equal-to-integer-negative-one

insert-in-block-executable
variable-graphics-draw-string
string-constant
addition
field-game-load-progress
integer-ten-next-argument
variable-word-y
append-return

append-executable
variable-graphics-draw-string
variable-partial-word
next-argument-variable-x
next-argument-variable-word-y

append-variable-declaration
Type: y
initialize
variable-word-y
addition-integer-ten

append-variable-declaration
Type: charWidth
initialize
variable-word-width
division
type-variable-partial-word-length
variable-partial-word-length

append-for-loop
declare-initializer
Type: i
enter-condition
variable-i-is-less-than-variable-partial-word-length
enter-incrementer
variable-i-post-increment

insert-in-block-executable
variable-graphics-draw-line
variable-x-addition-integer-one
variable-y
variable-x-addition
variable-character-width
subtraction-integer-one
variable-y
Copy previous line and add 1 to 2nd and 4th arguments
copy-selection
append-copy
addition-integer-one
addition-integer-one

append-executable
variable-x-addition-assign
variable-character-width

append-variable-declaration
Type: definition
type-string
initialize
field-game-current-word-choose-member
select-field-definition

append-if-test
variable-definition-is-not-equal-to-null-constant

insert-in-block-executable
variable-word-width-assignment
field-fm-2-string-width
variable-definition

append-executable
variable-x-assignment
method-get-width-subtraction-variable-word-width
division-integer-two

append-executable
variable-font-height-assignment
field-fm-2-get-height

append-executable
variable-graphics-set-font
field-font-2

append-executable
variable-graphics-draw-string
variable-definition
variable-x
variable-word-y-addition-variable-fontHeight

	public void paint(Graphics graphics){
		if(game.partialWord == null){
			return;
		}
		String partialWord = game.partialWord.toString();
		int wordWidth = fm.stringWidth(partialWord);
		int x = (getWidth() - wordWidth)/2;
		int fontHeight = fm.getHeight();
		int wordY = fontHeight + 10;
		graphics.setColor(new Color(127, 255, 127));
		graphics.fillRect(0, 0, getWidth(), getHeight());
		graphics.setFont(font);
		graphics.setColor(Color.black);
		if(game.loadProgress != -1){
			graphics.drawString("Loading, please wait. " + game.loadProgress + " words.", 10, wordY);
			return;
		}
		graphics.drawString(partialWord, x, wordY);
		int y = wordY + 10;
		int characterWidth = wordWidth/partialWord.length();
		for (int i = 0; i < partialWord.length(); i++){
			graphics.drawLine(x + 1, y, x + charWidth - 1, y);
			graphics.drawLine(x + 1, y + 1, x + charWidth - 1, y + 1);
			x+= characterWidth;
		}
		String definition = game.currentWord.definition;
		if(definition != null){
			wordWidth = fm2.stringWidth(definition);
			x = (getWidth() - wordWidth)/2;
			fontHeight = fm2.getHeight();
			graphics.setFont(font2);
			graphics.drawString(definition, x, wordY + fontHeight + 10);
		}
	}

LetterCanvas.java - LetterCanvas.MouseHandler:

append-class-definition
Type: MouseHandler
implements-type-mouse-motion-listener
implements-type-mouse-listener

LetterCanvas.MouseHandler.mouseMoved

insert-in-block-method-definition
public
Type: mouseMoved
add-argument-type-mouse-event
Type: e

insert-in-block-executable
field-over-letter-index-assignment
variable-e-get-y
division
field-letter-height

append-if-test
field-over-letter-index-is-greater-than-or-equal-to
field-game-letters
choose-member
select-method-length

insert-in-block-executable
field-over-letter-index-assignment-integer-negative-one

append-executable
method-repaint

LetterCanvas.MouseHandler.mouseDragged

append-method-definition
Type: mouseDragged
public
add-argument-type-mouse-event
Type: e

LetterCanvas.MouseHandler.mousePressed

append-method-definition
override-mouse-pressed

insert-in-block-if-test
field-over-letter-index-is-greater-than-integer-negative-one

insert-in-block-executable
field-game-try-letter
field-over-letter-index

LetterCanvas.MouseHandler.mouseReleased

append-method-definition
override-mouse-released
Type: e

LetterCanvas.MouseHandler.mouseClicked

append-method-definition
override-mouse-clicked
Type: e

LetterCanvas.MouseHandler.mouseExited

append-method-definition
override-mouse-exited
Type: e

insert-in-block-executable
field-over-letter-index-assignment
integer-negative-one
append-executable
method-repaint

LetterCanvas.MouseHandler.mouseEntered

append-method-definition
override-mouse-entered
Type: e

LetterCanvas.LetterCanvas

append-method-definition
public-constructor

insert-in-block-executable
field-metrics-assignment
method-get-font-metrics
field-font

append-executable
method-add-mouse-motion-listener
new-type-mouse-handler

append-executable
method-add-mouse-listener
new-type-mouse-handler

	class MouseHandler implements MouseMotionListener, MouseListener{
		public void mouseMoved(MouseEvent e){
			overLetterIndex = e.getY()/letterHeight;
			if(overLetterIndex >= game.letters.length()){
				overLetterIndex = -1;
			}
			repaint();
		}

		public void mouseDragged(MouseEvent e){
		}

		public void mousePressed(MouseEvent e){
			if(overLetterIndex > -1){
				game.tryLetter(overLetterIndex);
			}
		}

		public void mouseReleased(MouseEvent e){
		}

		public void mouseClicked(MouseEvent e){
		}

		public void mouseExited(MouseEvent e){
			overLetterIndex = -1;
			repaint();
		}

		public void mouseEntered(MouseEvent e){
		}
	}

LetterCanvas.java - LetterCanvas.paint():

append-method-definition
override-paint
insert-in-block-variable-declaration
Type: x
initialize
integer-ten

append-variable-declaration
Type: y

append-variable-declaration
Type: letters
type-string
initialize
field-game-letters

append-if-test
variable-letters
is-equal-to-null-constant
insert-in-block-return

append-executable
field-letter-height-assignment-field-metrics-get-height
addition-integer-four

append-executable
variable-graphics-set-color
new-type-color
three-arguments
integer-one-hundred-twenty-seven
integer-one-hundred-twenty-seven
integer-two-hundred-fifty-five

append-executable
variable-graphics-fill-rectangle
sequence-integer-zero-integer-zero-method-get-width-method-get-height

append-executable
variable-graphics-set-font
field-font

append-for-loop
declare-initializer
enter-condition
variable-i-is-less-than-variable-letters-length
enter-incrementer
variable-i-post-increment

insert-in-block-variable-declaration
Type: letter
type-string
initialize
variable-letters-substring
two-arguments
variable-i
variable-i-addition-integer-one

append-if-test
variable-i-is-equal-to
field-over-letter-index

insert-in-block-executable
variable-graphics-set-color
type-color-choose-member
select-field-gray

append-executable
variable-graphics-fill-rectangle
integer-zero
variable-y-addition-integer-one
method-get-width
field-letter-height

append-executable
variable-graphics-set-color
type-color-choose-member
select-field-black

append-executable
variable-graphics-draw-string
variable-letter
variable-x
variable-y
addition
field-metrics-get-height

append-executable
variable-y-addition-assign
field-letter-height

append-executable
variable-graphics-draw-line
integer-zero
variable-y
method-get-width
variable-y

	public void paint(Graphics g){
		int x = 10;
		int y = 0;
		String letters = game.letters;
		if(letters == null){
			return;
		}
		letterHeight = metrics.getHeight() + 4;
		g.setColor(new Color(127, 127, 255));
		g.fillRect(0, 0, getWidth(), getHeight());
		g.setFont(font);
		for (int i = 0; i < letters.length(); i++){
			String letter = letters.substring(i, i + 1);
			if(i == overLetterIndex){
				g.setColor(Color.gray);
				g.fillRect(0, y + 1, getWidth(), letterHeight);
			}
			g.setColor(Color.black);
			g.drawString(letter, x, y + metrics.getHeight());
			y+= letterHeight;
			g.drawLine(0, y, getWidth(), y);
		}
	}

LetterCanvas.java - LetterCanvas.LetterCanvas():

append-method-definition
public-constructor

insert-in-block-executable
field-metrics-assignment-method-get-font-metrics
field-font

append-executable
method-add-mouse-motion-listener
new-type-mouse-handler

append-executable
method-add-mouse-listener
new-type-mouse-handler

	public LetterCanvas(){
		metrics = getFontMetrics(font);
		addMouseMotionListener(new MouseHandler());
		addMouseListener(new MouseHandler());
	}