Hangman wrong guesses not printing correctly - java

I have this Hangman program that i am working on for school and i cant get the number of wrong guesses to print correctly when the user guesses a wrong letter. Here is my code that i got so far, i would appreciate any tips.
import java.util.Scanner;
public class HangmanTest {
public static void main(String[] args) {
String[] wordBank = { "madelynn", "crystal", "mcbride", "daughter",
"adorable", "beautiful", "andrew", "programming", "alyssa",
"computers", "mcbreezy", "maddy", "happy", "vacation", "beach",
"java", "benefical", "military", "veteran", "standale",
"lions", "tigers", "redwings", "pistons", "michigan",
"football", "baseball", "hockey", "basketball", "golf" };
int minimum = 0;
int maximum = wordBank.length - 1;
String again;
do {
int choice = minimum + (int) (Math.random() * maximum);
String word = wordBank[choice];
// Converts the random word to asterix
String userWord = "";
for (int i = 0; i < word.length(); i++) {
userWord += "*";
}
// Breaks into a bunch of characters
char[] userWordCh = userWord.toCharArray();
// Show the random word
System.out.println("The word for you to guess is " + userWord);
// instantiate a scanner object
Scanner input = new Scanner(System.in);
int size = word.length();
int rightGuesses = 0;
int wrongGuesses = 0;
while (size != rightGuesses) {
System.out.println("Enter a character: ");
String response = input.next();
char ch = response.charAt(0);
char[] wordChars = word.toCharArray();
for (int i = 0; i < word.length(); i++) {
if (wordChars[i] == ch) {
userWordCh[i] = ch;
++rightGuesses;
} else {
++wrongGuesses;
}
} // end of for loop
System.out.print("The word is: ");
for (int j = 0; j < userWordCh.length; j++)
System.out.print(userWordCh[j]);
System.out.println();
} // end of while loop
System.out.println("You had " + wrongGuesses + " wrong guesses.");
System.out.println("Would you like to play again y/n: ");
again = input.next();
} while (again.equals("y"));
}
}

for (int i = 0; i < word.length(); i++) {
if (wordChars[i] == ch) {
userWordCh[i] = ch;
++rightGuesses;
} else {
++wrongGuesses;
}
} // end of for loop
In this loop, you increment rightGuesses by 1 every time the guess matches a letter in the word, and wrongGueeses by 1 every time the guess does not match a letter in the word. As you can imagine, this will lead to the numbers, collectively, being incremented by the same number as the number of letters, when it should only be incremented once.
Try something like:
boolean foundMatch = false;
for (int i = 0; i < word.length(); i++) {
if (wordChars[i] == ch) {
userWordCh[i] = ch;
if (!foundMatch)
{
++rightGuesses;
foundMatch = true;
}
}
}
if (!foundMatch)
{
++wrongGuesses;
}
// end of for loop
Now we only increment one of rightGuesses and wrongGuesses once - rightGuesses can only be incremented if we have not found a match (setting found match to true), and wrongGuesses can only be incremented once if we have not found a match.

