Adding an int in a method and displaying it in the main - java

public class Race {
public static void main(String[] args) {
int maxSpeed = Car.getMaxSpeedForAll();
int raceLength = 1000;
Car mario = new Car(30, "Mario");
Car luigi = new Car(30, "Luigi");
while(mario.getLocation() < raceLength || luigi.getLocation() < raceLength){
mario.randomSpeedChange();
luigi.randomSpeedChange();
if (mario.getLocation() > luigi.getLocation()){
System.out.println(mario + " is in first place at " + mario.getLocation() + "!");
}
if (luigi.getLocation() > mario.getLocation()){
System.out.println(luigi + " is in first place at " + mario.getLocation() + "!");
}
if (mario.getLocation() == luigi.getLocation()){
System.out.println(mario + luigi + "are neck and neck! Who will pull ahead and take the lead?!");
}
}
}
}
import java.util.Random;
public class Car {
private int speed;
private String carName;
private int location = 0;
Random r = new Random();
private int rand;
private static int maxSpeedForAll = 120;
private static int minSpeedForAll = 0;
public Car(int speed, String name) {
this.speed = speed;
this.carName = name;
}
public int getLocation(){
return location;
}
public void setLocation(int location, int speed){
this.location += speed;
}
public static int getMaxSpeedForAll(){
return maxSpeedForAll;
}
public static void setMaxSpeedForAll(int maxSpeedForAll){
Car.maxSpeedForAll = maxSpeedForAll;
}
public static int getMinSpeedForAll(){
return minSpeedForAll;
}
public static void setMinSpeedForAll(int minSpeedForAll){
Car.minSpeedForAll = minSpeedForAll;
}
public int getSpeed(){
return speed;
}
public void setSpeed(int speed){
if(speed <= maxSpeedForAll){
this.speed = speed;
} else {
this.speed = maxSpeedForAll;
}
if(speed < minSpeedForAll){
this.speed = minSpeedForAll;
}
}
public String getName(){
return carName;
}
public void setName(String name){
this.carName = name;
}
public String toString(){
String result;
result = carName;
return result;
}
public void accelerate(int rand){
if (rand > 0){
speed += 10;
}
}
public void decelerate(int rand){
if (rand < 0){
speed += -10;
}
}
public void randomSpeedChange(){
setRand(r.nextInt(10 - -10) + -10);
}
public int getRand() {
return rand;
}
public void setRand(int rand) {
this.rand = rand;
}
}
So I am currently doing an assignment where I need to race two cars in a set race length. To determine the current position of the cars in the race, I have to add the value of the cars' positions to the value of the cars' speed, and that value has to be displayed in the main. Simple enough I suppose, but the speed of the cars are altered randomly every time the race loops on an interval of -10 to 10. I have been working on different solutions to this for a few days and I am no closer to actually making this code work how it is meant to work, and if someone could give me some pointers on what the heck I am doing wrong I would greatly appreciate it.
In summary, I am attempting to:
1) Add an integer (location) to an integer (speed) and return it to the main.
2) Change one integer (speed) by adding/subtracting randomly between -10 and 10 during every loop before adding it to the other integer (location).
I apologize in advance if this was answered somewhere already - I have searched this site high and low for a similar problem with a solution and couldn't really find any that was the same situation as my problem.

A few things for a possible result:
After the value of rand is determined, you should perform a check to see whether or not to call accelerate or decelerate. These methods should only modify the value of speed.
accelerate and decelerate should call setSpeed using the modified value of speed as an argument.
After the speed is set, setLocation should be called. If the location parameter in the setLocation method will not be used, it does not need to be listed as a formal parameter.

