让玩家在java

时间:2017-02-11 10:07:55

标签: java multithreading timer

我想在tictactoe游戏中添加以下功能:如果一个玩家轮流但是他/她在一段时间(10秒)内没有做任何事情,那么就是另一个玩家的回合。

在“GameHub”类中(扩展一个Server类只用于创建一个游戏)我有内部类“GameState”,它维护游戏的当前状态并将其作为消息传递给服务器(然后它被转发给所有客户/玩家。

public class GameHub extends Server {

private GameState state;

public GameHub(int port) throws IOException {
    super(port);
    state = new GameState();
    setAutoreset(true);
}

protected void messageReceived(int playerID, Object message) {
    state.applyMessage(playerID, message);
    sendToAll(state);
}

protected void playerConnected(int playerID) {
    if (getPlayerList().length == 2) {
        shutdownServerSocket();
        state.startFirstGame();
        sendToAll(state);
    }
}

protected void playerDisconnected(int playerID) {
    state.playerDisconnected = true;
    sendToAll(state);
}

public static class GameState implements Serializable {

    public boolean playerDisconnected;

    public char[][] board;

    public boolean gameInProgress;

    public int playerPlayingX;
    public int playerPlayingO;
    public int currentPlayer;

    public boolean gameEndedInTie;
    public int winner;

    public void applyMessage(int sender, Object message) {        

        if (gameInProgress && message instanceof int[] && sender == currentPlayer) {
            int[] move = (int[]) message;
            if (move == null || move.length != 2) {
                return;
            }
            int row = move[0];
            int col = move[1];
            if (row < 0 || row > 2 || col < 0 || col > 2 || board[row][col] != ' ') {
                return;
            }

            board[row][col] = (currentPlayer == playerPlayingX) ? 'X' : 'O';

            if (winner()) {
                gameInProgress = false;
                winner = currentPlayer;
            } else if (tie()) {
                gameInProgress = false;
                gameEndedInTie = true;
            } 

            else {
                currentPlayer = (currentPlayer == playerPlayingX) ? playerPlayingO : playerPlayingX;
            }

        } else if (!gameInProgress && message.equals("newgame")) {
            startGame();
        }
    }

    void startFirstGame() {
        startGame();
    }

    private void startGame() {
        board = new char[3][3];
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                board[i][j] = ' ';
            }
        }
        int xPlr = (Math.random() < 0.5) ? 1 : 2;
        playerPlayingX = xPlr;  // Will be 1 or 2.
        playerPlayingO = 3 - xPlr;  // The other player ( 3 - 1 = 2, and 3 - 2 = 1 )
        currentPlayer = playerPlayingX;
        gameEndedInTie = false;
        winner = -1;
        gameInProgress = true;
    }

    private boolean winner() {
        if (board[0][0] != ' '
                && (board[0][0] == board[1][1] && board[1][1] == board[2][2])) {
            return true;
        }
        if (board[0][2] != ' '
                && (board[0][2] == board[1][1] && board[1][1] == board[2][0])) {
            return true;
        }
        for (int row = 0; row < 3; row++) {
            if (board[row][0] != ' '
                    && (board[row][0] == board[row][1] && board[row][1] == board[row][2])) {
                return true;
            }
        }
        for (int col = 0; col < 3; col++) {
            if (board[0][col] != ' '
                    && (board[0][col] == board[1][col] && board[1][col] == board[2][col])) {
                return true;
            }
        }
        return false;
    }

    private boolean tie() {
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                if (board[i][j] == ' ') {
                    return false;
                }
            }
        }
        return true;
    }

}

}

对于时间测量,我有“倒计时”课程,目的是在经过所需的时间后更换球员。

     public class Countdown {

        int timer;

        public void counter(int timeFrame) {

            timer = timeFrame;

            Timer TimerA = new Timer();
            TimerTask TaskA = new TimerTask() {

                @Override
                public void run() {
                    if (timer >= 0) {
                        timer--;
                    }
                    if (timer == -1) {
                        currentPlayer = (currentPlayer == playerPlayingX) ? playerPlayingO : playerPlayingX;
                        TimerA.cancel();
                    }

                }
            };
            TimerA.schedule(TaskA, 0, 1000);
        }

        public int getTimer(){
            return timer;
        }

    }

正是在那一部分我被困住了。在我看来,我需要在“GameState”类中的某处添加和启动计时器,但由于某种原因,我无法弄清楚究竟在哪里。

int timeFrame = 10;
Countdown C = new Countdown();
C.counter(timeFrame);

我认为它应该在“else block”中启动

else {currentPlayer = (currentPlayer == playerPlayingX) ? playerPlayingO : playerPlayingX;
int timeFrame = 10;
Countdown C = new Countdown();
C.counter(timeFrame);}

但它无法正常工作=&gt;它适用于“playerPlayingO”(如果他延迟了10秒,他就错过了他的回合)。 playerPlayingX不受影响......

可能我也错过了其他的东西......

1 个答案:

答案 0 :(得分:0)

如果你正在使用JavaFX,你可以使用task - 只需让任务运行如下:

Thread.sleep(10000); //Wait 10 Secs
if (activePlayer == initialActivePlayer) switchPlayer(); //Better write your own "ShouldWeSwitch"-Condition

您可能需要稍微调整一下同步,并在玩家触发开关时终止任务,但这可能适用于您的游戏。

PS:如果你没有使用JavaFX,你可以通过创建一个扩展Thread

的类来创建自己的任务。