tags:

views:

74

answers:

2
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?

A: 

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()

Midhat
The timer will already be running in another thread. I believe the current code will actually work in terms of displaying the existing guesses (when `timesUP.run()` calls `endGame()`, although it won't shut down cleanly. It also doesn't address the thread safety of displaying from one thread having added guesses from another.
Jon Skeet
Ah your right. endGame() gets called but the program doesn't exit as I was expecting. Im not familiar with threads though, could you give me hint where I go from here?
hspim
+1  A: 

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.

Jon Skeet
Ah, didnt realise inner classes inherit the reference. I'm a little confused to the problem Midhat is referring to though, could you clarify?
hspim
@hspim: Well, the timer is being called on one thread of execution - but you're still in the `while (true)` loop on the main thread. You can make `endGame()` store a flag saying "I'm done" and change your while loop to stop when that's changed... although you'll still have to wait for the player to finish their current guess.
Jon Skeet
tried using a boolean to achieve this but it doesnt seem to end the while loop. edited the code above to its current format. any advice?
hspim
@hspim: Try making it volatile - currently you don't have any synchronization between the threads. Don't forget that setting active to false won't stop the `nextLine()` call - you'll still need to wait for the player to hit return.
Jon Skeet