problem is in your for loop. You are iterating over each letter, and for every letter that doesn't match yours, you mark it as an incorrect guess. It should only be marked incorrect if NONE of the letters are correct. Additionally it should only be marked right if you haven't marked it already.
import java.util.Scanner;
import java.util.ArrayList;
public class HangmanTest {
public static void main(String[] args) {
String[] wordBank = { "madelynn", "crystal", "mcbride", "daughter",
"adorable", "beautiful", "andrew", "programming", "alyssa",
"computers", "mcbreezy", "maddy", "happy", "vacation", "beach",
"java", "benefical", "military", "veteran", "standale",
"lions", "tigers", "redwings", "pistons", "michigan",
"football", "baseball", "hockey", "basketball", "golf" };
int minimum = 0;
int maximum = wordBank.length - 1;
String again;
do {
int choice = minimum + (int) (Math.random() * maximum);
String word = wordBank[choice];
// Converts the random word to asterix
String userWord = "";
for (int i = 0; i < word.length(); i++) {
userWord += "*";
}
String guessedLetters="";
// Breaks into a bunch of characters
char[] userWordCh = userWord.toCharArray();
// Show the random word
System.out.println("The word for you to guess is " + userWord);
// instantiate a scanner object
Scanner input = new Scanner(System.in);
int size = word.length();
int rightGuesses = 0;
int wrongGuesses = 0;
boolean foundLetter;
char[] wordChars = word.toCharArray();
guessLoop:
while (size != rightGuesses) {
System.out.println("Enter a character: ");
String response = input.next();
char ch = response.charAt(0);
foundLetter=false;
for (int i=0;i<guessedLetters.size();i++){
if (ch == guessedLetters.charAt(i)){
System.out.println("Already guessed that letter!");
continue guessLoop;
}
}
guessedLetters+=response;
for (int i = 0; i < word.length(); i++) {
if (wordChars[i] == ch) {
foundLetter=true;
userWordCh[i] = ch;
++rightGuesses;
}
} // end of for loop
if(!foundLetter)
++wrongGuesses;
System.out.print("The word is: ");
for (int j = 0; j < userWordCh.length; j++)
System.out.print(userWordCh[j]);
System.out.println();
} // end of while loop
System.out.println("You had " + wrongGuesses + " wrong guesses.");
System.out.println("Would you like to play again y/n: ");
again = input.next();
} while (again.equals("y"));
}
}

I'm guessing here, but I think this might be wrong:
for (int i = 0; i < word.length(); i++) {
if (wordChars[i] == ch) {
userWordCh[i] = ch;
++rightGuesses;
} else {
++wrongGuesses;
}
} // end of for loop
This will increment the rightGuesses and wrongGuesses variables for each character in the word that matches/doesn't match the inputted character. Instead, you need to set a flag when a character "matches", then check that flag at the end to update rightGuesses and wrongGuesses.

for (int i = 0; i < word.length(); i++) {
if (wordChars[i] == ch) {
userWordCh[i] = ch;
++rightGuesses;
} else {
++wrongGuesses;
}
} // end of for loop
This for loop is causing your problem with wrong guesses, since it will say that a character is a wrong guess even though it is in the word. An option you can do is have some boolean that is switched to true when it finds the letter. That way, when you leave the for loop, you check to see if that value is true. If it isn't, increment the wrong guesses.

Related

Palindrome with even numbers

