Reputation: 31
I am creating a Hangman Game in Java and it almost works perfectly. So I have two problems. The first being that:
When the user inputs a letter and the word has repeated letters, how can I make it print both instances of the letter.
My code is below:
There may be other threads with same questions but none seem to help as I cannot implement it into this person's 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];
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);
if (RW >= 0 ){
genRadmLetter[RW] = guessedLetter;
System.out.println(genRadmLetter);
}
if (RW == -1){
System.out.println("Wrong letter, try again.");
counter = counter - 1;
System.out.println("Lives left: " + counter);
}
while (counter != 0) {
System.out.println("Guess a letter.");
guessedLetter = Input.next().charAt(0);
RW = radmWord.indexOf(guessedLetter);
if (RW >= 0 ){
genRadmLetter[RW] = guessedLetter;
System.out.println(genRadmLetter);
}
if (RW == -1){
System.out.println("Wrong letter, try again.");
counter = counter - 1;
System.out.println("Lives left: " + counter);
} else {
System.out.println(genRadmLetter);
while (RW >= 0 ){
genRadmLetter[RW] = guessedLetter;
RW = radmWord.indexOf(guessedLetter, RW+1);
}
}
boolean result = Arrays.equals(genRadmLetter, genRadmLetter2);
if (result == 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);
}
}
}
Upvotes: 1
Views: 1618
Reputation: 11
I made a little helper clas that could help you...
static class GuessString {
private char[] mask;
private String solution;
private boolean lastGuessResult;
GuessString(String word) {
this.solution = word;
this.mask=word.toCharArray();
Arrays.fill(mask, '?'); // Build a mask like: ??????
}
public String guess(char guess) {
char c = Character.toLowerCase(guess); // case insensitive
int i = solution.indexOf(c);
lastGuessResult = i != -1; // -1 means "not found)
if (lastGuessResult)
while (i != -1) { // this will loop till c is replaced everywhere.
mask[i] = c;
i = solution.indexOf(c, i+1);
}
return new String(mask); // return the updated mask.
}
public boolean lastGuessIsRight() {
return lastGuessResult;
}
public String getCurrent() {
return new String(mask);
}
public boolean isSolved() {
return getCurrent().equals(solution);
}
}
Upvotes: 0
Reputation: 2873
There are multiple issues with the code:
you are using this:
int radmNumber = (int) Math.ceil (Math.random() * CollectionOfWords.length)
if you use
int radmNumber = (int) Math.ceil (Math.random() * CollectionOfWords.length-1)
you can start the arrey without a empty string and it wont randomly crash
you wont need to duplicate the input code if you use this:
System.out.println(String.valueOf(genRadmLetter));
System.out.print("Hello.");
char guessedLetter;
int RW;
while (counter != 0)
{
System.out.println("Guess a letter.");
...
you do the output before changing it. so this fixes your problem:
...
else
{
while (RW >= 0)
{
genRadmLetter[RW] = guessedLetter;
RW = radmWord.indexOf(guessedLetter, RW + 1);
}
System.out.println(genRadmLetter);
}
So simply move the output behind the while.
Upvotes: 0
Reputation: 347334
Instead of using...
int RW = radmWord.indexOf(guessedLetter);
To determine if the entered value matches a character, which will only return the first index, you should, instead, use a loop of some kind to check every character
boolean found = false;
for (int rw = 0; rw < genRadmLetter2.length; rw++) {
if (genRadmLetter2[rw] == guessedLetter) {
genRadmLetter[rw] = guessedLetter;
found = true;
}
}
Now, because you're relying on the value of RW
to determine if a match was found or not, I changed it so that the boolean
found
flag can used instead, for example...
if (!found) {
System.out.println("Wrong letter, try again.");
counter = counter - 1;
System.out.println("Lives left: " + counter);
}
You also have duplicate sets of code, which can be reduced to a single do-while
loop instead, which will make it easier to read and make changes, for example...
do {
//...
} while (counter != 0);
To your second problem, a Set
of some kind would be the simplest solution...
Set<Character> guesses = new HashSet<Character>();
//...
char guessedLetter = Input.next().charAt(0);
if (guesses.contains(guessedLetter)) {
System.out.println("You've used this guess, guess again");
} else {
guesses.add(guessedLetter);
For example...
And because it's not always easy to translate code snippets ... this is my test code...
import java.util.Arrays;
import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;
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 = "banana"; //CollectionOfWords[radmNumber];
char[] genRadmLetter = radmWord.toCharArray();
char[] genRadmLetter2 = radmWord.toCharArray();
for (int x = 0; x < genRadmLetter.length; x++) {
genRadmLetter[x] = '?';
}
Set<Character> guesses = new HashSet<Character>();
do {
System.out.println("Guess a letter.");
System.out.println(String.valueOf(genRadmLetter));
System.out.println("Hello. Guess a letter.");
char guessedLetter = Input.next().charAt(0);
if (guesses.contains(guessedLetter)) {
System.out.println("You've used this guess, guess again");
} else {
guesses.add(guessedLetter);
boolean found = false;
for (int rw = 0; rw < genRadmLetter2.length; rw++) {
if (genRadmLetter2[rw] == guessedLetter) {
genRadmLetter[rw] = guessedLetter;
found = true;
}
}
if (!found) {
System.out.println("Wrong letter, try again.");
counter = counter - 1;
System.out.println("Lives left: " + counter);
}
}
boolean result = Arrays.equals(genRadmLetter, genRadmLetter2);
if (result == true) {
break;
}
if (counter == 0) {
break;
}
} while (counter != 0);
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);
}
}
}
Upvotes: 1