Return Statements in a Finite State Machine - java

Could anyone tell me what purpose a return statement in a Finite State Machine's state serves? For example I have this code for a soccer player's state:
public class ChaseBall extends State<FieldPlayer> {
private static ChaseBall instance = new ChaseBall();
private ChaseBall() {
}
//this is a singleton
public static ChaseBall Instance() {
return instance;
}
#Override
public void Enter(FieldPlayer player) {
player.Steering().SeekOn();
}
}
#Override
public void Execute(FieldPlayer player) {
//if the ball is within kicking range the player changes state to KickBall.
if (player.BallWithinKickingRange() && player.isReadyForNextKick()) {
player.GetFSM().ChangeState(KickBall.Instance());
return;
}
//if the player is the closest player to the ball then he should keep
//chasing it
if (player.isClosestTeamMemberToBall()) {
player.Steering().SetTarget(player.Ball().Pos());
return;
}
//if the player is not closest to the ball anymore, he should return back
//to his home region and wait for another opportunity
player.GetFSM().ChangeState(ReturnToHomeRegion.Instance());
}
#Override
public void Exit(FieldPlayer player) {
player.Steering().SeekOff();
}
}
I was wondering if someone could explain what purpose the the return keywords in the first two if statements of the Execute() method serve?
Thanks

In this case it's mainly a formatting alternative to a series of else if clauses. It is logically equivalent to
if (<condition>) {
<code>
} else if (<condition>) {
<code>
} else {
<code>
}

Related

Import Boolean from another Class

I have a DataHolders class.
It contains:
public static boolean hit;
In my other class theres:
public void onHit(ProjectileHitEvent event) {
if (event.getHitEntity() != null || event.getHitBlock() != null) {
DataHolders.hit = true;
}
}
ProjectileHitEvent gets triggered when a Player hits something with a Projectile (Arrow)
In my last class:
public void onLaunch(ProjectileLaunchEvent event) {
while (!DataHolders.hit) {
//..............
}
}
ProjectileLaunchEvent gets triggered when a Player launches the Projectile (Arrow)
I want to do something while the Projectile (Arrow) is in the air (ProjectileLaunchEvent triggered but ProjectileHitEvent not).
But when the Arrow hits something (ProjectileHitEvent gets triggered and boolean hit becomes true) the loop should stop but the while loop goes on. I've already tested if ProjectileHitEvent really gets triggered, it works but the loop doesn't.
check if DataHolders.hit is true/false.
public void onLaunch(ProjectileLaunchEvent event) {
while (!DataHolders.hit) {
System.out.println(DataHolders.hit);
//..............
}
}
If true
You should focus on setting DataHolders.hit properly
If false
Print the value before/after setting the value
public void onHit(ProjectileHitEvent event) {
if (event.getHitEntity() != null || event.getHitBlock() != null) {
System.out.println(DataHolders.hit);
DataHolders.hit = true;
System.out.println(DataHolders.hit);
}
}
If the latter output is true then there is a problem with the class where public static boolean hit; exists.

Can you Implement a Singleton Pattern with a State Pattern

