user3207654
user3207654

Reputation:

Java hangman - repeated letters

I've been developing a hangman code for java and managed to get it working, but when it comes to words with repeated letters such as "banana" where the 'a' is repeated, my code does not seem to work. So far, I've created a loop, where it loops from 0 to the 'genRadmLetter's array length. Inside the loop, I've created a if statement saying if the position is not -1, then update the array. Else print 'letter not found'. Here is the particular piece of code I'm talking about:

int rpCount = 0; 
        for (int y = 0; y<genRadmLetter.length; y++){
            int position = radmWord.indexOf(guessedLetter, rpCount);

            if (position != -1){

                genRadmLetter[RW] = guessedLetter;
                System.out.println(genRadmLetter);
                result = true;

            }

        }

    }

    if (result != true){

                System.out.println("Wrong letter, try again.");

    }

Here is my whole code:

    import java.util.Scanner;
    import java.util.Arrays;

    public class Hangman{

    public static void main(String []args){
    Scanner Input = new Scanner(System.in);

        String[] CollectionOfWords = {"","gravity","banana","gate","processor","momentum","earth","star","light","television","pan","cupboard"};

        int radmNumber = (int) Math.ceil (Math.random() * CollectionOfWords.length);
        int counter = 10;
        String radmWord = CollectionOfWords[radmNumber];

        System.out.println(radmWord);

        char[] genRadmLetter = radmWord.toCharArray();
        char[] genRadmLetter2 = radmWord.toCharArray();
        for (int x = 0; x<genRadmLetter.length; x++){
            genRadmLetter[x]='?';
        }

        System.out.println(String.valueOf(genRadmLetter));
        System.out.println("Hello. Guess a letter.");
        char guessedLetter = Input.next().charAt(0);
        int RW = radmWord.indexOf(guessedLetter);
        boolean result = false; 
        if (RW >= 0 ){

            int rpCount = 0; 
            for (int y = 0; y<genRadmLetter.length; y++){
                int position = radmWord.indexOf(guessedLetter, rpCount);

                if (position != -1){

                    genRadmLetter[RW] = guessedLetter;
                    System.out.println(genRadmLetter);
                    result = true;

                }



            }

        }

        if (result != true){

                    System.out.println("Wrong letter, try again.");

        }


        while (counter != 0) {



            if (RW >= 0 ){
            {

            int rpCount = 0; 
            for (int y = 0; y<genRadmLetter.length; y++){
                int position = radmWord.indexOf(guessedLetter, rpCount);

                if (position != -1){

                    genRadmLetter[RW] = guessedLetter;
                    System.out.println(genRadmLetter);
                    result = true;

                }



            }

        }

        }

            if (RW == -1){
            System.out.println("Wrong letter, try again.");
            counter = counter - 1; 
            System.out.println("Score: " + counter);
        }

            boolean result2 = Arrays.equals(genRadmLetter, genRadmLetter2);
            if (result2 == true){
                break;
            }

            if (counter == 0){
                break;
            }

        }

        if (counter == 0){
            System.out.println("You lose. The word was: " + radmWord);
        }

        else {
            System.out.println("Well done, you have guessed the word.");
            System.out.println("Your final score is: " + counter + "/10");
        }

    }

}

Any help is appreciated! Thanks!

Upvotes: 1

Views: 1099

Answers (2)

Radiodef
Radiodef

Reputation: 37875

RW and rpCount are not updated inside the loop so you are always:

  • Checking for the first occurrence.
  • Replacing the first occurrence.

If you want to do this using indexOf, you need to update the fromIndex parameter each time. (fromIndex is the index it begins the search from, so if it's always 0 it will always find the first occurrence.) Something like this:

int last = 0;
for(int y = 0; y < genRadmLetter.length; y++) {
    int pos = radmWord.indexOf(guessedLetter, last);

    if(pos > -1) {
        genRadmLetter[pos] = guessedLetter; // use found index to replace
        result = true;

        last = pos + 1; // skip to the next letter
    }
    if(pos == radmWord.length() - 1) {
        break; // it was the last letter
    }
}

A new break condition is also needed (or you will get an out of bounds exception if indexOf is called with the index of the last letter + 1).

So if you are doing the replacement based on containment, you do not need the for(each index) idiom. You aren't really using the y variable and for(each index) results in redundant calls to indexOf. The loop can be shortened like this:

int pos = 0;
do {
    pos = radmWord.indexOf(guessedLetter, pos);

    if(pos > -1) {
        genRadmLetter[pos] = guessedLetter;
        result = true;
        pos++;
    }
} while(pos > -1 && pos < radmWord.length());

But note that if the array is simply parallel, there is a simpler way to do this using charAt:

for(int i = 0; i < genRadmLetter.length; i++) {
    if(radmWord.charAt(i) == guessedLetter) {
        genRadmLetter[i] = guessedLetter;
        result = true;
    }
}

Upvotes: 1

SeaNick
SeaNick

Reputation: 511

By "doesn't work", I'm guessing you mean that it's only finding the first instance of 'a' in 'banana'. This is because the indexOf method always returns the first instance of the specified character starting from the index specified by the second argument. You are specifying rpCount, which was initialized to 0, but never gets updated, so it will only ever find the first instance.

Simple fix:

if (position != -1){

   genRadmLetter[RW] = guessedLetter;
   System.out.println(genRadmLetter);
   result = true;

   **rpCount = position;**

}

Upvotes: 0

Related Questions