Coding a simple HiLo card game where the user is given a card value from a deck of cards and then inputs 'higher', 'lower' or 'equal' trying to guess the balue of the next card.
Just really can't get my head around user input validation with iteration ie. not moving on until a string with the required parameters has been entered.
My code so far:
import java.util.Scanner;
import java.util.Random;
public class HiLoGame {
public static void main(String[] args) {
Scanner reader = new Scanner(System.in);
Random randomCard = new Random();
int numberOfSuccesses = 0;
boolean finished = false;
int card = (randomCard.nextInt(13) + 2);
while (finished != true) {
int nextCard = (randomCard.nextInt(13) + 2);
String pictureCard = "";
if (((numberOfSuccesses < 0) ? nextCard : card) == 11) {
pictureCard = "Jack";
} else if (((numberOfSuccesses < 0) ? nextCard : card) == 12) {
pictureCard = "Queen";
} else if (((numberOfSuccesses < 0) ? nextCard : card) == 13) {
pictureCard = "King";
} else if (((numberOfSuccesses < 0) ? nextCard : card) == 14) {
pictureCard = "Ace";
}
System.out.println("The card is a " + ((card > 10) ? pictureCard : card));
if (numberOfSuccesses == 4) {
System.out.println("Congratulations. You got them all correct");
finished = true;
break;
}
while (!reader.nextLine().toLowerCase().equals("higher")
|| !reader.nextLine().toLowerCase().equals("lower")
|| !reader.nextLine().toLowerCase().equals("equal")) {
System.out.println("Try again!");
reader.next();
}
String userGuess = reader.nextLine().toLowerCase();
//TODO validate input
if (userGuess.equals("higher")) {
if (nextCard > card) {
numberOfSuccesses++;
} else {
finished = true;
break;
}
} else if (userGuess.equals("lower")) {
if (nextCard < card) {
numberOfSuccesses++;
} else {
finished = true;
break;
}
} else if (userGuess.equals("equal")) {
if (nextCard == card) {
numberOfSuccesses++;
} else {
finished = true;
break;
}
}
System.out.println(numberOfSuccesses);
card = nextCard;
}
if (numberOfSuccesses < 4) {
System.out.println("Sorry, incorrect!");
}
}
}
and the relevant code extract:
while (!reader.nextLine().toLowerCase().equals("higher")
|| !reader.nextLine().toLowerCase().equals("lower")
|| !reader.nextLine().toLowerCase().equals("equal")) {
System.out.println("Try again!");
reader.next();
}
It kinda just gets stuck at the above part giving "Try again" over and. I've completed programs having to use .hasNextInt() but I'm struggling with this string validation.
Thanks for any and all help/comments!
You are calling reader.nextLine() up to 3 times and so you are comparing 3 different strings.
If I enter "xxx" your code says "xxx != higher so read another line" - it never compares "xxx" to "lower" or "equal".
Also pay attention to && vs ||.
Solution is to read one line into a variable and use that variable for each condition. I'm not going to write it out as this is clearly homework or a self learning exercise, so best for you to do it yourself.
I think your condition logic needs to change. You are checking if input not equal to "higher" or not equal to "lower" or not equal to "equal" so it will always be false overall even if you enter expected value - if you enter "higher" it's not equal to lower. You need to change ors to ands.
Related
I want to write a program that checks the inserted password for:
Length is minimum of 8
At least 1 uppercase letter
At least 1 lowercase letter
At least 3 digits
I wrote this program, but it doesn't give me the right output:
import java.util.Scanner;
public class Question5 {
public static void main(String[] args) {
Scanner in = new Scanner (System.in);
System.out.println("Please enter your password: ");
String input = in.nextLine();
boolean flag = validate(input);
if (flag = true) {
System.out.println("password verified");
}
else {
System.out.println("not a good password");
}
}
public static boolean validate(String input) {
boolean flag = false;
int uppercaseCounter = 0;
int lowercaseCounter = 0;
int digitCounter = 0;
int letterCounter = 0;
for (int i = 0; i<(input.length()); i++) {
int totalCounter = digitCounter + letterCounter;
if (totalCounter >= 8 && digitCounter >= 3 && uppercaseCounter > 0 && lowercaseCounter > 0) {
flag = true;
}
else {
if (Character.isDigit(i)) {
digitCounter++;
}
if (Character.isLetter(i)) {
letterCounter++;
}
if (Character.isUpperCase(i)) {
uppercaseCounter++;
}
if (Character.isLowerCase(i)) {
lowercaseCounter++;
}
}
}
return flag;
}
}
Can someone help me with this? Thank you very much!
Here is the catch:
if (flag = true)
{
System.out.println("password verified");
}
= is an assignment operator == is the relational operator. To fix, do flag==true.
Also, in your method, you are comparing i, which is the counter, and not the
char At i. So do this
if(Character.isDigit(input.charAt(i))){ //Do this for all Character.isSomething() Methods
for all the checks you make.
You are actually checking the i counter in your various if instead of the input string...
use something like
char c = s.charAt(i);
and check the input chars
moreover you should change the check if(flag = true) with if(flag)
Change
if (flag = true)
{
System.out.println("password verified");
}
else
{
System.out.println("not a good password");
}
to
if (flag)
{
System.out.println("password verified");
}
else
{
System.out.println("not a good password");
}
When you write if(flag=true) then you are doing an assignment operation and not an equality comparison.
Also, the logic should be Character.isDigit(input.charAt(i)) since you want to check the character at i and not i itself.
To conclude, I would like to say that this problem would be fun to solve with Regular Expressions. Check this tutorial on regular expressions in Java.
In addition to other answers, this code should be moved below the counter increments:
int totalCounter = digitCounter + letterCounter;
if (totalCounter >= 8 && digitCounter >= 3 && uppercaseCounter > 0 && lowercaseCounter > 0) {
flag = true;
}
Otherwise, you run the risk of returning false when your password would become valid on the last character.
First of all, I apologize because this code seems inefficient to me, but my professor wants it this way (the comments are hers). I have many problems here, but a central one seems to be that when I run the program it does not enter the for loop. Therefore I'm assuming it is not entering the while loop that the for loop is in, and I'm not sure why. Here is the "modified" blackjack program, any help is appreciated:
import java.util.Scanner;
import java.util.Random;
public class BlackJack {
enum Decisions
{
HIT, STAND, SURRENDER, QUIT, PLAY, NOTVALID;
// NOTVALID is used to re-ask to play again
}
enum Card {
ACE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, QUEEN, JACK, KING;
}
// Tells you if the Decision enum is valid or not
public static boolean containsDecision(String decision) {
for (Decisions d : Decisions.values()) {
if (d.name().equals(decision)) {
return true;
}
}
return false;
}
// Tells you what is the integer value of said Card enum
public static int getCardValue(int pick) {
if (pick == 0) {
return 1;
} else if (pick >= 10 && pick <= 12) {
return 10;
}
return pick + 1;
}
// 1 pts
public static int housePlay(int houseCardSum) {
int cardPick;
cardPick = -1;
while (houseCardSum <= 17)
{
getCardValue(cardPick);
houseCardSum = (cardPick + houseCardSum);
System.out.println("Hit from house! CARD: " + cardPick + " VALUE: " + houseCardSum);
}
return houseCardSum;
}
// 1.5 pts
public static void findWinner(int playerCardSum, int houseCardSum, Decisions decision) {
houseCardSum = housePlay(houseCardSum);
if ( (playerCardSum > 21) || (houseCardSum > 21))
{
if (houseCardSum > 21)
{
System.out.println("Sorry you lose!");
}
else
{
System.out.println("You win!");
}
}
else if (decision == Decisions.SURRENDER)
{
System.out.println("You lose because you surrendered!");
}
else if (playerCardSum == houseCardSum)
{
System.out.println("Its a push (tie)!");
}
else if ((playerCardSum > houseCardSum) && (playerCardSum < 21))
{
System.out.println("You win!");
}
else if ( (playerCardSum == 21) && (houseCardSum != 21) )
{
System.out.println("Blackjack win!");
}
else
{
System.out.println("Sorry you lose!");
}
// if, else if, else, check playerCardSum, houseCardSum as well as if
// Decision equaled to SURRENDER
// print the House and You Hand at the end
// call housePlay function and assign the output to houseCard function
// iff not playerCardSum is not 21 and Decisions is not Surrender
// these below will be used moved them around freely in this function
// where you need too.
// put in correct branch sub
// statement
System.out.println("House Hand: " + houseCardSum + " Your Hand: " + playerCardSum); // this
// is
// printed
// out
// after
// all
// branch
// statements
// assessed
}
// 7.5pts
public static void main(String[] args) {
System.out.println("========== BlackJack ==========");
System.out.print("What is your name: ");
Scanner keyboard = new Scanner(System.in);
String playerName;
playerName = keyboard.nextLine();
System.out.println("Okay, " + playerName + ", let's play!");
Decisions decision = Decisions.PLAY ;
int cardPick;
cardPick = -1;
while ( decision != Decisions.QUIT);
{
int playerSum;
int houseSum;
playerSum = 0;
houseSum = 0;
Card holeCard = null;
for ( int i = 0; i < 3; i++)
{
Random newCard = new Random();
cardPick = newCard.nextInt(14);
playerSum = playerSum + getCardValue(cardPick);
System.out.println("Card: " + (Card.values()[cardPick]) );
System.out.println("Sum of your hand: " + playerSum );
}
}
Remove the semicolon after the while statement.
while ( decision != Decisions.QUIT);
while ( decision != Decisions.QUIT)
I am trying to make battleship. Here i want to get input from the console with a Scanner to determain a place to shoot.
while (x) {
while (counter) {
userInput = input.nextLine();
if (userInput.equals("cheat")) {
cheat = true;
}
uppercased = userInput.toUpperCase();
char[] c = uppercased.toCharArray();
if (uppercased.length() < 2) {
System.out.println("Error, invalid input9, try again");
break;
} else if (uppercased.equals("")) {
System.out.println("Error, invalid input1, try again");
break;
} else if (uppercased.length() > 2) {
System.out.println("Error, invalid input2, try again");
break;
} else if (c[0] < 65 || c[0] > 74) {
System.out.println("Error, invalid input3, try again");
break;
} else if (c[1] < 48 || c[1] > 57) {
System.out.println("Error, invalid input4, try again");
break;
} else {
code = uppercased;
target = map.get(uppercased);
targetPosition = target.getSymbol();
if (targetPosition != 46) {
System.out.println("You have shot here, try again");
break;
}
}
counter = false;
}
x = false;
code = uppercased;
}
the problem is, when I give a wrong input, it doesn't ask about new input, but it will execute the rest of my program.
It is supposed to filter input so it is like this:
"A1"
than it is used to determain a place to shoot.
How can I filter the wrong input and get new input?
using break, will move you outside of current loop.
using continue, will move you to the beginning of current loop.
So in your case continue would be better, because it will move you to part of code where you are reading input in inner loop.
Extracting main body from this loop (like below) would also be easy to test:)
Update:
while (x) {
while (!runCheck()) { Your main method is extracted from loop, making it more readable
}
x = false;
code = uppercased;
}
boolean runCheck(){
userInput = input.nextLine();
if ("cheat".equals(userInput)) { // prefer to compare String agains a constant in this way, it's immune to NPE, when by any chance userInput would be a null
cheat = true;
}
uppercased = userInput.toUpperCase();
char[] c = uppercased.toCharArray();
if (uppercased.length() < 2) {
System.out.println("Error, invalid input9, try again");
return true;
} else if ("".equals(uppercased)) {
...
} else {
code = uppercased;
if(!map.conainsKey(uppercased)){ // target can be null, or not existing in map
return true;
}
target = map.get(uppercased);
targetPosition = target.getSymbol();
if (targetPosition != 46) {
System.out.println("You have shot here, try again");
return true;
}
}
return false;
}
For some reason, with this code, tests that I've run shows that the program entirely skips the nextLine request for an input from the user and it registers as blank space for its first iteration. Afterwards it'll go back to the beginning of the while loop and take an input, but no matter what I type in it (whether it's y or Y for yes, N or n for no) it'll go to the else statement. I don't understand what I'm doing wrong, help!
private static boolean promptForPlayAgain(Scanner inScanner) {
boolean play = true;
int test = 0;
while(test == 0)
{
System.out.println("Would you like to play again [Y/N]?:");
String input = inScanner.nextLine();
System.out.println(input);
if (input == "y" || input == "Y")
{
test++;
}
else if (input == "n" || input == "N")
{
play = false;
test++;
}
else
{
System.out.println("ERROR! Only 'Y' or 'N' allowed as input!");
}
}
return play;
}
With the tips from what you guys said I've edited and ran my code which now works. Thanks a lot guys!
private static boolean promptForPlayAgain(Scanner inScanner) {
boolean play = true;
int test = 0;
while(test == 0)
{
System.out.println("Would you like to play again [Y/N]?:");
inScanner.nextLine();
String input = inScanner.nextLine();
if (input.equals("y") || input.equals("Y") )
{
test++;
}
else if (input.equals("n") || input.equals("N") )
{
play = false;
test++;
}
else
{
System.out.println("ERROR! Only 'Y' or 'N' allowed as input!");
}
}
return play;
}
This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 9 years ago.
This is a tid bit of my total program, consisting of 4 classes. The classes goal is to print out a card with a numerical value and suit, the user than proceeds to guess wether the next card has a higher numerical value. If the cards are the same, the suit method determis the greatest suit in the order // SPADES >>>> HEARTS >>>> CLUBS >>>> DIAMONDS (As seen in the card method). The problem however, occurs in my HighLowrev class, in the do while loop as the user is asked to play again, if the user responds with 'y', the program continues and even if the user responds with 'n' the program continues. I have tried Looking up further usage of Boolean but have realized that I'm quite sure they work this way. Any help would be much appreciated.
CARD CLASS
public class Card {
// card class initalize varibles (NOtice the FINAL (THEY NEVER CHANGE VALUE!!!))
public final static int SPADES = 3; // Codes for the 4 suits, plus Joker.
public final static int HEARTS = 2;
public final static int DIAMONDS = 0;
public final static int CLUBS = 1;
public final static int JOKER = 4;
// SPADES >>>> HEARTS >>>> CLUBS >>>> DIAMONDS
public final static int ACE = 1; // Codes for the non-numeric cards.
public final static int JACK = 11; // Cards 2 through 10 have their
public final static int QUEEN = 12; // numerical values for their codes.
public final static int KING = 13;
private final int suit;
private final int value;
public static void main (String [] args){
} // joker constructor
public Card() {
suit = JOKER;
value = 1;
}
// incase an illegal field occurs
public Card(int theValue, int theSuit) {
if (theSuit != SPADES && theSuit != HEARTS && theSuit != DIAMONDS &&
theSuit != CLUBS && theSuit != JOKER)
throw new IllegalArgumentException("Illegal playing card suit");
if (theSuit != JOKER && (theValue < 1 || theValue > 13))
throw new IllegalArgumentException("Illegal playing card value");
value = theValue;
suit = theSuit;
}
public int getSuit() {
return suit;
}
// getter methods
public int getValue() {
return value;
}
// cases for suits...
public String getSuitAsString() {
switch ( suit ) {
case SPADES: return "Spades";
case HEARTS: return "Hearts";
case DIAMONDS: return "Diamonds";
case CLUBS: return "Clubs";
default: return "Joker";
}
}
// cases for numerical values...
public String getValueAsString() {
if (suit == JOKER)
return "" + value;
else {
switch ( value ) {
case 1: return "Ace";
case 2: return "2";
case 3: return "3";
case 4: return "4";
case 5: return "5";
case 6: return "6";
case 7: return "7";
case 8: return "8";
case 9: return "9";
case 10: return "10";
case 11: return "Jack";
case 12: return "Queen";
default: return "King";
}
}
}
public String toString() {
if (suit == JOKER) {
if (value == 1)
return "Joker"; // if the suit is the joker ....
else
return "Joker #" + value;
}
else { // return suit and number
return getValueAsString() + " of " + getSuitAsString() ;
}
}
}
MAIN PROGRAM CLASS
import java.io.*;
public class HighLowrev {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader (new InputStreamReader (System.in)); // allow input
System.out.println("This program lets you play the simple card game,");
System.out.println("HighLow. A card is dealt from a deck of cards.");
System.out.println("You have to predict whether the next card will be");
System.out.println("higher or lower. Your score in the game is the");
System.out.println("number of correct predictions you make before");
System.out.println("you guess wrong.");
System.out.println();
int gamesPlayed = 0; // Number of games user has played.
int sumOfScores = 0; // The sum of all the scores from
// all the games played.
double averageScore; // Average score, computed by dividing
// sumOfScores by gamesPlayed.
boolean playAgain = true;; // Record user's response when user is
// asked whether he wants to play
// another game.
do {
int scoreThisGame; // Score for one game.
scoreThisGame = play(); // Play the game and get the score.
sumOfScores += scoreThisGame;
gamesPlayed++;
System.out.print("Play again? ");
String input = br.readLine();
if(input== "Y" || input =="y") {
playAgain = true;
}
else {
playAgain =false;
}
} while (playAgain=true);
averageScore = ((double)sumOfScores) / gamesPlayed;
System.out.println();
System.out.println("You played " + gamesPlayed + " games.");
System.out.printf("Your average score was %1.3f.\n", averageScore);
} // end main()
private static int play() throws IOException {
BufferedReader br = new BufferedReader (new InputStreamReader (System.in)); // allow input
Deck deck = new Deck(); // Get a new deck of cards, and
Card currentCard; // The current card, which the user sees.
Card nextCard; // The next card in the deck. The user tries
int correctGuesses ; // The number of correct predictions the
char guess; // The user's guess. 'H' if the user predicts that
deck.shuffle(); // Shuffle the deck into a random order before
correctGuesses = 0;
currentCard = deck.dealCard();
System.out.println("The first card is the " + currentCard);
while (true) { // Loop ends when user's prediction is wrong.
/* Get the user's prediction, 'H' or 'L' (or 'h' or 'l'). */
System.out.println("Will the next card be higher (H) or lower (L)? ");
do { /// THE SECTION HERE IS THE SPECIFIED PROBLEM, THE IF AND ELSE STATEMENTS DONT DO ANYTHING!
guess = (char)br.read();
guess = Character.toUpperCase(guess);
if (guess != 'H' && guess != 'L')
System.out.println("Please respond with H or L: ");
} while (guess != 'H' && guess != 'L');
nextCard = deck.dealCard();
System.out.println("The next card is " + nextCard);
if(nextCard.getValue() == currentCard.getValue()) {
if(guess == 'H') {
if(nextCard.getSuit() > currentCard.getSuit()) {
System.out.println("Your prediction was correct.");
correctGuesses++;
}
}
else {
System.out.println("Your prediction was incorrect.");
break; // End the game.
}
if(guess == 'L') {
if(nextCard.getSuit() < currentCard.getSuit()) {
System.out.println("Your prediction was correct.");
correctGuesses++;
}
}
else {
System.out.println("Your prediction was incorrect.");
break;
}
}
else if (nextCard.getValue() > currentCard.getValue()) {
if (guess == 'H') {
System.out.println("Your prediction was correct.");
correctGuesses++;
}
else {
System.out.println("Your prediction was incorrect.");
break; // End the game.
}
}
else { // nextCard is lower
if (guess == 'L') {
System.out.println("Your prediction was correct.");
correctGuesses++;
}
else {
System.out.println("Your prediction was incorrect.");
break; // End the game.
}
}
currentCard = nextCard;
System.out.println();
System.out.println("The card is " + currentCard);
} // end of while loop
System.out.println();
System.out.println("The game is over.");
System.out.println("You made " + correctGuesses
+ " correct predictions.");
System.out.println();
return correctGuesses;
}
}
String comparison in Java is not done with == but with String#equals
That is, instead of
if(input== "Y" || input =="y") {
You should be using something more like...
if("Y".equalsIgnoreCase(input)) {
Updated...
There is also a never ending assignment of true to playAgain
} while (playAgain=true);
This will assign true back to playAgain, which means the loop can never be exited. Try using something like...
} while (playAgain);
...instead
The variable you are comparing input is a String.
Strings cannot be equated using == you must use String#equals()
The == operator checks whether the references to the objects are equal. See this post
In this case you may want to use String#equalsIgnoreCase()
Also as mentioned you need to fix while (playAgain=true); This is assigning true the variable playAgain and will always be true, Here you want to use == or just the varaible itself (no need to compare booleans)
while (playAgain=true);
should it be while (playAgain == true); ?
The comparison operator is not correct.