Java Input Validation, only loops twice, not detecting Upper/Lower Case Characters - java

I want my input to be a minimum of 4 strings and a maximum of 8. I am tokenizing them for practice. My loop will rerun if I the input is outside of these parameters, but will only rerun once and continue on with the rest of the program. I feel like I am using the wrong loop for validation because I would just have while/if to infinity at this point I think.
Finally, at the end, when trying to determine how many chars are upper or lower case, my results returns a count of 0, but my letters, digits and white spaces counts are accurate.
I really appreciate any insight.
Here is my code:
import java.util.ArrayList;
import java.util.Scanner;
import java.util.StringTokenizer;
public class charEvaluation {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
ArrayList<String> tokenizedInput = new ArrayList<>();
String sentenceRetrieved;
// getting the sentence from the user
System.out.println("Please type a sentence containing at least 4 words, with a maximum of 8 words: ");
sentenceRetrieved = sc.nextLine();
StringTokenizer strTokenizer = new StringTokenizer(sentenceRetrieved);
// checking to ensure the string has 4-8 words
while (strTokenizer.hasMoreTokens()) {
if (strTokenizer.countTokens() > 8 || strTokenizer.countTokens() < 4) {
System.out.println("Please re-enter a sentence with at least 4 words, and a maximum of 8: ");
//sentenceRetrieved = null;
//tokenizedInput.removeAll(tokenizedInput);
sentenceRetrieved = sc.nextLine();
while (strTokenizer.hasMoreTokens()) {
tokenizedInput.add(strTokenizer.nextToken());
}
} else {
while (strTokenizer.hasMoreTokens()) {
tokenizedInput.add(strTokenizer.nextToken());
}
System.out.println("Thank you.");
break;
}
}
// printing out the sentence
System.out.println("You entered: ");
System.out.println(sentenceRetrieved);
// count the characters in each word
int totalLength = 0;
for (String each : tokenizedInput) {
totalLength += each.length();
System.out.println( each + " has " + each.length() + " characters.");
}
System.out.println("The total number of characters entered without spaces: "+
sentenceRetrieved.replace(" ", "").length());
/*
* Setting up a character array and determining how many
* letters, digits, lower case letters, upper case letters and white spaces in the input.
*/
char [] array;
int letters = 0,
digits = 0,
lowerCase = 0,
upperCase = 0,
whitespaces = 0;
array = sentenceRetrieved.toCharArray();
for(int i = 0; i< array.length; i++) {
if (Character.isLetter(array[i]))
letters ++;
else if(Character.isDigit(array[i]))
digits++;
else if(Character.isUpperCase(array[i]))
upperCase++;
else if(Character.isLowerCase(array[i]))
lowerCase++;
else if(Character.isWhitespace(array[i]))
whitespaces++;
}
System.out.println("The number of letters is " + letters + ".");
System.out.println("The number of digits is " + digits + ".");
System.out.println("The number of lower case letters is " + lowerCase+ ".");
System.out.println("The number of upper case letters is " + upperCase + ".");
System.out.println("The number of white spaces is " + whitespaces + ".");
}
}
My output then looks like this:
Please type a sentence containing at least 4 words, with a maximum of 8 words:
hi there3
Please re-enter a sentence with at least 4 words, and a maximum of 8:
hi there3
You entered:
hi there3
hi has 2 characters.
there3 has 6 characters.
The total number of characters entered without spaces: 8
The number of letters is 7.
The number of digits is 1.
The number of lower case letters is 0.
The number of upper case letters is 0.
The number of white spaces is 1.

