Java working out which number hits zero first - java

I'm building a simple fighting game to test out loops and if statements, however I've run into a kind of complex logic issue.
The loop ends when either the player or enemy HP hits zero however I've discovered that my code can't detect which HP hits zero first results in the player always winning.
Is there a simple way of tracking which number hits zero first therefor breaking the loop?
do {
#SuppressWarnings("resource")
Scanner reader = new Scanner(System.in);
System.out.println("1: Attack. 2: Defend");
int n = reader.nextInt();
if (n == 1){
PHP = (PHP-EATK);
EHP = (EHP-PATK);
} else if (n == 2){
PHP = (PHP-Math.max(0, EATK-PDEF));
}
System.out.println("P "+PHP);
System.out.println(EHP);
}
while (PHP >= 1 || EHP >= 1);
if(PHP <= 0){
System.out.println("You Lose!");
}else if (EHP <= 0){
System.out.println("You win!");
}

Look at your loop continuation condition:
while (PHP >= 1 || EHP >= 1)
It means "while the player or his enemy can fight, go on". In other words, you continue fighting until they both die, at which point you declare the player the winner, even though it's a draw.
Changing the condition to ""while the player and his enemy can fight" will fix this problem.

change while (PHP >= 1 || EHP >= 1); to while (PHP >= 1 && EHP >= 1);.
You using OR operation where you want AND

Related

Java: Do-while loop with multiple conditions

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

Java Conditions Confusion? (Beginner)

The aim of this program is to make a Rock Paper Scissors game. I have succeeded in making it however I can not get it to loop no matter what I try. I tried:
while (index = 0)
while (index < gamesCount)
However, while my index is 0 and my condition says while (index != 0), it seems to be the only condition that runs the program but it will not loop regardless. How can I get my game to loop?
import java.util.Scanner;
import java.util.Random;
public class RockPaperScissors {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
Random randomGen = new Random();
//Variables
String player1;
int cpu;
int start = 1;
int end = 3;
int index = 0;
// 1 = Rock | 2 = Scissors | 3 = Paper
//Code
System.out.println("Welcome to Rock, Paper, Scissors!");
while (index != 0) {
System.out.print("Rock, Paper, or Scissors?: ");
player1 = in.nextLine();
cpu = randomGen.nextInt(3);
System.out.println(cpu);
if (player1.equals("Rock") && (cpu == 2)) {
System.out.println("You lose!");
} else if (player1.equals("Rock") && (cpu == 1)) {
System.out.println("You win!");
} else if (player1.equals("Rock") && (cpu == 0)) {
System.out.println("Draw!");
}
// --------------------
if (player1.equals("Scissors") && (cpu == 2)) {
System.out.println("Draw!");
} else if (player1.equals("Scissors") && (cpu == 1)) {
System.out.println("You win!");
} else if (player1.equals("Scissors") && (cpu == 0)) {
System.out.println("You lose!");
}
//---------------------
if (player1.equals("Paper") && (cpu == 2)) {
System.out.println("You lose!");
} else if (player1.equals("Paper") && (cpu == 1)) {
System.out.println("You win!");
} else if (player1.equals("Paper") && (cpu == 0)) {
System.out.println("Draw!");
}
}
}
}
You have your index variable set to 0. The condition of the while loop is saying, if index does not equal 0, execute the code in the loop. Since your index equals 0, the instructions in the loop will not be executed. Also, you will need to update the index variable in the loop so that if the condition you are looking for is met, the code will stop looping.
ie:
int gamesPlayed = 0;
int gamesRequested = 3; // or get this from the user
while (gamesPlayed < gamesRequested){
String player1Choice = in.nextLine();
if(!"".equals(player1)){
// your code
gamesPlayed++;
} else {
System.out.print("Rock, Paper, or Scissors?: ");
}
}
Two mistakes:
while (index != 0);
this is the entire loop. it ends either at the end of the { } block (which you don't have), or at the first ; which is immediately after the statement.
Correct this, though, and it still won't loop:
int index = 0;
// 1 = Rock | 2 = Scissors | 3 = Paper
//Code
System.out.println("Welcome to Rock, Paper, Scissors!");
while (index != 0);
index = 0, so (index != 0) will never return true.
Your index variable is set to a value of 0.
Your while loop says
while (index != 0);
Which means, while the index isn't 0, run my code. The problem is your code will never run then because your index value is always 0.
Try changing it to another value (say 5 for example), and it should work now.
:)

Tic tac toe computer choosing spot?

I have my tic tac toe game 90% finished, and had a form of computer AI, but that did not turn out too well. I am looking for a new easier source of generating a spot for the computer to move on the game board.
I need this computer move selection to pick a spot, but to also make sure that spot is freely available and there are no 'X's in that spot. Any ideas as to how to make the computer choose a spot?
/* I have 3 other methods drawing the board, and determining a tie, a loss, and a win not shown here for simplicity*/
public static void main(String[] args) {
//Variable declaration
Scanner kbReader = new Scanner(System.in);
char[][] Board = new char[3][3];
String MenuInput;
int BoardOutput;
int UserSpotChoice;
int ComputerSpotChoice = 0;
int UserTurn = 0;
int Winner = 0;
Board[0][0] = '-';
Board[0][1] = '-';
Board[0][2] = '-';
Board[1][0] = '-';
Board[1][1] = '-';
Board[1][2] = '-';
Board[2][0] = '-';
Board[2][1] = '-';
Board[2][2] = '-';
//Welcome
System.out.println("Welcome to Alex Montague's Tic Tac Toe game!");
System.out.println("");
System.out.println("If you wish to play, type 'Play'");
System.out.println("If you wish to read the instructions, type 'Instructions'");
System.out.println("If you wish to exit, type 'Exit'");
MenuInput = kbReader.next();
do {
if (MenuInput.equals("Play") || MenuInput.equals("play")) {
while (!GameOver) {
System.out.println("\f");
System.out.println(" Tic Tac Toe");
BoardOutput = DrawBoard(Board);
System.out.println(" 1 2 3");
System.out.println(" 4 5 6");
System.out.println(" 7 8 9");
System.out.println("Please enter the number you would like to move your spot to");
UserSpotChoice = kbReader.nextInt();
if (UserSpotChoice == 1) Board[0][0] = 'X';
if (UserSpotChoice == 2) Board[0][1] = 'X';
if (UserSpotChoice == 3) Board[0][2] = 'X';
if (UserSpotChoice == 4) Board[1][0] = 'X';
if (UserSpotChoice == 5) Board[1][1] = 'X';
if (UserSpotChoice == 6) Board[1][2] = 'X';
if (UserSpotChoice == 7) Board[2][0] = 'X';
if (UserSpotChoice == 8) Board[2][1] = 'X';
if (UserSpotChoice == 9) Board[2][2] = 'X';
do {
ComputerSpotChoice = (int)(Math.random() * 9) + 1;
}
while (Board[(ComputerSpotChoice - 1) / 3][(ComputerSpotChoice - 1) % 3] != '-'); //HERE IS THE OLD COMPUTER SPOT GENERATION THAT DID NOT WORK
if (ComputerSpotChoice == 1) Board[0][0] = 'O';
if (ComputerSpotChoice == 2) Board[0][1] = 'O';
if (ComputerSpotChoice == 3) Board[0][2] = 'O';
if (ComputerSpotChoice == 4) Board[1][0] = 'O';
if (ComputerSpotChoice == 5) Board[1][1] = 'O';
if (ComputerSpotChoice == 6) Board[1][2] = 'O';
if (ComputerSpotChoice == 7) Board[2][0] = 'O';
if (ComputerSpotChoice == 8) Board[2][1] = 'O';
if (ComputerSpotChoice == 9) Board[2][2] = 'O';
Winner(Board);
Loser(Board);
Tie(Board);
} //While loop
//if (GameOver) System.exit (0) ;
} //If play
else if (MenuInput.equals("Instructions") || MenuInput.equals("instructions")) {
System.out.println("\f");
System.out.println("You will be playing the game of Tic Tac Toe against the computer.");
System.out.println("The object of this game is to get three of your own x's or o's in a line.");
System.out.println("You take turns placing the x's and o's and whoever gets three in a row first wins.");
System.out.println("Good Luck!");
System.out.println("");
System.out.println("If you wish to play, type 'Play'");
System.out.println("If you wish to exit, type 'Exit'");
MenuInput = kbReader.next();
} else if (MenuInput.equals("Exit") || MenuInput.equals("exit")) {
System.out.println("Thank you for using Alex Montague's Tic Tac Toe game!");
System.exit(0);
} else {
System.out.println("Sorry, that is not a valid choice.");
System.out.println("If you wish to play, type 'Play'");
System.out.println("If you wish to read the instructions, type 'Instructions'");
System.out.println("If you wish to exit, type 'Exit'");
MenuInput = kbReader.next();
}
} //do while
while (!MenuInput.equals("Instructions") || !MenuInput.equals("instructions") || !MenuInput.equals("Play") || !MenuInput.equals("play") || !MenuInput.equals("Exit") || !MenuInput.equals("exit"));
Create a method public static boolean isSpotAvailable(int x, int y). Check after randomly finding a spot for pc, if it is available, use it, if not then choose a new spot.
A simplistic approach could be that, for every square you have, you check how many rows of 3 items you can create from that row. So for instance, the square in the middle would yield 4 (since you can create a horizontal row passing from the middle, a vertical row passing from the middle and two diagonals). On the other hand, squares at the edges would yield a value of 2 (since you can have 1 vertical and 1 horizontal).
If you want to have a more robust approach, then I think that the recommended way would be to use a MiniMax Tree. This will allow you to build a decision tree so that your algorithm decides where to place the next piece. An example of such an approach for tic tac toe can be found here.
You can keep track of the indices by using a HashSet object. As long as you can add a position between 1 to 9 into the set object successfully, the position is available. The other way is to use an ArrayDequeue object. Everytime a spot is used, the relevant spot index will be "removed" and if it is already out, the computer cannot use it.
/* For HashSet<Integer> object - Integer is an immutable wrapper class for int */
spotObj.add(spotLoc); // Returns falls if the spot already exists i.e. used
/* For ArrayDequeue<Integer> object */ - Implementation of Queue interface */
spotObj.remove(spotLoc); returns false if it is already removed i.e. used
Hope this helps you solve your problem
There is an easy way to improve your AI by a lot.
First: check the current state of the board and find all of the possible moves for the AI (which means: find all fields which are empty).
Second: find an opportunity to win this game which means you should simulate all of those possible moves from our first step and see if any of them lets you win the game.
-> if so: do that move!
-> if not: do a random move.
By doing this your AI would already be improved. But you can go even further by using a simple database. Keep track of all those moves your AI and the enemy does.
Whenever you find yourself from now on in a situation where you would do a random move just check your database if you ever were in this situation before and how it turned out for you. According to the outcome of the former game in your database it might be a good idea to do the same move again or try out something different (by doing a random move).
Just append every game and its outcome to this database and you will see how your AI will get better from game to game.
If you need any code-examples just let me know.
Greetings Tim

Math.random if statement error

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;
}

Having trouble with || and &&

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.

Categories

Resources