import java.util.Scanner;
import java.util.Timer;
import java.util.TimerTask;
public class Boggle {
Board board;
Player player;
Timer timer;
boolean active;
static Scanner in = new Scanner(System.in);
public Boggle() {
board = new Board(4);
timer = new Timer();
}
public void newGame() {
System.out.println("Please enter your name: ");
String line = in.nextLine();
player = new Player(line);
active = true;
board.shuffle();
System.out.println(board);
timer.schedule(new timesUP(), 20000);
while(active) {
String temp = in.nextLine();
player.addGuess(temp);
}
}
public void endGame() {
active = false;
int score = Scoring.calculate(player, board);
System.out.println(score);
}
class timesUP extends TimerTask {
public void run() {
endGame();
}
}
public static void main(String[] args) {
Boggle boggle = new Boggle();
boggle.newGame();
}
}
I have the above class which should perform a loop for a given length of time and afterwards invoke an instance method. Essentially I need the loop in newGame() to run for a minute or so before endGame() is invoked on the current instance. However, using the Timer class I'm not sure how I would invoke the method I need on the current instance since I can't pass any parameters to the timertasks run method?
Is there an easy way to do this or am I going about this the wrong way? (note: this is a console project only, no GUI)
==========
code edited
I've changed the code to the above following the recommendations, and it works almost as I expect however the thread still doesnt seem to end properly. I was the while loop would die and control would eventually come back to the main method. Any ideas?
Because timesUP (please change the name!) is an inner class, it already has a reference to the instance of Boggle which created it. (That wouldn't be the case if it were marked as static.) If you wanted to create an instance of timesUP associated with another instance, you'd do something like:
otherBoggle.new timesUp();
It's pretty odd syntax, admittedly :)
This doesn't fix the problem that Midhat identified, admittedly - but it means you don't need to worry about getting a reference to the outer class. Just call endGame() from within timesUP.run() and it will call it on the appropriate instance.
You have blocking console input in the thread. The running time will be dictated by that. You can have the console input in a seperate thread, and add a timer in the current thread to kill the input thread after a minute, and call this.endGame()
Related
I got an assignment for university where I have to implement a hangman game with Threads in Java.
My problem is that I can't understand how to handle the threads.
In my code there is a GameLeader who prompts the GuessingPlayer to enter a char which he guesses in the startWord. After he did that (run()-method) he takes the message further.
The connection between the two players should be arranged with 'Messages' (own implemented class). It's working if I use run() instead of wait().
Can u help me to understand why the while loop is not working after the first entered message?
Thanks!
Class GameLeader:
public class GameLeader {
public static void main(String[] args) throws IOException {
GuessingPlayer guessingPlayer = new GuessingPlayer(userInterface);
String guess;
System.out.println("Please enter a startWord to begin!");
String startWord = userInterface.enterWord();
guessingPlayer.start();
while (attempts < 11) {
synchronized (guessingPlayer) {
System.out.println("It's your turn, Guessing Player!");
guessingPlayer.wait();
guess = guessingPlayer.message.toString();
if (startWord.contains(guess)) {
...
}
} else {
...
}
userInterface.mainMenu(guess);
}
}
}
}
Class GuessingPlayer:
public class GuessingPlayer extends Thread {
Message guessMessage;
private UserInterface userInterface;
GuessingPlayer(UserInterface userInterface) {
this.userInterface = userInterface;
}
#Override
public void run() {
synchronized (this) {
guessMessage = new Message(userInterface.enterWord());
notify();
}
}
}
I think you would be well served to review the course material on threads, and/or talk to your instructor. But, a few comments and suggestions:
I imagine the game leader is supposed to be a thread, and the player(s) are also supposed to be threads (as your current GuessingPlayer class is). These are all instantiated and started when your program starts by calling the start() method on the thread.
You don't have to call run, that gets called internally by the thread once it's started. But you probably want a loop in the run method that waits for the thread to be notified, and then repeats.
By "message passing" they mean something general like having a shared object or Queue that all the threads can read/write and have a reference to. One thread writes something in that object, and calls Thread.notify() to notify the other threads that something interesting has happened in that object. When that happens, the other thread will wake up right where it called the Thread.wait() method. Then it can check that shared object to see what's up.
http://web.mit.edu/6.005/www/fa14/classes/20-queues-locks/message-passing/
http://www.programcreek.com/2009/02/notify-and-wait-example/
Hope this helps.
You are using wait() method in a wrong way. You do not need an object reference to call wait() method. It is a method defined in Java's Object class.
Therefore, just write wait() instead of using guessingPlayer object reference.
Hope this helps. :)
The tile does not describe it properly so im going to try and describe it here:
I have a bukkit plugin, its a minigame.
It must have some code run for 10 minutes and then run another code until that game is finished
I currently have this:
Timer timer = new Timer();
timer.schedule(new TimerTask() {
public void run() {
// code for 10 minutes
}
}, 600000);
//code for after
Yet, this is only affects a single player and not that world.
So if one player joins he will wait 10 minutes and then run the otherpart of the code and so on, when the purpose is the 10 minutes start couting on their own, even if there is no player.
Thanks
Your problem is probably caused because your code is all triggered by an event?
Meaning it will only ever effect the player that triggered that event.
Instead you need a generic plugin that does not trigger on events (except for login), but instead it uses a timer and then grabs a list of all players and runs your code on each/all of them. Then after 10min it will exit to your other code and run that for the rest of the time.
Edit: rough example:
import org.bukkit.plugin.java.JavaPlugin;
public final class {$PluginName} extends JavaPlugin {
#Override
public void onEnable() { //This should proberbly be done onCommand rather than onEnable
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
long time = System.currentTimeMillis();
while (some condition....){
//load list of players
//now iterate through player list and do your code
//check if 10min has passed:
if ((System.currentTimeMillis() - time) > 600000){
//now break the loop and run your other code for the rest of the minigame
break;
}
}
//code for the rest of the minigame
while (true){
//load list of players
//now iterate through player list and do your code for the rest of the time
}
}
});
thread.start();
}
}
I need to generate a new Thread every 2 seconds. So I tried to use the Timer class in the main(String[]) method but my program just exists after the milliseconds I specified in the Timer constructor.
Program.java:
public class Program
{
private static int panelWidth;
private static int panelHeight;
private static MyPanel panel = new MyPanel();
public static void main(String[] args)
{
MyFrame frame = new MyFrame();
frame.add(Program.panel);
Program.panelWidth = frame.getWidth();
Program.panelHeight = frame.getHeight();
Timer generateBallTimer = new Timer(2000, new GenerateBalls());
while (true)
{
generateBallTimer.start();
}
} // End of main method
/**
* Generate a new ball every 2 seconds.
*
*/
public static class GenerateBalls implements ActionListener
{
#Override
public void actionPerformed(ActionEvent e)
{
Program.generateBalls();
}
}
public static void generateBalls()
{
// Generate a ball each 2 seconds
while (true)
{
Program.panel.balls.add(new Ball(Program.panel));
}
}
} // End of program class
If in the Timer constructor I will specify 3000ms my program will be closed after 3 seconds and so on.
What am I doing wrong here?
Can you give me example of that "display list"?
You talk about "balls". What does your program need to know about a ball? Probably its position, maybe its speed, maybe its mass. Size? color? other stuff? It's up to you. The simplest implementation of a Ball object would just be a class with public fields to hold all of that information. Then, if Ball is the only kind of moving object in your animation, then your display list could just be a List<Ball>.
In a more complicated program, your Ball class might be an extension of some more general class, maybe VisibleObject, and then your display list would be a List<VisibleObject>.
As far as I know,for all the objects in a game to work concurrently they need to be Threads.
In a sense, you are right because there is only one class in all of Java that can do any work at all, and that class is Thread. No other class actually ever does anything. Other classes merely define methods that can be called by threads.
The trick is, to decouple the threads in the program from the work that they do. That's the motivation for the Runnable interface. Instead of having one object that both is a thread and also, describes the work to be done by the thread, you can have two classes; One takes care of all the thread-y stuff (.start(), .interrupt(), .join(), ...), and the other describes the work to be done (.run()).
Some say, it's hard to write a program that has too many classes/objects, but it's easy to write one that has too few.
As long as your Ball objects or your VisibleObject objects cleanly describe the things that you want to see on the screen and the ways in which you want to see those things move, there's no reason why each one's methods must be called by its own dedicated thread. There's no reason why you can't have just one thread that does the calculations for each one in its turn.
In my program I am calling the thread to do some job but the other method of thread class executes before the run method.
public class Verify extends JFrame implements Runnable
{
long Local_cid;
String local_path;
static boolean isIntialised=false;
JProgressBar bar;
final static ArrayList<Long> ContactList=new ArrayList<>();
final static ArrayList<Long> Scanned=new ArrayList<>();
static boolean flag=true;
static boolean Duplicate_flag=true;
boolean[] flags=new boolean[6];
public Verify(long ID,String path)
{
Local_cid=ID;
local_path=path;
}
public boolean[] Return_Flag()
{
System.err.println("Verify Id");
return flags;
}
public void dispose_Frame()
{
System.err.println("Executing First");
dispose();
}
#Override
public void run()
{
System.err.println("This should Executed First");
}
}
When I call this thread via start call the output is as follows:
Verify Id
Executing First
This should Executed First
You should follow the Java coding standard style guides, it will make it much easier for people to read.
There is nothing in the code you have posted that calls Return_Flag() so you must be calling it somewhere else - probably from the code that creates the thread in the first place.
Run is only called once the thread is started, and other threads are still running at the same time and can call whatever methods they like in whatever order they like...
I'm 100% sure that you are calling those methods somewhere in your code before actually starting the thread. Just look more careful and you will find it.
I was making a clock, which displays time in Java, I will show the code below:
public class MyApp extends javax.swing.JFrame {
int timeRun = 0;
/**
* Creates new form MyApp
*/
public MyApp() {
initComponents();
System.out.println("We'll start here!");
new Thread ()
{
public void Run(){
while(timeRun == 0)
{
Calendar cal = new GregorianCalendar();
int hour = cal.get(Calendar.HOUR);
int min = cal.get(Calendar.MINUTE);
int sec = cal.get(Calendar.SECOND);
int AM_PM = cal.get(Calendar.AM_PM);
String time = hour + ":" + min + ":" + sec;
System.out.print(time);
System.out.print("We'll end here!");
}
}
}.start();
}
I have a JLabel, and the other components needed for this JFrame to work.
I also have main set up, although you can't see it in the example above
My issue is, that I can't get a value from time, nor can I print "We'll end here" inside the Run, I'm new to Java, so any help would be much appreciated.
My console prints this:
run:
We'll start here!
BUILD SUCCESSFUL (total time: 6 seconds)
You've created a thread, but you haven't overridden the run method - instead you've created a Run method. Java is case-sensitive. Change this:
public void Run() {
...
}
to this:
#Override
public void run() {
...
}
Using #Override asks the compiler to validate that you really are overriding something - if you'd used that before, you'd have received a compile-time error.
Additionally, I'd recommend implementing Runnable and passing that to the Thread constructor instead of overriding run in Thread itself:
Runnable runnable = new Runnable() {
#Override
public void run() {
...
}
};
new Thread(runnable).start();
Again, if you'd implemented the interface instead of creating an anonymous subclass of Thread, the compiler would have picked up the problem.
EDIT: As noted in comments, your loop is never-ending, too... but you'll see that when it actually gets as far as running.
The thread's method you must override is run. Because that's the one you are inheriting and which is intented to actually run what thread must do.
So:
It's all about inheritance.
Add #Override annotations in such codes. (IDE should have suggested it).
Remember Java is case sensitive.
Stick to Camel notation. In Java, all is supposed to be coded according to it.
4.1 Classes and Interfaces are supposed to start with capital letters.
4.2 Attributes and methods are supposed to start with small letters.
You should have done:
#Override
public void run() {
//Your code here
}