Hangman Game Not Reading From File - java

This program is supposed to pick a random word from a .txt file and have the user try and guess the letters to the word. It runs, but it always says "letter was not found in word" even when I know it's a letter that all of the words have. This makes me think that it isn't properly reading my .txt file.
package hangman;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Random;
import java.util.Scanner;
public class Hangman{
public static void main(String[] args) {
ArrayList<String> dictionaryList = new ArrayList<>();
File file = new File("src/hangman.txt");
try {
try (Scanner scanner = new Scanner(file)) {
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
dictionaryList.add(line);
}
}
} catch (FileNotFoundException e) {
}
/*
* Getting the word and hiding it
*/
Random rng = new Random();
int word = rng.nextInt(dictionaryList.size()); //randomly chooses a word from the text file
Scanner scanner = new Scanner(System.in);
int guessesLeft = 6; // the total amount of guesses the user gets
ArrayList<Character> alreadyGuess = new ArrayList<>(); // keep tracks of the user's guesses
boolean wordFound = false; // keeps track of when the game will end after the user runs out of guesses
String wordSelected = dictionaryList.get(word); //converts the int value of the randomly choose word to a string
char[] letters = wordSelected.toCharArray(); // converts the word to a char
char[] hideWord = new char[letters.length]; // gets the length of hiding the word
// the for loop hides the word by replacing it with '_'
for(int i = 0; i < letters.length; i++) {
hideWord[i]='_';
}
/*
* Starts the hangman game. The while loop will keep running the game.
*/
while(true){
//for testing purposes they can use the print statement below to replace the other print statement
//System.out.print("\n" + wordSelected + "\n" + "Word: ");
System.out.print("\n" + "Word: ");
for(int i = 0; i < letters.length; i++){
System.out.print(hideWord[i]);
} // Display the word
// Allows user to input and displays the guesses that are left
System.out.print("\n" + "Guesses Left: " + guessesLeft +"\nAlready Guess: " + alreadyGuess + "\nGuess: ");
char userInput = scanner.nextLine().toUpperCase().charAt(0); // uppercase the String first, and then pick the char
// Checks to see if the user already guess the same word
for(int i = 0; i < alreadyGuess.size(); i++){
if(userInput==alreadyGuess.get(i)){
System.out.println("\nYou already guessed this letter. Try Again. ");
break;
}
}
// records the user's guesses
if(!(alreadyGuess.contains(userInput))){
alreadyGuess.add(userInput);
}
// Checks if the user guesses the right letter in the word
for(int i = 0; i < letters.length; i++) {
if(userInput==letters[i]) {
hideWord[i] = userInput;
wordFound = true;
}
}
// If user guesses the incorrect letter it will display this and lower the amount of guesses
if(!wordFound){
System.out.println("\nThe letter was not found in the word. \n");
guessesLeft = 1;
}
wordFound = false; // resets the wordFound boolean back to false
// if user runs out of guesses left, they will lose.
if(guessesLeft<=0){
System.out.println("\nYou lose, you hanged the man.");
break;
}
// if user guesses correctly on the word, they win. Uses the array class to compare two char arrays
if(Arrays.equals(letters,hideWord)){
System.out.println("\nWord: " + wordSelected);
System.out.println("\nCongratulations! You guess the right word and save the man from being hang.");
break;
}
}
}
}

Never, ever, ever catch and ignore exceptions! Change the catch clause at the top of the program like this:
catch (FileNotFoundException e) {
e.printStackTrace();
}
so that you will at least have a hint if something bad happened while you were trying to read your word list.
This is such an important lesson it bears repeating, in bold type: Never, ever, ever catch and ignore exceptions!

Related

Why won't the code write to the txt file, even though the txt file exists

