CS106A Assignment 4 – Hangman

The URS.

Hangman.

  • 12 days to program.
  • Create a Hangman program using multiple classes in a single application.
  • Part 1
  • Program to select a word at random (from a supplied list).
  • Print out series of dashes representing word.
  • User guesses a letter.  If letter wrong, add piece to hangman drawing.  If correct, show letter in place of dash(es).  Source works in caps, user must be allowed to enter in upper or lower case and if multiple chars are entered, an error should be printed in the console and the game should re-prompt for a character.  If a correctly guessed letter is re-input, program should not reduce turns or accept the char, just re ask for a char, though the flip side of this is that if the same wrong char is guessed again, the program does count down.
  • Game ends when either word guessed or man/female/thing hung by the neck until it is dead.

Part 2:

Add  graphical elements to the program that:

  • draw the scaffold and the various body parts – scaffold to be to the left and a little higher than screen center. body parts to be aligned to the center of the RHS window
  • show a graphical text object in the same manner as the dashes in the text only version. Show this below the scaffold (more of less left aligned
  • show the words guessed so far.  Place under the dashes with same alignment, settlers about 45% size of the above element.

Started 28/04/2017 – Completed 10/05/2017.  About half of that was thinking about the project as life intruded.

Program Setup

Design and test in 3 parts:

  1. get interactive portion working with no graphics.
  2. build a separate class that maintain the scaffold diagram (hangman).
  3. replace supplied secret word list with one that reads from a file.  (this could extend Breakout by saving high scores…)

Creating the Program Including Beta Testing

Part 1

Here I used the principle of top down design.  An example of the first iteration of this follows:

public void run() {
/* You fill this in */
//      HangmanLexicon.getWord = chosenWord; // assignment says operation performed once if the program extended to run repeatedly so it need to be outside the gameplay loop.
welcomeMessage();
determineWord(); // included in HangmanLexicon class as getWord(i)
putChosenWordInArray();
lettersLeft(); // while i
askForLetter();
determineIfLetterInWord();
guessCorrect(); //(if loop) = if livesLeft >0 and all chars guessed, player wins,
guessWrong();//(if loop) = if livesLeft <0 and not all guessed, player loses
playerLoses();
playerWins();
}

I then got stuck into the coding.  I needed to jump online for some help to figure out how to call the HangmanLexicon class.  That wound up being really simple – private HangmanLexicon chosenWords = new HangmanLexicon();

From there I could set up my random generator to grab a word out of the class and away I went without looking at any completed program online.  My resources were a lots of PDF’s from the course, the Java website and a pen and pad to scribble down ideas.

A couple of the methofs do more than one thing.  I plan on cleaning that up before I close this project.  At the conclusion of part one, some code works in certain methods, but when taken out and put in its own and then called, things get iffy.  A couple of times I needed to set up if statements in the correct order and I feel I should be using boolean statements more than I am, especially as the course documentation says boolean statements are very important in programming.

A won game vs a lost game showing the various error checks required.

A won game vs a lost game showing the various error checks required.

Completed 03/05/2017

Part 2

This began with a big fat ?  It was back to my GLine’s etc to work out the code.

It was not much trouble to draw the body parts or two get the GLabel’s onto the canvas (at least in test form).  I had to make the gallows structurally sound by drawing in bracing.  No sticking the pole in concrete in the ground here.

The real question, though was how to get the body parts to draw if there was an error and how to get the GLabels to update?  Can I just call them canvas.bla’s from the main program and they would magically display or not?

Initial bit of Part 2 Completed.

Initial bit of Part 2 Completed.

Telling to program to draw the dashes updater sort of worked at the start.  I needed to think about how to remove the existing label.  I tried to tell the main code to remove the canvas item – all it would do was say bla de bla could not be resolved.

How to fix this?

How to fix this?

I knew I needed to check the the presence of the label before drawing it.  However, I tried quite a few checks along the lines of “if (obscuredWord.getElementAt(labelX, labelY) != 0)” etc before working out the actual label name was not needed.   It also looked like I needed to specify the x and y coords of the label before the checks (not when drawing it) to get the code to work.  A frustrating hour or so of trial and error.  In the end I got rid of some offsets and worked out where to draw the label with the x and y coords only.  After that, the label did not draw another one over the top of itself.  Woo hoo.

The same label check for the obscured word was recycled for the incorrect guess label.

At the end of part 2, this is what is produce on screen.

At the end of part 2, this is what is produce on screen.

Part 3

Before starting to code this section, it was time to watch Lecture 16 and Lecture 17  (here the lecturer appeared to be dressed as Evil Spock). The assignment handout suggested this section would be easy.  It was.  The hardest bit was figuring out how to tell the array to read the file of words.  My code for that was a little buggy – I’d get the Welcome to Hangman message, and that was that. The debugger would show the array was being filled.

The program hung at return “getWordCount;” where return “getWordCount = wordList.size();”.  However, this would only give me a “0”. Setting “getWordCount” to specific numbers would pull the word at getWordCount  from the list and this would not be randimised.  getWordCount  is supposed to be passed into the random generator and I should not need to change any code in the main program….so, what’s wrong with the code. I did use a switch statement for the list of words in HangmanLexicon.  Perhaps I need something similar, but why is the result not being passed back to the main program and back to the next method?

Hmm. My code in the getWord method was  “return wordList.get(getWordCount);”. Changing this to getWordCount(index) got the program working correctly and curiously, the WordList.size() started returning the correct value.   I confirmed this using the debugger.  Odd.  I must not be viewing the correct break point.  Oh well, the program works as per the URS and appears not to be buggy.  Job done.

With the code changes, the program performed in the same manner as it does at the end of part 2, however the list of potential words to choose from is greatly expanded!

The Shipped Program

As above.  I’m not coding any extensions as I know how to do them and I’ve spent too long on this assignment already as the 12 days are up.  The final word gets printed out under the dead dude.  Bonus bug caused by resizing screen as word very long.

Packaged Jar file.  Extract zipped contents and run the hangman.jar file if you have java installed on your system.

CS106A hangman final - wow, I got that one out!

CS106A hangman final – wow, I got that one out!

Program Modifications / Extensions

  • Draw the final dead dude and gallows.  Chop it up in Photoshop and then draw it onto the canvas as the game goes along.
  • Once dead, make dude’s head angle to one side and put a red “x” on each eye.
  • Remove a part if two letters guessed correctly in a row. did not implement
  • Add the construction of the gallows to the “lives” list so around 12 turns lost = end game. did not implement, mostly as the current code taught me enough in this regard

SummarySave

Save

Save

Summary

During this project, I tried to format my comments and space out the code better (should that be nicer) than previously.

It was nice to only “need” to look at a line of existing code for part one and another for part two and being able to figure out all of part three on my own.

Lessons Learned

  • How arrays can be used to automatically suck information from a file.
  • How to show text and graphics images side by side
  • How the getElement function works (I was a bit fuzzy on it after Assignment 3).