Doug Smith
Doug Smith

Reputation: 29314

Could anyone help me with why my Java method isn't quite doing what I'm expecting it to do?

For a class project, we have to create a hangman game in Java (we're starting off with object oriented programming, so this is getting us used to it) and I have the class file then the main file.

Everything's working great, but I want one of my methods in the class file to tell the player if they've already guessed a particular character.

Basically, the method uses a for loop to add the guessed characters into a character array, and every time the player guesses it checks to see if that character is there (if it is, it breaks out of the loop) and if not, and the index value is 0 (this means it's unwritten, right?) it will write the character that was guessed to that index value.

The only other thing that I don't think is self explanatory in the code, is that if the player has yet to make any guesses, it makes the first value the guess, so it has something to start with in the array.

Any help would be appreciated, and if anyone has any input on how to improve my code or whatever, I'd be happy to hear that as well. Thanks so much. :)

public void makeGuess(char c) { 
    boolean alreadyGuessed = false, anyMatches = false;
    matches = 0;
    guesses++;
    if (guesses == 1) {
        guessedChars[0] = c;
    }
    for (int i = 0; i < guessedChars.length; i++) { //it goes through it and will see that it was already guessed
        if (guessedChars[i] == c) {
            alreadyGuessed = true;
            break;
        }
        else if (guessedChars[i] != c && guessedChars[i] == 0) {
            guessedChars[i] = c;
        }
    }

    if (alreadyGuessed == false) {
        for (int i = 0; i < word.length; i++) {
            if (word[i] == c) {
                anyMatches = true;
                matches++;
                disguisedWord[i] = c;
            }
        }
    }       
    if (anyMatches == true) {
        System.out.println("You guessed correctly!");
        System.out.println("There were " + matches + " matches.");
    }
    else if (alreadyGuessed == true) {
        System.out.println("You already guessed this letter, derp.");
    }
    else {
        System.out.println("Sorry, that character is not in the word to be guessed.");
        wrongGuesses++;
    }
//      for (int i = 0; i < guessedChars.length; i++) {
//          System.out.print(guessedChars[i] + " "); 
//      }       
    }

MAIN METHOD:

import java.util.Scanner;
class HangmanDemo {
    public static void main(String[] args) {
        //Object initialization
        Scanner keyboard = new Scanner(System.in);
        Hangman word = new Hangman("jordan");

        //Variable declaration
        char letterGuess;
        int limit;

        //Interact with user
        System.out.print("What would you like the limit of guesses to be: ");
        limit = keyboard.nextInt();

        //BEGIN ZE GAME
        while (word.isFound() == false && word.getWrongGuessCount() <= limit) {
            System.out.println();
            System.out.print("Letter guess: ");
            letterGuess = keyboard.next().charAt(0);
            word.makeGuess(letterGuess);
            System.out.println(word.getDisguisedWord());
        }
        if (word.getGuessCount() == limit) {
            System.out.println("\nSorry, too many guesses.");
        }
        else {
            System.out.println("\nCongratulations! You succesfully solved the word!");
        }
    }
}

Upvotes: 0

Views: 308

Answers (4)

Felix
Felix

Reputation: 566

One possible solution is to use the integer value of an char, because every letter is represented by a number. For the ANSI-Standard it is useful to know, that the common letters starting a number 65 for 'A' up to 90 for 'Z'. From 97 up to 122 you will find the small letters.

You need a boolean array of 25, every value stand for one letter. Here is some code to demonstrate the functionality:

    boolean[] guessedChars = new boolean[25];
    char[] test = "HELLO".toCharArray();

    for (char element : test) {
        System.out.println(element);
        System.out.println((int) element);
        if (guessedChars[element - 65] == false) {
            guessedChars[element - 65] = true;
        } else {
            System.out.println("You already guessed this letter, derp.");
        }
    }

'Hello' is the example string, to get the right position in the array you have to substract 66 from the element integer value. An 'A' with the value of 65 will be stored in guessedChars[0]. It is easy to extend for small letters for the hangman game, because you can changed the String to upper case with the toUpperCase()-method before checking.

Upvotes: 0

SpartanDonut
SpartanDonut

Reputation: 365

The main problem I'm seeing is in your looping logic.

This will always be true the first time because guessedChars[0] will be equal to the first entry added and you add the first entry before checking if a letter was guessed.

    if (guessedChars[i] == c) {
        alreadyGuessed = true;
        break;
    }

Also, you don't tell us how guessedChars[] is defined. Depending on how you did this you might have problems with the whole thing given that the loop is driven off of guessedChars.length and assuming that an unassigned value would be 0. The big thing I notice is that you don't break after you have determined that the letter has not yet been guessed. You at a minimum need to do this otherwise all other elements after guessedChars[i] will also be set to that guessed letter. I do recommend perhaps using a different type of loop though.

bool searchingForLetter = true;
do
{
    //.... Your Logic
    //.... searchingForLetter = false when you have either found the letter 
    //.... or placed the letter in the array
    //.... or reached the end of the array
} while(searchingForLetter)

Upvotes: 0

vlad-ardelean
vlad-ardelean

Reputation: 7622

So, check this out:

First time you call the method, both alreadyGuessed and and anyMatches will stay false... and that's obviously not good.

Second: OOP is NOT procedural P. More concretely: a method is not supposed to do as many things as you do. A method should have a lot of explaining to do it if plans to be larger than 10 lines. That's so full of language constructs you can't go over it fast. Split your code... less local variables, more methods.

Hope that helps.

Upvotes: 2

Makoto
Makoto

Reputation: 106440

One way to keep track of guesses would be to use either a boolean or char array (to correspond to the cardinal letter guessed; a=0, b=1, etc).

Upvotes: 0

Related Questions