I have coded a program to randomly spit out characters until it hits the right word. For example, if I put the word "hello", it would spit out random five letter words until it hit "hello." I have all guesses printed in the console, which is currently working; however, I also wanted it written in a txt file, which isn't working. It won't print the guesses in the txt file. I even checked to make sure I have the right file. Here is my code:
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.*;
public class RandomeWords {
public static void main(String[] args) throws IOException {
File file = new File("hey.txt");
if(file.exists())
System.out.println("The File Exists");
FileWriter writer = new FileWriter(file);
writer.write("go");
Scanner scanner1 = new Scanner(System.in);
System.out.println("Enter Words");
String words = scanner1.nextLine();
int letters = words.length();
for(int i1 = 1; i1 > 0; i1++) {
if(words.contains(" "))
{
String[] alpha = " abcdefghijklmnopqrstuvwxyz".split("");
StringBuilder sb = new StringBuilder("");
for( int i3 = 0; i3 < letters; i3++) {
sb.append(alpha[(int)(Math.random()*72)]);
}
String finall = sb.toString();
if(!finall.equals(words)) {
System.out.println(finall);
writer.write("\n" +finall);
}
if(finall.equals(words)) {
System.out.println(finall);
System.out.println(i1);
System.out.println("it took " +i1 + " tries to randomly find the word.");
System.out.println("It should have taken " +Math.pow((int) 27, letters) +" times, statistacally");
System.out.println("The difference of statistically, and with the simulation is " +(int)Math.abs((int)i1 - (int)Math.pow(27, letters)));
System.exit(0);
}
}
if(!words.contains(" ")){
String[] alpha1 = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!##$%^&*?".split("");
StringBuilder sb1 = new StringBuilder("");
for(int i2 = 0; i2 < letters; i2++) {
sb1.append(alpha1[(int)(Math.random()*71)]);
}
String finall1 = sb1.toString();
if(!finall1.equals(words))
System.out.println(finall1);
if(finall1.equals(words)) {
System.out.println(finall1);
System.out.println(i1);
System.out.println("it took " +i1 + " tries to randomly find the word.");
System.out.println("It should have taken " +Math.pow((int) 26, letters) +" times, statistacally");
System.out.println("The difference of statistically, and with the simulation is " +Math.abs((int)i1 - (int)Math.pow(26, letters)));
System.exit(0);
}
}
}
// writer.close();
}}
Can someone please help? Thanks.
It looks like writer.write("\n" +finall) is only called inside the if-block, if(words.contains(" ")). This code is only reached if the input contains spaces.
If the input does not contain spaces, the call to writer.write should also be made in the other if-block, if(!words.contains(" ")).
In other words, replace
if(!finall1.equals(words))
System.out.println(finall1);
with
if (!finall1.equals(words)) {
System.out.println(finall1);
writer.write("\n" + finall1);
}

null is returned when i try to print an array which logs userinput [Java]

