Reset each variable in java - java

Is there a way to reset a value of a static variable to their initial state? For example:
I have a lot of variables which holds score, speed, etc. All those variables are changing during the program execution. So when the user fails in a game, I would like to reset ALL variables to their initial state. Is there some way? Because i don't know if it is a good idea to do this manually for EACH variable in my program. for example:
static int SCORE = 0;
static float SPEED = 2.3f;
public void resetGame() {
SCORE = 0;
SPEED = 2.3;
}

Use an object, and set its initial state in the constructor:
public class GameSettings {
private int score = 0;
private float speed = 2.3F;
// methods omitted for brevity
}
...
public void resetGame() {
gameSettings = new GameSettings();
}
Also, please respect the Java naming conventions. ALL_CAPS is reserved for constants. Variables should be lowerCase.

Store the default values.
static final int DEFAULT_SCORE = 0;
static final float DEFAULT_SPEED =2.3;
static int SCORE = DEFAULT_SCORE;
static float SPEED = DEFAULT_SPEED;
public static void resetGame() {
SCORE = DEFAULT_SCORE;
SPEED = DEFAULT_SPEED;
}

Why not just recreate the object if you want it reset? Then it'll implicitly have the default values.

You could just declare your variables without values and have a method initGamestate() which sets all variables to their initial values. Call this function both on initialization of the application and when the user starts a new game.
A more object-oriented solution would be to have a class GameState which has all these variables and sets the default in its constructor. You then start every game by initializing a fresh object with new GameState();

You'll just have to reset them one by one. If you're worried about typos you could do: int initialscore = 0; int score = initialscore; and then reset them to the initial... variables in your function.

