I'm having an issue with my very first program in Java. I'm trying to reproduce a game you play with matches, but the program never stops when it's supposed to...
When I enter numbers like 6, 3, 2, 1 or 7, 3, 2, 1 the loop should stop there but it just continues to the next turn as if nothing happened, even though the variables have the right value and should match the end conditions.
I'm pretty sure the problem lies in the while part of the main loop (at the very end) but I can't see it! It's probably something obvious, but well...
Here is the full source code (the rules of the game are below it):
import java.util.Scanner;
public class JeuDeNim {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
//Starting the game
int totalMatches;
do {
System.out.println("How many matches do you want to play with? "
+ "(from 6 to 60)");
totalMatches = sc.nextInt();
}
while(totalMatches < 6 || totalMatches > 60);
int matchesPlayer1 = 0;//to keep track of
int matchesPlayer2 = 0;//the previous round
int i = 1;//to know whose turn it is
do{
//player 1
if(!(i % 2 == 0)) {//if odd number, player 1
//round 1
if(i == 1) {
do {
System.out.println("Player 1: How many matches do you "
+ "want to pick? (1, 2 or 3)");
matchesPlayer1 = sc.nextInt();
}
while(matchesPlayer1 < 1 || matchesPlayer1 > 3);
totalMatches = totalMatches - matchesPlayer1;
i++;
}
//odd round x
else {
do {
System.out.println("Player 1: How many matches do you "
+ "want to pick this turn?");
matchesPlayer1 = sc.nextInt();
if(totalMatches - matchesPlayer1 < 0) {
System.out.println("Pick a smaller number");
//totalMatches cannot be negative
} else if(matchesPlayer1 == matchesPlayer2) {
System.out.println("You cannot pick the same number "
+ "of matches as Player 2");
}
}
while(matchesPlayer1 < 1 || matchesPlayer1 > 3
|| (totalMatches - matchesPlayer1 < 0)
|| (matchesPlayer1 == matchesPlayer2));
totalMatches = totalMatches - matchesPlayer1;
if(totalMatches == 0
|| (totalMatches == 1 && matchesPlayer1 == 1)) {
System.out.println("Player 1 Wins!");
}
i++;
}
}
//player 2
else {
//round 2
if(i == 2) {
do {
System.out.println("Player 2: How many matches do you "
+ "want to pick? (1, 2 or 3)");
matchesPlayer2 = sc.nextInt();
if(matchesPlayer2 == matchesPlayer1) {
System.out.println("You cannot pick the same "
+ "number of matches as Player 2");
}
}
while(matchesPlayer2 < 1 || matchesPlayer2 > 3
|| matchesPlayer2 == matchesPlayer1);
totalMatches = totalMatches - matchesPlayer2;
i++;
}
//even round x
else {
do {
System.out.println("Player 2: How many matches do you "
+ "want to pick this turn?");
matchesPlayer2 = sc.nextInt();
if (totalMatches - matchesPlayer2 < 0) {
System.out.println("Pick a smaller number");
//totalMatches cannot be negative
} else if(matchesPlayer2 == matchesPlayer1) {
System.out.println("You cannot pick the same number "
+ "of matches as Player 1");
}
}
while(matchesPlayer2 < 1 || matchesPlayer2 > 3
|| (totalMatches - matchesPlayer2 < 0)
|| (matchesPlayer2 == matchesPlayer1));
totalMatches = totalMatches - matchesPlayer2;
if(totalMatches == 0
|| (totalMatches == 1 && matchesPlayer2 == 1)) {
System.out.println("Player 2 Wins!");
}
i++;
}
}
System.out.println("totalMatches: " + totalMatches + " "
+ "matchesPlayer1: " + matchesPlayer1 + " " + "matchesPlayer2: "
+ matchesPlayer2);//to check that everything is working. It is not...
}
while(totalMatches > 0
|| !(!(i % 2 == 0) && totalMatches == 1 && matchesPlayer1 == 1)
|| !((i % 2 == 0) && totalMatches == 1 && matchesPlayer2 == 1));
}
}
Here are the rules of the game: it's a two-player game, where the players take turns picking matches (1, 2 or 3) and cannot pick the same number of matches as the other player: if player one picks 2 matches, player two will have to pick either 1 or 3 matches. The player who cannot pick anymore matches loses the game, which means there are two end scenarios : when there are no more matches, or there is 1 but the other player picked 1 during the previous round.
Look at the conditions in your final while loop
totalMatches > 0 ||
!(!(i % 2 == 0) && totalMatches == 1 && matchesPlayer1 == 1) ||
!((i % 2 == 0) && totalMatches == 1 && matchesPlayer2 == 1));
This means the loop will repeat as long as there are any matches left, or it isn't player 1's turn with 1 match left and a pick of 1 match, or it isn't player 2's turn with 1 match left and a pick of 1 match.
This can never happen because (among other reasons), it requires i%2==0 and i%2 != 0. Switch the || to &&, and it should fix the problem. As was pointed out in the comments, you also need to reverse the player turn check, because the turn counter has already been incremented by this point.
The reason you want to use && here instead of ||, like in the other spots in your code is that your checking for a different concept. Every other time, you check the reasons why the loop should be repeated. This time, you check the reasons why the loop should end, and negate them. When in doubt, actually plug in values for the comparison, and see if it evaluates to what you think it should.
The game ends when there is no more matches left. So while(totalMatches > 0); is just enough.
Remove the unnecessary lines:
|| !(!(i % 2 == 0) && totalMatches == 1 && matchesPlayer1 == 1)
|| !((i % 2 == 0) && totalMatches == 1 && matchesPlayer2 == 1));
Related
i am trying to detect a jokerStraightFlush when analysing a poker hand.
I need to add a feature where this hand works 8S JK 6S JK 4S. The JK are jokers. I am using the exact same code logic as https://www.codeproject.com/Articles/38821/Make-a-poker-hand-evalutator-in-Java.
cardsTable represents the distribution of the Card ranks present in the hand. Each element of this array represents the amount of card of that rank(from 1 to 13, 1 being ace) present in the hand. So for 8S JK 6S JK 4S, the distribution would be
0 0 0 0 1 0 1 0 1 0 0 0 0 0
note that the position 1 is for ace (because it's simpler)
I need to find a way to detect if cardsTable[i] == 1 failed and decrement the amount of jokers used (numberOfJokers) to detect a jokerStraightFlush because in this incomplete piece of code, numberOfJokers dont decrement and i dont know how to write it in a nice way. What i do here is i check if the card at this rank exists cardsTable[i] == 1 or if its a joker... but i dont know how to check for a joker in the others consecutive rankings
I dont know if i'm clear, it's a twisted situation.. if i'm not let me know.
straight = false; // assume no straight
int numberOfJokers = 2; //(the maximum number of jokers in a hand is 2)
for (int i = 1; i <= 9; i++) { // can't have straight with lowest value of more than 10
numberOfJokers = 2 //reset the number of jokers available after each loop
if ((cardsTable[i] == 1 || numberOfJokers > 0) &&
(cardsTable[i + 1] == 1 || numberOfJokers > 0) &&
(cardsTable[i + 2] == 1 || numberOfJokers > 0) &&
(cardsTable[i + 3] == 1 || numberOfJokers > 0) &&
(cardsTable[i + 4] == 1 || numberOfJokers > 0)) {
straight = true;
break;
}
}
I also have this code but i don't know how to detect if the first condition failed so i can decrement the number of jokers remaining.
for (int i = 1; i <= 9; i++) {
numberOfJokers = 2
if (cardsTable[i] == 1 || numberOfJokers>0) {
if (cardsTable[i + 1] == 1 || numberOfJokers>0) {
if (cardsTable[i + 2] == 1 || numberOfJokers > 0) {
if (cardsTable[i + 3] == 1 || numberOfJokers > 0) {
if (cardsTable[i + 4] == 1 || numberOfJokers > 0) {
straight = true;
break;
}
}
}
}
}
}
Due to "short-circuiting" behaviour, you don't need to detect the left operand of a || resulted in true: the right operand gets evaluated if the left one was false, only.
(cardsTable[i + c] == 1 || numberOfJokers-- > 0) would work; note that
(numberOfJokers-- > 0 || cardsTable[i + c] == 1) would not.
Whether or not such code is maintainable or readable is an independent consideration, as is the quality of the overall approach to problem and solution.
Conceptually, you just need 3 of the 5 slots to be equal to 1, and the other 2 equal to 0. You could do something like this:
for (int i = 1; i <= 9; i++) {
boolean straight = true;
int numberOfJokers = 2;
for (int j = i; j <= i + 5; j++) { // I used a for loop instead of writing the statement 5 times
if (cardsTable[j] > 1) { // Can't have straight if more than one of a kind
straight = false;
}
if (cardsTable[j] == 0) {
numberOfJokers--;
}
}
if (numberOfJokers >= 0 && straight == true) {
break;
}
}
Alternatively, maybe a simpler way would be to add a position in the cardsTable array indicating the number of jokers.
nvm i used a function inside my conditions.. i don't know if it's the right way but it's logic to me x)
straight = false; // assume no straight
for (int i = 1; i <= 9; i++) // can't have straight with lowest value of more than 10
{
remainingJokers=jokers;
System.out.println("resetjokers : "+jokers);
if (cardsTable[i] == 1 || useJoker()) {
if (cardsTable[i + 1] == 1 || useJoker()) {
if (cardsTable[i + 2] == 1 || useJoker()) {
if (cardsTable[i + 3] == 1 || useJoker()) {
if (cardsTable[i + 4] == 1 || useJoker()) {
System.out.println("straight");
straight = true;
topStraightValue = i + 4; // 4 above bottom value
break;
}
}
}
}
}
}
}
private boolean useJoker() {
int remaining = remainingJokers;//remainingJokers is a global variable
remainingJokers--;
return remaining>0;
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("Enter value: ");
int value = input.nextInt();
if (value == 1 || value == 3 || value == 5 ||value == 7 || value == 9) {
if (value % 3 == 0)
System.out.println(value + " is an odd number less than 10"
+ " and divisible by 3");
}
else if (value == 2 || value == 4 || value == 6 ||value == 8) {
if (value % 3 == 0)
System.out.println(value + " is an even number less than 10"
+ " and divisible by 3");
}
else
System.out.println("Invalid number");
input.close();
}
if-else statement only recognizes integers that are divisible by 3 which are 3, 6 or 9. When I type 1 or 5, for example, the programme does not display any of the input and just stop running.
If you type "1" then if(value == 1) is true so then the program checks if(value %3 == 0). Since value%3 is 1 when value is 1 it doesn't print anything and exits. So you see nothing.
Normally, in any IDE there are some debugging facilities so by using them you will be able to see how the program works step by step.
I don't know why you used this particular logic in your if statements, but we can refactor assuming what you print is actually what you want:
is an odd/even number less than 10 and divisble by 3
if (value < 10 && value % 2 == 1 && value % 3 == 0) {
System.out.println(value + " is an odd number less than 10"
+ " and divisible by 3");
}
else if (value < 10 && value % 2 == 0 && value % 3 == 0) {
System.out.println(value + " is an even number less than 10"
+ " and divisible by 3");
}
else {
System.out.println("value does not meet our conditions.");
}
The immediate reason why 1 and 5 apparently cause the code to do nothing is that they enter the first if statement but then fail the next condition as they are not divisible by three, and your code does not output in this case.
This happens because of the given logic. When you type 1 or 5 as input first outer if becomes true. But if(value % 3 == 0) isn't true, that's why program ended up without giving any output.
If I understand your expectation of this program correctly please try the following code
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("Enter value: ");
int value = input.nextInt();
if (value < 10 && value % 2 == 0 && value % 3 == 0) {
System.out.println(value + " is an even number less than 10" + " and divisible by 3");
}
else if (value < 10 && value % 2 != 0 && value % 3 == 0) {
System.out.println(value + " is an odd number less than 10" + " and divisible by 3");
}
else
System.out.println("Invalid number");
input.close();
}
when you enter 1 or 5 for example, below condition becomes true
if (value == 1 || value == 3 || value == 5 ||value == 7 || value == 9)
however, value %3 is not equal to 0 hence nothing is printed and program control directly goes to
input.close();
First of all, you should not use if-else statements that way. Now, the problem is that when you enter 1 or 5, they pass the first if statement, but neither (1 % 3 ==0) or (5 % 3 == 0) will be true, and that is why your code does nothing in those cases. Try this instead:
if(value % 3 == 0 && value <10) {
if(value % 2 != 0){
System.out.println(value + " is an odd number less than 10"
+ " and divisible by 3");
}else{
System.out.println(value + " is an even number less than 10"
+ " and divisible by 3");
}
}else{
System.out.println("Invalid number");
}
I just started coding with more complex methods than the main method. I was given an assignment to make a race with three coins. Whichever coin flips 2 heads and 2 tails first in that order wins. I coded an if else statement to determine which coin wins but neither of the if statements are ever executed. Please tell me if you see an error in my if else statements or somewhere else. I also have to other programs of code that include other methods.
public class FlipRace
{
public static void main (String[] args)
{
final int GOALHEAD = 2;
final int GOALTAIL = 2;
int count1 = 0, count2 = 0, count3 = 0, count10 = 0, count20 = 0, count30 = 0;
// Create three separate coin objects
Coin coin1 = new Coin();
Coin coin2 = new Coin();
Coin coin3 = new Coin();
while (count1 <= GOALHEAD && count10 <= GOALTAIL || count2 <= GOALHEAD && count20 <= GOALTAIL || count3 <= GOALHEAD && count30 <= GOALTAIL)
{
coin1.flip();
coin2.flip();
coin3.flip();
// Print the flip results (uses Coin's toString method)
System.out.print ("Coin 1: " + coin1);
System.out.println (" Coin 2: " + coin2);
System.out.println (" Coin 3: " + coin3);
// Increment or reset the counters
if (coin1.isHeads())
count1++;
else
count10++;
if (coin2.isHeads())
count2++;
else
count20++;
if (coin3.isHeads())
count3++;
else
count30++;
}
// Determine the winner
if (count1 == GOALHEAD && count10 == GOALTAIL)
System.out.println ("Coin 1 wins!");
else if (count2 == GOALHEAD && count20 == GOALTAIL)
System.out.println ("Coin 2 wins!");
else if (count3 == GOALHEAD && count30 == GOALTAIL)
System.out.println ("Coin 3 wins!");
else
System.out.println ("It's a TIE!");
}
}
Here is my output:
Coin 1: Heads Coin 2: Heads
Coin 3: Tails
Coin 1: Heads Coin 2: Heads
Coin 3: Heads
Coin 1: Heads Coin 2: Tails
Coin 3: Heads
Coin 1: Heads Coin 2: Heads
Coin 3: Tails
Coin 1: Heads Coin 2: Tails
Coin 3: Heads
It's a TIE!// this message comes up every time because something is wrong
try changing your comparison to
if (count1 >= GOALHEAD && count10 >= GOALTAIL)
System.out.println ("Coin 1 wins!");
else if (count2 >= GOALHEAD && count20 >= GOALTAIL)
System.out.println ("Coin 2 wins!");
else if (count3 >= GOALHEAD && count30 >= GOALTAIL)
System.out.println ("Coin 3 wins!");
else
System.out.println ("It's a TIE!");
of course another way would to simply debug your code and inspect the values
I don't understand how your code would solve the problem. If I understand it right, you want the first coin that shows the combination H-H-T-T. Now, you are counting the heads and tails in ANY order. So, if you have H-T-H-T for the first coin and H-H-H-T and H-T-T-T for the second and third respectively, the first one wins.
In order to solve the problem considering the order of heads and tails, I think you should change the if-else statement for each coin (I'll make it only for coin1 here):
if (coin1.isHeads()) {
if (count1 < 2 && count2 == 0) { //less than 2 heads and zero tails
count1++;
} else {
count1 = 0;
count10 = 0;
}
} else { //tails
if (count1 == 2 && count10 < 2) { //we already have two heads and 0 or 1 tail
count10++;
} else { // either less than two heads or too many tails - we have to restart!
count1 = 0;
count10 = 0;
}
}
You should also change the while statement... You want to stop when you have two heads ant two tails for any coin. So, it'd be something like this:
while (!(count1 == 2 && count10 == 2) && !(count2 == 2 && count20 == 2) && ....) {...}
I am trying to create the scissors-paper-stone-game in Java with a do-while loop. The computer will randomly select 1, and the user makes his choice. The exit condition is if the user wins twice (userWin) or the computer wins twice (compWin). If there is a draw, neither counter increases.
// Scissors, paper, stone game. Best of 3.
// scissors = 0; paper = 1; stone = 2;
import java.util.Scanner;
public class Optional2 {
public static void main(String[] args) {
int userWin = 0;
int compWin = 0;
do {
//comp choice
int comp = 1; //TEST CASE
// int comp = (int) (Math.random() * (2 - 0 + 1) + 0);
//user choice
System.out.println("0 for scissors, 1 for paper, 2 for stone");
Scanner sc = new Scanner(System.in);
int user = sc.nextInt();
//Draw
if (comp == user) {
System.out.println("Draw");
//Win =)
} else if (comp == 0 && user == 2 || comp == 1 && user == 0 ||
comp == 2 && user == 1) {
System.out.println("WIN!");
userWin++;
//Lose =(
} else {
System.out.println("Lose =(");
compWin++;
}
} while (compWin < 2 || userWin < 2);
System.out.println("You won " + userWin + " times!");
}
}
For int comp, it should be random, but I am setting it to 1 (paper) for easy testing.
However, presently only the 1st condition will exit the loop if it becomes true. I am expecting the 2nd condition to exit the loop too if it becomes true with the || operator, but the loop just keeps looping even if it comes true.
ie. if I put while (userWin < 2 || compWin < 2), it will exit if the user wins twice but not if the computer wins twice. If I put while (compWin < 2 || userWin < 2), it will exit if the computer wins twice but not if the user wins twice.
I tried changing it to while ((userWin < 2) || (compWin < 2)) too but it doesn't work.
but the loop just keeps looping even if it comes true
A while loops keeps looping as long as the condition remains true.
I think the problem is that you should rewrite the condition to:
while ((userWin < 2) && (compWin < 2))
with && instead of ||. Indeed: now the while loop is something like: "Keep looping as long as the the user has not won two or more times, and the computer has not won two or more times."
You should use && instead:
while (userWin < 2 && compWin < 2);
This is because you want to be in the loop as long as none of the user or comp gets 2 consecutive wins
That is translated into
userWin < 2 && (=AND) compWin < 2
Which means: as long as both the user AND the comp has less than 2 consecutive wins, stays in the loop.
Or in other words, as you have phrased it: if any of user or comp gets two consecutive wins, gets out from the loop.
Try replace with &&. You need both less that 2 to keep loop going on
I am creating a program that asks the user for several integers and one of the statements ask the user "Enter an integer that is negative and even or positive and odd". How exactly would I go about setting up such a question? I have this so far. I have no idea how exactly I should do this, as my instructions are pretty confusing. This is what the question is for my problem:
4.
Ask the user for an integer that is either negative and even or positive
and odd. Use an if statement and compound conditional.
import java.util.Scanner;
public class ExerciseFour
{
public static void main ( String[] argsv )
{
int choice;
int choiceTwo;
int choiceThree;
Scanner input = new Scanner(System.in);
System.out.println( "Enter a number between 0 and 10" );
choice = input.nextInt();
if ( choice > 0 && choice < 10 )
{ System.out.println( "Valid number" );
}
else
{ System.out.println( "Invalid number" );
return;
}
System.out.println( "Enter a number divisible by 2 or 3?" );
choiceTwo = input.nextInt();
if ( choiceTwo % 2 == 0 && choiceTwo % 3 == 0 )
{ System.out.println( "Valid number" );
}
else
{ System.out.println( "Number not divisible by 2 or 3" );
return;
}
System.out.println( "Enter an integer that is negative and even or positive and odd (Ex. -2 or 7 )" );
choiceThree = input.nextInt();
if ( choiceThree )
{
}
else
{
}
((choiceThree > 0) && (choiceThree % 2 == 1)) || ((choiceThree < 0) && (choiceThree % 2 == 0))
The above is the compound condition you're looking for, which means:
(
(choiceThree > 0) //positive number / greater than zero
&& // AND
(choiceThree % 2 == 1) //odd number: (an odd number divided by two has a remainder of 1)
)
|| // OR
(
(choiceThree < 0) //negative number / less than zero
&&
(choiceThree % 2 == 0) //even number (an even number divided by two has a remainder of 0)
)
EDIT: % is the modulo operator.
The result of a % b is the remainder of the integer division a / b.
The key is to use The modulo operator. An even number is divisible by 2 with no remainder. So:
if (choiceThree < 0) {
if (choiceThree % 2 == 0) {
System.out.println ("Valid");
} else {
System.out.println ("Invalid");
}
} else {
if (choiceThree % 2 != 0) {
System.out.println ("Valid");
} else {
System.out.println ("Invalid");
}
}
This is a bit cumbersome, of course. A more elegant way to express this boolean logic would be by using the exclusive or (xor) operator. This operator returns true if one and only one of its operands evaluate to true:
if (choiceThree > 0 ^ choiceThree % 2 == 0) {
System.out.println ("Valid");
} else {
System.out.println ("Invalid");
}
I think there is a mistake in the second question
choiceTwo % 2 == 0 && choiceTwo % 3 == 0
you may want to write || instead of && becouse you sad devisible to 2 OR 3 ;-)
For your other problem: You have two boolean expressens wich may be true:
Ask the user for an integer that is either negative and even
(choiceThree < 0 && choiceThree % 2 == 0)
or positive and odd.
(choiceThree > 0 && choiceThree % 2 == 1)
Use an if statement and compound conditional.
So just combine these to statements with a logical OR (||)
Create a method that returns true if it's one of those scenarios:
public boolean isCorrectInteger(int number){
if ((number < 0) && (number % 2 == 0)) { //negative and even
return true;
} else if((number < 0) && (number % 2 == 1)) { // positive and odd
return true;
} else { // other cases
return false;
}
}
This can be written in a one bigger condition, I've just split it into two for the sake of a simple example.
Also take into consideration that zero is currently assigned neither to positive nor negative - you can change this as you please by using the <= or >= operators.
Try this:
System.out.println( "Enter an integer that is negative and even or positive and odd (Ex. -2 or 7 )" );
choiceThree = input.nextInt();
if ( (choiceThree>0 && choiceThree%2==1) || (choiceThree<0 && choiceThree%2==0) )
{
System.out.println("Correct");
}
else
{
System.out.printlnt("ERROR");
}