How about something like this. It will keep prompting until the conditions are met.
while (true) {
System.out.println(
"Please type a sentence containing at least 4 words, with a maximum of 8 words: ");
sentenceRetrieved = sc.nextLine();
StringTokenizer strTokenizer =
new StringTokenizer(sentenceRetrieved);
int count = strTokenizer.countTokens();
if (count <= 8 && count >= 4) {
break;
}
}
To fix your second problem, get rid of the first else. Once you determine it is a letter, you don't do any other testing. You can also just test for upper/lower once you figure out it's a letter.
if (Character.isLetter(array[i]))
letters++;
if (Character.isDigit(array[i])) {
..
} else if(

If isLetter, it can be upper or lower. Try this.
if (Character.isLetter(array[i])){
letters ++;
if(Character.isUpperCase(array[i]))
upperCase++;
else if(Character.isLowerCase(array[i]))
lowerCase++;
} else if(Character.isDigit(array[i])){
digits++;
} else if(Character.isWhitespace(array[i]))
whitespaces++;
In your code, you checked if isUpper or isLower only if !isCharacter which is wrong I believe.
That is why your counts were not correct

Related

How to find the length of the last word in java?

I want to find the length of the last word to initially find the length of the second word in the phrase. here's my plan, If I find the length of the last phrase then in the for loop if I subtract x, it should give me the length of the second word always. This has to be done using for loop and a scanner, where the user inputs any phrase.
Basically, I need to know how to find the length of the last phrase. Thats what I need to know only.
here's my code:
else if (option == 2){
int counter = 0 ;
for (int x = 0; x < phrase.length() - x; x++){
//in the "int x = 0" i need to put the length of the last word
// in a phrase
char n = phrase.charAt(x);
if (n == x);
counter++;
}
System.out.print("Second word has "+counter+" letters");
}
With only the for-loop, length of last word in the phrase:
else if (option == 2){
int lastSpaceChar = 0;
for (int x = 0; x < phrase.length(); x++){
char n = phrase.charAt(x);
if (n == ' ') { //Indicate space
lastSpaceChar = x;
}
}
//When loop is finished, it will have the index of the last space
//So if you take total length - last space, you'll get the last word
int lengthOfLastWord = phrase.length() - spaceChar;
System.out.print("Last word has " + lengthOfLastWord + " letters");
}
If you want the second word, you need to do the same, except find 1st and 2nd space, because characters between first 2 spaces form the 2nd word.
else if (option == 2){
int firstSpace = -1;
int secondSpace = -1;
for (int x = 0; x < phrase.length(); x++){
char n = phrase.charAt(x);
if (n == ' ' && firstSpace == -1) { //Space found the first time
firstSpace = x;
} else if (n == ' ') {
//FirstSpace has already been found
//So this should be second
secondSpace = x;
break; //No need to look anymore, we have both spaces
}
}
//When loop is finished, you will have first 2 spaces
//Characters between first 2 spaces is 2nd word
int lengthOfSecondWord = firstSpace - secondSpace;
System.out.print("Second word has " + lengthOfSecondWord + " letters");
}
I'm assuming you're just learning, so this will do.
Of course, you should probably do error handling and look out for edge cases in actual practice.
The length of the last word in a sentence can be obtained like this:
public int getLengthOfLastWord(String sentence) {
if (sentence == null || sentence.length() == 0) {
return 0;
}
// Split the sentence into words on space(s).
String[] words = sentence.split("\\s+");
return words[words.length - 1].length();
}
To be accurate, you'll want to do more than just check for spaces between words, because if you are only looking for spaces then it is going to treat punctuation like commas and periods as part of the lengths of words. So your best bet is something like isAlphabetic().
If your plan is to loop through characters in the string (i.e. you don't want to use string functions), one very simple way (that wouldn't require you to change your code much) is to count forward through the array. The first time you find one where:
phrase.charAt(x).isAlphabetic()
is true, you know you've reached the beginning of the first "word" in the phrase.
Then you keep looking forward and when
!phrase.charAt(x).isAlphabetic()
Then you know you've reached the space between the first word and the second word. But there might be punctuation so you keep scanning forward until you're back to isAlphabetic() being true again, at which point you've reached the beginning of the second word. You now start counting characters until you find isAlphabetic() going false again (you've reached a space or punctuation). At which point you know you've reached the end of the second word, and now you can check your character count for how long it was.
This method doesn't count numbers, punctuation, spaces, and special characters as part of a phrase. So you might need to special-case it for things like an apostrophe in a contraction like "don't", but hopefully this gives you a general idea.
There are other approaches, but this is the closest to how you have your code right now. Obviously you can use String functions and get a shorter piece of code, etc, but you asked specifically for a version that conformed to your loop method.
int word_wanted = 2; // Want length of the second word. Or set to -1 if you want the last word.
int counter = 0; // How long is the current word
int on_word = 0; // What word number are we on
boolean in_word = false; // Are we currently in a word
for (int x = 0; x < phrase.length() - x; x++){
if (phrase.charAt(x).isAlphabetic()) {
if (!in_word) {
on_word++;
counter = 0;
in_word = true;
}
counter++;
} else {
if (in_word) {
in_word = false;
if (on_word == word_wanted) break; // Stop if we found the length of the word requested.
}
}
}
// counter now contains the length of the requested word. It can be returned
// as a return value from your method, or used for other purposes.
It is not clear from your question whether you want to find the length of the last word or the length of the second word from the start or the length of the second last word in a phrase. So, I've written solutions to all of these requirements. I've put enough comment in the code so that you can understand it easily.
Length of the last word:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner keyboard = new Scanner(System.in);
System.out.print("Enter option: ");
int option = Integer.parseInt(keyboard.nextLine());
if (option == 2) {
System.out.print("Enter phrase: ");
String phrase = keyboard.nextLine();
int i;
// Start the loop from the end in the backward direction
for (i = phrase.length() - 1; i >= 0; i--) {
if (phrase.charAt(i) == ' ') {
System.out.println("Length of the last word: " + (phrase.length() - i - 1));
break;
}
}
// If the loop terminated without finding any space, it means there is only one
// word in the phrase
if (i == -1) {
System.out.println("Length of the last word: " + phrase.length());
}
}
}
}
A sample run:
Enter option: 2
Enter phrase: Good morning world
Length of the last word: 5
Another sample run:
Enter option: 2
Enter phrase: Good morning
Length of the last word: 7
Another sample run:
Enter option: 2
Enter phrase: Good
Length of the last word: 4
Length of the second word from the beginning:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner keyboard = new Scanner(System.in);
System.out.print("Enter option: ");
int option = Integer.parseInt(keyboard.nextLine());
if (option == 2) {
System.out.print("Enter phrase: ");
String phrase = keyboard.nextLine();
int index = 0, counter = 0;
for (int i = 0; i < phrase.length(); i++) {
if (phrase.charAt(i) == ' ') {
if (counter == 0) {
index = i;
}
counter++;
}
// Print the length when space has been found second time, and break the loop
if (counter == 2) {
System.out.println("Length of the second word: " + (i - index - 1));
break;
}
}
// If there are only two words in the phrase, space will be found only once. In
// that case the length of the second word will be phrase.length() - index - 1
if (counter == 1) {
System.out.println("Length of the second word: " + (phrase.length() - index - 1));
}
}
}
}
A sample run:
Enter option: 2
Enter phrase: Hello world
Length of the second word: 5
Another sample run:
Enter option: 2
Enter phrase: Good morning world
Length of the second word: 7
Length of the second last word:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner keyboard = new Scanner(System.in);
System.out.print("Enter option: ");
int option = Integer.parseInt(keyboard.nextLine());
if (option == 2) {
System.out.print("Enter phrase: ");
String phrase = keyboard.nextLine();
int index = 0, counter = 0;
// Start the loop from the end in the backward direction
for (int i = phrase.length() - 1; i >= 0; i--) {
if (phrase.charAt(i) == ' ') {
if (counter == 0) {
index = i;
}
counter++;
}
// Print the length when space has been found second time, and break the loop
if (counter == 2) {
System.out.println("Length of second last word: " + (index - i - 1));
break;
}
}
// If there are only two words in the phrase, space will be found only once. In
// that case the length of the second last word (which is the first word out of
// the two words) will be index (as the loop is running in the backward
// direction)
if (counter == 1) {
System.out.println("Length of second last word: " + index);
}
}
}
}
A sample run:
Enter option: 2
Enter phrase: Good morning world
Length of second last word: 7
Another sample run:
Enter option: 2
Enter phrase: Hello world
Length of second last word: 5

