在Java的Rummikub游戏中实现计时器

时间:2018-12-04 19:22:54

标签: java timertask

我正在用Java制作rummikub游戏,我想实现一个运行2分钟的计时器。在2分钟内,用户必须输入有关他们是否要播放,跳过还是要转弯(如果已经播放了图块)的输入。如果他们选择游戏,则需要选择是要播放单个图块,进行融合还是退出序列(所有这些输入都必须在2分钟内完成)。如果他们在2分钟内仍未完成转牌,则该转牌必须结束且不需输入任何信息,下一位玩家将进行转牌。我将在下面发布一些代码。我应该如何实施此计时器?我在Human类和GameTimer类中有2种播放方法,在Game类中有playTurn()方法。此刻我正在测试10秒

package com.COMP3004.Rummikub.models;

import java.util.Timer;
import java.util.TimerTask;

public class GameTimer {
    private int seconds;
    private boolean started;
    private boolean stopped;
    private Timer timer;
    private TimerTask task = new TimerTask() {

        public void run() {
            seconds++;
            System.out.print(seconds + ", ");
            if(seconds % 30 == 0) {
                System.out.println();
            }
            if(seconds == 10) {
                stop();
            }
        }
    };

    public GameTimer() {
        started = false;
        stopped = true;
        seconds = 0;
        timer = new Timer();
    }

    public void start() {
        started = true;
        stopped = false;
        //timer.schedule(task, 0, 1000);
        new Timer(true).schedule(task, 0, 1000);
        //System.out.println("Timer Started");

        /*if(seconds == 10) {
            stop();
        }*/
    }

    public boolean isStarted() { return started; }

    public void stop() {
        task.cancel();
    seconds = 0;
    //System.out.println("Timer Stopped");

    stopped = true;
}

public boolean isStopped() { return stopped; }

public int getSeconds() { return seconds; }

public boolean stopsAtRightTime() {
    start();
    /*System.out.println(seconds);
    int secondsPassed = 0;

    do {
        secondsPassed = seconds;
        System.out.println(seconds);
    }
    while(seconds <= 10);
    System.out.println(secondsPassed);

    this.stop();

    if(secondsPassed == 10) {
        return true;
    }*/
    int secondsPassed = 0;

    try {
        Thread.sleep(60000);
        secondsPassed = seconds;
        System.out.println(seconds);
    }
    catch(InterruptedException e) {

    }
    if(secondsPassed == 60 || secondsPassed == 0) {
        //stop();
        return true;
    }

    return false;
}

}