I have an application that I have been working on for a little while, I understand a little of Java.
The scope of the application is combine multiple design patterns in a way that allows reusability, which code can be edited without having to scroll through hundreds of lines of code.
I have implemented a true Singleton Player class.
I have also implemented a decorator weapon class.
I am not looking to add a state pattern for the player class, an example of this would be AliveState and DeadState. Something simple so I understand the workings of it all.
For the sake of this I will post the full PlayerSingleton class:
public class PlayerSingleton{
private static PlayerSingleton player;
Scanner scanner = new Scanner(System.in);
private String playerName;
private Integer playerHealth;
private Weapon weapon;
private PlayerSingleton(Weapon weapon, String pName, int pHealth) {
this.weapon = weapon;
playerName = pName;
playerHealth = pHealth;
}
public static Weapon chooseWeapon(String choice) {
switch (choice) {
case "MP5":
System.out.println("You have chosen MP5!");
return new MP5Weapon();
case "SNIPER":
System.out.println("You have chosen Sniper!");
return new SniperRifleWeapon();
case "SHOTGUN":
System.out.println("You have chosen Shotgun!");
return new ShotgunWeapon();
default:
System.out.println("No gun by that name found!");
return null;
}
}
public static PlayerSingleton getInstance(String choice, String name, int health) {
System.out.println("Choose Weapon to play the with: ");
Weapon weapon = PlayerSingleton.chooseWeapon(choice);
weapon.getDescription();
if (player == null) {
player = new PlayerSingleton(weapon, name, health);
}
return player;
}
public void getWeaponDamage(Weapon damage) {
System.out.println("Damage of weapon: " + weapon.damage());
}
public void attackState(double damage) {
damage = player.weapon.damage();
}
// #Override
// public void aliveState() {
// if(playerHealth >= 1){
//
// }
// }
// #Override
// public void deadState() {
// if(playerHealth ==0){
// System.out.println("You are dead");
// System.out.println("GameOver");
// }
// }
public void chosenWeapon() {
System.out.println("Player Info: " + playerName + " " + "Has: " + playerHealth + " health");
System.out.println(weapon.getDescription() + ":" + " base damage: " + weapon.damage());
}
public void addBasicAttachment(String attachment) {
switch (attachment) {
case "SIGHT":
weapon = new BasicSight(weapon);
break;
case "SILENCER":
weapon = new BasicSilencer(weapon);
break;
case "STOCK":
weapon = new BasicStock(weapon);
break;
default:
System.out.println("No Attachment found!");
}
}
I've tried to implement this with help of Head first design patterns (State) but using the Singleton Pattern on the player class means that I cannot call the object from another class.
public class DeadState implements PlayerState{
PlayerSingleton player;
public DeadState(PlayerSingleton player){
this.player = player;
}
#Override
public void deadState() {
System.out.println("You are Dead!");
}
#Override
public void aliveState() {
System.out.println("You are Dead!");
}
}
Above is a test on making a DeadState implementing from a PlayerState interface.
Is there any way to do this with separate classes using the state pattern with PlayerSingleton?
Seriously any help would be amazing!
Also if you could explain the answer so I understand better.
First of all about this sentence that you said:
using the Singleton Pattern on the player class means that I cannot call the object from another class.
Actually you can call the object from other classes, as long as you have access to the instance, and that's how state pattern works.
I took your classes and remove some code just for the sake of simplicity and explain better the solution, you can add back the parts of the code I removed if you use this solution:
I used the two states you have in your code, first this is the PlayerState interface, it has two methods, one for taking damage and other for respawning:
public interface PlayerState {
void respawn();
void takeDamage(int damage);
}
Then the implementation of Alive state has only implementation for the takeDamage method, which receives the amount of damage taken:
public class AliveState implements PlayerState {
private PlayerSingleton player;
public AliveState(PlayerSingleton player) {
this.player = player;
this.player.setHealth(PlayerSingleton.MAX_PLAYER_HEALTH);
}
#Override
public void takeDamage(int damage) {
System.out.println(String.format("Suffering %d damage!", damage));
player.setHealth(player.getHealth() - damage);
if (player.getHealth() <= 0) {
player.setLives(player.getLives() - 1);
player.setState(new DeadState(player));
}
}
#Override
public void respawn() {
System.out.println("Nothing to do, player is alive!");
}
}
Same for the implementation of the DeadState, which has only implementation for the respawn method, as long as the player has lives left:
public class DeadState implements PlayerState {
private PlayerSingleton player;
public DeadState(PlayerSingleton player) {
this.player = player;
}
#Override
public void takeDamage(int damage) {
System.out.println("Nothing to do, player is dead!");
}
#Override
public void respawn() {
if (player.getLives() > 0) {
System.out.println("respawning to start location!");
player.setState(new AliveState(player));
} else {
System.out.println("Game Over!");
}
}
}
And finally the PlayerSingleton class, which is assigned the state AliveState when the player is created, the takeDamage and respawn methods call the implementations in the current player's state, and if you noticed, the State implementations have a reference to the player's instance, so they can change the object state.
public class PlayerSingleton {
public static Integer MAX_PLAYER_HEALTH = 500;
public static Integer DEFAULT_PLAYER_LIVES = 2;
private static PlayerSingleton player;
private Integer health = MAX_PLAYER_HEALTH;
private int lives = DEFAULT_PLAYER_LIVES;
private PlayerState playerState;
private PlayerSingleton() {
setState(new AliveState(this));
}
public static PlayerSingleton getInstance() {
if (player == null) {
player = new PlayerSingleton();
}
return player;
}
public void sufferDamage(int damage) {
playerState.takeDamage(damage);
}
public void respawn(String location) {
playerState.respawn();
}
// Getters and Setters
}
I used the following main method to test:
public static void main(String[] args) {
PlayerSingleton playerSingleton = PlayerSingleton.getInstance();
playerSingleton.takeDamage(300);
playerSingleton.respawn();
playerSingleton.takeDamage(300);
playerSingleton.respawn();
playerSingleton.takeDamage(600);
playerSingleton.respawn();
}
And this was the output:
Suffering 300 damage!
Nothing to do, player is alive!
Suffering 300 damage!
Player is dead!
respawning to start location!
Suffering 600 damage!
Player is dead!
Game Over!

Boolean with multiple classes

I am trying to take a 3 class program and pass a boolean for reserving a room. I have driver program, building, room programs. I set the reserve to false and I can't figure out how to print out a text statement when it's already set to true. I think I am either doing the passing of the boolean through the classes from the driver wrong or missing something. I have played with reserveRoom in building class with an if statement to see if it's already true to print a statement and no matter which way I go it doesn't work.
Any help would be appreciated.
Thank you.
From my driver program that sends the boolean to the building program
System.out.print ("Which room would you like to reserve?");
System.out.print (building);
System.out.print ("reserve: ");
reservNum = input.nextInt();
building.reserveRoom(reserve, reservNum);
From my building class.
public void reserveRoom (boolean reserve, int count)
{
//class constant
//class variables
/*****************************************************/
room [count].updateReserve(reserve);
} // end
From the room class.
public void updateReserve(boolean newReserve)
{
//class constant
//class variables
/*****************************************************/
if (newReserve == false)
{
roomAvail = true;
}
else
{
roomAvail = false;
}
} // END
Well, there is some information missing in your question, however it think you are looking for:
public void updateReserve(boolean newReserve) {
if(newReserve && !roomAvail) {
System.out.println("Sorry this room is taken")
} else {
roomAvail = !newReserve;
}
}
With whatever i could understand about your question this is what i came up with -
public class Reservation {
public static void main(String args[]) {
Building building = new Building(20);
boolean reserve= false;
System.out.println("Which room would you like to reserve?");
System.out.println(building);
System.out.println("reserve: ");
int reservNum = 2;
building.reserveRoom(reserve, reservNum);
System.out.println("Is Reserved?:"+building.getRoom(reservNum).getRoomAvail());
}
}
class Building {
Room room[];
public Building(int numOfRooms) {
room = new Room[numOfRooms];
for(int i=0; i<numOfRooms; i++) {
room[i] = new Room();
}
}
public String toString() {
return "This Building has "+room.length+"rooms";
}
public Room getRoom(int roomNum){
return room[roomNum];
}
public void reserveRoom (boolean reserve, int count)
{
//class constant
//class variables
/*****************************************************/
room [count].updateReserve(reserve);
} // end
}
class Room {
boolean roomAvail;
public boolean getRoomAvail() {
return roomAvail;
}
public void updateReserve(boolean newReserve)
{
//class constant
//class variables
/*****************************************************/
if (newReserve == false)
{
roomAvail = true;
}
else
{
roomAvail = false;
}
} // END
}

How to set/call object and method in condition

How is it possible to set an object and method in a condition? I understand that, if the animal is over 50kg it weighs too much. But how about if an animal is hangry, need Love and feel boring return the method feelingNegative()?
I don't know how to set it. But after an animal sleeps, it is hangry. A thought would be:
Animal {
if (hangry == false && needLove == false && boring == false) {
return feelingNegative();
}
}
still don't know how to set it.
public class Animal {
private boolean needLove;
private boolean hangry;
private boolean boring;
private int kg;
public boolean sleep() {
return hangry = true;
}
public boolean watchTv() {
return needLove = true;
}
public void feelingPositive() {
System.out.println("I feel good");
}
public void feelingNeutral() {
System.out.println("Someting is missing...");
}
public void feelingNegative() {
System.out.println("I need love, food and fun!");
}
public void weight(int kg) {
if(50 < kg) {
System.out.println("You ate way too much");
}else {
System.out.println("You need to eat more");
}
}
}
The methods you are calling don't return anything (they are void). Just remove the return. And use boolean negation (!) instead of == false. Like,
if (!hangry && !needLove && !boring) {
feelingNegative();
}
The Method feelingNegative() doesn't return anything (Void). So you just have to define a method that call feelingNegative() when all the conditions are satisfied.
public void myMethod ()
{
if(!hangry && !needLove && !boring)
feelingNegative();
}

Java: Breaking Loop

What is the best way to implement the following pseudo-code in java?
method_one():
while(condition_one):
EXECUTE method_two(); // (A)
method_two():
while(condition_two):
EXECUTE method_three(); // (B)
method_three():
if (condition_three):
GOTO EXECUTE method_two();
else:
//do some stuff
Edit: Thanks for prompt replies, everybody. Helped a lot. Figured it out now.
If you don't need separate methods, this should be equivalent:
boolean exit_from_three = false;
while (condition_one || exit_from_three) {
exit_from_three = false;
while (condition_two) {
if (condition_three) {exit_from_three = true; break;}
// do some stuff
}
}
I think you could do something like:
public void method_one() {
while (condition_one) {
method_two();
}
}
public void method_two() {
while (condition_two) {
method_three();
}
}
public void method_three() {
if (condition_three) {
return;
} else {
// do something magical
}
}
Assuming I've read the pseudo-code right, it's a pretty simple case of calling methods. The only catch is that whatever represents conditions one, two, and three have to be updated somewhere or this will be an infinite loop at method_two (or method_one).
public class LoopingClass {
private void method_one() {
while(/* condition_one, where condition_one results in a boolean value */) {
method_two();
}
}
private void method_two() {
while(/* condition_two, where condition_two results in a boolean value */) {
method_three();
}
}
private void method_three() {
if(/* condition_three - where condition_three results in a boolean value */) {
return;
} else {
// other stuff here
}
}
}

Categories