Hangman: How to compare and replace a dash with a letter found

I am learning Java, I know it exists several solutions on stackoverflow but I am stuck. I am trying to create a basic Hangman.
I would like to know how Could I replace a dash with a letter found?
Here is a demonstration:
The word to search is:no
I enter the letter n
You have 5 attempts.
--
Enter your letter: n
I enter the letter o
You have 4 attempts.
--
Enter your letter: o
Idem.
You have 3 attempts.
--
Enter your letter:
Here is my code:
Scanner input = new Scanner(System.in);
char letter = 0; // declares and initialises letter
String[] words = {"yes", "no"}; // declares and initialises an array of words to guess
String word = words[(int) (Math.random() * words.length)]; // chooses random word
boolean[] found = new boolean[word .length()];
int attempts = 5;
while(attempts > 0){
System.out.println("You have " + attempts + " attempts.");
for(int i=0; i<word.length(); i++) {
if ( found[i] ) {
System.out.print(word.charAt(i));
}
else {
System.out.print('-');
}
}
System.out.println("");
System.out.print("Enter your letter : ");
letter = input.next().charAt(0);
attempts--;
}
I have to add a loop perhaps?
I share you my code here => https://repl.it/repls/PeriodicLegitimateMatrix
You can use the indexOf(char) method in the String class to check whether the character was in the word.
It should look like this:
while (attemps > 0) {
//...
System.out.println("");
System.out.print("Enter your letter : ");
letter = input.next().charAt(0);
int characterPosition = word.indexOf(letter);//use a loop because the character could appear in more than one position in the word
while (characterPosition != -1) {//if indexOf(char) returns -1 it means the char was not found
found[characterPosition] = true;
characterPosition = word.indexOf(letter, characterPosition);//this time search the character starting from the last position to find the next one
}
attempts--;
}