public boolean makeAPlay(Scanner reader) {
    returned = false;
    while(true) {
    System.out.println("Choose one of the following commands:");
    System.out.println(" - 'M' to play a meld.");
    System.out.println(" - 'T' to play an individual tile.");
    System.out.println(" - 'B' to move an existing tile on the board.");
    System.out.println(" - 'L' to exit this sequence.");
    decision2 = 'K';

    TimerTask timerTask = new TimerTask() {
        public void run() {
            if(decision2 == 'K') {
                decision2 = 'L';
                return;
            }
        }
    };

    try {
        Timer timer = new Timer();
        timer.schedule(timerTask, 10000 - getTimer().getSeconds()*1000);
        decision2 = (decision2 == 'L')? 'L': reader.next().toUpperCase().charAt(0);
        timer.cancel();
    }
    catch(Exception e) {

    }

    if (decision2 == 'M') {
        String tileChoice = "";
        Meld meld = new Meld();
        this.getHand().createMeld();

        while (!tileChoice.equals("D")) {
            if (this.getHand().size == 0) { break; }
            System.out.println("Current Meld: " + meld.meldToString());
            System.out.println("Hand: " + this.getHand().handToString());
            System.out.println("Select a tile you'd like to add to your meld, type 'D' to exit.");
            tileChoice = reader.next().toUpperCase();
            if (tileChoice.equals("D")) { break; }
            for (int i = 0; i < this.getHand().size; i++) {
                if (this.getHand().getTile(i).tileToString().equals(tileChoice)) {
                    meld.addTile(this.getHand().getTile(i));
                    this.getHand().removeFromHand(i);
                    break;
                } else if (i == (this.getHand().size - 1) && !(tileChoice.equals("D"))) {
                    System.out.println("It seems that the tile " + tileChoice + " isn't in your posession. Please try again.");
                }
            }
        }
        if (tileChoice.equals("D")) {
            if (meld.getMeldSize() >= 3 && meld.checkIfValidMeld() == true) {

                for (int i = 0; i < meld.getMeldSize(); i++) {
                    System.out.println(meld.getTileInMeld(i).tileToString());
                }

                this.playMeld(meld, reader);
                turnValue = turnValue + meld.getMeldValue();
            } else {
                System.out.println("Invalid meld. Please try again.");
                for (int i = 0; i < meld.getMeldSize(); i++) {
                    this.getHand().addTile(meld.getTileInMeld(i));
                }
                this.getHand().sortHand();
                tileChoice = "";
            }
        }
    }

    if (decision == 'T') {
        if (initialMeldPlayed == true) {
            String tileChoice = "";
            System.out.println("Hand: " + this.getHand().handToString());
            System.out.println("Which tile would you like to add to the board?");
            tileChoice = reader.next().toUpperCase();
            Tile tempTile = this.getHand().getTile(tileChoice);

            if (this.getHand().getPlayerHand().contains(tempTile)) {
                System.out.println("Where would you like to put " + tempTile.tileToString() + " ?");
                System.out.println("X-Coordinate: ");
                int xTile = reader.nextInt();
                System.out.println("Y-Coordinate: ");
                int yTile = reader.nextInt();

                for (int i = 0; i < this.getHand().size; i++) {
                    if (this.getHand().getTile(i).tileToString().equals(tileChoice)) {
                        this.addTile(this.getHand().getTile(i), xTile, yTile);
                    }
                }

                System.out.println("Board:");
                board.boardToString();
            } else {
                System.out.println("It seems that you don't have " + tileChoice + " isn't in your hand. Please try again.");
            }
        } else {
            System.out.println("You cannot play individual tiles on the board during your initial meld.");
        }
    }

    if (decision == 'B') {
        if (initialMeldPlayed == true) {
            while(true) {
                board.boardToString();
                System.out.println("Which tile would you like to move on the board?");
                System.out.println("Current X-Coordinate ('-1' to exit): ");
                int xTile = reader.nextInt(); if (xTile == -1) { break; }
                System.out.println("Current Y-Coordinate ('-1' to exit): ");
                int yTile = reader.nextInt(); if (yTile == -1) { break; }
                Spot oldSpot = board.getSpot(xTile, yTile);
                Tile tile = oldSpot.getTile();
                System.out.println("Where would you like to move tile " + tile.tileToString() + " to?");
                System.out.println("New X-Coordinate: ");
                int xTileNew = reader.nextInt();
                System.out.println("New Y-Coordinate: ");
                int yTileNew = reader.nextInt();
                Spot newSpot = board.getSpot(xTileNew, yTileNew);
                this.moveTile(tile, newSpot);
            }
        } else {
            System.out.println("You cannot manipulate the board during your initial meld.");
        }
    }

    if (decision == 'L') {
        if (board.checkIfValidMelds() == false) {
            System.out.println("That wasn't a valid move. Please try again.");
            this.setTilesBeenPlayed(false);
            this.undoTurn();
            return false;
        } else {
            return false;
        }
    }
    return returned;
    }
    //return false;
}

public GameTimer getTimer() { return timer; }