I've been working on a palindrome and it won't support an even number of words. I'm not the best at coding. It supports words like "racecar" or "tacocat", but it won't let me use a word/name like "Hannah". I'm new at this coding stuff so anything would really be appreciated.
import java.util.Scanner;
public class Palindrome
{
public static void main(String args [])
{
System.out.printf("\f");
Scanner input = new Scanner(System.in);
System.out.println("enter a word");
String word = input.nextLine();
int size = word.length();
int correct = 0;
int incorrect = 0;
for (int count = 1; count < size; count++)
{
int start = (word.charAt(count));//starting
int end = (word.charAt(size-count));//ending
if (start == end)
correct++;
else
incorrect++;
}
if (correct == 0)
System.out.printf("%s is a palindrome", word);
else
System.out.printf("%s is not a palindrome", word);
}
}
Your code has many problems:
You are comparing characters of wrong indices. For example, you compare the second character (whose index is 1) to the last character (whose index is size - 1). count should be initialized to 0, and end should be word.charAt(size-count-1).
You report the String to be a palindrome when correct == 0, when it should be incorrect == 0 (BTW you don't need a counter, just a boolean).
If you want the check to be case insensitive, you can convert the String to lower case prior to running your loop.
This should work:
public static void main(String args [])
{
System.out.printf("\f");
Scanner input = new Scanner(System.in);
System.out.println("enter a word");
String word = input.nextLine().toLowerCase();
int size = word.length();
boolean isPalindrome = true;
for (int count = 0; count < size; count++)
{
int start = (word.charAt(count));//starting
int end = (word.charAt(size-count-1));//ending
if (start != end) {
isPalindrome = false;
break;
}
}
if (isPalindrome)
System.out.printf("%s is a palindrome", word);
else
System.out.printf("%s is not a palindrome", word);
}
There are several mistakes in your code
You should convert everything to lowercase if you are planning to ignore capital letter in the checking, since it is identified differently in ASCII
For starting, you should start from index 0 instead of 1, to start from the first letter
For ending, you should start from index size-count-1 instead of size-count, to start from the last letter
You should check for incorrect == 0 instead of correct == 0 to determine if it is a palindrome
public static void main(String args[]) {
System.out.printf("\f");
Scanner input = new Scanner(System.in);
System.out.println("enter a word");
String word = input.nextLine().toLowerCase();
int size = word.length();
int correct = 0;
int incorrect = 0;
for (int count = 0; count < size; count++)
{
int start = (word.charAt(count)); //starting
int end = (word.charAt(size-count-1)); //ending
if (start == end)
correct++;
else
incorrect++;
System.out.println(start + " " + end);
}
if (incorrect == 0)
System.out.printf("%s is a palindrome", word);
else
System.out.printf("%s is not a palindrome", word);
}
Bonus: You could check for just half of the word instead of looping through the whole word
First of all you should know that array in java start at 0, not one. so set your count from 0 not one.
Then, word.charAt(count) is a char so better have char variable instead of int.
It's seem that the algorithm you use to decide whether a word is a palindrome or not is by matching first char with last char, second char with second last char, and so on.
If that the case, you will only need to loop halfway for (int count = 1; count < size / 2; count++).
The last one is, you only need one variable to hold the status of palindrome, if your matching process ever find a false then break the loop and just set the isPalindrome status into false.
public static void main (String args[])
{
Scanner input = new Scanner (System.in);
System.out.println ("enter a word");
String word = input.nextLine ();
int size = word.length ();
boolean isPalindrome = true;
int maxIndex = size - 1;
for (int count = 0; count < size / 2; count++)
{
char start = word.charAt (count);
char end = word.charAt (maxIndex - count);
if (start != end)
{
isPalindrome = false;
break;
}
}
if (isPalindrome)
System.out.printf ("%s is a palindrome", word);
else
System.out.printf ("%s is not a palindrome", word);
}
And bear in mind that java's String is case sensitive, so "Tiger" is different than "tiger". Hence, Hannah will not be treated as palindrome. If you want it to be case insensitive, just lowercase all the char in the word like this word = word.toLowerCase() before doing the macthing process.
Check palindrome function is very simple:
public boolean isPalindrome(String str) {
if(str == null)
return false;
str = str.toLowerCase();
for(int i = 0, j = str.length() - 1; i < j; i++, j--)
if(str.charAt(i) != str.charAt(j))
return false;
return true;
}
you may use Stringbuilder to do palindrome check as below
public class test {
public static void main(String args [])
{
System.out.print("\f");
Scanner input = new Scanner(System.in);
System.out.println("enter a word");
String word = input.nextLine();
StringBuilder originalStr = new StringBuilder(word);
String revString = originalStr.reverse().toString();
if(word.equalsIgnoreCase(revString))
System.out.print( word +" is a palindrome");
else
System.out.print( word +" is not a palindrome");
}
}

Array out of Bounds? with string split

Array out of bounds ? i'm trying to perform the output in the picture:
Using this INPUT
"JAVA IS A PROGRAMMING LANGUAGE"
This is my code so far
import java.util.Scanner;
public class Main
{
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.print("Input Phrase:");
String s = in.nextLine();
String[] word=s.split(" ");
String rts=" ";
for(int i=0;i<word.length;i++){
if(word[i].length()>=rts.length()){
rts=word[i];
}
}
int thisislength = rts.length();
for (int a = 0; a < thisislength ;a++ ) {
for (int b = 0; b < word.length ;b++ ) {
System.out.print(word[b].charAt(a)+" ");
}
System.out.println();
}
}
}
When the second word reaches its last letter it doesn't continue the for loop, is there any way to continue the loop even if the second word reaches its max length.
< should have been <=. Reversing left and right hand sides makes it more readably I think.
for (int a = 0; a < thisislength; a++) {
System.out.printf("%3d ", a+1);
for (int b = 0; b < word.length; b++) {
if (a >= word[b].length()) {
System.out.print(' ');
} else {
System.out.print(word[b].charAt(a));
}
System.out.print(' ');
}
System.out.println();
}
Or instead of the if-else statement:
for (String w : word) {
System.out.print(a >= w.length() ? ' ' : w.charAt(a));
}
This gives the result you want:
for (int a = 0; a < thisislength ;a++ ){
for (int b = 0; b < word.length ;b++ ){
if(word[b].length() < a + 1){
System.out.print(" ");
}else{
System.out.print(word[b].charAt(a) + " ");
}
}
System.out.println();
}
This line was changed:
if(word[b].length() < a + 1) and not if(word[b].length() < a)
and 2 spaces print in the if statement
TRY THIS SOLUTION HOPE IT WILL HELP YOU :
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Main
{
public static void main(String[] args) {
// GET VALUE FROM THE CONSOLE
Scanner in = new Scanner(System.in);
System.out.print("Input Phrase:");
String s = in.nextLine();
// SPLIT STRING TO WORDS
String[] words = s.split(" ");
// CREATE A LIST OF CHAR_ARRAY CALLED : matrix
List<char[]> matrix = new ArrayList<char[]>();
// REFERENCE THE LARGEST WORD IN WORDS ARRAY EX : PROGRAMMING IS THE LARGEST
int max = 0;
// FILL OUR LIST OF ARRAY OF CHARS
for (int b = 0; b < words.length ;b++ ) {
char[] chars = words[b].toCharArray();
max = (chars.length >= max)? chars.length : max ;
matrix.add( chars );
}
// PRINT OUR CHAR
for (int a = 0; a < max ;a++ ) {
for (int b = 0; b < words.length ;b++ ) {
if(a < matrix.get(b).length) {
System.out.print(matrix.get(b)[a]);
System.out.print(" ");
}else {
System.out.print(" ");
System.out.print(" ");
}
}
System.out.println("");
}
}
}