Counting matching characters on a string

I have been asked to created a program that asks the user for two inputs, both of which have to be stored as strings. The first input can be one or multiple words, and the second input has to be one sole character. After the user enters both inputs the program should count how many times, if any, the sole charter appears in the first string. Once the iteration through the first string is done the program should then output the number of instances of the second string. Example:
"There is 1 occurrence(s) of 'e' in test."
The program must use the a while loop and string values. This is the solution I have as of right now following the parameters established by the professor
public static void main(String[] args) {
String inputEntry; // User's word(s)
String inputCharacter; // User's sole character
String charCapture; // Used to create subtrings of char
int i = 0; // Counter for while loop
int charCount = 0; // Counter for veryfiying how many times char is in string
int charCountDisplay = 0; // Displays instances of char in string
Scanner scan = new Scanner(System.in);
System.out.print("Enter some words here: "); // Captures word(s)
inputEntry = scan.nextLine();
System.out.print("Enter a character here: "); // Captures char
inputCharacter = scan.nextLine();
if (inputCharacter.length() > 1 || inputCharacter.length() < 1) // if user is not in compliance
{
System.out.print("Please enter one character. Try again.");
return;
}
else if (inputCharacter.length() == 1) // if user is in compliance
{
while( i < inputEntry.length()) // iterates through word(s)
{
charCapture = inputEntry.substring(charCount); // Creates substring of each letter in order to compare to char entry
if (charCapture.equals(inputCharacter))
{
++charCountDisplay;
}
++charCount;
++i;
}
System.out.print("There is " + charCountDisplay +
" occurrence(s) of " + inputCharacter + " in the test.");
}
}
This iteration has a bug. Instead of counting all the instances of the inputCharacter variable it only counts up to one, regardless of how many instances appear on the string. I know the problem is in this part of the code:
while( i < inputEntry.length()) // iterates through word(s)
{
charCapture = inputEntry.substring(charCount); // Creates substring of each letter in order to compare to char entry
if (charCapture.equals(inputCharacter))
{
++charCountDisplay;
}
++charCount;
++i;
}
I just can't quiet pin down what I'm doing wrong. It seems to me that the charCountDisplay variable reverts to zero after each iteration. Isn't that supposed to be avoided by declaring the variable at the very beginning?... I'm one confused fellow.
This is wrong
charCapture = inputEntry.substring(charCount);
does not return one char
try using inputEntry.charAt(charCount)
Another hint is to define your variables close to where you use them rather than at the top of your method like:
String inputEntry;
inputEntry = scan.nextLine();
Even better would be to do inline
String inputEntry = scan.nextLine();
It will make your code a lot more concise and readable.
A more concise way to do your code is:
Scanner scan = new Scanner(System.in);
System.out.print("Enter some words here: "); // Captures word(s)
String inputEntry = scan.nextLine();
System.out.print("Enter a character here: "); // Captures char
String inputCharacter = scan.nextLine();
// validate
// then
int len = inputEntry.length();
inputEntry = inputEntry.replace(inputCharacter, "");
int newlen = inputEntry.length();
System.out.format("There is %d occurrence(s) of %s in the test.%n",
len - newlen, inputCharacter);
output
Enter some words here: scarywombat writes code
Enter a character here: o
There is 2 occurrence(s) of o in the test.
Here is a complete MVCE:
package com.example.countcharacters;
/**
* EXAMPLE OUTPUT:
* Enter some words here:
* How now brown cow
* Enter a character here:
* abc
* Please enter one character. Try again.
* Enter a character here:
* o
* There are 4 occurrence(s) of o in the text How now brown cow.
*/
import java.util.Scanner;
public class CountCharacters {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
// Captures word(s)
String inputEntry;
System.out.println("Enter some words here: ");
inputEntry = scan.nextLine();
// Captures char
char inputCharacter;
while (true) {
System.out.println("Enter a character here: ");
String line = scan.nextLine();
if (line.length() == 1) {
inputCharacter = line.charAt(0);
break;
} else {
// if user is not in compliance
System.out.println("Please enter one character. Try again.");
}
}
// iterates through word(s)
int charCountDisplay = 0;
int i = 0;
while(i < inputEntry.length()) {
char c = inputEntry.charAt(i++);
if (c == inputCharacter) {
++charCountDisplay;
}
}
// Print results
System.out.print("There are " + charCountDisplay +
" occurrence(s) of " + inputCharacter +
" in the text " + inputEntry + ".");
}
}
NOTES:
You can use "char" and "String.charAt()" to simplify your code.
In general, it's preferable to declare variables close to where you use them (rather than at the top).
You can put your test for "one character only" in its own loop.
'Hope that helps!
inputEntry.chars().filter(tempVar -> tempVar == inputCharacter).count() will give you the number of occurrences of a character in the string.
String inputEntry = "text";
char inputCharacter = 'x';
System.out.print("There is " + inputEntry.chars().filter(tempVar -> tempVar == inputCharacter).count() + " occurrence(s) of " + inputCharacter + " in the text " + inputEntry + ".");