I have a lot of variables which holds score, speed, etc
You should put them all into one class and every member get initialsed (if the default won't work).
You will hold the player's state in one reference to an object of this class. To reset simply create a new object of this class and assign it to the reference.

Usually games use more than one thread (for example when using Swing or painting any graphics), e.g. so inputs are not blocked. That means with all the other solutions you might run into race conditions. This solution of Evan Knowles came closest.
I would suggest a immutable GameState class, e.g.
public GameState {
private final int score;
private final int speed;
// initial state/"reset game"
public GameState() {
score = 0;
speed = 2.3;
}
// Private so we are always in a valid state
private GameState(int _score, int _speed) {
score = _score;
speed = _speed;
}
public GameState updateSpeed(int _speed) { return new GameState(this.score, _speed); }
public GameState updateScore(int _score) { return new GameState(_score, this.speed); }
public int getSpeed() { return speed;}
public int getScore() { return score;}
// add getters, setters and whatsoever here. But watch for proper synchronization between threads!
}
The advantage here is that once the values are assigned, they can't be changed anymore ("immutable"/read-only) from the outside, so there are no concurrency issues. Plus, you get a sort of chaing for free (see below)! Moreover, you can safely (de-)serialize the game state for saving/loading games.
Effectively, each GameState represents one state in a finite state machine. Calling either updateSpeed or updateScore is a transition to a new state.
The public default constructor is a transition to the initial state of the state machine.
On a side note, the state machine is finite because the value ranges of score and speed are finite, thus all combiniations of them result in a finite amount of states.
I now assume your class for doing other game stuff is called Game.
public Game {
private volatile GameState gameState = new GameState();
public void resetGame() {
gameState = new GameState();
}
// Just an example
public increaseSpeed(int _additionalSpeed) {
gameState = gameState.updateSpeed(gameState.getSpeed() + _additionalSpeed);
}
// Change more than one value
public changeBoth(int _newSpeed, int _newScore) {
// First way: Create a new GameState, change both values step by step and then assign afterwards.
GameState _newState = gameState.updateScore(_newScore);
// other computations follow
// Do NOT assign to gameSpate here, because the state would be inconsistent then.
_newState = _newState.updateSpeed(_newSpeed);
// At the END of the method, assign the new game state. That ensures that the state is always valid
gameState = _newState;
// Second way: Use method chaining if you don't need to make other computations in between. Again, do this at the end of the method
gameState = gameState.updateScore(_newScore).updateSpeed(_newSpeed);
}
}
The volatile keyword makes sure every thread sees the same value of the gameState variable. You might want to consider using other synchronization/locking techniques instead, too. Alternatively you can make the gameState field static and skip the volatile keyword if you only have one Game object.
Because GameState is immutable(read-only), the state of your game now is always consistent/valid.

A good way is to use a static init() and call it when exception occurs.
package com.kvvssut.misc;
public class ResetStatic {
private static int SCORE = 0;
private static float SPEED = 2.3f;
private static void init() {
SCORE = 0;
SPEED = 2.3f;
}
public static void main(String[] args) {
SCORE = 100;
SPEED = 230.3f;
try {
throw new RuntimeException();
} catch (Exception e) {
init();
}
System.out.println(SCORE);
System.out.println(SPEED);
}
}

Related

Card - Deck - Hand Java Project

I know everyone gets skeptical whenever people put homework on here but I've run out of options and could really use some direction. I have a project where I have to create a deck of cards and allow the user to pick the size of the hand and then fill that hand with random cards and display that to the user. I've found plenty of answers using ArrayLists but mine requires an array and I've tried everything I know and my code is either completely wrong or throws a bunch of errors.
So here are the problems I have:
1) The addCard method in the Hand class can be used to add one Card object at a time to the hand array until it is full. It should increment the cardsInHand counter each time a Card object is added to the Hand as long as there is room for the Card to fit into the Hand.
Here is the code for the Hand class:
public class Hand
{
private int handSize; //Holds the size of the hand
private int cardsInHand; //Holds the number of cards allowed in the hand
private Card[] hand; //Array of card objects
public Hand()
{
this.handSize = 5;
this.cardsInHand = 0;
this.hand = new Card[52];
}//end Default Constructor
public Hand(int handSize)
{
this.handSize = handSize;
}//end Parameterized Constructor
public Hand(Hand handIn)
{
this.handSize = handIn.handSize;
this.cardsInHand = handIn.cardsInHand;
this.hand = handIn.hand;
}//end Copy Constructor
public void addCard(Card card)
{
hand[card]; //--> throws a type mismatch exception (change card param to an int)
}//end addCard()
public int getHandSize()
{
return handSize;
}
public void setHandSize(int handSize)
{
this.handSize = handSize;
}
public int getCardsInHand()
{
return cardsInHand;
}
public void setCardsInHand(int cardsInHand)
{
this.cardsInHand = cardsInHand;
}
public Card[] getHand()
{
return hand;
}
public void setHand(Card[] hand)
{
this.hand = hand;
}
public String toString()
{
String msg = "";
return msg;
}//end toString()
}//end class
My addCard method is just all janky and I could really use some help trying to fill it so my program works. Any help or even a pointing in the right direction would be appreciated!
My addCard method is just all janky and I could really use some help trying to fill it so my program works. Any help or even a pointing in the right direction would be appreciated
Sometimes the best thing to do is stop, turn the screen off, get a pen and piece of paper and just nut it out without any code. Try to understand the problem and get the logic straight in your head.
Basically, you have a series of buckets into which you can put a Card. Before you can put a Card in a bucket, you need to know if you have any free buckets available.
If there are, you need to add the Card to the next available bucket (which should be pointed to by cardsInHand) and increment cardsInHand
Your error is because you're trying reference a "bucket" using a Card, but you can only reference a "bucket" by an index (number) so...
hand[card];
should be more like...
hand[cardsInHand] = card;
but only after you've determined if there is a free "bucket" available, and you should increment cardsInHand AFTER this statement
I'd also be worried about your constructors
public Hand(int handSize)
{
this.handSize = handSize;
}//end Parameterized Constructor
isn't initialising hand, so that's going to be null. A better solution might be to use existing constructors where possible to build a common "initialisation" path
public Hand() {
this(5);
}//end Default Constructor
public Hand(int handSize) {
this.handSize = handSize;
this.cardsInHand = cardsInHand;
this.hand = new Card[handSize];
}//end Parameterized Constructor
Also
public Hand(Hand handIn)
{
this.handSize = handIn.handSize;
this.cardsInHand = handIn.cardsInHand;
this.hand = handIn.hand;
}//end Copy Constructor
is worrying, as it's possible for some external class to make a change to handIn's hand and that change will be reflected by this instance as well (as they are pointing to the same array).
A "copy" constructor should be making a "copy" of the data. Realistically, this should probably be a "deep" copy, so any changes to Card don't mess with the Hand as well, but I'll start with a simple "shallow" copy to get you started
public Hand(Hand handIn) {
this.handSize = handIn.handSize;
this.cardsInHand = 0;
this.hand = new Card[this.handSize];
// Yes, I know there is a better way to do this, but
// I want the OP to learn something
for (int index = 0; index < handIn.hand.length; index++) {
Card card = handIn.hand[index];
if (card != null) {
hand[cardsInHand] = card;
cardsInHand++;
}
}
}//end Copy Constructor
#MadProgrammer already give better answer, I only want to chime a little. Knowing the OP project assignment using Java I want to comment a little about the Hand class design.
The task clearly said that user can pick hand with custom size, then the user will add card into the hand until the hand is full. Thus, I would propose the Hand class design like below.
public class Hand {
private int size; // Hold the amount of card can be hold by hand.
private int counter; // Count how many card added.
private Card[] cards; // The card on hand.
public Hand(int size) {
this.counter = 0;
this.size = size;
this.cards = new Card[size];
}
public void addCard(Card card) {
if (this.counter > this.size) {
throw new IllegalStateArgument("The hand is full of card!");
}
this.cards[this.counter] = card;
this.counter++;
}
public String show() {
StringBuilder result = new StringBuilder("The card on hand is: \n");
for (int i=0; i<this.size; i++) {
result.append(this.cards[i].toString()).append("\n");
}
return result.toString();
}
}
In my opinion the Hand class more easy to understand and achieve the goals of the Hand purpose from the task. However, just use this as reference and write code that you understand well.