I am trying to print an array which is populated by users input in a hangman game, but when printed it is returning [null,null,null,null,null,null].
Complete code
import java.util.Arrays;
import java.util.Random;
import java.util.Scanner;
import javax.swing.JOptionPane;
public class Hangman {
public static void main(String[] args) {
Scanner consolereader= new Scanner(System.in); //Scanner
JOptionPane.showMessageDialog(null, "Welcome to Hangman");
Object[] options = {"Easy","Medium","Hard"};
int difficulty = JOptionPane.showOptionDialog(null,
"What difficulty would you like to "+ "play","A Question", //asking for what difficulty to play
JOptionPane.YES_NO_CANCEL_OPTION,
JOptionPane.QUESTION_MESSAGE,
null,
options,
options[2]);
switch(difficulty){ //switch that selects which difficulty
case 0: //case 0=easy
boolean endgame=false;
String[] easywords= new String[]{"integer","project","octopus"};
int lives = 12;
String[] lStorage= new String[12]; // array that stores the used letter bank
String easyrnd = (easywords[new Random().nextInt(easywords.length)]); // random word picker
String[] workingGuess= new String[easyrnd.length()];
for(int i=0;i<easyrnd.length(); i++)
{
workingGuess[i]=" _"; //making the lines
}
System.out.println(Arrays.toString(workingGuess)); //printing the lines
char[] chararray= easyrnd.toCharArray(); // making the word into char array
System.out.println("The word has " + easyrnd.length() + " Letters");
while(lives>0)
{ //the loop that controls game
System.out.println("\n Guess a letter");
String letterguess = consolereader.nextLine(); //reading their guess
char charletterguess = letterguess.charAt(0); // making their guess a chaar
if(easyrnd.contains(letterguess))
{ //if contains their guess then:
System.out.println("Correct ");
for(int i=12;i>0;i--){
lStorage[i]=letterguess;
}
for(int i=0;i<easyrnd.length(); i++)
{
if(chararray[i]==charletterguess) //checks where the letteer is in word
{
String charfound = Character.toString(charletterguess);
workingGuess[i]=charfound; //makes the line the letter they guessed if correct
}
}
for(int i =0;i<easyrnd.length();i++)
{
System.out.print(workingGuess[i]); //printing out the lines with any added letters
}
int count=0;
for(int i=0;i<easyrnd.length();i++)
{
if(workingGuess[i]=="_")
{ //the part we are stuck on!
count++;
}
}
} //closing what to do if guess is correct
else{
System.out.println("You have made a WRONG guess");
lives--; // subtracts a life
System.out.println("You have " + lives + " lives left on the hangman board ");
System.out.println(Arrays.toString(lStorage)); //need to display guessed words and pictures
}
if(lives==0)
{
System.out.println("sorry Game OVER"); //if out of lives game over
lives=0;
} //need to add PLAY AGain
}
break;
case 1:
String[] mediumwords= new String[]{"stereo","cyclone","element"};
String medrnd = (mediumwords[new Random().nextInt(mediumwords.length)]);
break;
case 2:
String[] hardwords= new String[]{"antidisestablishmentarianism","pessamistic","synonym"};
String hrdrnd = (hardwords[new Random().nextInt(hardwords.length)]);
break;
default:
System.out.println("you haven't chosen any");
break;
}
}
}
If the guess is correct then only
for(int i=12;i>0;i--){
lStorage[i]=letterguess;
}
this code will execute.. In else the IStorage array will be always null.
You are getting the null,null, .... because you are entering the else branch in
if(easyrnd.contains(letterguess))
If you guess the correct letter, you would get an "Invalid array range exception" here:
for(int i=12;i>0;i--){
lStorage[i]=letterguess;
}
Better:
for(int i=11;i>=0;i--){ //arrays start at 0 and finish at size-1
lStorage[i]=letterguess;
}
You have some other problems in your code:
First of all, you are initializing
workingGuess[i]=" _";
and checking for something else
workingGuess[i]=="_" // no space;
Compare with "equals":
if(" _".equals(workingGuess[i]){
}

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.

How can I make letters in a word appear as underscores for a Hangman game?

I am not able to figure out how to compare what the user guessed to the letters in the word and change the blanks to the letters guessed.
package hangman;
import java.util.ArrayList;
import java.util.Random;
import java.util.Scanner;
public class HangMan {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// user intro
System.out.println("Hello welcome to HangMan");
System.out.println("The obecjt of this game is to guess all the letters of the word.");
System.out.println("You get three tries");
//create an arraylist to store the words that will be guessed
ArrayList<String> wordBank = new ArrayList<>();
//assign words to the wordbank in the array list
wordBank.add("car");
wordBank.add("house");
wordBank.add("girl");
wordBank.add("boy");
wordBank.add("farm");
//create the random object generator
Random rand = new Random();
//this variable holds the random number generated
int numberStored;
numberStored = rand.nextInt(5);
//the random number generated will link to the index of the arraylist to generate the random word
String randomWord;
randomWord = wordBank.get(numberStored);
//display dots to show number of letters in the word
for (int j = 0; j < randomWord.length(); j++) {
System.out.printf("_ ");
}
//create scanner object
Scanner input = new Scanner(System.in);
//this while loop controls the number of guesses
int wrongGuesses = 0;
while (wrongGuesses != 3) {
//prompt
System.out.printf("Guess a letter you think is in the word");
//create a variable to hold the guessed letter
String guessLetter = input.nextLine();
//check to see if guessed letter is in the random word
boolean value = randomWord.contains(guessLetter);
// if else statment to decide what to do
if (value == true) {
System.out.println("Letter " + guessLetter + " is correct");
System.out.println("Now guess a different letter");
//find the position of the guessed letter in the word
//char g = randomWord.charAt(0);
//loop through all the letters of the word
//for (int j = 0; j < randomWord.length(); j++){
// if (gueesLetter.eq)
// int comparedstring
//}
} else {
System.out.println("Sorry "+guessLetter+ " is not in the word");
System.out.println("Try again");
wrongGuesses = wrongGuesses + 1;
}
System.out.println("random word = " + randomWord);
}
}
}
I need to match the guessed letters with and replace them in the _ _ _ setup.
One way to do this is:
public static void main(String[] args) {
String currentWord = "hello";
List<Character> guessedCharacters = new ArrayList<Character>();
guessedCharacters.add('e');
guessedCharacters.add('o');
guessedCharacters.add('q');
guessedCharacters.add('i');
System.out.println(maskString(guessedCharacters, currentWord));
}
private static String maskString(List<Character> guessedCharacters, String currentWord){
char[] currentWordList = currentWord.toCharArray();
StringBuilder maskedString = new StringBuilder();
int tempLength;
for(char letter : currentWordList){
tempLength = maskedString.length(); //store the current length of the string
for(char guessedLetter : guessedCharacters){
if(letter == guessedLetter){
maskedString.append(letter);
}
}
if(tempLength == maskedString.length()){// if the string is still the same length,
// then the tested letter hasn't been guessed yet.
// if the letter hasn't been guessed the we 'mask' it with an underscore.
maskedString.append('_');
}
}
return maskedString.toString();
}
Output:
_e__o