I have to make a tweet tester in java, but can't figure out how to count the amount of times a character shows up in the tweet

Alright, so for a class I am taking I have to make a program that tests tweets. It asks you to input a tweet, then tells you if the tweet is valid (less than 140 characters), tells you the amount of mentions (indicated by the character #) and the number of hashtags (indicated by a #), and tells you whether or not it is a retweet (if it contains "RT:" it is considered a retweet).
I can tell whether it is a valid tweet and can tell if it is a retweet (I coded it so that if the index of "RT:" is greater than or equal to 0, it says it is a retweet), but can't figure out how to count the number of # and # in the string the user enters. I know how to find the index, but am having trouble finding out where to go from there. I don't know what to do as a next course of action. Is there a way to count the amount of a certain character in a string?
I know what the code is currently doing, outputting the index of the first time the character shows up, but I am lost on what else I could do. I thought that maybe I could truncate every letter before and including the # and use a loop to count the amount of times that I get an index for #, then do the same for the #, but I don't know how to truncate every letter before and including a certain character. Or is there a better option? Any help is appreciated
import java.util.Scanner;
import java.lang.Math;
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.println("Please enter a tweet:");
String s = scan.nextLine();
int length = s.length();
if(length > 140)
System.out.println("Excess Characters: " + ( length - 140));
else{
System.out.println("Length Correct");
int at = s.indexOf('#');
System.out.println("Number of Mentions: " + (at));
int hash = s.indexOf('#');
System.out.println("Number of Hashtags: " + (hash));
if (s.indexOf("RT:") >=0)
System.out.println("The input was a retweet.");
else
System.out.println("The input was not a retweet.");
}}}
.indexOf will return the index of that character in your String.
That might not be the best approach to resolve your problem.
You could do something like this :
for(int i=0; i<s.length(); i++) {
if(s.charAt(i) == '#') {
count++; //or whatever mechanism you want to keep track of those chars.
}
}
Improving slightly on Caleb's answer:
Since you know which two characters you need to count, '#' and '#,' you can have a counter for each and just iterate over the tweet once. Then you just check if a character is one you're looking for, and if it is, the counter is incremented!
int mentions = 0;
int hashtags = 0;
for(int i = 0; i < s.length; i++) {
if(s.charAt(i) == '#') {
mentions++;
} else if(s.charAt(i) == '#') {
hashtags++;
}
}
Now mentions and hashtags should have the countes of #'s and #'s respectively.
You can solve this problem by implementing a simple counting method:
public int charCount(char c, String tweet) {
int count = 0;
for(int i = 0; i < tweet.length()) {
if(tweet.charAt(i) == c) count++;
}
return count;
}
With this, you can count the number of times a character appears in a tweet.
System.out.println("Length Correct");
int at = charCount('#', s);
System.out.println("Number of Mentions: " + at);
int hash = charCount('#', s);
System.out.println("Number of Hashtags: " + hash);
if (s.indexOf("RT:") >= 0)
System.out.println("The input was a retweet.");
else
System.out.println("The input was not a retweet.");

