I am new to programming and wanted to make a dice rolling programm in Java for execise.
The code is the following:
import java.math.*;
public class Dices {
public static int dice1=0;
public static int dice2=0;
public static int x;
public static void main(String args[]){
do {
x++;
dice1=(int) (Math.random()*6+1);
dice2=(int) (Math.random()*6+1);
System.out.println(dice1+", "+dice2);
} while(dice1 !=1 || dice2 !=1);
System.out.println("Finalthrow: "+dice1+", "+dice2);
System.out.println("Snake-Eyes after "+x+" tries.");
}
}
This way it works fine, but in my opinion there is something wrong with the code. In the while condition should actually be. But if I use && it stops as soon as it rolls a 1 on the first dice. I thought && means "AND" and || means "OR". So actually it should behave exactly the other way around, or am I misinterpreting something?
Some understanding about Morgan's laws could help here. The law says (sorry for the weird syntax, but I think the message is clear) that :
(!P) OR (!Q) == !(P AND Q)
(!P) AND (!Q) == !(P OR Q)
So when you use || (OR) in your condition
while(dice1 !=1 || dice2 !=1)
is exactly the same as
while(!(dice1 == 1 && dice2 == 1))
so it will looop until both dice are 1.
On the other hand, if you use && (AND):
while(dice1 !=1 && dice2 !=1)
it's the same as
while(!(dice1 == 1 || dice2 == 1))
so it means that it will loop until one or two of the dice is/are 1.
&& means and
|| means or
So (dice1 != 1 || dice2 != 1) means continue the loop while dice1 is not 1 or dice 2 is not 1.
So (dice1 != 1 && dice2 != 1) means continue the loop while dice1 is not 1 and dice 2 is not 1.
The code is fine. You want the loop to end when dice1 == 1 and dice2 == 1. So it must loop until that is true, or until its opposite is false. The opposite of dice1 == 1 && dice2 == 1 is !(dice1 == 1 && dice2 == 1) which is equivalent to dice1 != 1 || dice2 != 1.
Think of it this way: if dice1 != 1, keep looping. Also, if dice2 != 1, keep looping. So if either is true, keep looping. And to test if either is true, regardless of if both are true, use ||.
The behavior is wright. You're saying with dice1 !=1 && dice2 !=1 that repeat the loopuntil BOTH of the dices are NOT 1. But when one dice rolls a 1 the condition is false and the loop escapes. Try it with a truth table.
Let's make a truth table.
What can we conclude from this? If you want your loop to continue while either A or B are different from 1 (or, as De Morgan's laws say: until both of them are equal to 1) then you can narrow it down to these values:
Since we need to find the operator that allows us to continue the loop (aka: the condition is true), we take the column that returns true for all 3 different kinds of inputs, which is A || B.
Note that A && B and A || B refer to the result of A != 1 and B != 1, not the actual input.
Related
newbie here,
I have two variables which generate random numbers through .Random. I want them keep rolling until both variables generate two different values, simultaneously. Therefore, I'm using while loop with && for this purpose. As I have understood, please correct me if I'm wrong, the line while ((diceRolled1 != 5) && (diceRolled2 != 4)) translates as, keep rolling until the values of diceRolled1 is not equal to 5 AND diceRolled2is not equal to 4. But the program ends if either variable matches its value (diceRolled1 = 5 OR diceRolled2 = 4). This is not what && is supposed to do, right? I have ran the code like 10s of times, but not a single time it generated 5 and 4 at the same time.
I also tried ==on both sides and either side, but in that case the program didn't run at all, nor it gave any error.
Your help will be much appreciated. Thanks
import java.util.Random;
import static java.lang.System.out;
public class DiceRoller {
public static void main(String[] args) {
Random dice1 = new Random();
Random dice2 = new Random(); //Removing this doesn't work either
int diceRolled1 = 0;
int diceRolled2 = 0;
while ((diceRolled1 != 5) && (diceRolled2 != 4)) { //& didn't work either
diceRolled1 = dice1.nextInt(6) + 1;
diceRolled2 = dice2.nextInt(6) + 1;
out.println(diceRolled1 + " " + diceRolled2);
}
out.println("Program ends");
}
}
Your logic is incorrect. The loop will continue as long as both values don't match - as soon as one value matches, the loop exits. We can invert your logic to show this:
while (!(diceRolled1 == 5 || diceRolled2 == 4)) {
which is logically equivalent to what you have.
What you want is this:
while (diceRolled1 != 5 || diceRolled2 != 4) {
which says "Continue while any variable does not have the desired value"
You're getting the logical result you describe, but it wasn't what you expect. Specifically, when either of your conditions evaluates to false the logical and will not evaluate to true. I think you wanted
while (!(diceRolled1 == 5 && diceRolled2 == 4)) {
which is while not dice1 equal to 5 and dice2 equal to 4. And then, using De Morgan's Laws that might also be expressed as
while (diceRolled1 != 5 || diceRolled2 != 4) {
which means loop while dice1 is not equal to 5 or dice2 is not equal to 4.
the while execute the statement untill the condition is true.
In your code the condition is given by (diceRolled1 != 5) && (diceRolled2 != 4).
The && operator require true that all operands be true.
Given this Your loop will end when at least one of the expression will be false.
To finish the program when it generate 5 and 4 you have to use this:
(!(diceRolled1 == 5) && (diceRolled2 == 4))
Yeah,it should be. The program should end if dicerolled is either 5 or 4 because as far as it is not 4 and not 5 it is in while loop. It exits the while loop if only the value is either 4 or 5. So your logic is incorrect. Sorry! :)
Try:
while (!(dicerolled ==4 && dicerolled == 5))
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 making a counter between number ranges and not sure the correct way to do this. I have always used the || operator but reading some examples, I feel I should be using the && command. Here is my example problem...
if(value >= 1 || value <=10){
count1++;
}
else if(value >= 11 || value <= 20){
count2++;
// AND SO ON........
Or should I be using the && operator like
if(value >= 1 && value <= 10){
count1++;
}
else if value >= 11 && value <= 20){
count2++;
}
|| means "or".
&& means "and".
value >= 1 || value <= 10 makes no sense because it's always true. All numbers are 1 or more, or 10 or less. Some numbers are both, but that doesn't matter.
value >= 1 && value <= 10 makes far more sense. There's a limited range of numbers ([1..10]) for which both the first condition and the second condition are true.
|| is the or operator, so the condition value >= 1 || value <=10 is true for all values if you think about it. So, unless you want your counts to be meaningless, use && which is the and operator.
int Comproll1= (int) (Math.random()*6+1);
int Comproll2= (int) (Math.random()*6+1);
while (m==1)
{
{
if (Comproll1==1 || Comproll2==1)
{
System.out.println("One of the computer's dice rolls was a 1, it lost all the points for the round & it is now your turn!");
cr= cr-cr;
m++;
}
else if (Comproll1==1 && Comproll2==1)
{
System.out.println("The Computer rolled 2 1's, their total number of points is now 0 & it is now your turn!");
cp=cp-cp;
m++;
}
else
{
cr= Comproll1+Comproll2;
cp= cp+cr;
}
}
Hey everyone! Above is my code- for some reason regardless, it WILL ALWAYS, no matter what, always display the first option, which is "One of the computer's dice rolls was a 1, it lost all points for the round...". Even when I change the order of the statements, it still does this. Can someone please explain to me why this is happening?? Thanks!
As far as I can tell, because you aren't re-rolling
int Comproll1= (int) (Math.random()*6+1);
int Comproll2= (int) (Math.random()*6+1);
while (m==1)
{
Should be
while (m==1)
{
int Comproll1= (int) (Math.random()*6+1);
int Comproll2= (int) (Math.random()*6+1);
Also, Java naming convention is camel case for variables (and starts with a lower case letter). So, Comproll1 might be compRoll1. Finally, I personally prefer Random.nextInt() and for 6 sided dice that might look like
Random rand = new Random();
while (m==1)
{
int compRoll1 = rand.nextInt(6) + 1;
int compRoll2 = rand.nextInt(6) + 1;
Edit Actually, you also need to reverse the order of your tests. Because if either is true then it will never be possible that the test for both being true will be entered.
if (Comproll1==1 || Comproll2==1) {
// Here.
}else if (Comproll1==1 && Comproll2==1) {
// Will never enter here.
}
Switch the order to,
if (Comproll1==1 && Comproll2==1) {
// Both.
}else if (Comproll1==1 || Comproll2==1) {
// Either.
}
The problem is that you need to check if they are both 1, before checking if either of them are 1s. If we look at the code:
if (Comproll1==1 || Comproll2==1)
{
System.out.println("One of the computer's dice rolls was a 1, it lost all the points for the round & it is now your turn!");
cr= cr-cr;
m++;
}
else if (Comproll1==1 && Comproll2==1)
{
System.out.println("The Computer rolled 2 1's, their total number of points is now 0 & it is now your turn!");
cp=cp-cp;
m++;
}
if:
Comproll1 = 1
Comproll2 = 1
You expect that it will go into the else if (Comproll1==1 && Comproll2==1) however, if this is true than if (Comproll1==1 || Comproll2==1) will always be true.
To fix this simply change the order of the ifs, like this:
if (Comproll1==1 && Comproll2==1)
{
System.out.println("The Computer rolled 2 1's, their total number of points is now 0 & it is now your turn!");
cp=cp-cp;
m++;
}
else if (Comproll1==1 || Comproll2==1)
{
System.out.println("One of the computer's dice rolls was a 1, it lost all the points for the round & it is now your turn!");
cr= cr-cr;
m++;
}
Hope this helps :)
(Also you need to reroll the dice (as Elliott Frisch Said in his answer))
Try changing the order of your if statements. Logically, if one of the two comparisons are true, the first statement will execute. In the case that the second conditions else if (Comproll1==1 && Comproll2==1) are true, the first conditions if (Comproll1==1 || Comproll2==1) will also be true.
Since you've chained the if statements in an if-else-if fashion, the first if statement to equate to true will execute.
if (Comproll1==1 && Comproll2==1)
{
System.out.println("The Computer rolled 2 1's, their total number of points is now 0 & it is now your turn!");
cp=cp-cp;
m++;
}
else if (Comproll1==1 || Comproll2==1)
{
System.out.println("One of the computer's dice rolls was a 1, it lost all the points for the round & it is now your turn!");
cr= cr-cr;
m++;
}
else
{
cr= Comproll1+Comproll2;
cp= cp+cr;
}
Is it possible to have a statement such as...
if(delco == 1 && heavy < 5)
System.out.println("The total cost of your delivery is: $" + OPT_ONE);
if(delco == 1 && heavy >= 5 && heavy <= 20)
System.out.println("The total cost of your delivery is: $" + OPT_TWO);
...that also applies boolean logic to express an output? Something like this...
boolean overnight;
if(delco == 1 && heavy < 5) && (overnightShip == YES)
System.out.println("The total cost of your delivery is: $" + OPT_ONE + OVERNIGHT);
if(delco == 1 && heavy >= 5 && heavy <= 20) && (overnightShip == NO)
System.out.println("The total cost of your delivery is: $" + OPT_TWO);
I have tried a few variations of this code and the error I'm receiving states that they are incomparable types. How do I go about making them comparable?
You just missed some parentheses, because your logic seems OK. It should be, e.g.:
if ( (delco == 1 && heavy < 5) && (overnightShip == YES) )
...
Note the outer parentheses.
Also that assumes that you've defined YES to be a boolean constant equal to true, and that is redundant, so:
if ( (delco == 1 && heavy < 5) && (overnightShip) )
...
And in this case, those parentheses are redundant as well, and the whole thing simplifies to:
if ( delco == 1 && heavy < 5 && overnightShip )
...
Just use the boolean on its own:
if (delco == 1 && heavy < 5 && overnightShip)
Comparing a boolean "flag" variable with a boolean constant is poor style - always prefer testing the boolean as-is.
Boolean types in Java have the values:
true
false
Not:
YES
NO
unless you have defined these constants yourself somewhere
So your code should look like:
(overnightShip == true)
(overnightShip == false)
or even:
(overnightShip) // true
(! overnightShip) // false