Struggling with my sentinel program

This is my first submission, I have completed one quarter of Java programming.
I have an assignment to create a Palindrome Checker. Fairly straight forward, I had that portion of the code figured out in the first hour. However, in typical fashion (for me) I want my code to do a bit more. This is where I run into issues.
I want this code to do the following:
Take user input
Correctly identify if the input is a palindrome regardless of case or punctuation
Run in a loop so that multiple tests can be performed
So far it works, I just don't know if I went about it the right way. Would anyone be willing to take a look and let me know how inefficient this is, or if it has any obvious rookie mistakes? Thanks so much.
Code:
/**
* Created by Travis on 1/10/2015.
*/
import java.io.IOException;
import java.util.*;
import javax.swing.*;
import java.text.*;
import java.lang.StringBuilder;
public class Palindrome
{
public static void main(String[] args) throws IOException //main class
{
String str = "", answer = "", test1 = "yes", test2 = "no"; //strings
int len = 10; //initial value for len so it doesn't trip the success if
Scanner KB = new Scanner(System.in); //user input
System.out.println("Greetings, Welcome to the Palindrome Checker.\n" + //initial greeting
"Would you like to check a Palindrome? (Yes or no)");
answer = KB.nextLine(); //input is for the sentinel program.
if (!(answer.equalsIgnoreCase(test1) || answer.equalsIgnoreCase(test2))) //error message in case user inputs incorrect string.
{
System.out.println("Error! You can only choose 'yes' or 'no'. Please try again:");
answer = KB.nextLine(); //allows for new answer
}
System.out.println(answer + " y"); //debugging so i can see answer
while (answer.equalsIgnoreCase(test1)) //compares to test1 which is: yes. as long as answer equals yes, the program should loop
{
System.out.println("Please provide a word or phrase:");
str = KB.nextLine(); //prompt for palindrome
String str2 = str.toLowerCase().replaceAll("\\s+", "").replaceAll("\\W+", ""); //converts input to a string that is a single group of chars with no space or punctuation
System.out.println(str2); //debug
StringBuilder str1 = new StringBuilder(str2); //takes the string and makes a stringbuilder so i can delete chars to test
len = str1.length(); //sets for length. This lets me account for any length of phrase
System.out.println(len); //debug
System.out.println(str1); //debug
for (int i = 0; len >= 2; i++) //for loop to progressively test front and back letters and proceed if they are the same
{
char ch1 = str1.charAt(0); //takes the letter at [0] and converts to char
char ch2 = str1.charAt(len - 1); //takes the last letter and converts to char
System.out.println("The first letter in your phrase is: " + ch1); // lists the letter at [0]
System.out.println("The last letter in your phrase is: " + ch2); //lists the letter at the end
if (!(ch1 == ch2)) //if the front and back letter do not match, fails and prompts for new phrase
{
System.out.println("Sorry, this phrase is not a palindrome. \n" +
"Would you like to try again?");
answer = KB.nextLine();
break;
}
else if (ch1 == ch2) //if front and back do match, removes front and back letters and updates stringbuilder
{
System.out.println("Removing letters on each end of the phrase and performing " +
"new check:\n");
str1.deleteCharAt(len - 1); //deletes the last letter from str1
str1.deleteCharAt(0); //deletes first letter from str1
len = str1.length(); //updates len with the new length of str1
i++;
}
}
if (len <= 1) //if the for loop successfully reduces stringbuilder to 1 or less characters, prompts for success
{
System.out.println("Congratulations, your phrase: '" + str + "' is a palindrome! \n\n" +
"Would you like to try again?");
answer = KB.nextLine();
len = 10; //resets len
}
}
if (answer.equalsIgnoreCase(test2)) //ends sentinel loop.
{
System.out.println(answer + " N");
System.exit(0);
}
}
}

Categories