Java Scramble Game Input after Hint - java

I'm modifying an unscramble game in Java. I have two arrays: one for the original words and another for their hints. So when the user guesses incorrectly, the corresponding hint shows up and what I want is for the user to have another chance to guess after the hint is shown. But right now, I can't seem to get that 'another chance' to work. Can someone pls help? Thank you.
Code:
import java.util.Scanner;
import java.util.concurrent.ThreadLocalRandom;
import java.util.Calendar;
import java.util.Date;
// How to create a Jumble word game in Java
public class MyProgram {
private static final String[] WORDS_DATABASE = new String[] {
"code","kids","baby", "dosa", "beach","house","apple", "paper",
"Java", "school", "science", "Oracle", "Disney", "cricket", "carrot",
"vada"
};
private static String[] hints = new String[] {
"Programs are made of ___", "Synonym for children", "Synonym for infant",
"Idli, vada, and ___", "This place is next to ocean", "Other word for 'home'",
"This is a red color fruit", "pencil and ____", "programming language",
"place for education", "Physics, chemistry, biology are all ____",
"Larry Ellison founded this company", "the ____ princesses", "Famous sport with bat and ball",
"What rabbits eat", "idli and ___"
};
public static void main(String[] args) {
MyProgram jg = new MyProgram();
jg.startGame();
}
/**
* Run a game of Jumble in Java. The steps in the game are,
* 1. Get a random word from the words database
* 2. Shuffle/jumble the word by randomly shuffling characters
* 3. Present the jumbled word to the user and ask him to guess the word.
* 4. Repeat the guess till answer is found or user decides to quit.
*/
private void startGame() {
// int numberOfGuesses = 0;
// String original = selectRandomWord();
//String shuffled = getShuffledWord(original);
boolean gameOn = true;
while(gameOn) {
int numberOfGuesses = 0;
String original = selectRandomWord();
String shuffled = getShuffledWord(original);
System.out.println("Shuffled word is: "+shuffled);
numberOfGuesses++;
String userGuess = getUserGuess();
if(original.equalsIgnoreCase(userGuess)) {
System.out.println("Congratulations! You found the word in "+numberOfGuesses+" guesses");
System.out.println("");
//gameOn = false;
}else {
System.out.println("Sorry, Wrong answer");
System.out.println("--------");
if (numberOfGuesses > 0){
displayHint(original);
System.out.println("");
// String userGuess = getUserGuess();
}
}
}
}
/**
* Get the user's word guess from command line
* #return
*/
public String getUserGuess() {
Scanner sn = new Scanner(System.in);
System.out.println("Please type in the original word: ");
return sn.nextLine();
}
/**
* Select a random word from the WORDS_DATABASE array.
* #return
*/
public String selectRandomWord() {
int rPos = ThreadLocalRandom.current().nextInt(0, WORDS_DATABASE.length);
return WORDS_DATABASE[rPos];
}
/**
* Shuffle the original word by randomly swapping characters 10 times
* #param original
* #return
*/
public String getShuffledWord(String original) {
String shuffledWord = original; // start with original
int wordSize = original.length();
int shuffleCount = 10; // let us randomly shuffle letters 10 times
for(int i=0;i<shuffleCount;i++) {
//swap letters in two indexes
int position1 = ThreadLocalRandom.current().nextInt(0, wordSize);
int position2 = ThreadLocalRandom.current().nextInt(0, wordSize);
shuffledWord = swapCharacters(shuffledWord,position1,position2);
}
return shuffledWord;
}
/**
* Swaps characters in a string using the given character positions
* #param shuffledWord
* #param position1
* #param position2
* #return
*/
private String swapCharacters(String shuffledWord, int position1, int position2) {
char[] charArray = shuffledWord.toCharArray();
// Replace with a "swap" function, if desired:
char temp = charArray[position1];
charArray[position1] = charArray[position2];
charArray[position2] = temp;
return new String(charArray);
}
private void displayHint(String s){
for (int i = 0; i < WORDS_DATABASE.length; i++){
if (WORDS_DATABASE[i].equals(s)){
System.out.println("HINT:" + hints[i]);
}
}
}
}