code block getting executed twice in a single threaded program

In my below program i observe that the value of score variable is twice(999000 instead of 499500) it's expected value. Closer look at it suggests that the computation is done twice even though the flag gets set to true after the first invocation. Any idea what is going wrong here? The program is single threaded. Actual computation involves invoking a rest API, but for testing purpose i have removed it.
public class DataClient {
public static void main(String[] args) {
System.out.println(CalculationCache.getScore());
}
}
class CalculationCache{
static{
computeScore();
}
private static int score;
public static int getScore() {
computeScore();
return score;
}
private static boolean flag=false;
static void computeScore(){
if(!flag) {
//calculate the score
for (int i = 0; i < 1000; i++) {
score = score + i;
flag = true;
}
}
}
}
The issue is due to the ordering of class initialization. The static initializers are executed in the order they are defined. The variable flag is initialized only after computeScore() is invoked. Hence flag will be false when the method is called the second time. You might want to get rid of the static block
static{
computeScore();
}
if you want lazy initialization.

Boolean not changing in thread

I have a class MPClient and MultiplayerMatch. MultiplayerMatch, in his constructor, creates a MPClient runnable thread.
To avoid data overflow, I have a boolean named "moved" in MultiplayerMatch that changes to true when the player is moving.
In the updateMatch method, if there's any player movement, "moved" changes to true, which allow MPClient to enter an if statment (inside while). This way MPClient only sends data to the server when something changes on the game.
Neverthless, when the flag is true, in MPClient that change is not registed! MPClient still "thinks" moved equals false, even after that flag changed in MultiplayerMatch, and as a consequence, nothing is sent to the server...
After a few tests, I noticed that if I run it in Debug Mode, since I have some breakpoints, that change is registered and everything works great!
Why is the boolean change only "seen" though Debug Mode? Does it have something to do with the app "running speed", since there are breakpoints?
Here's only the important part of the code:
MPClient:
public class MPClient {
static final int TIME_OUT = 5000;
Client client;
MultiPlayMatch match;
public MPClient(String name, int team, MultiPlayMatch match) {
this.match = match;
client = new Client();
client.start();
Network.registerPackets(client);
addListeners();
try {
client.connect(TIME_OUT, "127.0.0.1", Network.PORT);
} catch (IOException e) {
e.printStackTrace();
client.stop();
}
/*this comment is just to show that here is the place where the login information is sent to the server, instead of showing all the code*/
PlayerInfo playerInfo = new PlayerInfo();
Network.UpdatePlayer updatePlayer = new Network.UpdatePlayer();
updatePlayer.name = name;
updatePlayer.team = team;
while(true) {
if(match.moved) { //--> this is the variable that is always false
playerInfo.x = match.getClientPlayerX(team);
playerInfo.y = match.getClientPlayerY(team);
updatePlayer.x = playerInfo.x;
updatePlayer.y = playerInfo.y;
client.sendTCP(updatePlayer);
match.moved = false;
}
}
}
private void addListeners() {
client.addListener(new Listener.ThreadedListener(new Listener() {
#Override
public void received(Connection connection, Object object) {
if(object instanceof Network.UpdatePlayer) {
Network.UpdatePlayer updatePlayer = (Network.UpdatePlayer) object;
match.setPlayerPosition(updatePlayer.x, updatePlayer.y, updatePlayer.name, updatePlayer.team);
}
}
}));
}
}
MultiplayerMatch:
public class MultiPlayMatch extends Match {
public boolean moved;
public MultiPlayMatch(){
super(0);
Random r = new Random();
int aux = r.nextInt(2);
aux = 0;
if(aux == 0){
homeTeam = new Team("Benfica", Team.TeamState.Attacking, w);
visitorTeam = new Team("Porto", Team.TeamState.Defending, w);
} else{
homeTeam = new Team("Benfica", Team.TeamState.Defending, w);
visitorTeam = new Team("Porto", Team.TeamState.Attacking, w);
}
//homeTeam.controlPlayer(0);
numberOfPlayers = 0;
moved = false;
}
#Override
public void updateMatch(float x, float y, Rain rain, float dt) {
homeTeam.updateControlledPlayerOnline(x, y);
rain.update();
w.step(Constants.GAME_SIMULATION_SPEED, 6, 2);
if(x != 0 || y != 0) moved = true; //this is the place the variable is changed, but if it isn't in debug mode, MPClient thinks it's always false
}
public void setPlayerPosition(float x, float y, String name, int team) {
if(team == 0)
homeTeam.changePlayerPosition(x, y, name);
else
visitorTeam.changePlayerPosition(x, y, name);
}
}
volatile
This is because it is reading a cached value of match.moved variable instead of the latest. To avoid this, declare the variable as volatile
public volatile boolean moved;
Read more here
tl;dr
AtomicBoolean is a convenient alternative to volatile.
This class wraps and protects a nested primitive boolean value while ensuring proper visibility.
Instantiate:
public final AtomicBoolean moved = new AtomicBoolean( false ) ;
Getter:
boolean x = moved.get() // Returns current value.
Setter:
moved.set( false ) // Sets a new value.
Get, then set:
boolean x = moved.getAndSet( false ) ; // Retrieves the old value before setting a new value.
AtomicBoolean
The Answer by agamagarwal is correct. You have fallen into the visibility conundrum that occurs when accessing variables across threads. One solution is the use of volatile shown there.
Another solution is the Atomic… classes bundled with Java. In this case, AtomicBoolean.
The Atomic… classes wrap a value, and add thread-safe methods for accessing and setting that value.
I often prefer using the Atomic… classes rather than volatile. One reason for this preference is that it makes quite clear and obvious to the user that we are using a protected resource across threads.
Instantiation:
public class MultiPlayMatch extends Match {
public final AtomicBoolean moved = new AtomicBoolean( false ) ;
…
Notice two things about that instantiation:
final ensures that we do not swap out one AtomicBoolean object for another. Such swapping would put us right back into the variable visibility conundrum we are trying to escape.
The AtomicBoolean object is being instantiated at the same time as this outer object (MultiPlayMatch in your case) is being instantiated. So we have ensured that an instance of AtomicBoolean exists before any access, including any access across threads. If we waited until later (“lazy” loading), then we would be falling back into that variable visibility conundrum we are trying to escape.
Getting the value:
if ( this.match.moved.get() ) { … // Returns the primitive `true` or `false` value wrapped within this `AtomicBoolean` object.
And setting the value:
this.match.moved.set( false ) ;
You may want to get the current value while also setting a value in an immediate thread-safe “atomic” (combined) operation:
boolean oldValue = this.match.moved.getAndSet( false ) ;
To learn all about concurrency in Java, see the book, Java Concurrency in Practice by Brian Goetz, et al.

Why another branch is unreachable in my code?

Why the output of the following code is always suck. How to get happy as the output? Why the happy branch is unreachable?
public class HowToMakeStackoverflowBetter {
private static final int HUMAN_PATIENCE = 10;
private List<Member> members = new ArrayList<>();
private int atmosphere = -10;
private Random r = new Random();
public HowToMakeStackoverflowBetter(int size) {
for (int i = 0; i < size; i++) { members.add(new Member()); }
}
public Member pick() { return members.get(r.nextInt(members.size())); }
public class Member {
private int patience = HUMAN_PATIENCE;
private Question question = null;
public Member() { patience = r.nextInt(patience+1) + atmosphere; }
public void vote(Question q) {
if (patience >= 0) {
voteUp(q);
} else {
voteDown(q);
}
}
public void ask() {
question = new Question();
for (Member member : members) {
member.vote(question);
}
}
private void voteUp(Question q) { ++q.vote; }
private void voteDown(Question q) { --q.vote; }
public String toString() {
return (question.vote >= 0)? "Happy!" : "Suck!";
}
}
public class Question { private int vote; }
public static void main(String[] args) {
HowToMakeStackoverflowBetter stackoverflow = new HowToMakeStackoverflowBetter(100);
Member me = stackoverflow.pick();
me.ask();
System.out.println(me);
}
}
After a 1000 times loop, it gives us 1000 sucks. I remember 2 or 3 years ago, this was not the case. Something changed.
Two problems. First:
linkedList::linkedList(){
*sentinel.last=sentinel;
*sentinel.next=sentinel;
sentinel.str="I am sentinel!!";
};
sentinel is your member variable, and .last is its pointer to another node. This hasn't been initialised, so trying to use it is undefined behaviour. In practice, it's effectively pointing at a random address in (or out of) memory, and you attempt to dereference the pointer then copy the entire sentinel object over the node at the imagined pointed-to address: i.e. you try to copy the 3 pointers in the sentinel node member variable to a random address in memory.
You probably want to do this:
linkedList::linkedList()
{
sentinel.last = &sentinel;
sentinel.next = &sentinel;
sentinel.str = "I am sentinel!!";
}
Secondly, you explicitly call the destructor for linkedList, which results in undefined behaviour when the compiler-arranged destruction is performed as the object leaves the stack scope it's created in - i.e. at the end of main().
I suggest you change node.str to be a std::string, as in any realistic program you'll want to be able to handle variable text, and not just point to (constant) string literals. As is, if you mix string literals and free-store allocated character arrays, you'll have trouble knowing when to call delete[] to release the memory. You could resolve this by always making a new copy of the string data to be stored with new[], but it's safer and easier to use std::string.
Since you allocated it as a local variable, your mylist will be destroyed automatically upon exiting main. Since you've already explicitly invoked its destructor, that leads to undefined behavior (attempting to destroy the same object twice).
As a quick guideline, essentially the only time you explicitly invoke a destructor is in conjunction with placement new. If you don't know what that is (yet), that's fine; just take it as a sign that you shouldn't be invoking destructors.
You forgot to initialize sentinel
In code below you are trying to initialize sentinel (which is not yet constructed) with sentinel(same thing). So you have to pass something to constructor which can be used to initialize your member variable sentinel
*sentinel.last=sentinel;
Also no need to call destructor like this. Destructor will be called once your myList goes out of scope.
myList.~linkedList();
the program may crash, with this:
*sentinel.last=sentinel;
*sentinel.next=sentinel;
sentinel is not initialized sot i has random value on stack.
You're trying to de-reference the pointers last and next of member variable sentinel when they are not yet initialized.
And these de-references *sentinel.last=sentinel *sentinel.next=sentinel are causing the crash because without assigning the values to pointers you're changing the value pointed by the pointers.
You can do like this
sentinel.last=&sentinel;
sentinel.next=&sentinel;
And as pointed out by other explicit destructor calls aren't need here.

Changes being made to an object in Java

I have created a Compound class that holds the number of Carbon, Hydrogen, Oxygen, Nitrogen and it's bond count. I have a stack that holds these objects.
Initially the stack will start off at empty and I will pop that. Then I will apply addHydrogen function to it so it's Hydrogen will = 1, Oxygen=0, Nitrogen=0 and Carbon=0.
I then want to take the same object and apply the addCarbon function so that Hydogren will = 0, Oxygen=0, Nitrogren=0 and Carbon=1.
How can I write my program so I can use the same object but not with the changes I made from adding the Hydrogen? I know I could use some if cases initially but I don't think it will work because I will eventually start with a compound that has hydrogen=2, oxygen=2, Nitrogren=0, Carbon=1.
*I didn't include my constructors in the code, they just initialize everything to 0.
class compound {
int Hydrogen;
int Carbon;
int Nitrogen;
int Oxygen;
int bond;
public void addHydrogen(compound comp) {
Hydrogen++;
}
public void addCarbon(compound comp) {
Carbon++;
}
}
public static void main(String[] args) {
Compound a= new Compound();
a.addHydrogen(a);
a.addCarbon(a);
}
Your question isn't very clear, but one option you might wish to consider would be to make your object immutable - so you could never change the values within a single object, but you could instead make your addCarbon (etc) methods return a new object with appropriate new values in.
(Note that currently you're not using your parameters, which appear to have the wrong case anyway...)
Sample code:
public class Compound {
private final int hydrogen;
private final int carbon;
private final int nitrogen;
private final int oxygen;
public Compound(int hydrogen, int carbon, int nitrogen, int oxygen) {
this.hydrogen = hydrogen;
this.carbon = hydrogen;
this.nitrogen = nitrogen;
this.oxygen = oxygen;
}
public int getHydrogen() {
return hydrogen;
}
// ... etc for the other getters
public Compound plusHydrogen() {
return new Compound(hydrogen + 1, carbon, nitrogen, oxygen);
}
// etc for the other plus calls
}
Note that I've called the methods plusHydrogen etc to make it clear that they're not mutating the existing object, but returning a new one.
Then you can have:
Compound base = new Compound(0, 0, 0, 0);
Compound withHydrogen = base.plusHydrogen();
Compound withCarbon = base.plusCarbon();
// whatever

Categories

Resources