Problems with a word guessing game

I'm trying to get Java to recognize the output of a while loop as a variable and to use that output in further operations.
I wanted to try and upgrade it by letting one player set the word and the other one guess it. The problem came from making the number of dashes equal to the number of letters in the word that the player entered, so I separated the code out, which worked.
But when I put it all back in main, it would not recognize how many dashes are there after the loop finishes; it only recognizes the initial one which is only 1 dash, and so it poses a problem.
EDIT: Thank you so much guys, its my first time on stack overflow, tnx again.
Works like a charm :D
package iB;
import java.util.Scanner;
import java.lang.String;
public class WordGuess {
/**
* #param args
*/
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
String secretWord ;
String guess, dash = "-", upWord;
int numGuesses = 0;
int numWord;
final String SENTINEL = "!";
System.out.println("Player 2, please look away. Player 1, please enter the secter word: \n");
secretWord = input.next().toUpperCase().trim();
numWord = secretWord.length();
//System.out.println("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
for(int dashNum = 1; dashNum < numWord; dashNum++) {
dash += "-" ;
}
System.out.println("WordGuess game!\n");
do {
System.out.println("Enter a letter (" + SENTINEL + "to guess entire word): ");
guess = input.next().toUpperCase().trim();
numGuesses ++;
if (secretWord.contains(guess) && guess.length() == 1) {
upWord = dash.substring(0, secretWord.indexOf(guess));
upWord += guess;
upWord += dash.substring(secretWord.indexOf(guess) + 1, dash.length());
dash = upWord.toUpperCase();
System.out.println(dash);
if (dash.equals(secretWord)) {
System.out.println("You won!\n" + "The secret word is " + secretWord);
System.out.println("You made " + numGuesses + " guesses."); }
} else if (guess.length() >= 2) {
System.out.println("Please only enter one letter at a time! \n"); }
if (guess.contains(SENTINEL)) {
System.out.println("What is your guess? ");
guess = input.next().toUpperCase().trim();
if (guess.equals(secretWord)) {
System.out.println("You won!\n" + "The secret word is " + secretWord);
System.out.println("You made " + numGuesses + " guesses.");
break;
} else {
System.out.println("You Lose!");
System.out.println("The secret word was " + secretWord);
System.out.println("You made " + numGuesses + " guesses.");
break;
}
}
} while(!guess.contains(SENTINEL));
input.close();
}
}
The problem
The following piece of code appears to be trying to show where in a word the correctly chosen letter can be found
if (SecretWord.indexOf(guess) >= 0) {
UpWord = dash.substring(0, SecretWord.indexOf(guess));
UpWord += guess;
UpWord += dash.substring(SecretWord.indexOf(guess) + 1, dash.length());
System.out.println(UpWord);
} else {
So if the word was this and you guessed i then the output should be
--i-
dash.substring does not repeat dash, it takes a sub part of dash, as dash is 1 letter long, anything other than substring(0,1) will lead to an exception.
Basic solution
I believe you want to repeat dash until you get to the guessed letter, and then after it till the end of the word. Something along the lines of:
if (SecretWord.indexOf(guess) >= 0) {
int guessedIndex=SecretWord.indexOf(guess);
String outString="";
for(int i=0;i<guessedIndex;i++){
outString+=dash; //repeat dash until we get to the correctly guessed letter
}
outString+=guess; //put the letter in
for(int i=guessedIndex;i<SecretWord.length();i++){
outString+=dash; //repeat dash until we get to end of the word
}
System.out.println(outString);
} else {
Better Solution
This however leaves the problem that only the first instance of the letter is shown. This can be solved using annother stack overflow answer in which we see that we can get all the occurances of a character using a function
public static ArrayList<Integer> getAllIndexes(String testChar, String string){
int index=string.indexOf(testChar);
ArrayList<Integer> indexes=new ArrayList<Integer>();
while(index>0){
indexes.add(index);
index=string.indexOf(testChar,index+1);
}
return indexes;
}
Then using that function to find all the indexes at which the letter occurs we can deal with repeated letters
if (SecretWord.indexOf(guess) >= 0) {
int guessedIndex=SecretWord.indexOf(guess);
ArrayList<Integer> indexes=getAllIndexes(guess,SecretWord);
String outString="";
for(int i=0;i<SecretWord.length();i++){
if (indexes.contains(i)){
outString+=guess; //if its one of the guessed letters, put that in
}else{
outString+=dash; //otherwise add a dash
}
}
System.out.println(outString);
} else {
Now a word of hello and a guess of l correctly outputs --LL-
Notes
It is usual to follow the naming convention that variable names are
in lower camel case, meaning they start with a lower case letter, as
such SecretWord should be secretWord. As it is currently written
it looks like SecretWord is a class, which are usually writen in
upper camel case.
It would be nice, if once you've guessed a letter it stops putting a dash in and starts putting the letter in every time after that, this could be achieved by using an array of booleans to check if the letter has been guessed but that is beyond the scope of this question
All of these solutions have appended strings, which can be slow for huge numbers, in your case this is the right thing to do, but is joining lots of strings together in a loop consider using a StringBuilder to remove the overhead of creating loads of intermediate strings
Solution
If the secret word is pony, the String dash should be equal to ----. The problem is that you never actually change dash from being equal to -. Therefore, when you do things like dash.substring(SecretWord.indexOf(guess) + 1, dash.length()), you get errors because dash only contains one character. Here's how I'd make dash the same length as the secret word:
for(int i = 0; i < NumWord; i++) {
dash += "-";
}
With this one change inserted directly before your do-while loop, your program works like a charm. Below are some other things to consider in order to further improve your program.
Improving readability
Java convention dictates that the first word of method and variable names is lowercase. So NumWord should be numWord, SecretWord should be secretWord, etc.
SecretWord.indexOf(guess) >= 0 should be changed to
SecretWord.contains(guess)
Gameplay suggestions
As in hang man, you should probably show all the spots where the guessed letter occurs. For example, if the secret word is happy, a guess of p should produce the output of --PP- instead of --P--.
As a rule, never accept bad input even if it doesn't cause errors. The program shouldn't allow any of the scenarios below:
A user enters a String containing non-alphabetic characters or multiple words as the secret word
When making guesses, non-alphabetic characters are input (excluding !)
When guessing letters, multiple characters are input.
I have made a couple of modifications to your code, it seems to work fine now.
First though, I added an extra method, just to make it a little easier:
public static String printOutWord(String[] UpWord){
String out = "";
for(int i = 0; i < UpWord.length; i++){
out += UpWord[i];
}
return out;
}
Here are the first few changes to you code:
String[] UpWord = new String[NumWord];
for(int i = 0; i < NumWord; i++){
UpWord[i] = "-";
}
printOutWord(UpWord);
System.out.println("\nWordGuess game!");
So, you no longer need the variable dash, and the variable UpWord has been changed to an array of Strings.
And this is the rest of it:
do {
System.out.println("Enter a letter (! to guess entire word): ");
guess = input.next().toUpperCase().trim();
Numguesses++;
if(guess.length() > 1){
System.out.println("Please only enter one letter at a time");
}else if (SecretWord.indexOf(guess) >= 0) {
int index = SecretWord.indexOf(guess);
UpWord[index] = guess;
while(SecretWord.indexOf(guess, index+1) >= index){
index = SecretWord.indexOf(guess, index+1);
System.out.println(index);
UpWord[index] = guess;
}
System.out.println(printOutWord(UpWord));
if(printOutWord(UpWord).equals(SecretWord)){
System.out.println("You won!\n" + "The secret word is " + SecretWord);
return;
}
} else {
if (guess.contains("!")) {
System.out.println("What is your guess? ");
guess = input.next().toUpperCase();
if (guess.equals(SecretWord)) {
System.out.println("You won!\n" + "The secret word is " + SecretWord);
System.out.println("You made " + Numguesses + " guesses");
} else if (!guess.equals(SecretWord)) {
System.out.println("You Lose!");
System.out.println("You made " + Numguesses + " guesses");
}
}
}
} while (!SecretWord.equals(guess));
input.close();
}
Most of the changes are within the first if statement.
I hope this helped, if any clarification is needed about anything, just ask, I'd be happy to help :)

Categories

Resources