Java score points automatically increasing - java

I'm doing a school project. I am building a text based game on Java for PC.
The game I'm building is quite simple, you buy homes and you rent them out. So what I am asking is, how can i get the money to automatically increase per second ($1 per second) from each house and then automatically add it to their users bank account automatically. I have looked around and they say use a thread to pause the game for 1000(milliseconds) and then do counter++. But I have tried that, and for a text based game that pauses the game and makes the user wait. I want the user to continue interacting with other functionalities of the text based game whilst the money per second in his bank is increasing.

I agree that putting in a thread to sleep for 1000 ms is probably the best solution. The issue that you seem to have encountered when trying that solution is likely caused not using multithreading. The Thread.sleep(1000); command should be on a separate thread from the main thread that you are using for the user interface.
The following could be a possible way to implement the thread that modifies the bank balance:
public class RevenueThread implements Runnable {
public void run() {
while(true){
// add to bank balance
MainClass.BankBalance += MainClass.PropertyCount * INCOME_PER_PROPERTY;
// sleep for 1 second
try{
Thread.sleep(1000);
}catch(Exception ex){
System.err.println( ex.getMessage() );
}
}
}
}
Modify that code to your needs with the proper variable names and whatnot.
To integrate this with your code, you could add this to your main() function:
Runnable rev = new RevenueThread();
Thread revThread = new Thread(rev);
revThread.start();`
Note: I apologize if my answer seems somewhat brief or if it contains any errors. I am typing this solution from my phone, so bear with me :P
EDIT: The following is an alternative (and perhaps more accurate) way to increment the bank balance every second:
public class RevenueThread implements Runnable {
public void run() {
// Variable to keep track of payout timing:
long lNextPayout = System.currentTimeMillis() + 1000; // Current time + 1 second
while(true){
if(lNextPayout <= System.currentTimeMillis()){
// At least 1000 milliseconds have passed since the last payout
// Add money to the player's bank balance
MainClass.BankBalance += MainClass.PropertyCount * INCOME_PER_PROPERTY;
// Now set up the next payout time:
lNextPayout += 1000;
}
// sleep for 50 milliseconds to prevent CPU exhaustion
try{
// Thread.sleep() can throw an InterruptedException.
Thread.sleep(50);
}catch(Exception ex){
// If sleep() is interrupted, we should catch the exception
// and print the error message to the standard error stream
// (STDERR) by using System.err
System.err.println( ex.getMessage() );
}
}
}
}
What's different about this version and why is it better? This version uses the system's current time to payout every 1000 milliseconds. Because sleep() can possibly throw an exception, this updated version prevents a user from being paid multiple times within 1 second just because sleep() threw an exception and did not sleep for the full second.
How can this be used? This can be used in the exact same way as the previous version. (I.e., just create a new RevenueThread object, then create a Thread object for it, and call .start() on that new thread.) Again, though, you should replace and rename variables as needed to fit into your project.

Since you are doing a text based game and it is not indicated in your question whether this will be a multiplayer or single player game, if this is a single player game, I will not implement this simulation (game) in real time.
It is probably more suitable to implement a discrete-time simulation (which means you don't have to use threads). You can create each house as an object with a currentTime attribute. Every time a house is rented, update its currentTime. Whenever you need to check the bank account for the money received from renting. Check the elapsed renting time of each house and update your bank account accordingly.

Related

Java Nonsynchronized threads using the same resource

I have to make a very simplified Joint Bank Account program (in this example with 3 users who all have access to the bank accounts resources) but I'm having trouble correctly using Java threads.
Here is how the program should work. There are "users" that all have access to one Joint Bank Account with an arbitrary set initial balance(I used 5000). They can each withdraw or deposit money (whether they withdraw or deposit is randomly generated each time) three times over one run of the program.
The amount they deposit or withdraw is also randomly generated, with the only rule for that being that the amount can never exceed 1/3rd of the current balance.
Finaly after each transaction the current Thread has to "wait" a random amount of seconds between 1 and 10.
Now here is the confusing part. Our teacher asked us to make a unique NotEnoughBalance exception class in case one of the users somehow withdraws more money than what is currently in the account (but here is my first point of confusion: in theory this could never occur due to the 1/3rd rule).
Here is the full code posted on pastebin:
http://pastebin.com/Upam56NF
Currently, when I run the main:
public class BankAccount{
public static void main(String[] args) throws InterruptedException{
int capital = 5000;
JointBankAccount acc = new JointBankAccount(capital);
Thread t1 = new Thread(new Owner("Josh", acc));
Thread t2 = new Thread(new Owner("Wade", acc));
Thread t3 = new Thread(new Owner("Ben", acc));
System.out.println(capital);
String tname = Thread.currentThread().getName();
System.out.println(tname);
t1.start();
t2.start();
t3.start();
t1.join();
t2.join();
t3.join();
for(AccountTransaction s : acc.history){
System.out.println(s.toString());
}
System.out.println(acc.getBalance());
}
}
I randomly sometimes get a NPE exception at System.out.println(s.toString()).
This is completely fixable if I make both deposit and withdraw function Synchronized.
The problem is, somehow I think makign them synchronized defeats the purpose of what our teacher is asking. If I make them synchronized, then I feel like I'm ensuring that the 1/3rd rule gets sucessfuly followed with each withdrawal correctly, and the not enough Balance exception can never exist.
The fact that I get NPEs when I remove synchronized also makes me think possibly the error is in me not properly handling the exception when it does occur. I don't know.
Any help would be greatly appreciated.
This looks to me like a fine exercise in understanding atomic transactions.
But first the NPE: one JointBankAccount instance is shared between several threads, and thus anything contained by the JointBankAccount like the history list. The history list is of type ArrayList which is not thread-safe, i.e. if two threads call the add method at the same time, the list breaks. This is easy to fix though: List<AccountTransaction> history = Collections.synchronizedList(new ArrayList<AccountTransaction>());
Now for the atomic transactions. Since the balance can be changed at any time by any thread, the moment you read the balance, the balance is already outdated. I.e. a statement like if (balance > 1000) then updateBalance() is not valid since the balance could have changed after then. One way to circumvent this is to synchronize everything (although even then you have to be careful, e.g. use AomticInteger to register the balance). But the NotEnoughBalanceException implies a different way of working using a ReentrantReadWriteLock. Before the balance is updated, use a read-lock to read the latest balance and apply any rules to determine if the balance can be updated. This allows you to inform the "owner" that the balance can probably be updated. But since you used a read-lock you cannot be certain: the balance might have already been updated. Now use a write-lock and apply the rules again. This time you can be certain about the balance value (it can only be updated by the code that has the single write-lock) and you might find the balance is no good (one of the rules fails). This is where the NotEnoughBalanceException comes into play: you promised the "owner" the balance could be updated but now that you have the final write-lock you find the balance cannot be updated (the atomic transaction cannot be completed).
This follows a pretty common pattern: use "cheap" locks to determine if a transaction can be done (perform pre-checks) and then use an "expensive" lock to perform the transaction but always assume the transaction might fail and retry the transaction when appropriate.

Prevent Thread Subclass from waiting

I'm making a coding game for the Java class I TA. The game is to manage a fleet of trucks (Truck extends Thread) on an undirected graph to deliver parcels to their various destinations using as little time/fuel as possible. The student extends an abstract manager class that fills in the gaps in the Truck's behavior (what to do upon reaching a destination, etc). The truck class's run method is a event loop that waits for user instruction and then follows it when it receives travel destinations. Here's the event loop:
#Override
/** The Truck's main running routine. While the travel directions are empty,
* Waits for more instructions in WAIT_TIME intervals. While the travel directions
* are not empty, pops off the next travel direction
*/
public void run(){
while(game.isRunning()){
setGoingTo(null);
while(travel.isEmpty() && game.isRunning()){
try{
Thread.sleep(WAIT_TIME);
}
catch (InterruptedException e){
e.printStackTrace();
}
setStatus(Status.WAITING);
game.getScore().changeScore(Score.WAIT_COST);
}
while(!travel.isEmpty() && game.isRunning()){
Edge r = getTravel();
try {
travel(r);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
The first inner while loop loops while there are no travel instructions to follow. As you can see, every WAIT_TIME milliseconds (a frame), the score is decreased by the wait cost - the cost of the truck idling.
I realized, however, that a way for a potential solution to get around this cost is to tell the truck (thread) to wait while it doesn't have instructions, then notify it once the user has computed instructions for it. I'd like to prevent this programmatically, rather than just put in the instructions not to do it.
Is this even possible? Perhaps a method in the thread class to override? Can a class that extends Thread be prevented from waiting (on anything?) I'd settle for any kind of exception being thrown if a truck thread tries to execute .wait().
Thanks for reading and for any suggestions for how to tackle this gap in the rules! The game will be up on a public repo soon if you want to try your hand at it.
I don't have a solution for the exact question you asked (how to prevent wait), but a suggestion that is kind of too long for a comment:
How about measuring the time between the start of the first while loop and the end.
long starttime = System.currentTimeMillis();
setStatus(Status.WAITING);
while(travel.isEmpty() && game.isRunning()){
try{
Thread.sleep(WAIT_TIME);
}
catch (InterruptedException e){
e.printStackTrace();
}
}
long endtime = System.currentTimeMillis();
long waittime = endtime - starttime;
game.getScore().changeScore(Score.WAIT_COST * (1 + waittime / WAIT_TIME));
Even if the thread is sent to sleep, the score will change according to the ellapsed time. You will just not have a live game score update.
I'm pretty sure you can't prevent .sleep() or .wait() because you can't override or tamper with them. So the only way is monitoring for them.
I don't know of a method inside the thread but from outside the thread (for example from a monitoring thread) you can get the thread staus with
Thread.getState()
if someone called sleep on the thread or the thread is waiting becuase of a wait call the result should be Thread.State.TIMED_WAITING. Then all you have to ensure is that the monitoriong thread knows it were the students that called sleep and not you (a private flag for example).
The monitoring thread can then of course take any counter measures you want like throwing an Exception or simply silently decucting points.
Relevant docs :
http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.State.html#TIMED_WAITING
http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#getState()
I wonder whether having a Thread per Truck is the right approach. Are you trying to teach them about threads? or are you trying to teach them about graph algorithms and heuristics? (If the Single Responsibility Principle applies to homework assignments, then the answer should be one or the other, but not both.)
If the emphasis was on algorithms and heuristics, then I would write a single-threaded program where the main loop executes a series of "moves". In each move, it would ask each of the truck objects what the truck wants to do next, and then it would either move the truck accordingly, or it would flag the assignment as invalid if the truck asked to do something that did not make sense.
In my version, the "time" in the simulation would be completely decoupled from real-time, so if some student put a Thread.sleep() in her/his strategy routine, it would not have any effect on the outcome of the program; it only would make the program take that much longer to run. (Of course, I would run them all under control of a batch script that would abort any assignment that took longer than... say, three minutes.)

implement a scheduler in spring

A project requires the following scenario to happen:
class A has some objects(dynamically created) which it generates along with a time interval associated with each object. This class needs the generated object after this time interval only. I need to implement a mechanism which provides the class with the objects after it's associated time interval. It may also, sometime, need a particular object before the time interval expires.
Here's what I did:
Looked upon ConcurrentTaskExecutor and org.springframework.scheduling.concurrent but didn't find it useful because I don't want thousands of thread running each for an object. Also, I don't want to repeat a particular job after a time interval.
I created a Thread B which takes all the object in a queue, has an infinite loop which constantly checks all the object's time interval with the current time, and puts back if it's time interval has not expired.
while (true) {
timerObject = queue.take();
if (timerObject.getEndTime() < System.currentTimeMillis()) {
//Do something
} else {
queue.put(timerObject);
}
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
This is not a very efficient implementation itself. It has a logical error associated with it. When the objects are very low in number(like 1 or 2), the objects are not in the queue and whenever I try to remove the object from the queue, it shows unsuccessful, because the while loop is having the object all the time. And hence I had to put a sleep to avoid that. I don't want to check each and every time interval when the queue size grows up to 10K or so.
Is there any simple and efficient way to achieve the solution. Any help appreciated.
You can use ConcurrentTaskScheduler, or implement something like it using DelayQueue.
You can use it with spring's Concurrent framework (for example subclassing ThreadPoolExecutorFactoryBean) or with core java Executors.

Make a simple timer in Java

I can't seem to figure out how to make a simple timer in java. All I need it to do is just display time, really. So just a start method, and it keeps counting up like 0:00, 0:01, 0:02, etc. I've seen some other similar forum posts on this, but all the code is kind of complicated for my level of understanding; I'm kind of new to java. But it shouldnt be that hard to make a timer that just performs such a basic function? If anyone could help it would be greatly appreciated :)
This is not difficult. However, I would caution you that I have seen some very confused answers on stack overflow, in some cases shockingly poor coding habits, so be very careful. First let me answer the question.
If seem that the biggest mistake that programmers make in implementing a timer, is thinking that they need something to keep track of the current time. That is, they write some sort of loop that increments a variable every second or some such silly thing. You do not need to write code to keep track of the time. The function System.currentTimeMillis() will do that for you, and it does it quite accurately.
Timer code will involve two aspects which many programmers mix up:
calculation of the time
refresh of the display
All you need to do to calculate the time to display, is to record the time that the timer started:
long startTime = System.currentTimeMillis();
Later, when you want to display the amount of time, you just subtract this from the current time.
long elapsedTime = System.currentTimeMillis() - startTime;
long elapsedSeconds = elapsedTime / 1000;
long secondsDisplay = elapsedSeconds % 60;
long elapsedMinutes = elapsedSeconds / 60;
//put here code to format and display the values
The biggest mistake that programmers make is to think they need a variable to hold the current time and then to write code to increment that variable every second, e.g. something called "elapsedSeconds" which they maintain. The problem is that you can schedule code to be called every second, but there is no guarantee of exactly when that code will be called. If the system is busy, that code might be called quite a bit later than the second. If the system is extremely busy (for example page fetching from a faulty disk) it could actually be several seconds late. Code that uses the Thread.sleep(1000) function to loop every second will find that the error builds up over time. If sleep returns 300ms late one time, that error is compounded into your calculation of what time it is. This is all completely unnecessary because the OS has a function to tell you the current time.
The above calculation will be accurate whether you run this code every second, 100 times a second, or once every 3.572 seconds. The point is that currentTimeMillis() is the accurate representation of the time regardless of when this code is called -- and that is an important consideration because thread and timer events are not guaranteed to be accurate at a specific time.
The second aspect of a timer is refresh of the display. This will depend upon the technology you are using to display with. In a GUI environment you need to schedule paint events. You would like these paint events to come right after the time that the display is expected to change. However, it is tricky. You can request a paint event, but there may be hundreds of other paint events queued up to be handled before yours.
One lazy way to do this is to schedule 10 paint events per second. Because the calculation of the time does not depend on the code being called at a particular point in time, and because it does not matter if you re-paint the screen with the same time, this approach more or less guarantees that the displayed time will show the right time within about 1/10 of a second. This seems a bit of a waste, because 9 times out of 10 you are painting what is already on the screen.
If you are writing a program with animation of some sort (like a game) which is refreshing the screen 30 times a second, then you need do nothing. Just incorporate the timer display call into your regular screen refresh.
If paint events are expensive, or if you are writing a program that does terminal-style output, you can optimize the scheduling of events by calculating the amount of time remaining until the display will change:
long elapsedTime = System.currentTimeMillis() - startTime;
long timeTillNextDisplayChange = 1000 - (elapsedTime % 1000);
The variable timeTillNextDisplayChange holds the number of milliseconds you need to wait until the seconds part of the timer will change. You can then schedule a paint event to occur at that time, possibly calling Thread.sleep(timeTillNextDisplayChange) and after the sleep do the output. If your code is running in a browser, you can use this technique to update the page DOM at the right time.
Note, that there is nothing in this calculation of the display refresh that effects the accuracy of the timer itself. The thread might return from sleep 10ms late, or even 500ms late, and the accuracy of the timer will not be effected. On every pass we calculate the time to wait from the currentTimeMillis, so being called late on one occasion will not cause later displays to be late.
That is the key to an accurate timer. Do not expect the OS to call your routine or send the paint event exactly when you ask it to. Usually, of course, with modern machines, the OS is remarkably responsive and accurate. This happens in test situations where you are not running much else, and the timer seems to work. But, in production, under rare stress situation, you do not want your timer "drifting" because the system is busy.
You can either use Timer class from java.util or another way, which is more complicated, is with Threads. Timer also has thread action, but it's pretty easy to understand to use it.
For creating a simple timer as you explained as per your need , it is very easy to write a code for that. I have written the below code for your reference. If you wish you can enhance it.
import java.util.concurrent.TimeUnit;
public class PerfectTimer {
public static void main(String[] args) throws InterruptedException
{
boolean x=true;
long displayMinutes=0;
long starttime=System.currentTimeMillis();
System.out.println("Timer:");
while(x)
{
TimeUnit.SECONDS.sleep(1);
long timepassed=System.currentTimeMillis()-starttime;
long secondspassed=timepassed/1000;
if(secondspassed==60)
{
secondspassed=0;
starttime=System.currentTimeMillis();
}
if((secondspassed%60)==0)
displayMinutes++;
System.out.println(displayMinutes+"::"+secondspassed);
}
}
}
if you want to update something in the main thread (like UI components)
better to use Handler
Handler h = new Handler();
h.postDelayed(new Runnable() {
#Override
public void run() {
//do something
}
}, 20);
20 - the delay In MS to do something.
and run it in a loop.
I have created a Timer that has everything you might need in it.
I even documented it!
And I also compiled it for faster usage.
Here's an example:
//...
//For demo only!
public static void main(String[]a){
Timer timer=new Timer();
timer.setWatcher(new Timer.TimerWatcher(){
public void hasStopped(boolean stopped){
System.out.print(stopped+" | ");
}
public void timeElapsed(long nano, long millis, long seconds){
System.out.print(nano+", ");
System.out.print(millis+", ");
System.out.print(seconds+" | ");
}
public void timeLeft(long timeLeft){
System.out.print(timeLeft+"\r");
}
});
//Block the thread for 5 seconds!
timer.stopAfter(5, Timer.seconds); //You can replace this with Integer.MAX_VALUE.
//So that our watcher won't go to waste.
System.out.println();
}
//...
This is not for promotion, made this to help people not waste their time in coding classes themselves!

UI updates as expected in debug mode, but does nothing when run normally

I'm creating a simple game turn based game in NetBeans. After the initialization of the GUI it calls the function herosTurn() to which waits for the users choice and and creates the outcome of that choice from a separate class Hero. When I step through the code in Debug mode, I get correct outcomes, but if I just run the code nothing is ever appended to the Text Area unless I have the wait function constantly appending text while it waits for input. I've seen other questions similar to this but they all involved multi-threading, and I don't believe that is what I am doing. Any help would be greatly appreciated.
This is the main class:
package Flow;
import Forms.Battleinterface;
/**
*
* #author Steemo
*/
public class battle {
public static int hAct;
public static int gLife = 200;
public static void herosTurn() {
hAct = 0;
Forms.Battleinterface.biText.append("What will you do?");
while (hAct == 0){
// adding the line below makes code work but is ugly.
//Forms.Battleinterface.biText.append(".");
continue;
}
if (hAct == 1){
Entities.Hero.attack();
}
}
public static void main(String args[]) {
Battleinterface battleinterface = new Forms.Battleinterface();
Battleinterface.Start();
while (gLife > 0) {
herosTurn();
}
}
}
And this is the Hero() class that is in a separate package:
package Entities;
import java.util.Random;
/**
*
* #author Steemo
*/
public class Hero {
static Random hGen = new Random(54154454);
public static void attack() {
int hAtt = 0;
hAtt = hGen.nextInt(6) + 15;
Forms.Battleinterface.biText.append("\nYou swing your axe and do " + hAtt
+ " Damage!!!");
}
}
I am not attaching the class I use to generate the GUI (Battleinterface) because the GUI generates fine and the only other thing happening there is the passing of the input hAct.
If it is needed I can attach it.
Replace this code...
while (hAct == 0){
continue;
}
...with this instead:
while (hAct == 0){
try {
Thread.yield();
} catch (InterruptedException interruptedEx) {
// Log the interruption somewhere.
}
}
Assuming you're using AWT/Swing on some level? This is an infinite loop, preventing other threads from ever running. By doing this you never let the UI thread actually do any updating, which means it appears to hang. You may not be doing any threading on your own, but AWT/Swing comes with Threads built in to do various functions, and they need to periodically get CPU time to do their work.
The reason this works in debugging is because the debugger is pausing the herosTurn method as you're stepping through it, allowing the UI thread to do its updates (including getting input from the user), but when simply running your game, the herosTurn method never pauses, and that method is occupying 100% of the available CPU time for your app.
Finally, as Mike Clark mentions, you typically shouldn't write UI with infinite loops. Instead you define components, which trigger events. Your code is notified of those events and reacts appropriately. This is what is known as the UI's event model. If you're using Swing, the introductory info on working within the event model is covered here.
I also wouldn't typically use AWT/Swing for games, because of the complications of UI coding, rendering performance, and several other reasons relating to the reality that AWT/Swing were not built to be good tools for games. That being said, a turn-based game can work fine this way (because the rendering performance requirements are often much lower) if you're willing to delve into the UI code to get it done, in addition to a few other reasons which I've outlined in a previous answer.
Hmm, there might be an issue with flushing your text buffer to the text area. Try explicitly flushing your text buffer after every print to see if that makes a difference.
It seems to me that your program is stuck in a while loop in the method herosTurn() As long as that function has not returned, nothing is going to update if you program this game as a single thread application.
It works when you uncomment the Forms.Battleinterface.biText.append("."); line cos then you send a signal to the GUI every iteration which causes it to update.
Games usually have a main game loop from which all elements of the program are controlled. Maybe a change of your implementation strategy will help?
I'm not a games programmer, so this might not be the best approach, but why don't you try setting up a javax.swing.Timer that runs every, say, 100 milliseconds. In inside the timer action, you can write all the code which checks and advances the game state and generates output to the user.
I'd suggest collecting the user's input in a JTextField that is separate from the place where the game output is printed. If you want to know when the user presses enter to send what they've typed, you can register an ActionListener on the JTextField.
textField.addActionListener(yourListener);

Categories

Resources