How to scramble a word that is picked randomly from a text file

I am attempting to write a program that picks a random word from a text file, scrambles it, and allows the user to unscramble it by swapping 2 index locations at a time.
I have the program to the point where it grabs a random word from the text file and prints it out with the index numbers above it.
I am having trouble figuring out how to:
Get the word scrambled before it prints out on screen, and
How to get the user to be able to loop through swapping 2 indexes at a time until the word is unscrambled.
Is there a method I can write that will perform these actions?
Here is my code so far.
import java.io.*;
import java.util.*;
public class Midterm { // class header
public static void main(String[] args) { // Method header
int option = 0;
Scanner input = new Scanner(System.in);
int scrambled;
int counter = 0;
int index1;
int index2;
String[] words = readArray("words.txt");
/*
* Picks a random word from the array built from words.txt file. Prints
* index with word beneath it.
*/
int randWord = (int) (Math.random() * 11);
for (int j = 0; j < words[randWord].length(); j = j + 1) {
System.out.print(j);
}
System.out.print("\n");
char[] charArray = words[randWord].toCharArray();
for (char c : charArray) {
System.out.print(c);
}
/*
* Prompt the user for input to play game or quit.
*/
System.out.println("\n");
System.out.println("Enter 1 to swap a par of letters.");
System.out.println("Enter 2 to show the solution and quit.");
System.out.println("Enter 3 to quit.");
if (input.hasNextInt()) {
option = input.nextInt();
counter++;
}
else {
option = 3;
}
System.out.println("");
if (option == 1) {
System.out.println("Enter the two index locations to swap separated by a space. ");
index1 = 0;
index2 = 0;
if (input.hasNextInt()) {
index1 = input.nextInt();
}
else {
System.out.println("Please enter only numbers.");
}
if (input.hasNextInt()) {
index2 = input.nextInt();
}
else {
System.out.println("Please enter only numbers.");
}
}
}
// end main
public static String[] readArray(String file) {
// Step 1:
// Count how many lines are in the file
// Step 2:
// Create the array and copy the elements into it
// Step 1:
int ctr = 0;
try {
Scanner s1 = new Scanner(new File(file));
while (s1.hasNextLine()) {
ctr = ctr + 1;
s1.nextLine();
}
String[] words = new String[ctr];
// Step 2:
Scanner s2 = new Scanner(new File(file));
for (int i = 0; i < ctr; i = i + 1) {
words[i] = s2.next();
}
return words;
} catch (FileNotFoundException e) {
}
return null;
}
}
I made some pretty major modifications to your code, including adding a scrambler method. The program is almost perfect, its just that your file "words.txt" can not hold words with repeat letters. For example, yellow, green, and purple won't unscramble correctly, but white, gray, blue, orange, or red will work fine. Other than that, the program works well. It chooses a random word, then when it is solved, chooses a different word, changing the last word to null, so it does not get picked again. Here's the program:
import java.io.*;
import java.util.*;
public class Experiments { // class header
private static String[] words = readArray("/Users/UserName/Desktop/words.txt"); //change to your location of the file
public static void main(String[] args) { // Method header
int option = 0;
Scanner input = new Scanner(System.in);
int counter = 0;
String scrambledWord;
int index1;
int index2;
Random rand = new Random();
int randWord = rand.nextInt(words.length);
for (int j = 0; j < words[randWord].length(); j += 1) {
System.out.print(j);
}
System.out.print("\n");
scrambledWord = scrambler(words[randWord]);
System.out.println(scrambledWord);
System.out.println("\n");
System.out.println("Enter 1 to swap a pair of letters.");
System.out.println("Enter 2 to show the solution and quit.");
System.out.println("Enter 3 to quit.");
option = input.nextInt();
if (option == 1) {
while (!scrambledWord.equals(words[randWord])) {
index1 = 0;
index2 = 0;
boolean validOption = false;
System.out.println("Enter the two index locations to swap separated by a space.");
while (!validOption) {
if (input.hasNextInt()) {
index1 = input.nextInt();
index2 = input.nextInt();
validOption = true;
}
else {
System.out.println("Please enter only numbers.");
validOption = false;
break;
}
}
String letter1 = scrambledWord.substring(index1, index1+1);
String letter2 = scrambledWord.substring(index2, index2+1);
System.out.println("replacing " + letter1 + " with " + letter2 + "...");
if (index1 < index2) {
scrambledWord = scrambledWord.replaceFirst(letter2, letter1);
scrambledWord = scrambledWord.replaceFirst(letter1, letter2);
} else {
scrambledWord = scrambledWord.replaceFirst(letter1, letter2);
scrambledWord = scrambledWord.replaceFirst(letter2, letter1);
}
System.out.println();
for (int j = 0; j < words[randWord].length(); j += 1) {
System.out.print(j);
}
System.out.println("\n"+scrambledWord);
System.out.println();
counter++;
if (scrambledWord.equals(words[randWord])){
System.out.println("You did it! The word was " + words[randWord]);
System.out.println("You got it with " + counter + " replacements!");
words[randWord] = null;
if (words.length == 0){
System.out.println("I'm all out of words. You win!");
System.exit(0);
} else {
main(args);
}
}
}
} else if (option == 2) {
System.out.println(words[randWord]);
System.exit(0);
} else {
System.exit(0);
}
input.close();
}
//scrambles the word given to it
private static String scrambler(String word) {
String scrambled = "";
Random rand = new Random();
int length;
int index;
String letter;
String firststring;
String secondstring;
while (word.length()>0) {
length = word.length();
index = rand.nextInt(length);
letter = word.substring(index, index+1);
firststring = word.substring(0, index);
secondstring = word.substring(index+1);
word = firststring + secondstring;
scrambled += letter;
}
return scrambled;
}
public static String[] readArray(String file) {
int ctr = 0;
try {
Scanner s1 = new Scanner(new File(file));
while (s1.hasNextLine()) {
ctr = ctr + 1;
s1.nextLine();
}
String[] words = new String[ctr];
// Step 2:
Scanner s2 = new Scanner(new File(file));
for (int i = 0; i < ctr; i = i + 1) {
words[i] = s2.next();
}
return words;
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return null;
}
}
And here's the list of words in the file words.txt(I pretty much wrote down whatever popped into my head that did not have repeat letters):
orange
red
brown
black
white
blue
tiger
horse
bugs
stack
overflow
pathfinder
extra
zealous
wisdom
under
above
death
life
second
first
frost
forest
These are obviously not the only words that can go in, you can add as many as you want, as long as they do not have 2 occurrences of the same letter.
You are reading the file incorrectly. Do
public static String[] readArray(String file) {
int ctr = 0;
try {
Scanner s1 = new Scanner(new File(file));
while (s1.hasNext()) {
ctr = ctr + 1;
s1.next();
}
//..rest of code

Counting characters from a user inputted string of more than one word

I'm trying to create a program where the user inputs a word and then the program displays every letter of the alphabet with a number next to it that shows how many times that letter was used in the word. It works great, but the only problem is that it only works with one word strings. How can I add detection for strings of more than one word? Thanks in advance.
My code:
import java.util.Scanner;
public class LetterOccurrenceCount {
public static void main(String[] args) {
// TODO Auto-generated method stub
int array[] = new int[26];
for (int i = 0; i < array.length; i++)
{
array[i] = 0;
}
Scanner Keyboard = new Scanner(System.in);
String userInput;
System.out.println("Please enter a string.");
userInput = Keyboard.next().toLowerCase();
for (int i = 0; i < userInput.length(); i++)
{
char ch = userInput.charAt(i);
if (ch >= 'a' && ch <= 'z') {
array[ch - 'a'] ++;
}
}
for (char ch='a'; ch<='z'; ++ch) {
System.out.print(ch + " = " + array[ch-'a'] + " | ");
}
}
}

Output the word in a string with the largest amount of vowels

I mostly have the method done but I am confused when it comes to the If statement concerned with storing a variable with the word with the most amount of vowels, NOTE I am not allowed to use arrays.
below is my code
//method for vowels and consonants
public static int Vowelcount(String sentence)
{
int maxvowelcount =0;
int minvowelcount =0;
String vowel="";
int consonantcount = 0;
int vowelcount = 0;
int index = 0;
String currentword;
int spacePos;
int noOfchars = 0;
int largest = 0 ;
int smallest = 0 ;
//gets rid of leading and trailing spaces so as to get the last word
sentence=sentence.trim() + " ";
//assignments
spacePos=sentence.indexOf(" ");
currentword = sentence.substring(0, spacePos);
while (spacePos >-1)// when no spaces are found
{
noOfchars=0;
currentword = sentence.substring(0, spacePos);
// remove the first word
sentence = sentence.substring(spacePos+1);
spacePos=sentence.indexOf(" ");
// to count the number of vowels in the string
for(index = 0; index<currentword.length(); index++)
{
if(currentword.charAt(index)=='a' || currentword.charAt(index)=='e' ||
currentword.charAt(index)=='i' || currentword.charAt(index)=='o' ||
currentword.charAt(index)=='A' || currentword.charAt(index) == 'E' ||
currentword.charAt(index) == 'I' || currentword.charAt(index) == 'O' )
{
vowelcount++;
}
else
{
consonantcount++;
}
//if statement to overwrite currentword with largest/smallest
if (index == 0)
{
minvowelcount = currentword.length();
maxvowelcount = currentword.length();
}
if (vowelcount < minvowelcount)
{
minvowelcount = vowelcount;
}
if (vowelcount > maxvowelcount)
{
maxvowelcount = vowelcount;
vowel=currentword;
}
}
}
//output to show the word with largest amount of vowels
System.out.println( "word with largest amount of vowels is " + vowel);
return vowelcount;
}
First, many of the variables you use are redundant. All you need is the max number of vowels and the word.
Next point is that all your if statements should be outside the for loop. The general structure must be smth like
wordWithMaxVowels = "";
maxVowels = 0;
while (there is a word) {
fetch the word
vowelCount = 0;
for (every char in the word)
{
if (char is vowel)
vowelCount++;
}
if (vowelCount > maxVowels)
{
vowelCount = maxVowels;
wordWithMaxVowels = word;
}
}
// here maxVowels is the maximal number of vowels in a word, wordWithMaxVowels is the word itself;
Also note, that it's not any optimal to chop off the first word in the sentence. Try the following:
int wordStart = 0;
int wordEnd;
while(true) {
wordEnd = sentence.indexOf(" ", wordStart);
if (wordEnd < 0)
break;
String word = sentence.substring(wordStart, wordEnd);
// process the word
wordStart = wordEnd + 1;
}

Categories