public void play(Scanner reader, Deck deck) /*throws InterruptedException*/ {
    turnValue = 0;
    timer = new GameTimer();
    long startTime = System.currentTimeMillis();
    while( /*(System.currentTimeMillis()-startTime)<10000 ||*/ myTurn == true /*||timer.getSeconds()!=10*/) {
        //reader = new Scanner(System.in);
        System.out.println("Choose one of the following commands:");
        System.out.println(" - 'P' to play your turn.");
        System.out.println(" - 'S' to skip your turn & draw a tile.");
        System.out.println(" - 'E' to end your turn if you've already played atleast one tile.");


        if(timer.getSeconds() == 0) {
            timer.start();
        }

        //while(timer.getSeconds() != 10) {

        System.out.print(timer.isStopped());

        /*else if(timer.getSeconds() == 10) {
            //this.setHasInitialMeldBeenPlayed(false);
            this.setTilesBeenPlayed(false);
            this.undoTurn();
            Tile t = this.getHand().dealTile(deck);
            System.out.println("Out of time");
            System.out.println("Turn ended: Player drew " + t.tileToString() + ".");
            System.out.println("----------------------------------------");
            this.setTurnStatus(false);
            timer.stop();

        }*/
        decision = 'N'; //'N' for no input

        TimerTask task = new TimerTask() {
            public void run() {
                if(decision == 'N') {
                    Tile t = getHand().dealTile(deck);
                    System.out.println("Timeout");
                    System.out.println("Turn ended: Player drew " + t.tileToString() + ".");
                    System.out.println("----------------------------------------");
                    setTilesBeenPlayed(false);
                    undoTurn();

                    setTurnStatus(false);   
                    //return;
                }
                if(timer.getSeconds() == 10) {

                }
            }
        };

        try {

            Timer timer = new Timer();
            timer.schedule(task, 10000);

            decision = reader.next().toUpperCase().charAt(0);
            timer.cancel();
        }
        catch (Exception e) {

        }

        if (decision == 'P') {
            makeAPlay(reader);
        } else if (decision == 'S') {
            if (hasTileBeenPlaced == false) {
                Tile t = this.getHand().dealTile(deck);
                System.out.println("Turn ended: Player drew " + t.tileToString() + ".");
                System.out.println("----------------------------------------");
                this.setTurnStatus(false);
                timer.stop();
            } else {
                System.out.println("You've already made a play. Try typing 'E' to end your turn.");
            }
        } else if (decision == 'E') {
            if (initialMeldPlayed == false) {
                if (turnValue >= 1) {
                    System.out.println("Initial Meld Completed.");
                    System.out.println("----------------------------------------");
                    this.setHasInitialMeldBeenPlayed(true);
                    this.setTilesBeenPlayed(true);
                    this.setTurnStatus(false);
                    timer.stop();
                } else {
                    System.out.println("Your Initial Meld total must be greater than or equal to 30 points.");
                    System.out.println("You played: " + turnValue + ". Please try again."); 
                    this.setHasInitialMeldBeenPlayed(false);
                    this.setTilesBeenPlayed(false);
                    this.undoTurn();
                    turnValue = 0;
                }
            } else if (initialMeldPlayed == true) {
                if (hasTileBeenPlaced == true) {
                    this.setTurnStatus(false);
                    timer.stop();
                } else {
                    this.undoTurn();
                    System.out.println("You must either play your turn or draw a tile.");
                }
            }
        }
        else {
            System.out.println("You may have entered the wrong character. Please try again.");
        }
        //}
    }
}
public void playTurn(int i) {
    printAll();
    // Play if human
    if (allPlayers.get(i).isAI() == false && allPlayers.get(i).myTurnStatus() == true) {
        System.out.println("Player " + (i+1) + "'s Hand[" + allPlayers.get(i).getHand().size + "]: " + allPlayers.get(i).getHand().handToString());
        int oneMoreTile = allPlayers.get(i).getHand().getNumTiles() + 1;
        TimerTask timerTask = new TimerTask() {
            public void run() {
                if(allPlayers.get(i).getHand().getNumTiles() == oneMoreTile) {

                }
                else if(allPlayers.get(i).getHand().getNumTiles() == oneMoreTile - 1) {
                    Tile t = allPlayers.get(i).getHand().dealTile(deck);
                    System.out.println("ended: Player drew " + t.tileToString() + ".");
                    System.out.println("----------------------------------------");
                    allPlayers.get(i).setTurnStatus(false);
                }
            }
        };
        try {
            Timer timer = new Timer();
            timer.schedule(timerTask, 10000);
            allPlayers.get(i).play(reader, deck);
            timer.cancel();
            if(allPlayers.get(i).myTurnStatus() == false) {
                nextPlayersTurn(i);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    // Play if AI
    if (allPlayers.get(i).isAI() == true && allPlayers.get(i).myTurnStatus() == true) {
        allPlayers.get(i).play(reader);

        if (allPlayers.get(i).hasTilesBeenPlayed() == false) {
            Tile t = allPlayers.get(i).getHand().dealTile(deck);
            System.out.println("Turn ended: Player " + (i+1) + " has decided to draw a tile.");
            System.out.println("Tile drawn: " + t.tileToString());
            nextPlayersTurn(i);
        }
    }
    // Sets next players turn
    nextPlayersTurn(i);
}

1 个答案:

答案 0 :(得分:0)

这是非常快速的编写代码,但我希望它可以使您对事件管理有更好的看法。

private GameTimer _task; // the object.

// .....................

// Put these 2 lines wherever you call the event to start.
_task.setStartTime(System.currentTimeMillis() + (60000L * eventTime)); // eventTime == 2 minutes
ThreadPoolManager.getInstance().executeGeneral(_task);

// .....................


class GameTimer implements Runnable
{
    private long _startTime;
    public ScheduledFuture<?> nextRun;

    public GameTimer(long startTime)
    {
        _startTime = startTime;
    }

    public void setStartTime(long startTime)
    {
        _startTime = startTime;
    }

    @Override
    public void run()
    {
        int delay = (int) Math.round((_startTime - System.currentTimeMillis()) / 1000.0);

        if (delay == 0)
        {
            // start
            if (isStarted())
            {
                stop();
                // You can place a scheduler here to trigger an auto-start.
            }
            else
            {
                start();
                nextRun = ThreadPoolManager.getInstance().scheduleGeneral(this, endEvent);
                // endEvent is the time you want the run() method to run again.
                // In this case, when the event is finished.
                // This line is triggering the jvm to auto run this method again in the given time.
                // So if the event is already started, the run() method will run again and it will close it again.
            }
        }
    }
}

仅提及代码只是如何更好地重写事件计时器的示例。

希望有帮助!