This line does not compile:
System.out.println(mario + luigi + "are neck and neck! Who will pull ahead and take the lead?!");
You need to use your toString() method in order to make this work. I'd also recommend adding the word "and" as well as spaces because it currently outputs "MarioLuigiare neck and neck! (etc.)"
The way your code is currently written; mario.speed and luigi.speed are never modified, keeping both at a constant speed throughout the race. You need to either call the accelerate() and decelerate() methods or include code in randomSpeedChange() to modify their speed
You also never change their location, keeping them perpetually at the starting line. You should call the setLocation() method for each after changing their speed to fix this.
I would also recommend modifying the decelerate() method to ensure speed never falls below zero, unless you intend for them to be able to go backwards (the first time I ran it after fixing the issues I mentioned above, they ended up with huge negative numbers for location).
Here are the changes I made to the code (besides adding toString() to the line mentioned at the top of my answer):
The randomSpeedChange() method:
public void randomSpeedChange(){
setRand(r.nextInt(10 - -10) + -10);
accelerate(rand);
decelerate(rand);
}
The while loop in the main method:
while(mario.getLocation() < raceLength || luigi.getLocation() < raceLength){
mario.randomSpeedChange();
mario.setLocation();
luigi.randomSpeedChange();
luigi.setLocation();
//all the if statements here
}
The setLocation() method:
public void setLocation(){
location += speed;
}
(This method worked fine, but the parameters were unnecessary.)
The decelerate() method:
public void decelerate(int rand){
if ((rand < 0) && (speed >= 10)){
speed += -10;
}
}
This ensures that speed is at least 10 before reducing it, to make sure that it never falls below 0.

It seems you don't change speed and location in the loop block. I guess this maybe what you need:
Main class:
public class Race {
public static void main(String[] args) {
int maxSpeed = Car.getMaxSpeedForAll();
int raceLength = 1000;
Car mario = new Car(30, "Mario");
Car luigi = new Car(30, "Luigi");
while(mario.getLocation() < raceLength || luigi.getLocation() < raceLength){
if (mario.getLocation() > luigi.getLocation()){
System.out.println(mario + " is in first place at " + mario.getLocation() + "!");
}
if (luigi.getLocation() > mario.getLocation()){
System.out.println(luigi + " is in first place at " + mario.getLocation() + "!");
}
if (mario.getLocation() == luigi.getLocation()){
System.out.println(mario.getName() + luigi.getName() + "are neck and neck! Who will pull ahead and take the lead?!");
}
//change the speed randomly
mario.randomSpeedChange();
luigi.randomSpeedChange();
//change the location according to speed
mario.setLocation(mario.getLocation(), mario.getSpeed());
luigi.setLocation(luigi.getLocation(), luigi.getSpeed());
}
}
}
Car class:
import java.util.Random;
public class Car {
private int speed;
private String carName;
private int location = 0;
Random r = new Random();
private int rand;
private static int maxSpeedForAll = 120;
private static int minSpeedForAll = 0;
public Car(int speed, String name) {
this.speed = speed;
this.carName = name;
}
public int getLocation(){
return location;
}
public void setLocation(int location, int speed){
this.location += speed;
}
public static int getMaxSpeedForAll(){
return maxSpeedForAll;
}
public static void setMaxSpeedForAll(int maxSpeedForAll){
Car.maxSpeedForAll = maxSpeedForAll;
}
public static int getMinSpeedForAll(){
return minSpeedForAll;
}
public static void setMinSpeedForAll(int minSpeedForAll){
Car.minSpeedForAll = minSpeedForAll;
}
public int getSpeed(){
return speed;
}
public void setSpeed(int speed){
if(speed <= maxSpeedForAll){
this.speed = speed;
} else {
this.speed = maxSpeedForAll;
}
if(speed < minSpeedForAll){
this.speed = minSpeedForAll;
}
}
public String getName(){
return carName;
}
public void setName(String name){
this.carName = name;
}
public String toString(){
String result;
result = carName;
return result;
}
public void accelerate(int rand){
if (rand > 0){
speed += 10;
}
}
public void decelerate(int rand){
if (rand < 0){
speed += -10;
}
}
public void changeSpeed(int rand) {
if (rand > 0){
speed += 10;
}
if (rand < 0){
speed += -10;
}
}
public void randomSpeedChange(){
setRand(r.nextInt(10 - -10) + -10);
changeSpeed(rand);
}
public int getRand() {
return rand;
}
public void setRand(int rand) {
this.rand = rand;
}
}

Related

Selecting Random Method From Multiple Methods

