📄 gamemaster.java
字号:
//GameMaster.java
/**
*
* @author Sean Bridges
* @version 1.0.1
*
* The game master controls the state of the game, and is responsible for
* making the players move in sequence.
*
* If a subclass overrides start, restart or stop, it should call super.start,
* restart or stop respectively.
*
* Whenever start or restart are called a new thread is created which
* asks the players for their moves in sequence.
* If there was an old thread, the old thread will be interrupted, and discarded.
*/
import java.util.*;
public class GameMaster
{
//--------------------------------------------------------
//instance variables
private Vector listeners = new Vector(); //listeners to the state,
//use a vector for jdk1.0 compatability
private Player[] players; //the players of the game
private Board board;
private int currentPlayerIndex = 0;
private GameThread gameThread;
//--------------------------------------------------------
//constructor
/**
* Creates new GameMaster.
* The PlayerArray should have at least 1 player in it.
* The order the players occur in the array is the order in which the
* players will move.
* If the array is empty, an ArrayOutOfBoundsException will be thrown.
*/
public GameMaster(Board board, Player[] players )
{
if(players.length == 0)
{
System.err.println("Error, player array is empty, GameMaster() ");
throw new ArrayIndexOutOfBoundsException("Game Master created with empty array");
}
this.board = board;
this.players = players;
}
//--------------------------------------------------------
//instance methods
//------------------------------------------------------
//listeners
/**
* Add a game event listener.
*/
public synchronized void addListener(GameEventListener l)
{
listeners.addElement(l);
}
public synchronized void removeListener(GameEventListener l)
{
listeners.removeElement(l);
}
/**
* Clone the listener vector in case the list of listeners
* is modified while informing the listeners.
* This means the enumeration enumerates a copy of the list,
* and additions can be made to the list while informing listeners.
*/
private synchronized Enumeration enumerateListeners()
{
return ((Vector) listeners.clone() ).elements();
}
private void notifyListenersMoveMade(Move aMove)
{
Enumeration e = enumerateListeners();
while(e.hasMoreElements())
{
((GameEventListener) e.nextElement()).moveMade(aMove);
}
}
private void notifyListenersGameReStarted()
{
Enumeration e = enumerateListeners();
while(e.hasMoreElements())
{
((GameEventListener) e.nextElement()).gameRestarted();
}
}
private void notifyListenersGameStarted()
{
Enumeration e = enumerateListeners();
while(e.hasMoreElements())
{
((GameEventListener) e.nextElement()).gameStarted();
}
}
private void notifyListenersGameStoped()
{
Enumeration e = enumerateListeners();
while(e.hasMoreElements())
{
((GameEventListener) e.nextElement()).gameStoped();
}
}
//--------------------------------------------------------
//player management
/**
* The players whose move it currently is.
*/
private synchronized Player getCurrentPlayer()
{
return players[currentPlayerIndex];
}
/**
* Advance the player
*/
private synchronized void advancePlayer()
{
currentPlayerIndex ++;
if(currentPlayerIndex >= players.length)
{
currentPlayerIndex = 0;
}
}
//------------------------------------------------------
//state
/**
* Start the game.
* Tells the board to start, starts the game loop thread,
* then notifies listeners.
*/
public synchronized void startGame()
{
if(gameThread != null)
{
gameThread.stopThread();
gameThread = null;
}
board.gameStarted();
currentPlayerIndex = 0;
gameThread = new GameThread();
gameThread.start();
notifyListenersGameStarted();
}
/**
* Stop the game.
* Stops the game thread, tells the board the game is stopped, and
* then notifies listeners.
*/
public synchronized void stopGame()
{
if(gameThread != null)
{
gameThread.stopThread();
gameThread = null;
}
board.gameStoped();
notifyListenersGameStoped();
}
/**
* Restart the game.
* Stops the current game loop, tells the board to restart,
* starts a new game loop, and then notifies listeneres.
*/
public synchronized void restartGame()
{
if(gameThread != null)
{
gameThread.stopThread();
gameThread = null;
}
board.gameRestarted();
currentPlayerIndex = 0;
gameThread = new GameThread();
gameThread.start();
notifyListenersGameReStarted();
}
//--------------------------------------------------------
//inner classes
/**
* The game thread class does the work of
* making the players move.
* Exits after stop is called.
*/
class GameThread extends Thread
{
public boolean active = true;
public void stopThread()
{
if(active)
{
active = false;
this.interrupt();
}
}
public void run()
{
while( active && ! board.isGameOver() )
{
//get the players move.
Player player = getCurrentPlayer();
Move move = player.getMove((Board) board.clone());
if(move == null)
{
//ignore null moves
continue;
}
//if we are still active, make the move
boolean moveMade = false;
if(active)
{
moveMade = board.move(move);
}
//if we are still active, and the move was made, notify listeners
if(active && moveMade)
{
advancePlayer();
notifyListenersMoveMade(move);
}
}//end while
if(active && board.isGameOver())
{
notifyListenersGameStoped();
}
active = false;
}//end run
}//end class GameThread
}//end class GameMaster
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -