Hi I am new to Java OOP and I have some problems in running the program
The problem is there is no output and the loop never stops.
This is my Main.java
public class Main {
public static void main(String[] args) {
Dice firstDie = new Dice();
Dice secondDie = new Dice();
do {
count++;
if(firstDie==secondDie ){
same=true;
System.out.println("It took "+count+ " times " + firstDie.getValue() + " and " + secondDie.getValue());
}
}
while(!same);
}
}
and this is my Dice.java
public class Dice {
private int value;
public Dice() {
value = (int)(Math.random()*6)+1;
} public int getValue() { return value; }
}
in my Main.java class when I write int count = 0; and boolean same = false; the loop never ends.
Probably you have to compare the value firstDie.getValue() and secondDie.getValue().
What you are trying to do is compare the 2 instances of class Dice . When you compare those, unless they are the same object, it cannot be same.
Hence, same is not made true at all and this goes to a loop.
For more info, please refer, equals() method in java because that is what is called when two instances/objects are compared.
Edit:
Even if you try below code snippet of do-while (ie. compare the value firstDie.getValue() and secondDie.getValue(),
do {
count++;
int first = firstDie.getValue();
int sec = secondDie.getValue();
System.out.println(first+ " "+sec);
if(first==sec ){
same=true;
System.out.println("It took "+count+ " times " + first + " and " + sec);
}
}
while(!same);
It still goes to loop because of the fact that the value of Dice class is set only once i.e. in constructor.
So the ideal way is to write,
public Dice() {
value = 0;
} public int getValue() { return (int)(Math.random()*6)+1; }}
You are comparing the classe's instances and not the values stored within them.
Notice that on your println you are referring to each of the dices values (which is what you want to compare and have match), but on your comparison you are checking the objects.
Since they are 2 different instances they will never match, and therefore there will be no output and the loop never stops.
try firstDie.getValue() == secondDie.getValue() instead of firstDie== secondDie
You are checking for the two instances to be equal if you say firstDie== secondDie. These two are never equal.
Related
Like the caption said the method "scanInput1" runs two times in a row when it should only run once. Then the method "arrayskapare" runs as intended but after that. instead of running the method "medelvarde" is jumps back and runs "scanInput1" again and again and again
import java.util.*;
class Heltalshanterare{
private static String scanInput1(){
System.out.print("Skriv in antal heltal: ");
Scanner scr = new Scanner(System.in);
String antalHeltal = scr.next();
try {
Integer.parseInt(antalHeltal);
}
catch (NumberFormatException e) {
System.out.println("Ogilitigt värde");
scanInput1();
}
return antalHeltal;
}
private static List<Integer> arrayskapare() {
int antalangivnatal = Integer.parseInt(scanInput1());
int noll = 1;
int heltal = 0;
String tal1 = "";
Scanner tal = new Scanner(System.in);
List<Integer> list = new ArrayList<>();
while (noll <= antalangivnatal) {
noll++;
heltal++;
System.out.print("ange heltal " + heltal + ": ");
tal1 = tal.next();
try {
int num = Integer.parseInt(tal1);
list.add(num);
} catch (NumberFormatException e) {
System.out.println("Ogiltigt värde");
noll--;
heltal--;
}
}
return list;
}
public static int medelvarde(){
int antalsiffror = arrayskapare().size();
int sum = 0;
for (int i : arrayskapare()){sum += i;}
int medelvärde = sum / antalsiffror;
System.out.println("medelvärdet av dina tal är " + medelvärde);
return medelvarde();
}
public static void main(String [] args){
scanInput1();
arrayskapare();
medelvarde();
}
}
Im sorry that the code is so long but I have been struggling with this for too long and I really need some help.
Your main method is calling each method just once, which is what you need. But it's not actually holding onto any of the values being returned. So the number of heltal (integers in English) is captured from the user but then never actually stored anywhere. And later an array of numbers is captured but not stored anywhere.
Your second, bigger problem is that your methods are then calling the earlier methods all over again. So instead of asking the user to type in the data just once, you're forcing them to answer the exact same questions multiple times.
A much tidier approach is to alter your methods so that they take the required data as a parameter. Which means your arrayskapare (array producer) method should take the antalHeltal (number of integers) value as a parameter, and then it won't need to call the scanInput1 method again. Same thing can be done for your medelvarde (mean value) method: have it take the array as a method parameter, so that it won't need to call arrayskapare.
With those changes your main method can simply look like this:
public static void main(String [] args){
int antalHeltal = scanInput1();
List<Integer> heltalArray = arrayskapare(antalHeltal);
int medelvardet = medelvarde(heltalArray);
System.out.println("Medelvärdet är " + medelvardet);
}
Now each method just gets called once and the data captured from the user gets stored into variables and passed along the river of methods until the final result is reached.
I'm pretty new to java, but I'm trying to make a simulation of the finger game, 'Sticks', using my limited knowledge. This may not be the neatest, but if you're going to make a suggestion on me to do something, link a page explaining what that thing is, and I'll read it.
Ok, so the issue comes up basically when I call a method to decide who's turn it is and trying to return the value for the "count" up to 5, but it's not returning to main()
public static int TurnCalcBB(int PLH, int PRH, int BRH, int BLH, int Death)
{
//Attacking with bot Right hand
Random botAtk = new Random();
if(botAtk.nextInt(2) == 1 && PRH <= 5)
{
PRH = BRH + PRH;
JOptionPane.showMessageDialog(null,"Your right hand is now at " + PRH);
return PRH;
} else if(botAtk.nextInt(2) == 0 && PLH <= 5){
PLH = BRH + PLH;
JOptionPane.showMessageDialog(null, "Your left hand is now at " + PLH);
return PLH;
}
return Death;
}
Death is there because I was getting an error telling me that I always need to return SOMETHING so I'm returning a static value.
Basically, the problem is getting PLH (player left hand) or PRH (player right hand) to return to main. If I'm not wrong, they should return as their initial variable name (PL, and PR) with the returned value correct? If not, what can I do to fix this?
The code is a lot larger than this, and this issue is happening throughout the whole program, so I'm showing just 1 method and assuming they're all the same issue; the methods are almost all the same.
Also, while I'm typing a question already, is nextInt() the best way to do a random number generator? When I had it as nextInt(1) it was exclusively attacking the left hand, and when I switched it to nextInt(2) now it's attacking both, but occasionally the code... "crashes" (what I mean by crashes is that it generates a number outside of what the If statements are looking for). I obviously need to to generate either a 1 or a 2 (or 0 and 1 if 0 counts).
You can change your code to
public static Integer TurnCalcBB(int PLH, int PRH, int BRH, int BLH, int Death)
{
//Attacking with bot Right hand
Random botAtk = new Random();
if(botAtk.nextInt(2) == 1 && PRH <= 5)
{
PRH = BRH + PRH;
JOptionPane.showMessageDialog(null,"Your right hand is now at " + PRH);
return PRH;
} else if(botAtk.nextInt(2) == 0 && PLH <= 5){
PLH = BRH + PLH;
JOptionPane.showMessageDialog(null, "Your left hand is now at " + PLH);
return PLH;
}
return null;
}
NOTE: make sure you first check for null values where you call this function.
You are generating random number twice, this is why you can observe "strange" behvior.
Random botAtk = new Random();
if(botAtk.nextInt(2) == 1 && PRH <= 5) {
...
}
else if(botAtk.nextInt(2) == 0 && PLH <= 5) {
...
}
Try generating random only once:
Random botAtk = new Random();
boolean right = botAtk.nextInt(2) == 1; // flip coin only once
if(right && PRH <= 5) {
...
}
else if(!right && PLH <= 5) {
...
}
I know the answer will not get accepted, because there is an accepted one, but nevertheless:
I suspect that you have a wrong understanding of method parameter passing in Java.
What I read from your question and comments is that you expect this to work:
public static int psInt = 0;
static void main() {
int someNumber = 1;
int someOtherNumber = 5;
method1( someNumber, someOtherNumber );
// You expect "someNumber" to be 6 right now.
// But in fact, the value will be unchanged.
// What WILL work: psInt is 0 now
method3(); // this method will modify the static class var
// psInt is 5 now.
}
static void method1( int numParam, int someothervalue ){
numParam = numParam + someothervalue;
}
static void method2( int someNumber, int someothervalue ){
someNumber = someNumber + someothervalue; // <- same name won't work either!
}
public static void method3(){
psInt = 5;
}
But in Java method arguments are passed by value. That is: a copy!
So no matter how you name the variables and arguments, you will never have an "out" argument here.
What you can do:
In a static method, you can use and modify static class variables.
In a non-static method, you can use and modify non-static and static class variables.
You can pass a State-Object, of which you can modify field values.
You can return a value.
... there are more possibilites. These just to start with.
In your case, 4. does not make so much sense, because you wouldn't know if it is the new right or left hand value.
I am currently learning the basics of Java from a book and I've got this code as an example of Nested Loops using Recursion. I understand everything, but the usage of return function in the end of the code. I cannot figure out how the program decide, when to stop exactly when K=4. I've tried to debug it and this continued to be like a mystery for me. Here is the code :
import java.util.Scanner;
public class nestedLoops {
public static int numberOfLoops;
public static int numberOfIterations;
public static int[] loops;
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("N = ");
numberOfLoops = input.nextInt();
System.out.print("K = ");
numberOfIterations = input.nextInt();
input.close();
loops = new int[numberOfLoops];
nestedLoops(0);
}
public static void nestedLoops(int currentLoop) {
if (currentLoop == numberOfLoops) {
printLoops();
return;
}
for (int counter=1;counter<=numberOfIterations;counter++) {
loops[currentLoop] = counter;
nestedLoops(currentLoop + 1);
}
}
public static void printLoops() {
for (int i = 0; i < numberOfLoops; i++) {
System.out.printf("%d ", loops[i]);
}
System.out.println();
}
}
It would be very helpful if someone explain me how return works in this particular example in the end when numbers are "4.4" and also how it works at all in a void method, because I've been searching for explanation of that but did not succeed...
Thank you beforehand !
A return statement in a void method stops running the method and returns back to the calling code. In this example with the input:
numberOfLoops = 4
numberOfIterations = 4
Right after taking the input, you create an array based off of the input and then call the nestedLoops(0) method:
public static void nestedLoops(int currentLoop) {
if (currentLoop == numberOfLoops) {
printLoops();
return;
}
for (int counter=1;counter<=numberOfIterations;counter++) {
loops[currentLoop] = counter;
nestedLoops(currentLoop + 1);
}
}
The explanation
For starts, let's just ignore the for loop. The if statement checks to see if currentLoop == numberOfLoops and it does this every time this method is called. Right now currentLoop is 0 (the value we passed into this method when we called it) and numberOfLoops is 4 (the value we entered at the very beginning) so this is false and none of the code inside is called.
The for loop below the if statement is going to run numberOfIterations times. In our case, this loop is going to run 4 times. I will write out what happens below in sequential order:
- input is 4, 4
- nestedLoops(0) called- currentLoop = 0
- if evaluates to false
- for loop runs
- loops[0] = 1
- nestedLoops(1)
- if evaluates to false ( 1 != 4)
- for loop runs
- loops[1] = 1
- nestedLoops(2)
- if evaluates to false (2 != 4)
- for loop runs
- loops[2] = 1
- nestedLoops(3)
- if evaluates to false (3 != 4)
- for loop runs
- loops[3] = 1
- nestedLoops(4)
- if evaluates to TRUE (4 == 4)
- loops are printed (all values are 1 right now)
-returns to calling location
-Which is the for loop associated with this indention.
-For loop increments, and then sets loops[3] = 2.
- then this loop finishes
- then this loop finishes
etc. etc.
The return in a void method just means "okay, stop what you're doing and go back to who/whatever called this and move on" In this case its jumping back to previous for loop to keep working.
The for loop inside the nestedLoops method is calling itself numberOfIterations times. So it goes 0, then makes numberOfIterations calls. So if you entered 4 you would see 4 calls with currentLoop=1 then 16 calls with currentLoop=2 and so on....
When all else fails write some code to debug your code. I am a visual person myself so making some output helps when the debugger doing it for me.
public static HashMap<Integer, Integer> map = new HashMap();
public static void main(String[] args) {
....
System.out.println(map);
}
public static void nestedLoops(int currentLoop) {
if(map.containsKey(currentLoop)) {
map.put(currentLoop, map.get(currentLoop)+1);
} else {
map.put(currentLoop, 1);
}
...
}
What would be the best way for me to code the the actual attack / defend between the two characters and how would I store the health value so that re attacks could be stored until either player health or enemy health reached 0, and then declare the victor. This is my first ever attempt at any kind programming after self teaching from various sources, please also give me feed back on any improvement I could make, I'm sure there will be many.
Thank you in advance.
:-)
package test;
public class BattleClass {
public static void main(String[] args) {
PlayerStats ps = new PlayerStats();
EnemyStats es = new EnemyStats();
int eh = es.getEnemyHealth();
int ph = ps.getPlayerHealth();
ps.PlayerAttackDefend();
es.AttackDefend();
System.out.println("You chose to " + ps.getpInput() + " and rolled "
+ ps.getPlayerRoll());
System.out.println("The enemy chose to " + es.getEaod()
+ " and rolled " + es.getEnemyRoll() + ".");
if (ps.getpInput().equals("Attack")) {
if (es.getEaod().equals("Attack")) {
System.out
.println("YOUR SWORDS BOUNCE OFF EACHOUTHERS... TRY AGAIN!");
System.exit(0);
}
if (es.getEaod().equals("Defend")) {
if (ps.getPlayerRoll() > es.getEnemyRoll())
eh -= ps.getPlayerRoll() - es.getEnemyRoll();
System.out.println("Enemy Health is " + eh);
}
}
if (ps.getpInput().equals("Defend")) {
if (es.getEaod().equals("Defend")) {
System.out
.println("YOUR SHIELDS BOUNCE OFF EACHOTHERS... TRY AGAIN!");
System.exit(0);
}
}
if (es.getEaod().equals("Attack")) {
if (es.getEnemyRoll() > ps.getPlayerRoll())
ph -= es.getEnemyRoll() - ps.getPlayerRoll();
System.out.println("Your Health is " + ph);
}
}
}
package test;
import java.util.Random;
import java.util.Scanner;
public class PlayerStats {
static Scanner paod = new Scanner(System.in);
//Players initial health value.
private int playerHealth = 10;
//RNG for attack value / defence value using dice as object.
private int playerRoll = new Random().nextInt(6) + 1;
private String pInput;
//Method for selecting Attack or Defence.
public void PlayerAttackDefend() {
System.out.println("Do you want to Attack or Defend?");
System.out.println("a = Attack / d = Defend");
//Player selects attack or defend.
String userInput = paod.nextLine();
if (userInput.equals("a")) {
pInput = "Attack";
}
if (userInput.equals("d")) {
pInput = "Defend";
}
}
public static Scanner getPaod() {
return paod;
}
public int getPlayerHealth() {
return playerHealth;
}
public int getPlayerRoll() {
return playerRoll;
}
public String getpInput() {
return pInput;
}
public static void setPaod(Scanner paod) {
PlayerStats.paod = paod;
}
public void setPlayerHealth(int playerHealth) {
this.playerHealth = playerHealth;
}
public void setPlayerRoll(int playerRoll) {
this.playerRoll = playerRoll;
}
public void setpInput(String pInput) {
this.pInput = pInput;
}
}
package test;
import java.util.Random;
public class EnemyStats {
//Enemy initial health value.
private int enemyHealth = 10;
//RNG for attack value / defence value using dice as object.
private static int enemyRoll = new Random().nextInt(6) + 1;
//RNG for enemy decision to Attack or Defend.
private static int eAttackDefend = new Random().nextInt(2) + 1;
//Used for returning attack or defend string.
private static String eaod;
//Attack or Defend method.
public void AttackDefend() {
if (eAttackDefend == 1) {
eaod = "Attack";
} else {
eaod = "Defend";
}
}
public int getEnemyHealth() {
return enemyHealth;
}
public int getEnemyRoll() {
return enemyRoll;
}
public int geteAttackDefend() {
return eAttackDefend;
}
public String getEaod() {
return eaod;
}
public void setEnemyHealth(int enemyHealth) {
this.enemyHealth = enemyHealth;
}
public void setEnemyRoll(int enemyRoll) {
EnemyStats.enemyRoll = enemyRoll;
}
public void seteAttackDefend(int eAttackDefend) {
EnemyStats.eAttackDefend = eAttackDefend;
}
public void setEaod(String eaod) {
EnemyStats.eaod = eaod;
}
}
An easy way would to be to set maxHp and actualHp values, if you want to be able to "heal".
If you just decrease until one is dead, you can just decrease the actual health variable you already have.
You might wanna take a look at Inheritance in general, as you have a lot of duplicate code.
In general, just make a loop
while(ps.getHealth() > 0 && es.getHealth() > 0) {
// your battle code
}
you might want to remove the System.exit(0) calls, as they terminate the program.
Add to the player/enemy a dealDamage(int damage) method to actually be able to reduce their health
The health values should be in the objects, and you should not need to store them in your BattleClass.
I could give you the short answer but I guess you get more out of a detailed explanation :-)
You want to run your code "until either player health or enemy health reached 0" so you need a loop.
In java you have 3 kinds of loops:
The for loop
for(int i=1;i<=3;i++) System.out.println("Hello Musketeer Nr. "+i);
The most elaborate loop, the for loop consists of three parts, the initialization, the condition, and the afterthought. While the for loop can be used differently, it is mostly is used in the fashion shown here, that is, you have a counter variable whose value you need somehow.
If you don't need the counter variable value, you can use the short form with collections and arrays:
for(Person p: persons) System.out.println("Hello, "+person.getName()+"!");
The while loop
The second most commonly used (at least by me) loop, it has an initial condition and iterates, as long as it is true.
while(ph>0&&eh>0)
{
...
}
As you see, it fits your problem very well. For completeness, I will however describe the third loop which is the
do-while loop
do
{
...
}
while(ph>0&&eh>0)
You use this loop like the while loop but if you want to have at least one run through.
Other Remarks
Why have two classes PlayerStats and EnemyStats in combat system (they both seem to have the same actions and values) ? You could just have:
Stats playerStats=new Stats();
Stats enemyStats=new Stats();
Trying to add objects to a ArrayDeque at random intervals. This is what I have
for (int i = 0; i <= 100; i ++) {
if (window.isEmpty()) {
Customer customer = new Customer(r.nextInt(10)+1);
q.add(customer);
window.beginService();
}
else {
Customer customer = new Customer(r.nextInt(10)+1);
q.add(customer);
window.beginService();
totalCustomers++;
totalServiceTime += window.serviceTime;
totalWaitTime += customer.getArrivalTime();
}
}
The other methods being used are
public boolean isEmpty() {
if (serviceTime == 0) {
return true;
}
else
return false;
}
public void beginService() {
if (isEmpty()) {
serviceTime = r.nextInt(10)+1;
}
else
serviceTime += r.nextInt(10)+1;
}
public Customer(int arrivalTime) {
this.arrivalTime = arrivalTime;
}
public int getArrivalTime() {
return arrivalTime;
}
When I print out my customer count it is equal to my clock time, which should not be as customers are added at random intervals of 1-10. Any ideas?
Are you defining your "clock time" as the value of i? If so, I'm not sure why you would expect it and totalCustomers to be different.
In your for loop, you add a customer regardless of whether or not the windows is empty. After the first time around, the window will never be empty because you are always beginning service which always increments the serviceTime by at least 1.
So after the first iteration of the loop, the else branch of your if will exclusively be executed and totalCustomers will always increment alongside of i.
I think you have bigger logic gaps in your code but you haven't been very clear with how you've framed your question or shown your code. It is unclear how serviceTime is declared or what the code is supposed to be doing. You never seem to take an item off of the queue. If you need more help than this you need to put some more effort into your question.