I am trying to select a random method from the ones created inside the class. Is there a way to create an ArrayList and pass methods to it? I have attempted to do just that but I am getting an error when I try to add the method to the array.
public class Monkey{
private int energy;
String[] food = {"Meat", "Fish", "Bugs", "Grain"};
ArrayList<Activity> monkeyActivity = new ArrayList<>();
public Monkey(int energy) {
this.energy = energy;
}
public int getEnergy() {
System.out.println("Monkey energy level: " + energy);
return energy;
}
public void sound() {
System.out.println("Monkey: Oooo Oooo~!");
energy -= 3;
monkeyActivity.add(sound()); //I get an error message here when trying
//to add the method to the array
}
public void play(){
if (energy >= 8){
System.out.println("Monkey begins to play.");
energy -= 8;
}else {
System.out.println("Monkey does not have enough energy to play");
}
System.out.println("Energy remaining: " + energy);
}
public void eat(){
Random random = new Random();
int index = random.nextInt(food.length);
System.out.println("Monkey beings to eat " + food[index]);
energy += 5;
System.out.println("Energy remaining: " + energy);
}
public void sleep(){
System.out.println("Monkey is sleeping: Zzz...");
energy += 10;
System.out.println("Energy remaining: " + energy);
}
}
This is the separate class I have made for the generic Activity..
public class Activity {
private String sleep;
private String eat;
private String sound;
private String play;
public Activity(String sleep, String eat, String sound, String play) {
this.sleep = sleep;
this.eat = eat;
this.sound = sound;
this.play = play;
}
public String getSleep() {
return sleep;
}
public String getEat() {
return eat;
}
public String getSound() {
return sound;
}
public String getPlay() {
return play;
}
public void setSleep(String sleep) {
this.sleep = sleep;
}
public void setEat(String eat) {
this.eat = eat;
}
public void setSound(String sound) {
this.sound = sound;
}
public void setPlay(String play) {
this.play = play;
}
}
You are mixing up concepts.
technical issues:
return value clash
public void sound() {
// ...
monkeyActivity.add(sound());
The return value of your method sound() is void (which means no return value), but you try to add its (not existing) return value as element to the List. This is what your compiler complains about.
unintended recursion
public void sound() {
System.out.println("Monkey: Oooo Oooo~!");
energy -= 3;
monkeyActivity.add(sound());
In the last line you do a recursive call which means you call exactly the same method this code is in. If that happens unintended it almost ever results in a StackOverflowError.
writing classes without proper analysis
You have a class Activity.
But if you have a closer look this is not a single activity (as the classes name implies) but it is all possible activities.
As a result your collection monkeyActivity cannot hold single activities as elements.
Doing a wild guess I think what you wanted is more like this:
interface Activity{
void do();
}
public class Monkey{
private int energy;
String[] food = {"Meat", "Fish", "Bugs", "Grain"};
List<Activity> monkeyActivity = new ArrayList<>();
// ...
public void sound() {
monkeyActivity.add(new Activity(){
public void do(){
System.out.println("Monkey: Oooo Oooo~!");
energy -= 3;
}
});
}
You may store each method as Runnable, as any "action" is no-arg void method satisfying Runnable functional interface:
List<Runnable> actions = Arrays.asList(this::sound, this::play, this::eat, this::sleep);
to execute random method, just:
Random rnd = new Random();
actions.get(rnd.nextInt(actions.size())).run();

Player class winning percentage java

I am trying to create a method for " winning percentage " in a player class. I know I need to incorporate total wins divided by total games played, but the code is meant to be simple so I cannot use complex code. (beginner project in computer science) Any useful feedback would be great as I have spent multiple days attempting this and getting no where. By the way, ties count as half a win.
Update: Implemented the getters into the getWinningPercentage method. Also calculated everything inside the getWinningPercentage and removed the setWinningPercentage considering it was useless code. Results were as follows:
Bob
5 wins, 1 losses, 2 ties
Winning percentage = 0.75
public class Player
{
private int numWins = 0;
private int numTies = 0;
private int numLosses = 0;
private String name;
public void setWins(int w)
{
numWins = w;
}
public int getWins()
{
return numWins;
}
public void setTies(int t)
{
numTies = t;
}
public int getTies()
{
return numTies;
}
public void setLosses(int L)
{
numLosses = L;
}
public int getLosses()
{
return numLosses;
}
public void setName(String n)
{
name = n;
}
public String getName()
{
return name;
}
public void incrementWins()
}
numWins++;
}
public void incrementTies()
{
numTies++;
}
public void incrementLosses()
{
numLosses++;
}
public double getWinningPercentage()
{
double totalGames = getWins() + getTies() + getLosses();
double totalWins = getWins() + (getTies() / 2.0);
double winningPercentage = (totalWins / totalGames);
return winningPercentage;
}
}
The winning percentage should be a calculated property, not a field, and not have a setter method. Instead there should only be a "getter" (public double getWinningPercentage()) method and you should calculate and return this value from within the method itself from the other fields that your class already has.
We should leave it up to you to create this method and formula yourself.

Calling the same method multiple times without overwriting previous values

Apologies if this is trivial to most but I just can't figure this issue out!!
I am creating a mock game where I have a start, end, and hops along. There are portals where if you go on a white portal you jump further ahead and there are black ones where you go backwards. I have set up the class as a POJO;
private int totalSize;
private int minDice;
private int maxDice;
private int whitePortalStart;
private int whitePortalEnd;
private int blackPortalStart;
private int blackPortalEnd;
private int startPosition = 1;
private int currentPosition;
public GameObject(){}
public int getTotalSize() {
return totalSize;
}
public void setTotalSize(int totalSize) throws Exception {
if(totalSize <= 0){
throw new Exception("Can't have a total distance of less than or equal to 0");
} else {
this.totalSize = totalSize;
}
}
public int getMinDice() {
return minDice;
}
public void setMinDice(int minDice) throws Exception {
if(minDice <= 0){
throw new Exception("Can't have a min dice value of less than or equal to 0");
} else {
this.minDice = minDice;
}
}
public int getMaxDice() {
return maxDice;
}
public void setMaxDice(int maxDice) throws Exception {
if(getMinDice() > maxDice){
throw new Exception("Cant have minimum dice number greater than the larger dice number");
} else {
this.maxDice = maxDice;
}
}
public int getWhitePortalStart() {
return whitePortalStart;
}
public void setWhitePortalStart(int whitePortalStart) throws Exception {
this.whitePortalStart = whitePortalStart;
}
public int getWhitePortalEnd() {
return whitePortalEnd;
}
public void setWhitePortalEnd(int whitePortalEnd) throws Exception {
this.whitePortalEnd = whitePortalEnd;
}
public int getBlackPortalStart() {
return blackPortalStart;
}
public void setBlackPortalStart(int blackPortalStart) throws Exception {
this.blackPortalStart = blackPortalStart;
}
public int getBlackPortalEnd() {
return blackPortalEnd;
}
public void setBlackPortalEnd(int blackPortalEnd) throws Exception {
this.blackPortalEnd = blackPortalEnd;
}
public GameObject builder(int n) throws Exception {
setTotalSize(n);
return this;
}
public GameObject whitePortal(int m, int o) throws Exception {
setWhitePortalStart(m);
setWhitePortalEnd(o);
return this;
}
public GameObject blackPortal(int o, int m) throws Exception {
setBlackPortalStart(o);
setBlackPortalEnd(m);
return this;
}
public GameObject dice(int i, int j) throws Exception {
setMinDice(i);
setMaxDice(j);
return this;
}
public int rollDice(){
Random random = new Random();
int min = getMinDice();
int max = getMaxDice();
return random.nextInt(max - min + 1) + min;
}
public void build(){
int totalDistance = getTotalSize();
currentPosition = startPosition;
while(currentPosition < totalDistance){
int diceValue = rollDice();
if(currentPosition + diceValue > getTotalSize()){
System.out.println("CurrentPosition : " + (currentPosition + diceValue) + ", is larger than the total size of the road - " + totalSize);
continue;
} else if(currentPosition + diceValue == getWhitePortalStart()){
System.out.println("You landed on a white portal. Advancing from position " + (currentPosition + diceValue) + " to " + getWhitePortalEnd());
currentPosition = getWhitePortalEnd();
} else if(currentPosition + diceValue == getBlackPortalStart()){
System.out.println("You landed on a black portal. Moving from position " + (currentPosition + diceValue) + " to " + getBlackPortalEnd());
currentPosition = getBlackPortalEnd();
} else {
System.out.println("You landed on " + (currentPosition + diceValue));
currentPosition += diceValue;
}
}
}
So in my main method I call the it like create and call this class like;
WorldOfOz oz = new WorldOfOz();
oz.go.builder(30)
.dice(1, 4)
.whitePortal(5, 12)
.blackPortal(13, 2)
.build();
My issue is when I want to add in more than 1 whitePortal/blackPortal
WorldOfOz oz = new WorldOfOz();
oz.go.builder(30)
.dice(1, 4)
.whitePortal(5, 12)
.whitePortal(18, 26)
.blackPortal(13, 2)
.build();
The values 18 - 26 override 5 - 12. How can I set this up so I can have multiple white and black portals?
It seems that your data structure is not enough to solve this problem.
You need to define a collection of whitePortals and a collection of blackPortals. If you do so calling the method whitePortal(5, 12) add a new white portal insted of setting the white portal values of the only white existing portal.
You need to define a class Portal
public class Portal {
private int portalStart;
private int portalEnd;
...
public Portal(int s, int e) {
this.portalStart = s;
this.portalEnd = e;
}
}
Then you can use it in the GameObject as follow:
public GameObject {
List<Portal> whitePortals;
List<Portal> blackPortals;
public GameObject() {
whitePortals = new ArrayList<Portal>();
blackPortals = new ArrayList<Portal>();
}
public GameObject addWhitePortal(int m, int o) throws Exception {
whitePortals.add(new Portal(m, o));
return this;
}
...
// You need to change other methods to follow a different data structure
}
Well, you can use the following approach:
Introduce a new "Portal" type with start/end attributes
Replace white/black portal attributes in your class with lists for white and black portals (or any other type of collection you like)
Replace getWhite/Black methods with access to lists
Refactor whitePortal and blackPortal method to create new instances of a portal object and add them to an appropriate collection
You can, of course, use arrays instead of collections, but that's a bit more cumbersome.
Also, assuming portals are collections, you probably need to add helper methods for operating on those. Depending on what your actual needs are.
public class Portal
{
private int start;
private int end;
public Portal(int start, int end) { ... }
public getStart() {...}
public getEnd() {...}
public setStart(int end) {...}
public setEnd(int start) {...}
}
public class GameObject
{
...
private List<Portal> whitePortals = new ArrayList<Portal>();
private List<Portal> blackPortals = new ArrayList<Portal>();
...
public GameObject whitePortal(int m, int o) throws Exception {
whitePortals.add(new Portal(m, o));
return this;
}
public GameObject blackPortal(int o, int m) throws Exception {
blackPortals.add(new Portal(m, o));
return this;
}
...
}

javafx: How to monitor state change of a variable that has more than 2 states?

I have a variable money of type double. I want this variable to have 3 states like this:
double money = something;
public int getMoneyState(){
if (money > 0){
return 1;
} else if(money == 0){
return 0;
} else{
return -1;
}
}
Problem is: I only know how to formulate this problem in the most conventional way, that is without using any javafx libraries / functions.
Eventually, I want to have a tableView where one of the columns will display the money variable, and its font color will change depending on the state of this variable, i.e. if after editing the cell, money = 100, the state will be 1 and font color is yellow. If after editing the cell, money = 0, the state will be 0 and font color is grey.And if after editing the cell, money = -555, the state will be -1 and font color is Green.
What I am looking for: I want to be able to track the money variable as well as its state and any changes in state. By that, I mean a change in the money variable will lead to a change in the state by using a method similar to getMoneyState() above. And depending on the state of the variable, the cell's font color will change.
I need help re-writing getMoneyState() method such that the state will automatically be updated after the user edits the money cell.
Hope this makes more sense.
Assuming you have money represented as a DoubleProperty:
DoubleProperty money = new SimpleDoubleProperty();
for example, you can do
IntegerBinding moneyState = Bindings.createIntegerBinding(() -> {
if (money.get() > 0) {
return 1 ;
} else if (money.get() == 0) {
return 0 ;
} else {
return -1 ;
}
}, money);
The two arguments to createIntegerBinding are a function returning an Integer, and a list of other observables on which the binding depends (here there is only one, money).
Now you can add listeners to moneyState or bind to it in the usual way.
If money is a property in some bean, then you can expose moneyState as a ReadOnlyIntegerProperty in a similar way:
public class MyEntity {
private final DoubleProperty money = new SimpleDoubleProperty();
public DoubleProperty moneyProperty() {
return money ;
}
public final double getMoney() {
return moneyProperty().get();
}
public final void setMoney(double money) {
moneyProperty().set(money);
}
private final ReadOnlyIntegerWrapper moneyState = new ReadOnlyIntegerWrapper();
public ReadOnlyIntegerProperty moneyStateProperty() {
return moneyState.getReadOnlyProperty();
}
public int getMoneyState() {
return moneyStateProperty().get();
}
private IntegerBinding moneyStateBinding ;
public MyEntity(double money) {
setMoney(money) ;
moneyStateBinding = Bindings.createIntegerBinding(() -> {
if (getMoney() > 0) {
return 1 ;
} else if (getMoney() == 0) {
return 0 ;
} else {
return -1 ;
}
}, moneyProperty());
moneyState.bind(moneyStateBinding);
}
}
A couple of other options. First note that your logic is already implemented by Math.signum(), so you can do:
IntegerBinding moneyState = Bindings.createIntegerBinding(() ->
(int) Math.signum(money.get()), money);
You can also implement it with the fluent Bindings API:
IntegerBinding moneyState = Bindings.when(money.greaterThan(0)).then(1)
.otherwise(Bindings.when(money.isEqualTo(0)).then(0).otherwise(-1));
You could create and Observer and make a MoneyClass, which inherits the Observable Class for example. You could then track any changes to the Money and it´s state made
The result could be looking like this
// Money class
import java.util.Observable;
public class MoneyClass extends Observable{
private double money = 0;
private int state = 0;
public static final int POSITIV = 1;
public static final int ZERO = 0;
public static final int NEGATIV = -1;
public int getMoneyState(){
if (money > 0){
return MoneyClass.POSITIV;
} else if(money == 0){
return MoneyClass.ZERO;
} else{
return MoneyClass.NEGATIV;
}
}
public void setMoney(int money) {
this.money = money;
setChanged();
notifyObservers("Money");
setMoneyState();
}
public double getMoney() {
return money;
}
public int getState() {
return state;
}
private void setMoneyState() {
if (state != getMoneyState()) {
state = getMoneyState();
setChanged();
notifyObservers("State");
}
}
public static void main(String[] args) {
}
}
//Observer
import java.util.Observable;
import java.util.Observer;
public class MoneyObserver implements Observer{
public void addObserving(MoneyClass money) {
money.addObserver(this);
}
#Override
public void update(Observable o, Object arg) {
if(arg instanceof String) {
String type = (String) arg;
if(type.equals("Money")) {
System.out.println("Money got changed to " + ((MoneyClass)o).getMoney());
} else if(type.equals("State")) {
System.out.println("State got changed to " + ((MoneyClass)o).getState());
}
}
}
public static void main(String[] args) {
MoneyObserver o = new MoneyObserver();
MoneyClass c = new MoneyClass();
o.addObserving(c);
c.setMoney(20);
c.setMoney(50);
c.setMoney(-30);
}
}

Logic or Syntax Error Issue (In a VERY primitive turn based simiulation *EDITED*)

So I have a driver and entity class that simulates two "water balloon fighters". It is supposed to output the "fighter's" "dryness level" and then have both fighters try and attack each other until their dryness level is depleted. This all done in a loop within the driver class. It works and runs properly (as in java isn't complaining), but every time I run it I get very abnormal results. Such that after displaying the starting dryness level both of my fighter objects seem to be mimicking each others dryness level, despite if they hit or miss their attack. Here is an output example:
Round 1
Sub-Zero is Dry
Scorpion is Dry
Sub-Zero Lands a hit!
Scorpion attacks!
Round 2
Sub-Zero is Dry
Scorpion is Dry
Sub-Zero Lands a hit!
Scorpion attacks!
Round 3
Sub-Zero is Dry
Scorpion is Dry
Sub-Zero Lands a hit!
Scorpion attacks!
(Skipping a few for the sake of brevity)
Round 6
Sub-Zero is Damp, but hanging in there
Scorpion is Damp, but hanging in there
Sub-Zero Lands a hit!
Scorpion's attack failed
Round 7
Sub-Zero is Soggy and feeling heavy.
Scorpion is Soggy and feeling heavy.
Scorpion attacks!
Here is my Entity Class
public class WaterBalloonFighter {
private String combatantName;
private static double accuracy;
private static double dodge;
private static int dryness;
public static final double MIN_ACCURACY = 0.0;
public static final double MIN_DODGE = 0.0;
public static final double MAX_ACCURACY = 0.5;
public static final double MAX_DODGE = 0.5;
public static final double BASE_HIT_CHANCE = 0.5;
public static final double GUARANTEED_MISS = 0.05;
public static final double GUARANTEED_HIT = 0.95;
public static final int MIN_DRYNESS = 0;
public static final int MAX_DRYNESS = 5;
WaterBalloonFighter() {
combatantName = "";
accuracy = MIN_ACCURACY;
dodge = MIN_DODGE;
dryness = MAX_DRYNESS;
}
public void setName(String newName) {
combatantName = newName;
}
public void setAccuracy(double newAccuracy) {
if ((newAccuracy >= MIN_ACCURACY) && (newAccuracy <= MAX_ACCURACY)) {
accuracy = newAccuracy;
}
}
public void setDodge(double newDodge) {
if ((newDodge >= MIN_DODGE) && (newDodge <= MAX_DODGE)) {
dodge = newDodge;
}
}
public void setDryness(int newDryness) {
if ((newDryness >= MIN_DRYNESS) && (newDryness <= MAX_DRYNESS)) {
dryness = newDryness;
}
}
public String getName() {
return combatantName;
}
public double getAccuracy() {
return accuracy;
}
public double getDodge() {
return dodge;
}
public int getDryness() {
return dryness;
}
public void randomizeSkills() {
accuracy = Math.random() * MAX_ACCURACY;
dodge = Math.random() * MAX_DODGE;
}
public String getDrynessLabel() {
if (dryness == 5) {
return combatantName + " is Dry";
} else if (dryness == 4) {
return combatantName + " is Humid, yet not phased.";
} else if (dryness == 3) {
return combatantName + " is Damp, but hanging in there";
} else if (dryness == 2) {
return combatantName + " is Soggy and feeling heavy.";
} else if (dryness == 1) {
return combatantName + " is Wet...Will they make a comeback!?";
} else {
return combatantName + " is Soaked to the bone!";
}
}
public void getHit() {
dryness = dryness - 1;
if (dryness == 0) {
dryness = MIN_DRYNESS;
}
}
public boolean attack(WaterBalloonFighter enemy) {
double x = Math.random();
if (x < GUARANTEED_MISS) {
return false;
} else if (x > GUARANTEED_HIT) {
enemy.getHit();
return true;
} else if (((x + getAccuracy()) - enemy.getDodge()) > BASE_HIT_CHANCE) {
enemy.getHit();
return true;
}
return true;
}
public boolean isSoaked() {
if (dryness == MIN_DRYNESS) {
return true;
} else if (dryness < MIN_DRYNESS) {
return false;
}
return true;
}
}
And Here is the Driver
public class Project4 {
public static void main(String[] args) {
WaterBalloonFighter combatant1 = new WaterBalloonFighter();
WaterBalloonFighter combatant2 = new WaterBalloonFighter();
combatant1.setName("Sub-Zero");
combatant2.setName("Scorpion");
combatant1.randomizeSkills();
combatant2.randomizeSkills();
int r = 0;
do {
System.out.println("Round " + (r += 1));
System.out.println(combatant1.getDrynessLabel());
System.out.println(combatant2.getDrynessLabel());
combatant1.attack(combatant2);
combatant2.attack(combatant1);
if (combatant1.attack(combatant2) == false) {
System.out.println("Sub-Zero Misses");
} else if (combatant1.attack(combatant2)== true)
System.out.println("Sub-Zero Lands a hit!");
if (combatant2.attack(combatant1)== false){
System.out.println("Scorpion's attack failed");
}else if (combatant2.attack(combatant1)== true){
System.out.println("Scorpion attacks!");
}
System.out.println("");
} while ((combatant1.getDryness() > 0) || (combatant2.getDryness() > 0));
if (combatant1.isSoaked() == true) {
System.out.println("Fatality! Sub-Zero Wins!");
} else if (combatant2.isSoaked() == true) {
System.out.println("Fatality! Scorpion Wins!");
}
}
}
Its more than likely a very simplistic problem I am looking over due to my novice programming skills, but I have looked over it for a good couple hours now, tweaking a few things here and there. So I am not sure exactly what is going awry, but I feel like it is somewhere either in my do-while or in the last few methods of my entity class. Possibly both. If anyone could lend my a second pair of eyes to spot my problem I would be greatly appreciative.
If you declare a variable as static, it is a class variable, i.e., it only exists once for the whole class. All instances access and change the same variable.
So remove the static keyword from the variables accuracy, dodge, dryness that are intended to be one-per-instance.

Categories