Results 1 to 18 of 18
Thread: Stanford CS106a Hangman exercise
- 08-21-2012, 01:24 PM #1
Member
- Join Date
- Jul 2012
- Posts
- 33
- Rep Power
- 0
Stanford CS106a Hangman exercise
Hi
I've literally just begun doing the Hangman exercise on the online Stanford Cs106a course. Here's what I've done;
I was getting an error on line 9 and line 15 that read something like "can't assign static variable to non-static method". The quick fix suggested by Eclipse was to change the methods in the HangmanLexicon class to static. The HangmanLexicon class is a stub written by Stanford that you use till later in the exercise, when you link the game to a file with a bigger lexicon. I'm just wondering if I'm storing up problems for later if I leave it like this? Is there something I'm doing wrong?Java Code:public class Hangman extends ConsoleProgram { public void run() { createNewLexicon(); playHangman(); } private void createNewLexicon() { lexicon = HangmanLexicon.getWordCount(); } private void playHangman() { println("Welcome to Hangman!"); int nextword = rgen.nextInt(lexicon); String secretword = HangmanLexicon.getWord(nextword); //get random number from lexicon then use getword to return the string of the secret word. } private int lexicon; private RandomGenerator rgen = RandomGenerator.getInstance(); }
Thanks! R
- 08-21-2012, 04:03 PM #2
Re: Stanford CS106a Hangman exercise
Create an instance of the class using a new statement and use a reference to that instance to call its methods.
Don't create a new instance of the class every time you want to call one of its methods. Create one instance and use it as needed.Java Code:AClass aRef = new AClass(); // create an instance aRef.methodInAClass(); // call a method
If you don't understand my response, don't ignore it, ask a question.
- 08-21-2012, 06:31 PM #3
Member
- Join Date
- Jul 2012
- Posts
- 33
- Rep Power
- 0
- 08-22-2012, 02:11 PM #4
Member
- Join Date
- Jul 2012
- Posts
- 33
- Rep Power
- 0
Re: Stanford CS106a Hangman exercise
Hi Norm
I did some more work on this. Here's where I'm at;
Before moving on to writing the updateStringState method at line 53, I thought I'd check the correctOrIncorrect one at 42. I decided to use a boolean to check if it's a correct answer- so as to create two threads for the different effects on turn count and the lines printed after failed or successful guesses. Then if it's a correct guess, the stringstate is fed to the updateStringState method.Java Code:public class Hangman extends ConsoleProgram { public void run() { createNewLexicon(); playHangman(); } private void createNewLexicon() { lexicon = lexgen.getWordCount(); } private void playHangman() { println("Welcome to Hangman!"); int nextword = rgen.nextInt(lexicon); secretword = lexgen.getWord(nextword); wordlength = secretword.length(); String initstate = "-"; for (int i = 0; i < wordlength; i++) { //creates the initial state of the word as seen by the player initstate = "-" + initstate; } println("The word now looks like this:" + initstate); turns = 8; println("You have 8 guesses left."); stringstate = initstate; while (turns > 0) { String guess = readLine("Your guess: "); if (correctOrIncorrect(guess) == true) { println("That guess is correct"); println("The word now looks like this:" + (updateStringState(stringstate, guess))); println("You have " + turns + " guesses left."); } else { println("There are no " + guess + "'s in the word."); turns--; println("The word now looks like this:" + stringstate); println("You have " + turns + " guesses left."); } } } private boolean correctOrIncorrect(String guess) { for (int check = 0; check <= wordlength; check++) { String checkpart = secretword.substring(check, check); if (checkpart.equalsIgnoreCase(guess) == true) { return(true); } } return(false); } private String updateStringState(String stringstate, String guess) { String result = ""; return result; } private int wordlength; private String stringstate; private String secretword; private int lexicon; private int turns; private RandomGenerator rgen = RandomGenerator.getInstance(); private HangmanLexicon lexgen = new HangmanLexicon(); }
However, correctOrIncorrect is only giving replies of false. I'm assuming that it's possible to use strings of one character? Substring(p1, p2) subdivides the string at position one and everything up to but not including position 2. If I convert guess into a char, there doesnt seem to be many methods I can use...
- 08-22-2012, 02:26 PM #5
Re: Stanford CS106a Hangman exercise
Try debugging the code to see what it is doing. Add some println statements to print out the values of the variables used in the method to see what the computer sees when it executes the code.correctOrIncorrect is only giving replies of false.If you don't understand my response, don't ignore it, ask a question.
- 08-22-2012, 02:35 PM #6
Member
- Join Date
- Jul 2012
- Posts
- 33
- Rep Power
- 0
- 08-22-2012, 02:47 PM #7
Re: Stanford CS106a Hangman exercise
Read the API doc for the methods you are using to make sure you are using them correctly.substring is coming up blankIf you don't understand my response, don't ignore it, ask a question.
- 08-22-2012, 06:42 PM #8
Member
- Join Date
- Jul 2012
- Posts
- 33
- Rep Power
- 0
Re: Stanford CS106a Hangman exercise
Yes, what I was trying to do wasn't possible with that method. So I used a char instead and that part of it now works;
Now the problem is that stringstate is not being updated. I've made it an ivar thinking that when it gets passed back at lines 66-68 the ivar will be updated, So when it gets called, again after a new guess at line 30, or is used at line 36, it will be the most recent, updated version. Clearly its being wiped at some point and is returning to it's initial state. Do I misunderstand what an ivar does?Java Code:public class Hangman extends ConsoleProgram { public void run() { createNewLexicon(); playHangman(); } private void createNewLexicon() { lexicon = lexgen.getWordCount(); } private void playHangman() { println("Welcome to Hangman!"); int nextword = rgen.nextInt(lexicon); secretword = lexgen.getWord(nextword); wordlength = secretword.length(); String initstate = ""; for (int i = 0; i < wordlength; i++) { //creates the initial state of the word as seen by the player initstate = "-" + initstate; } println("The word now looks like this:" + initstate); turns = 8; println("You have 8 guesses left."); stringstate = initstate; while (turns > 0) { String input = readLine("Your guess: "); //convert to upper case at this point String guess = input.toUpperCase(); if (correctOrIncorrect(guess) == true) { println("That guess is correct"); println("The word now looks like this:" + (updateStringState(stringstate, guess))); println("You have " + turns + " guesses left."); } else { println("There are no " + guess + "'s in the word."); turns--; println("The word now looks like this:" + stringstate); println("You have " + turns + " guesses left."); } } } private boolean correctOrIncorrect(String guess) { for (int check = 0; check < wordlength; check++) { Character checkpart = secretword.charAt(check); Character guesspart = guess.charAt(0); if (guesspart == checkpart) { return(true); } } return(false); } private String updateStringState(String stringstate, String guess) { String result = ""; for (int check = 0; check < wordlength; check++) { Character checkchar = secretword.charAt(check); Character guesschar = guess.charAt(0); if (guesschar == checkchar) { String part1 = stringstate.substring(0, check); String part2 = stringstate.substring(check + 1); result = part1 + guess + part2; } } stringstate = result; return stringstate; } private int wordlength; private String stringstate; private String secretword; private int lexicon; private int turns; private RandomGenerator rgen = RandomGenerator.getInstance(); private HangmanLexicon lexgen = new HangmanLexicon(); }
- 08-22-2012, 06:50 PM #9
Member
- Join Date
- Jul 2012
- Posts
- 33
- Rep Power
- 0
Re: Stanford CS106a Hangman exercise
Ok I'm being a moron, I can see I've done that myself by setting result to "" at the beginning of that method. Ignore me...
- 08-22-2012, 06:54 PM #10
Senior Member
- Join Date
- Oct 2011
- Location
- Sweden
- Posts
- 123
- Rep Power
- 0
Re: Stanford CS106a Hangman exercise
(Ignoring)
Last edited by Zyril; 08-22-2012 at 06:55 PM. Reason: OP solved problem...
- 08-27-2012, 03:26 PM #11
Member
- Join Date
- Jul 2012
- Posts
- 33
- Rep Power
- 0
Re: Stanford CS106a Hangman exercise
Hiya
A few days ago you helped me with this Hangman problem. I've now finished the main program, which looks like this;
I'm now working on the Hangman canvas, which is behaving strangely. It's a split console/graphics game, with the narrative of the game unfolding in the console and then the scaffold etc in the canvas. The course PDF instructs you to reset the canvas at the beginning of the game with a reset method (line 6 below) in the HangmanCanvas class. According to the PDF you're supposed to put the scaffold in this method. In the same class there's another method called NoteIncorrectGuess (line 42 below) where you put the body parts etc for wrong guesses. Here's where I'm at with the Hangman class;Java Code:public class Hangman2 extends ConsoleProgram { public void init() { canvas = new HangmanCanvas(); add(canvas); canvas.reset(); } public void run() { createNewLexicon(); playHangman(); endGame(); } private void createNewLexicon() { lexicon = lexgen.getWordCount(); } private void playHangman() { println("Welcome to Hangman!"); int nextword = rgen.nextInt(lexicon); secretword = lexgen.getWord(nextword); wordlength = secretword.length(); String initstate = ""; for (int i = 0; i < wordlength; i++) { //creates the initial state of the word as seen by the player initstate = "-" + initstate; } println("The word now looks like this:" + initstate); turns = 8; println("You have 8 guesses left."); stringstate = initstate; int checknum = 0; canvas.displayWord(stringstate); while (turns > 0) { String input = readLine("Your guess: "); //convert to upper case at this point String guess = input.toUpperCase(); Character ch = guess.charAt(0); if (checkLength(guess) == false || Character.isLetter(ch) == false) { println("That is an illegal guess ning-nong, try again."); } if (correctOrIncorrect(guess) == true && checkLength(guess) == true && Character.isLetter(ch) == true && checkRepeat(guess) == false) { println("That guess is correct"); checknum = checkCharIncidence(guess) + checknum; for (int check = 0; check < wordlength; check++) { Character checkchar = secretword.charAt(check); Character guesschar = guess.charAt(0); if (guesschar == checkchar) { String part1 = stringstate.substring(0, check); String part2 = stringstate.substring(check + 1); stringstate = part1 + guess + part2; canvas.displayWord(stringstate); } } if (checknum == wordlength) { println ("You guessed the word " + secretword); println ("You win."); endGame(); } println("The word now looks like this:" + stringstate); println("You have " + turns + " guesses left."); } if (correctOrIncorrect(guess) == false && Character.isLetter(ch) == true && checkLength(guess) == true) { canvas.noteIncorrectGuess(ch); println("There are no " + guess + "'s in the word."); turns--; println("The word now looks like this:" + stringstate); println("You have " + turns + " guesses left."); } } println("You are completely hung! Aaaaargh!"); println("The word was: " + secretword); println("You lose."); endGame(); } private boolean correctOrIncorrect(String guess) { for (int check = 0; check < wordlength; check++) { Character checkpart = secretword.charAt(check); Character guesspart = guess.charAt(0); if (guesspart == checkpart) { return(true); } } return(false); } private boolean checkRepeat(String guess) { for (int check = 0; check < wordlength; check++) { Character checkpart = secretword.charAt(check); Character guesspart = guess.charAt(0); if (guesspart == checkpart) { Character checkstringstate = stringstate.charAt(check); if (checkpart == checkstringstate) { return(true); } } } return(false); } private int checkCharIncidence(String guess) { int checknum = 0; for (int times = 0; times < wordlength; times++) { Character checkagainst = secretword.charAt(times); Character checkwith = guess.charAt(0); if (checkagainst == checkwith) { checknum++; } } return checknum; } private boolean checkLength(String guess) { int length = guess.length(); if (length > 1) { return false; } else { return true; } } private void endGame() { pause(9000); System.exit(0); } private HangmanCanvas canvas; private int wordlength; private String stringstate; private String secretword; private int lexicon; private int turns; private RandomGenerator rgen = RandomGenerator.getInstance(); private HangmanLexicon lexgen = new HangmanLexicon(); }
The reason why the maths in the graphics statements is all-over the place is because the canvas appears to behave differently from the reset method. I was getting in a muddle trying to work out why they arent behaving the same. On line 15 I made a test line that, on the normal canvas, would create a line going diagonally across the canvas. As far as I can make out, it appears to be a point in the top left hand corner. Normally the x coordinate should go up left to right and the y should go up top to bottom.Java Code:public class HangmanCanvas extends GCanvas { /** Resets the display so that only the scaffold appears */ public void reset() { wrongguessnum = 0; int width = getWidth(); GLine scaffold = new GLine(width + 50, getHeight() / 2 + SCAFFOLD_HEIGHT / 2 + 200, width + 50, getHeight() / 2 - SCAFFOLD_HEIGHT / 2 + 200); add(scaffold); GLine beam = new GLine(width + 50, getHeight() / 2 - SCAFFOLD_HEIGHT / 2 + 200, width + 50 + BEAM_LENGTH, getHeight() / 2 - SCAFFOLD_HEIGHT / 2 + 200); add(beam); GLine string = new GLine(width + 50 + BEAM_LENGTH, getHeight() / 2 - SCAFFOLD_HEIGHT / 2 + 200, width + 50 + BEAM_LENGTH, getHeight() / 2 - SCAFFOLD_HEIGHT / 2 + 200 + ROPE_LENGTH); add(string); GLine testline = new GLine(0, 0, getWidth(), getHeight()); testline.setColor(Color.RED); add(testline); } /** * Updates the word on the screen to correspond to the current * state of the game. The argument string shows what letters have * been guessed so far; unguessed letters are indicated by hyphens. */ public void displayWord(String word) { GObject last = getElementAt(getWidth() / 8, getHeight() - 50); if (last != null) { remove(last); } GLabel stringstate = new GLabel(word, getWidth() / 8, getHeight() - 50); stringstate.setFont("Ariel-28"); add(stringstate); } /** * Updates the display to correspond to an incorrect guess by the * user. Calling this method causes the next body part to appear * on the scaffold and adds the letter to the list of incorrect * guesses that appears at the bottom of the window. */ public void noteIncorrectGuess(char letter) { GObject last = getElementAt(getWidth() / 8, getHeight() - 25); if (last == null) { incorrectguess = ""; incorrectguess = incorrectguess + letter; GLabel badguesses = new GLabel(incorrectguess, getWidth() / 8, getHeight() - 25); badguesses.setFont("Ariel-18"); add(badguesses); } if (last != null) { remove(last); incorrectguess = incorrectguess + letter; GLabel badguesses = new GLabel(incorrectguess, getWidth() / 8, getHeight() - 25); badguesses.setFont("Ariel-18"); add(badguesses); } wrongguessnum++; switch (wrongguessnum) { case 1 : GOval head = new GOval(getWidth() / 2 - HEAD_RADIUS, getHeight() / 2 - SCAFFOLD_HEIGHT / 2 - HEAD_RADIUS + ROPE_LENGTH, HEAD_RADIUS, HEAD_RADIUS); head.setFilled(false); add(head); break; case 2 : GLine body = new GLine(getWidth() / 2, getHeight() / 2 - SCAFFOLD_HEIGHT / 2 - HEAD_RADIUS + ROPE_LENGTH / 2, getWidth() / 2, getHeight() / 2 + BODY_LENGTH / 2); add(body); break; case 3 : case 4 : case 5 : case 6 : case 7 : case 8 : case 9 : } } /* Constants for the simple version of the picture (in pixels) */ private static final int SCAFFOLD_HEIGHT = 360; private static final int BEAM_LENGTH = 144; private static final int ROPE_LENGTH = 18; private static final int HEAD_RADIUS = 36; private static final int BODY_LENGTH = 144; private static final int ARM_OFFSET_FROM_HEAD = 28; private static final int UPPER_ARM_LENGTH = 72; private static final int LOWER_ARM_LENGTH = 44; private static final int HIP_WIDTH = 36; private static final int LEG_LENGTH = 108; private static final int FOOT_LENGTH = 28; private String incorrectguess; private int wrongguessnum; }
Is there a reason why the reset method would cause the canvas to operate differently?
Thanks!
- 08-27-2012, 03:56 PM #12
Re: Stanford CS106a Hangman exercise
It's impossible/very difficult to test the code because it uses third party classes.
If you don't understand my response, don't ignore it, ask a question.
- 08-27-2012, 06:06 PM #13
Member
- Join Date
- Jul 2012
- Posts
- 33
- Rep Power
- 0
Re: Stanford CS106a Hangman exercise
Yes, the ACM library. HangmanCanvas imports
import java.awt.Color;
import acm.graphics.*;
and Hangman imports
import acm.program.*;
import acm.util.*;
I was hoping you'd spot something obvious. The course is taken by so many students both at Stanford and online, I figured maybe I was writing the reset method wrong...
- 08-27-2012, 06:24 PM #14
Re: Stanford CS106a Hangman exercise
I don't know anything about the acm packages and classes so I can't determine what the code is doing or if it is doing it correctly.
I guess the forum needs a special section for users of the acm package.If you don't understand my response, don't ignore it, ask a question.
- 08-27-2012, 07:31 PM #15
Member
- Join Date
- Jul 2012
- Posts
- 33
- Rep Power
- 0
- 08-27-2012, 07:56 PM #16
Member
- Join Date
- Jul 2012
- Posts
- 33
- Rep Power
- 0
Re: Stanford CS106a Hangman exercise
Actually it is the methods from the acm package, in this specific context. For some reason when you use getWidth() and getHeight() in relation to the reset method, they both return 0. Which is confusing cos the PDF specifically tells you to do the scaffold from the reset method. Maybe that's what you're supposed to discover. Even if you write a new drawScaffold method and call it from reset, they still return zero.
- 08-27-2012, 08:02 PM #17
Re: Stanford CS106a Hangman exercise
If you rewrite the program using java SE there might be more people that could help you.
If you don't understand my response, don't ignore it, ask a question.
- 08-27-2012, 08:16 PM #18
Member
- Join Date
- Jul 2012
- Posts
- 33
- Rep Power
- 0
Re: Stanford CS106a Hangman exercise
You have helped me, a great deal. I wrote a GLabel, which is the graphics package's version of println, to read out the values of getWidth() and getHeight()- which is what you told me to do earlier in this thread on a separate problem. Now I know what it's doing I can write the scaffold accordingly.
This course is good, as of a couple of months ago I had done no programming whatsoever. Should have finished it in another month or so I think. I'm just trying to learn the fundamentals before moving on to C++...
Similar Threads
-
Stanford CS106a breakout assignment
By Newbieprogrammer in forum New To JavaReplies: 3Last Post: 08-14-2012, 10:18 AM -
Stanford CS106a GraphicsHeirarchy
By Newbieprogrammer in forum New To JavaReplies: 0Last Post: 07-15-2012, 07:37 PM -
Stanford cs106a
By D.good in forum IntroductionsReplies: 1Last Post: 02-04-2012, 06:18 PM -
CS106A Stanford University
By Learning Java in forum New To JavaReplies: 116Last Post: 07-09-2011, 04:43 PM -
Class exercise CS106A (Stanford university)
By ccie007 in forum New To JavaReplies: 2Last Post: 09-11-2010, 01:47 AM


LinkBack URL
About LinkBacks
Reply With Quote

Bookmarks