Add a loop at startGame() for playing again with new word like:
boolean playAgain = true;
while(playAgain)
playAgain = jg.startGame();
Modify the startGame() to return true when the user wants to play again otherwise false. Also, move the random word selection and word shuffling statements outside of the gameOn loop to stop getting new word even when the user gives the right answer.
private boolean startGame() {
boolean gameOn = true;
int numberOfGuesses = 0;
String original = selectRandomWord();
String shuffled = getShuffledWord(original);
System.out.println("Shuffled word is: "+shuffled);
while(gameOn) {
numberOfGuesses++;
String userGuess = getUserGuess();
if(original.equalsIgnoreCase(userGuess)) {
System.out.println("Congratulations! You found the word in "+numberOfGuesses+" guesses");
System.out.println("");
gameOn = false;
}else {
System.out.println("Sorry, Wrong answer");
System.out.println("--------");
if (numberOfGuesses > 0){
displayHint(original);
System.out.println("");
}
}
}
if(checkIfUserwantsToPlayAgain())
return true; // To restart the game
return false; // To stop the game
}

So when the user guesses incorrectly, the corresponding hint shows up
and what I want is for the user to have another chance to guess after
the hint is shown. But right now, I can't seem to get that 'another
chance' to work.
You just need to move the selection and scrambling of the word to BEFORE the while loop so that it doesn't pick a new word when they guess wrong. Also, why did you comment out the gameOn = false; line? That is necessary to allow the game to end.
After you move the initialization lines to before the while loop, you can now place that entire thing inside another while loop that asks the user if they want to play a new game (I'll leave that to you, though).
int numberOfGuesses = 0;
String original = selectRandomWord();
String shuffled = getShuffledWord(original);
while(gameOn) {
System.out.println("Shuffled word is: "+shuffled);
numberOfGuesses++;
String userGuess = getUserGuess();
if(original.equalsIgnoreCase(userGuess)) {
System.out.println("Congratulations! You found the word in "+numberOfGuesses+" guesses");
System.out.println("");
gameOn = false;
}else {
System.out.println("Sorry, Wrong answer");
System.out.println("--------");
if (numberOfGuesses > 0){
displayHint(original);
System.out.println("");
}
}
}
Now, when the user guesses incorrectly, it will display the hint and go back to the top of the while loop where it will ask the user for another guess. It will stay in the loop until they get it correct and gameOn is toggled to false.
But how do I make it so that the user gets to input whether they want
to play on or not, after the round ends?
You could change your main() to something like this:
public static void main(String[] args) {
boolean keepPlaying = true;
Scanner sn = new Scanner(System.in);
while (keepPlaying) {
MyProgram jg = new MyProgram();
jg.startGame();
System.out.print("Would you like to play again? [Y or YES]: ");
String response = sn.nextLine().toUpperCase();
keepPlaying = (response.equals("Y") || (response.equals("YES")));
}
}

Related

Java chatbot mirroring and canned responses

So I got this java chatbot program that I'm working on.
Depending on what the user says, the chatbot either gives a canned response canned_phrases or a mirrored response if the user's response has one of the keywords I love pizza --> you love pizza.
The problem is that the chatbot does not give back the mirrored version. I think the problem is that the words are being overwritten by each other but I'm not sure how to fix that.
Thank for your help!
import java.util.Random;
import java.util.Scanner;
public class Conversation {
public static void main(String[] args) {
String[] canned_phrases = {"Yes",
"Hmmm. Please tell me more news",
"Of course",
"Okay",
"Interesting...",
"Indeed"};
int canned_times = canned_phrases.length;
Scanner conversation_start = new Scanner(System.in);
System.out.println("\nWelcome!\n");
System.out.println("How many rounds of conversation would you like to have?\n");
int rounds = conversation_start.nextInt();
conversation_start.nextLine();
String[] transcript = new String[2 * rounds + 1];
transcript[0] = "Sounds great! How are you doing today?";
System.out.println(transcript[0]);
for (int i = 0; i < rounds; i++) {
String user_words = conversation_start.nextLine();
String mirrored;
String new_version = user_words.replace("I", "you");
new_version = new_version.replace("me", "you");
new_version = new_version.replace("am", "are");
new_version = new_version.replace("you", "I");
new_version = new_version.replace("my", "your");
new_version = new_version.replace("your", "my");
new_version = new_version.replace("my", "you");
if (!new_version.equals(user_words)) {
mirrored = new_version;
}
else {
mirrored = canned_phrases[(int) Math.floor(canned_times * Math.random())];
}
System.out.println(mirrored);
transcript[2 * i + 1] = user_words;
transcript[2 * i + 1] = mirrored;
}
System.out.println("Thank you for chatting with me! Come back soon!");
System.out.println(" ");
System.out.println("TRANSCRIPT ");
for (int i = 0; i <= transcript.length; i++) {
System.out.println(transcript[i]);
}
System.exit(0);
}
}
I think the best way to achieve what you want is to split the user-entered sentence into words and change the individual words according to your rules, for example if the word is my then change it to your. In the below code, I iterate through all the words in order, changing each word as needed and appending them to a StringBuilder so that after iterating through all the words, the StringBuilder contains the mirrored sentence.
(More notes after the code.)
import java.util.Random;
import java.util.Scanner;
public class Conversation {
public static void main(String[] args) {
String[] cannedPhrases = {"Yes",
"Hmmm. Please tell me more news",
"Of course",
"Okay",
"Interesting...",
"Indeed"};
int cannedTimes = cannedPhrases.length;
Random rand = new Random();
Scanner conversationStart = new Scanner(System.in);
System.out.println("\nWelcome!\n");
System.out.println("How many rounds of conversation would you like to have?\n");
int rounds = conversationStart.nextInt();
conversationStart.nextLine();
String[] transcript = new String[2 * rounds];
transcript[0] = "Sounds great! How are you doing today?";
System.out.println(transcript[0]);
int index = -1;
for (int i = 0; i < rounds; i++) {
String userWords = conversationStart.nextLine();
String mirrored;
StringBuilder result = new StringBuilder();
String[] words = userWords.split(" ");
boolean first = true;
for (String word : words) {
if (first) {
first = false;
}
else {
result.append(' ');
}
switch (word) {
case "I":
word = "you";
break;
case "me":
word = "you";
break;
case "am":
word = "are";
break;
case "you":
word = "I";
break;
case "my":
word = "your";
break;
case "your":
word = "my";
break;
}
result.append(word);
}
String newVersion = result.toString();
if (!newVersion.equals(userWords)) {
mirrored = newVersion;
}
else {
mirrored = cannedPhrases[rand.nextInt(cannedTimes)];
}
System.out.println(mirrored);
transcript[++index] = userWords;
transcript[++index] = mirrored;
}
System.out.println("Thank you for chatting with me! Come back soon!");
System.out.println(" ");
System.out.println("TRANSCRIPT ");
for (int i = 0; i < transcript.length; i++) {
System.out.println(transcript[i]);
}
System.exit(0);
}
}
You should try to adhere to Java naming conventions. I changed the variable names in your code accordingly.
Rather than manipulate the [first] for loop variable i to handle both the conversation round and the transcript index, I used a separate variable, named index for the transcript.
Switching on string was added in Java 7.
The for loop that prints the transcript was wrong. The terminating condition should be i < transcript.length (and not i <= transcript.length).
The above code assumes that the user-entered sentence consists of words separated by single spaces. If you want more sophisticated handling of the user-entered sentence, for example handling punctuation, like commas, periods, etc, then you will need to change the split method's regular expression.
Here is output from a sample run:
Welcome!
How many rounds of conversation would you like to have?
2
Sounds great! How are you doing today?
OK
Of course
Why do you say that
Why do I say that
Thank you for chatting with me! Come back soon!
TRANSCRIPT
OK
Of course
Why do you say that
Why do I say that
I made little modification to your code and now it work as you expected:
public static void main(String[] args) {
String[] canned_phrases = {"Yes", "Hmmm. Please tell me more news", "Of course", "Okay", "Interesting...", "Indeed"};
int canned_times = canned_phrases.length;
Scanner conversation_start = new Scanner(System.in);
System.out.println("\nWelcome!\n");
System.out.println("How many rounds of conversation would you like to have?\n");
int rounds = conversation_start.nextInt();
conversation_start.nextLine();
String[] transcript = new String[2*rounds+1];
transcript[0] = "Sounds great! How are you doing today?";
System.out.println(transcript[0]);
for (int i = 0; i < rounds; i++) {
String user_words = conversation_start.nextLine();
String mirrored;
String new_version = user_words.replace("I", "you");
new_version = new_version.replace("me","you");
new_version = new_version.replace("am","are");
//1st change as you replaced it above so not swap it again
//new_version = new_version.replace("you","I");
new_version = new_version.replace("my","your");
new_version = new_version.replace("your","my");
new_version = new_version.replace("my","you");
//by commenting the line above, will enter the IF-block
if (!new_version.equals(user_words)) {
mirrored = new_version;
} else {
mirrored = canned_phrases[(int) Math.floor(canned_times * Math.random())];
}
System.out.println(mirrored);
transcript[2*i+1] = user_words;
//2nd change to not overwrite the same index i added 2 instead of 1
transcript[2*i+2] = mirrored;
}
System.out.println("Thank you for chatting with me! Come back soon!");
System.out.println(" ");
System.out.println("TRANSCRIPT ");
//3rd change i removed the = from the loop condition to prevent exception appeared
for (int i = 0; i < transcript.length; i++) {
System.out.println(transcript[i]);
}
System.exit(0);
}

Troubled with how and where to implement if/else statements

I am almost finished creating a hangman game in Java, although I am having difficulty with one last part. I want to make it so the program checks if all the letters of the word have been guessed correctly and if so, the game prints a message saying they have won, the game ends and the program goes to the do while loop in the main class asking if they would like to play again. If not however, the game continues until this point or if all 5 guesses have been used - to which again, it is sent to the do while loop in order to restart the game and not simply terminate the program.
The problem is I am unsure how and where exactly to structure the if and else statements in order to do so.
Any help would be greatly appreciated, if I can provide further information to help narrow anything down please ask too, thank you in advance.
Instantiable Class
public class Hangman {
private char letterGuess;
private int numberLives;
private String outputWord, endMessage;
private final String hiddenWord;
private final StringBuffer swapBuffer = new StringBuffer();
public Hangman() {
letterGuess = ' ';
numberLives = 5;
hiddenWord = "java";
outputWord = "";
endMessage = "";
for (int i = 0; i < hiddenWord.length(); i++) {
swapBuffer.append("*");
}
}
public void setLetterGuess(char letterGuess) {
this.letterGuess = letterGuess;
}
public void compute() {
boolean letterFound = false;
for (int i = 0; i < hiddenWord.length(); i++) {
if (letterGuess == hiddenWord.charAt(i)) {
swapBuffer.setCharAt(i, letterGuess);
letterFound = true;
}
}
if (!letterFound) numberLives--;
outputWord = swapBuffer.toString();
}
public int getNumberLives() {
return numberLives;
}
public String getHiddenWord() {
return hiddenWord;
}
public String getOutputWord() {
return outputWord;
}
public String getEndMessage() {
return endMessage;
}
}
Main Class
import javax.swing.*;
public class HangmanApp {
public static void main(String[] args) {
char letterGuess;
int numberLives;
String hiddenWord, outputWord, endMessage, restartGame;
do {
Hangman myHangman = new Hangman();
JOptionPane.showMessageDialog(null, "Welcome to Java Hangman!");
JOptionPane.showMessageDialog(null, "In this game, a word will be printed to you in asterisks - each letter will be revealed upon a correct guess!");
JOptionPane.showMessageDialog(null, "You have 5 lives for the game, the game will end if you make too many incorrect guesses!");
for (int i = 0; i < 10; i++) {
hiddenWord = myHangman.getHiddenWord();
numberLives = myHangman.getNumberLives();
JOptionPane.showMessageDialog(null, "You currently have " +numberLives+ " lives!");
letterGuess = JOptionPane.showInputDialog(null, "Now, please enter a letter : ").charAt(0);
myHangman.setLetterGuess(letterGuess);
myHangman.compute();
outputWord = myHangman.getOutputWord();
JOptionPane.showMessageDialog(null, "The word so far is : " +outputWord);
}
numberLives = myHangman.getNumberLives();
JOptionPane.showMessageDialog(null, "You have finished the game with : " +numberLives+ " lives!");
restartGame = JOptionPane.showInputDialog(null, "Would you like to play again?");
}
while (restartGame.equalsIgnoreCase("Yes"));
}
}
Here's the way I see it. After you call myHangman.compute();, you want to check to see if the player has either won the game or run out of lives. Each of these is a separate test using an if expression. There is no else part because if the test fails, the game just goes on.
If one of these conditions is recognized, then you want to display a message, and then you want to exit the current game loop so the user will be asked if they want to play another game. The way to do this is with the break statement.
One issue you have is that you don't have a way in your main game loop to ask the Hangman class if the user has guessed the whole word. To be able to do this, you can add this method to the bottom of your Hangman class:
public boolean getAllLettersFound() {
return outputWord.indexOf('*') < 0;
}
This method checks to see if there are any * in outputWord. If not, then the user has guessed all the letters. So with this method added, the main loop can query the Hangman object to find out if the player has won.
To put this all together, you need to add the two condition checks to your main game loop, right after you call myHangman.compute();. Here are those two if blocks:
if (myHangman.getAllLettersFound()) {
JOptionPane.showMessageDialog(null, "You Won!!!!");
break;
}
if (myHangman.getNumberLives() == 0) {
JOptionPane.showMessageDialog(null, "You Ran Out Of Guesses");
break;
}
That should do it. Happy coding!

The scanner would not scan the second line

I had this code where after reading the first three lines of input, it would just terminate the program and would not let me enter the next line. Here's the code:
import java.util.Arrays;
import java.util.Scanner;
public class cycle {
public static void main(String[] arg)
{
System.out.println("Put in numbers");
Scanner in=new Scanner(System.in);
int indicator=Integer.parseInt(in.nextLine());
if(indicator==1)
{
mission1();
}
else if(indicator==2)
{
mission2();
}
in.close();
}
static void mission1()
{
Scanner miss1=new Scanner(System.in);
int citizens=Integer.valueOf(miss1.nextLine());
String lines=miss1.nextLine();
lines=lines.replaceAll("\\s", "");
int length=lines.length();
String lines2=miss1.nextLine();
lines2=lines.replaceAll("\\s", "");
int length2=lines.length();
while(citizens!=length||citizens!=length2)
{
System.out.println("Citizens number do not match, try again" );
miss1=new Scanner(System.in);
citizens=Integer.valueOf(miss1.nextLine());
lines=miss1.nextLine();
lines=lines.replaceAll("\\s", "");
length=lines.length();
lines2=miss1.nextLine();
lines2=lines.replaceAll("\\s", "");
length2=lines.length();
miss1.close();
if(citizens!=length||citizens!=length2)
{
throw new IndexOutOfBoundsException("Numebr of citizens do not match. Please enter numbers again");
}
else if(citizens==length&&citizens==length2)
{
String[] strs=lines.trim().split("\\s");
length=lines.length();
int[] dspeed = new int[length];
for(int i=0; i<length;i++)
{
dspeed[i]=Integer.parseInt(strs[i]);
}
String[] strs2=lines2.trim().split("\\s+");
int[] pspeed = new int[length2];
for(int i=0; i<length2;i++)
{
pspeed[i]=Integer.parseInt(strs2[i]);
}
Arrays.sort(dspeed);
break;
}
}
}
static void mission2()
{
}
}
For example, with an input like this:
Put in numbers
1
3
1 3 5
1 3 5
It would just terminate the program and it is ok, but with an input like this:
Put in numbers
1
3
1 3
1 3
Citizens number does not match, try again
1
3
1 3 5
The program would terminate before I can't put in the fourth line.
As a test I put in
for(int n=0;n<length;n+=1)
{
System.out.println(dspeed[n]);
}
in between Arrays.sort(dspeed[n]) and break, and the result is like this
Put in numbers
1
3
1 3
1 3
Citizens number do not match, try again
1
3
1 3 5
3
It makes no sense since it is giving me an output of 3 while not letting me enter the second line. So it is like part of the code is being skipped. Why is this happening and how do I fix this?
Edit: For mission1 it suppose to get a number(let's say x), and then get x numbers of different numbers from the next line. Then, it should put those numbers in an array and sort them
As of writing my answer I realized what the actual cause of your error is; look at this piece of code:
lines=miss1.nextLine();
lines=lines.replaceAll("\\s", "");
length=lines.length();
lines2=miss1.nextLine();
/*Should be lines2!*/
lines2=lines.replaceAll("\\s", "");
/*Should be lines2!*/
length2=lines.length();
You're using linesfor all your variables. Changing lines to lines2 for the lines2 = ... and length2 variables fixed the issue that you posted. I also replaced
if (citizens != length || citizens != length2) {
/*If you decide to keep this, it should not be a "IndexOutOfBoundsException
(since no index was out of bounds) but should perhaps be a "IllegalArgumentException"
since you supplied it illegal arguments.*/
throw new IndexOutOfBoundsException("Numebr of citizens do not match. Please enter numbers again");
} else if (citizens == length && citizens == length2) { ... }
with
if (citizens == length && citizens == length2) { ... }
Since otherwise this would cause the program to crash if you gave it an invalid input twice in a row.
This part of the answer should be considered code-review and is here to (try to) help improve your code structure. Actual answer is above.
This is the entire class code. This seems to have resolved your error and I've also re-structured some of the code and added comments explaining what I edited and why I restructured it. Please leave a comment if anything is unclear or if it didn't actually resolve your error. Please note that the imports are left out of this answer for clarity.
public class Cycle {
/* Important! We can re-use the same scanner for all inputs. */
final Scanner in;
public Cycle() {
in = new Scanner(System.in);
run();
in.close();
}
private void run() {
System.out.println("Input mission number.");
final int indicator = Integer.parseInt(in.nextLine());
if (indicator == 1) {
mission1();
} else if (indicator == 2) {
// etc
}
}
private void mission1() {
while (true) {
System.out.println("Input number of citizens.");
final int citizens = Integer.valueOf(in.nextLine());
/* We don't edit these two first inputs just yet since we
* have to use the un-edited inputs later in our if-else
* statement. */
System.out.println("Input first number(s).");
final String inputOne = in.nextLine();
System.out.println("Input second number(s).");
final String inputTwo = in.nextLine();
final String lines = inputOne.replaceAll("\\s", "");
final int length = lines.length();
final String lines2 = inputTwo.replaceAll("\\s", "");
final int length2 = lines2.length();
if (citizens != length || citizens != length2) {
/* If the number of citizens doesn't match it just
* continues the while-loop and does it all over
* again. */
System.out.println("Citizens number do not match, try again");
} else {
/* Here we use the unedited inputs from before - which
* is why we didn't edit them. */
final int[] dspeed = createArrayFromInput(inputOne);
final int[] pspeed = createArrayFromInput(inputTwo);
break;
}
}
}
/* We shouldn't have duplicated code - use a method instead. */
private int[] createArrayFromInput(final String input) {
final String[] strs = input.trim().split("\\s+");
/* The arrays should be the same size so use 'strs.length' as
* length */
final int[] speed = new int[strs.length];
for (int i = 0; i < strs.length; i++) {
speed[i] = Integer.parseInt(strs[i]);
}
Arrays.sort(speed);
return speed;
}
public static void main(final String[] arg) {
/*We should use a class instance instead of static methods and variables.*/
new Cycle();
}
}

Hangman code stuck on three different problems

I'm trying to make a hangman game. On each turn, the user guesses a letter. If they guessed correctly, they can guess again. Otherwise, their remaining available guesses drops by one, and the guessed letter is put into an array.
When the user hits zero remaining guesses, the program is supposed to ask if they want to play again. If they answer yes, it is supposed to restart the game, and if they answer no, the program ends.
The problem I'm having is with the array that holds the guesses, and with restarting the game.
Also, the program will error every once in a while when starting. The error is
Exception in thread "main" java.lang.NullPointerException at Hangman1.main(Hangman1.java:27)
The error when trying to restart the game is
Exception in thread "main" java.lang.NullPointerException at Hangman1.main(Hangman1.java:101)
searchArray is the method that is supposed to take the position of the char array and copy that in asterisk array and return asterisk array, that doesn't seem to work. Running debug it seems the problem that causes the program to crash is that word will sometimes end up null, but only sometimes and I don't really know why
import java.util.*;
import java.io.*;
public class Hangman1 {
static Scanner keyboard = new Scanner(System.in);
public static final int MAXSIZE = 15000;
public static final int NUM_GUESS = 8;
public static final int WORD_LENGTH = 20;
public static void main(String[] args) {
int random = pickrandom(MAXSIZE);
try {
// Set up connection to the input file
Scanner input = new Scanner(new FileReader("dictionary.txt"));
instructions();
keyboard.nextLine();
clearScreen();
String word = randomWord(input, random);
System.out.println(word);
String[] charArray = word.split("");
System.out.print("\n");
String[] asterisk = asteriskLine(word);
String decision = "Y";
//decision = keyboard.nextLine().toUpperCase();
System.out.println("Word to guess :");
for (int count = 0; count < word.length(); count++) {
System.out.print(asterisk[count]);
}
System.out.print("\n");
int tries = NUM_GUESS;
System.out.println("Enter a letter to guess or 9 to quit");
String guess = keyboard.next();
String[] wrongGuesses = new String [NUM_GUESS];
int guessMade = 0;
do {
//System.out.println(tries);
while (!(guess.equals("9")) && !(guess.equals(word)) && (tries > 0))
{
String letter = guess.substring(0,1);
if (word.indexOf(letter) < 0) {
clearScreen();
tries--;
wrongGuesses = wrongGuesses(guessMade, wrongGuesses, letter);
printArray(asterisk, charArray, word, tries, wrongGuesses, guessMade);
guessMade++;
guess = keyboard.next();
}
else {
clearScreen();
asterisk = searchArray(charArray, asterisk, guessMade, letter, word);
printArray(asterisk, charArray, word, tries, wrongGuesses, guessMade);
guess = keyboard.next();
}
if (charArray == asterisk) {
System.out.println("You won!");
}
if (tries == 0) {
System.out.println("You have no more guesses left");
}
}
if (guess.equals("9")) {
System.out.println("Thanks for playing");
}
System.out.println("Play again? Y/N");
decision = keyboard.next().toUpperCase();
if (decision.equals("Y")) {
random = pickrandom(MAXSIZE);
word = randomWord(input, random);
charArray = word.split("");
System.out.print("\n");
asterisk = asteriskLine(word);
guess = keyboard.next();
}
} while (decision.equals("Y"));
//System.out.println("Play again? Y/N");
//decision = keyboard.nextLine().toUpperCase();
}
catch (FileNotFoundException e) {
System.out.println("There was an error opening one of the files.");
}
}
//Clears screen after introduction
private static void clearScreen() {
for (int blanks = 0; blanks < 80; blanks++) {
System.out.println();
}
}
// This method returns a randomly selected integer
// between 0 and count-1
public static int pickrandom(int count) {
Random generator = new Random();
return generator.nextInt(count);
}
// Places asterisks in place of the letters in the word
// Parameter is the string word. it holds mystery word
public static String[] asteriskLine(String word) {
int i;
String[] asteriskArray = new String [word.length()];
for (i = 0; i < word.length(); i++) {
asteriskArray[i] = "* ";
}
return asteriskArray;
}
public static void instructions() {
System.out.println(" H A N G M A N. "
+ "\n This is a word guessing game. "
+ "\n A word will be selected at random and kept hidden. You will try to figure out the secret word by"
+ "\n guessing letters which you think are in the word. "
+ "\n You will guess one letter at a time. "
+ "\n If the letter you guess is correct, the position(s) of the letter in the secret word will be shown. "
+ "\n You will be allowed "
+ NUM_GUESS
+ " wrong guesses If you guess incorrectly "
+ NUM_GUESS
+ " times, you lose the game. "
+ "\n If you guess all of the letters in the word, you win."
+ "\n\n Press enter to continue ");
}
public static String randomWord(Scanner input, int random) {
String[] dictionaryWords = new String [MAXSIZE];
int usedsize = 0;
while (usedsize < MAXSIZE && input.hasNextLine()) {
dictionaryWords[usedsize] = input.nextLine();
usedsize++;
}
String word = dictionaryWords[random];
return word;
}
//Replaces correct guess in blanks
public static String correctWord(String guess, String word, String asterisk, char letter) {
return null;
}
public static void printArray(String[] asterisk, String[] charArray, String word, int tries, String[] wrongGuesses, int guessMade) {
System.out.println("Word to guess");
for (int count = 0; count < word.length(); count++) {
System.out.print(asterisk[count]);
}
System.out.println("\nGuesses remaining: " + tries);
System.out.print("Incorrect letters tried: ");
for (int count = 0; count <= guessMade; count++) {
System.out.print(wrongGuesses[count] + " ");
}
System.out.println("\nEnter a letter to guess or 9 to quit");
}
public static String[] wrongGuesses(int guessMade, String [] wrongGuesses, String letter) {
wrongGuesses[guessMade] = letter;
return wrongGuesses;
}
public static String[] searchArray(String[] charArray, String[] asterisk, int guessMade, String letter, String word) {
int[] a = new int[word.length()];
for (int count = 0; count < word.length(); count++) {
if (letter == charArray[count]) {
asterisk[count] = charArray[count];
}
}
return asterisk;
}
}
One thing that you need to do is to read all of your words in once and only once, and store them all into an ArrayList. Your current code tries to re-use a Scanner object that is already spent, and that will fail. Instead get your random word from the ArrayList<String>.
Running debug it seems the problem that causes the program to crash is
that word will sometimes end up null, but only sometimes and I don't
really know why
public static String randomWord(Scanner input, int random) {
String[] dictionaryWords = new String [MAXSIZE];
int usedsize = 0;
while (usedsize < MAXSIZE && input.hasNextLine()) {
dictionaryWords[usedsize] = input.nextLine();
usedsize++;
}
String word = dictionaryWords[random];
return word;
}
Sometimes random will be bigger than usedsize.
So you need to move this line from outside the loop
int random = pickrandom(MAXSIZE);
into this function, and have the maximum be usedsize (or usedsize-1).
You can protect yourself against this error, and work out whether you should be using usedsize or usedsize-1, by writing a unit test. Look into a Junit tutorial.
In your junit test, call randomword and pass it a very high value for random. Then
assert(word!= null)
Word is null when random is longer than the length of your dictionary.

Hangman Code Issue (Java)

I am trying to create a simple hangman program in java for a school assignment and I have it working for the most part. The main problem I have with it is that it keeps printing out the hidden word twice. It also only goes through and asks the user to enter an word 8 times when it should be 15 times. Can someone tell me where I went wrong?
// Its in a separate method.
public static void application1() throws Exception {
// Tells the user about the game.
System.out.println("Welcome to Hangman!");
System.out.println("Please try to guess the word within 15 letters.");
String option = "";
// Creates a array of all the phrases.
String answer[] = new String[20];
answer[0] = "computer";
answer[1] = "radio";
answer[2] = "calculator";
answer[3] = "teacher";
answer[4] = "bureau";
answer[5] = "police";
answer[6] = "geometry";
answer[7] = "president";
answer[8] = "subject";
answer[9] = "country";
answer[10] = "environment";
answer[11] = "classroom";
answer[12] = "animals";
answer[13] = "province";
answer[14] = "month";
answer[15] = "politics";
answer[16] = "puzzle";
answer[17] = "instrument";
answer[18] = "kitchen";
answer[19] = "language";
do {
// Creates a random number to choose which word to choose from.
int rand = (int)(Math.random() * 20 + 0);
StringBuffer word = new StringBuffer("");
// This makes the unknown word as long as the actual word.
for (int i = 0; i < answer[rand].length(); i++) {
word.append("_");
}
System.out.println(word);
char input = ' ';
// This is where it checks the input and replaces the letters.
for (int i = 0; i < 15; i++) {
input = (char) System.in.read();
for (int j = 0; j < answer[rand].length(); j++) {
if (input == answer[rand].charAt(j)) {
word.setCharAt(j, input);
}
}
// This is where the hidden word get printed twice.
System.out.println(word);
}
// Asks the user if they want to restart the application.
System.out.println("Would you like to try again? (Y/N)");
option = input();
} while (option.equalsIgnoreCase("y"));
}
Use a Scanner to get your input.
Scanner in = new Scanner(System.in);
String line = in.nextLine();
char input = line.charAt(0);
I think System.in.read(); is returning the entered character and the enter key. (the \n char).
That makes your cycle run twice for each input, printing two times and looking like it only accepts 8 chars.
if (word.equals(answer[rand])) {
System.out.println("Congratulations! You guessed the word!");
// Asks the user if they want to restart the application.
System.out.println("Would you like to try again? (Y/N)");
option = input();
}
else if (i == 14) {
System.out.println("Sorry, you did not guess the word.");
// Asks the user if they want to restart the application.
System.out.println("Would you like to try again? (Y/N)");
option = input();
// Returns to the main menu.
menu();
}
This doesn't recognize the word is correct.

Categories