import java.util.Scanner;
import java.util.Random;
public class ResponseTimeProject
{
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
Random rand = new Random();
System.out.print("Please enter your full name: ");
String name = in.nextLine();
System.out.println("Hello " + name + ". Please answer as fast as you can." + "\n\nHit <ENTER> when ready for the question.");
in.nextLine();
for (int count = 0; count < 4; count ++) {
String alphabet="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int character=(int)(Math.random()*26);
String s = alphabet.substring(character, character+1);
Random r = new Random();
int i;
for (i = 0; i < 1; i++) {
System.out.println(alphabet.charAt(r.nextInt(alphabet.length())));
}
long startTime = System.currentTimeMillis();
System.out.print("What is the next letter in the alphabet?" + " ");
String response = in.nextLine();
long endTime = System.currentTimeMillis();
String outcome;
if (alphabet.substring(character+1, character+2).equals(response)) {
outcome = "Correct!";
} else {
outcome = "Incorrect.";
}
long reactionTime = endTime - startTime;
System.out.println(outcome);
System.out.println("The average time it took you was " + reactionTime + " milliseconds");
System.out.println("Thank you " + name + ", goodbye.");
}
}
}
HELP:
This code runs but it gives me the wrong answer. I do not know what is wrong. It prints incorrect for the right outcome. Not sure what I need to fix
The code in question is really a total mess (substring to get a character from a String, loops of a single iteration, etc.). But the fundamental issue relating to the question is that the "next letter in the alphabet" depends upon an output that is printed but never stored. It is currently
for (i = 0; i < 1; i++) {
System.out.println(alphabet.charAt(r.nextInt(alphabet.length())));
}
and therefore never saved, so there is nothing to compare it to.
So, save the next character, and then print it.
char nextLetter = alphabet.charAt(r.nextInt(alphabet.length());
Then in the comparison, for the response, check the response against an actual value, not some random substring from the alphabet String.
response = in.nextLine();
char chkChar = response.charAt(0);
if (chkChar == nextLetter) {
...
}
Related
I am creating a hangman program in java. The program is supposed to randomly generate the word and as the user correctly guesses a letter it should reveal it. I have created the function where it prints the amount of underscores depending on the length of the word. The issue I have is I'm not sure how I'm supposed to replace the underscore with the letter when it's guessed.
public static void main(String[] args) {
int choice;
String wordSoFar = "";
Console.print("Take your time.");
choice = Console.readInt("Enter your choice, when you're ready : ");
}
if (choice == 1) {
for (int i = 0; i < wordLength; i++) {
word += " _ ";
}
do {
String guess = Console.readString("Enter your guess here : ");
String response = secert(guess);
Console.print(response);
} while (incorrectLetters < maxIncorectLetters || correctLetters < wordLength);
}
}
public static String secretWordSelector(String secretWord) {
String[] secretWordsList = { "fun", "boring", "yellow", "phython", "tesla", "iphone", "computer", "adventure",
};
int min = 0;
int max = 8;
secretWord = secretWordsList[randomNumber(min, max)];
return secretWord;
}
public static String letterChecker(String guess, String wordSoFar) {
String response = "";
String secertWord = "";
if (secretWord == guess)) {
int index = secretWord.indexOf(guess);
correctLetters++;
answer = "Congratulations!
} else {
answer= "That is a incorrect guess!
}
return answer;
}
Your code can be improved a lot by the following changes:
You do not need the complex function, randomNumber. You can simply pass the length of the array to Random#nextInt and it will generate an int in the range of 0 to length_of_array - 1.
Similarly, your function, length is not required. You can simply call String#length to get the length of the string.
You have unnecessarily passed an argument to your function, secretWordSelector.
Since you are using String wordSoFar in multiple methods, it will be easier to process it by making it global.
You have called secretWordSelector again in letterChecker which is wrong. You have to process the same word which was selected randomly at the time when the user selected a choice.
Your while loop is infinite because of the wrong operator. It should be while (incorrectLetters < maxIncorectLetters && correctLetters < wordLength)
I have re-written the method, letterChecker with many changes which are self-explanatory. I have also put some comments to help you understand its code easily.
Code incorporating these improvements:
import java.util.Random;
import java.util.Scanner;
public class Main {
private static int incorrectLetters;
private static int correctLetters;
private static String wordSoFar = "";
public static void main(String[] args) {
int choice;
Scanner scanner = new Scanner(System.in);
final int maxIncorectLetters = 6;
System.out.println("Welcome to Mahmoud's Hangman game!");
System.out.println("Would you like to play. 1 - Yes. 0 - No");
System.out.print("Enter your choice: ");
choice = Integer.parseInt(scanner.nextLine());
if (choice == 0) {
System.out.println("Take your time.");
System.out.print("Enter your choice, when you're ready: ");
choice = Integer.parseInt(scanner.nextLine());
}
if (choice == 1) {
System.out.println("Be careful, you can only have 6 wrong guesses");
int wordLength = 0;
String secretWord = secretWordSelector();
wordLength = secretWord.length();
System.out.println("Your word has " + wordLength + " letters.");
for (int i = 0; i < wordLength; i++) {
wordSoFar += "_";
}
do {
System.out.print("Enter your guess here: ");
String guess = scanner.nextLine();
String response = letterChecker(guess.toLowerCase().charAt(0), secretWord);
System.out.println(response);
} while (incorrectLetters < maxIncorectLetters && correctLetters < wordLength);
}
}
public static String secretWordSelector() {
String[] secretWordsList = { "geography", "cat", "yesterday", "java", "truck", "opportunity", "fish", "token",
"transportation", "bottom", "apple", "cake", "remote", "boots", "terminology", "arm", "cranberry",
"tool", "caterpillar", "spoon", "watermelon", "laptop", "toe", "toad", "fundamental", "capitol",
"garbage", "anticipate", "pesky" };
return secretWordsList[new Random().nextInt(secretWordsList.length)];
}
public static String letterChecker(char guess, String secretWord) {
String response = "";
// Initialize a StringBuilder with wordSoFar
StringBuilder sb = new StringBuilder(wordSoFar);
if (secretWord.indexOf(guess) != -1) {// i.e. if guess is present in secretWord
// Replace each corresponding occurrence of '_' in the StringBuilder with guess
for (int i = 0; i < secretWord.length(); i++) {
char ch = secretWord.charAt(i);
if (ch == guess) {
sb.setCharAt(i, ch);
correctLetters++;
}
}
// Assign the updated StringBuilder to wordSoFar
wordSoFar = sb.toString();
return "Congratulations! You have guessed correctly. " + " You have " + incorrectLetters
+ " incorrect guesses " + wordSoFar;
}
incorrectLetters++;
response = "That is a incorrect guess! " + " You have " + incorrectLetters + " incorrect guesses " + wordSoFar;
return response;
}
}
A sample run:
Welcome to Mahmoud's Hangman game!
Would you like to play. 1 - Yes. 0 - No
Enter your choice: 1
Be careful, you can only have 6 wrong guesses
Your word has 4 letters.
Enter your guess here: o
That is a incorrect guess! You have 1 incorrect guesses ____
Enter your guess here: e
That is a incorrect guess! You have 2 incorrect guesses ____
Enter your guess here: a
That is a incorrect guess! You have 3 incorrect guesses ____
Enter your guess here: h
Congratulations! You have guessed correctly. You have 3 incorrect guesses ___h
Enter your guess here: f
Congratulations! You have guessed correctly. You have 3 incorrect guesses f__h
Enter your guess here: i
Congratulations! You have guessed correctly. You have 3 incorrect guesses fi_h
Enter your guess here: s
Congratulations! You have guessed correctly. You have 3 incorrect guesses fish
So the problem that I am currently running into is that the statement "Enter your command (reverse, replace first, replace last, remove all, remove)" is printing twice after I go through all the steps.
What I believe is happening is the loop is executing twice but I don't know why. Any help would be appreciated in solving this problem. Sorry in advance if my code formatting is bad still learning how to properly format.
import java.util.Scanner;
public class StringChangerenter {
public static void main(String[] args) {
Scanner keyboard = new Scanner(System.in);
// Output Variables
String userInput = "";
// Variables
String removeChar = "", removeAllChar = "";
int removeIndex = 0;
// First Output
System.out.println("Enter the string to be manipulated");
userInput = keyboard.nextLine();
String command = "";
// While loop
while (!command.equalsIgnoreCase("quit")) {
// Output
System.out.println("Enter your command (reverse, replace first, replace last, remove all, remove)");
command = keyboard.nextLine();
if (command.equalsIgnoreCase("remove")) {
System.out.println("Enter the character to remove");
removeChar = keyboard.nextLine();
int totalCount = 0;
for (int j = 0; j < userInput.length(); j++) {
if (userInput.charAt(j) == removeChar.charAt(0)) {
totalCount = totalCount + 1;
}
}
System.out.println("Enter the " + removeChar
+ " you would like to remove (Not the index - 1 = 1st, 2 = 2nd, etc.):");
removeIndex = keyboard.nextInt();
int currentIndex = 1;
if (removeIndex <= totalCount) {
for (int i = 0; i < userInput.length(); i++) {
if (userInput.charAt(i) == removeChar.charAt(0)) {
if (currentIndex == removeIndex) {
String firstpartOfString = userInput.substring(0, i);
String secondpartOfString = userInput.substring(i + 1, userInput.length());
System.out.println("The new sentence is " + firstpartOfString + secondpartOfString);
userInput = firstpartOfString + secondpartOfString;
break;
} else {
currentIndex = currentIndex + 1;
}
}
}
} else {
System.out.println("Can't find " + removeChar + " occuring at " + removeIndex + " int the string.");
}
// Remove All Code
} else if (command.equalsIgnoreCase("remove all")) {
System.out.println("Enter the character to remove");
removeAllChar = keyboard.next();
String newString = "";
for (int i = 0; i < userInput.length(); i++) {
if (userInput.charAt(i) != removeAllChar.charAt(0)) {
newString = newString + userInput.charAt(i);
}
}
userInput = newString;
System.out.println("The new sentence is " + userInput);
}
// Bracket for while loop
}
}
}
The reason you are getting two entries after you've processed a character, is that you have not fully read the line containing the character.
Specifically, you use keyboard.nextInt(); in the upper branch, and keyboard.next(); in the lower branch. While these read the next integer and character, respectively, they do not process the end of line marker.
Then when you reach the top of the loop, you call keyboard.nextLine() which processes whatever characters occurred after the int (or character, in the remove all case) until the end of line marker. With the expected user input, that's just an empty string.
To fix this, you need to ensure you read all the way through the keyboard.nextLine() in the cases where you are reading only integers, or a single character.
what is happening is, the condition for you while loop is
while (!command.equalsIgnoreCase("quit"))
which in english mean, as long as command is not equal to "quit" then run this loop.
Inside the loop, command is never actually set to "quit". ex if I give input string as "abcde" and ask to remove "c" at position 1.
Then your logic sets command to "remove" here
command = keyboard.nextLine();
and then prints the final value as "abde". Now when the loop ends, command is still "remove" and hence the loop executes again.
A possible solution is to explicitly ask the user if he wants to retry using a do while loop. Also just a tip, i see you have used nextInt. It is advisable to use a nextLine immediately after next int. see this for the reason why: Java Scanner doesn't wait for user input
this is what you code would be if you explicitly took user consent if you want to run any more commands:
public static void main (String[] args) throws java.lang.Exception
{
Scanner keyboard = new Scanner(System.in);
// Output Variables
String userInput = "";
// Variables
String removeChar = "", removeAllChar = "";
int removeIndex = 0;
// First Output
System.out.println("Enter the string to be manipulated");
userInput = keyboard.nextLine();
String command = "";
String retry = "";
// While loop
do {
// Output
System.out.println("Enter your command (reverse, replace first, replace last, remove all, remove)");
command = keyboard.nextLine();
if (command.equalsIgnoreCase("remove")) {
System.out.println("Enter the character to remove");
removeChar = keyboard.nextLine();
int totalCount = 0;
for (int j = 0; j < userInput.length(); j++) {
if (userInput.charAt(j) == removeChar.charAt(0)) {
totalCount = totalCount + 1;
}
}
System.out.println("Enter the " + removeChar
+ " you would like to remove (Not the index - 1 = 1st, 2 = 2nd, etc.):");
removeIndex = keyboard.nextInt();
keyboard.nextLine();
int currentIndex = 1;
if (removeIndex <= totalCount) {
for (int i = 0; i < userInput.length(); i++) {
if (userInput.charAt(i) == removeChar.charAt(0)) {
if (currentIndex == removeIndex) {
String firstpartOfString = userInput.substring(0, i);
String secondpartOfString = userInput.substring(i + 1, userInput.length());
System.out.println("The new sentence is " + firstpartOfString + secondpartOfString);
userInput = firstpartOfString + secondpartOfString;
break;
} else {
currentIndex = currentIndex + 1;
}
}
}
} else {
System.out.println("Can't find " + removeChar + " occuring at " + removeIndex + " int the string.");
}
// Remove All Code
} else if (command.equalsIgnoreCase("remove all")) {
System.out.println("Enter the character to remove");
removeAllChar = keyboard.next();
String newString = "";
for (int i = 0; i < userInput.length(); i++) {
if (userInput.charAt(i) != removeAllChar.charAt(0)) {
newString = newString + userInput.charAt(i);
}
}
userInput = newString;
System.out.println("The new sentence is " + userInput);
}
System.out.println("Do you want to go again?");
retry = keyboard.nextLine();
// Bracket for while loop
}while("yes".equalsIgnoreCase(retry));
}
I was writing some code for my class and I ran into this error, String index out of range. I checked to see if it might be the string = null but that's not the case. I'm guessing it has to do with my if statement in the method but I couldn't find how to fix it anywhere. Any help is appreciated, thank you very much!
import java.util.*;
public class Occurences {
public static void main(String[] args) {
int check = 0;
char characterInput = ' ';
do {
Scanner scan = new Scanner(System.in);
System.out.println("Please enter a string: ");
String input = scan.next();
System.out.println("Enter a character to find it's occurence in the string: ");
characterInput = scan.next().charAt(0);
int i = count(input, characterInput);
System.out.println(characterInput + ", is in " + input + ", " + i + " times.");
System.out.println("To continue enter any number, to exit enter -1: ");
check = scan.nextInt();
} while (check != -1);
}
public static int count(String input, char characterInput) {
int cnt = 0;
int j = input.length();
while (j > 0) {
if (input.charAt(j) == characterInput) {
cnt += 1;
}
j--;
}
return cnt;
}
}
The error happens on line 21: int j = input.length(), as others mentioned in the comments, java, and most programming languages, index strings and array types by zero-indexing - starting from zero. So you have to either 1) start counting at 0 or 2) stop counting at one-less-than the length of the string(array), which is why line 21 needs to be either:
int j = input.length()-1;
or as you solved it using method 1:
setting int j=0;
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.
I have been working on this for several days and I'm super frustrated. This is my first course in Java so please bear with me on lack of knowledge still. I'm supposed to write a program that contains an array of 10 grades entered by the user and I calculate the average. In particular I'm having problems with what is down below.
You should not read doubles numbers from the user, you should read a string. Here is the process:
Read a string from the user
trim the string and get the length
if the length <1 then the user hit and you get out
if the length is >0 then you convert the string into a double using
d =Double.parseDouble(S);
So far I just have this. I have been adding and deleting a lot of coding to this for the past week. And I still cant seem to get it to work. Any help would be much appreciated!
import java.util.*;
import java.io.*;
public class Arrays {
public static void main(String[] args) {
double d = 0;
final int SIZE = 10;
Scanner reader = new Scanner(System.in);
String[ ] grades = new String[SIZE];
System.out.println("Please enter up to 10 grades.");
for (int i = 0; i < grades.length; i++){
System.out.print("Grade " + (i + 1) + ": ");
grades[i] = reader.nextLine( );
}
System.out.println("\nNumber of valid grades entered: " + grades.length);
}
}
Try this
for (int i = 0; i < grades.length; ){
System.out.print("Grade " + (i + 1) + ": ");
String str = reader.nextLine();
if(str.trim().length() > 0){
try{
grades[i] = Double.parseDouble(str);
i++;
}catch(NumberFormatException e){
e.printStackTrace();
}
}
}
System.out.println("\nNumber of valid grades entered: " + i);
IMHO i think grades should be an array of double ie
double[] grades=new double[SIZE];
You can try it in following way
int correctGrades=0;
double[] grades=new double[SIZE]; //Create array of double instead of String
for (int i = 0; i < SIZE; i++){
System.out.print("Grade " + (i + 1) + ": ");
String str=reader.nextLine();
if(str.length() > 0){ // If length is greater than 0 then its correct grade
grades[i]=Double.parseDouble(str);
correctGrades++;
}
}
System.out.println("\nNumber of valid grades entered: " + correctGrades);
As per my understanding this should be your for loop
for (int i = 0; true; i++) {
System.out.print("Grade " + (i + 1) + ": ");
grades[i] = reader.nextLine();
if (grades[i].equals("")) {
break;
}
//check for number format exception if user enters invalid input
try {
d = Double.parseDouble(grades[i]);
}
catch (NumberFormatException exception) {
exception.printStackTrace();
}
}
System.out.println("The value of double entered is : " + d);
}
Here you run the loop for infinite number of times but with every loop you check the user input.
Now if the user enters an empty string you exit the loop using the break statement