Holger's
Java API

com.antelmann.game
Class AbstractGame

java.lang.Object
  extended by com.antelmann.game.AbstractGame
All Implemented Interfaces:
GamePlay, Serializable, Cloneable
Direct Known Subclasses:
AwariGame, BlackJack, CheckersGame, ChessGame, EightQueens, FourWinsGame, GomokuGame, MineSweeper, MuehleGame, ReversiGame, Solitaire, TickTackToe, TilePuzzle, WolfsheepGame, WSPuzzle

public abstract class AbstractGame
extends Object
implements GamePlay

This class implements the generic behaviour of a game to ease GamePlay implementations. The following functions are abstract and need to be implemented to represent the domain knowlege:

 protected GameMove[] listLegalMoves ();
 protected boolean    pushMove       (GameMove);
 protected boolean    popMove        ();
 
If the game does not support undoing of moves, the method popMove() may always simply return false.
Other than the given abstract functions, the following methods need to be declared by an inheriting class to account for the fact that AbstractGame implements GamePlay:
 public int    nextPlayer ()
 public int[]  getWinner  ()
 
The function getResult(int playerRole) is implemented in a way that it returns 1 if game is won, -1 if game is lost and 0 if no winners are present, which is appropriate for many games, but may have to be overridden. Finally, the method clone() must be overridden in case the extending class has non-primitive members to provide a deep copy. It is probably a good idea to also implement a useful toString() method, so that the game can be visualized properly.
In addition to the above, you will also have to provide a GameMove object that represents a move that can be applied to a game to alter its status.
Note that this implementation of GamePlay is designed for game that have a finite rather easily determinable list of legal moves. Also, this implementation assumes that the next player in a game is well defined at any given state.

Version:
0.8
Author:
Holger Antelmann
See Also:
GamePlay, GameMove, Serialized Form

Constructor Summary
AbstractGame(String name, int numberOfPlayers)
           
 
Method Summary
 boolean addObserver(GameObserver observer)
          observer is called on makeMove(GameMove); cloned games will point to the same set of observers.
protected  void clearRedoList()
          may be called by the subclass if certain events alter the game status so that the given redo moves cannot be applied anymore
 Object clone()
          Any inheriting class with non-primitive members must override this clone() method to provide a full deep copy of the object, which is essential for spawnChild() to work correctly.
 boolean gameOver()
          This convenience function gameOver() simply checks whether there are any legal moves left; consequently, unless this function is overridden, listLegalMoves() must not check for gameOver().
 String getGameName()
          returns the name of the game for display in titles (as toString() may be used to display something else)
 GameMove getLastMove()
          getLastMove() is a convenience function which returns the last element of the GameMove[] from getMoveHistory() in case the array has any elements in it; null is returned otherwise.
 int getLastPlayer()
          getLastPlayer() is a convenience function which simply looks up the last move and then returns the playerRole that played it
 GameMove[] getLegalMoves()
          Instead of overriding this (final) function, implement listLegalMoves() instead.
 GameMove[] getLegalMoves(int playerRole)
          getLegalMoves(playerRole) returns the subset of getLegalMoves() where player == move.getPlayer().
 GameMove[] getMoveHistory()
          returns an array containing all moves that have been applied to the current game status; the last move that was applied is the last move in the array at index (getMoveHistory().length-1)
 int getNumberOfRedoMoves()
           
 GameObserver[] getObservers()
           
 GameMove[] getRedoList()
          returns an array containing all moves that have been taken back and could be reapplied; the GameMove at the index 0 is the next object that can be reapplied.
 double getResult(int playerRole)
          a default implementation for convenience which may suit most games that do not involve betting or any form of measuring how 'big' the win was.
 boolean isLegalMove(GameMove move)
          this implementation checks whether the move is contained in the array returned by getLegalMoves(); thus this method relies on GameMove.equals() being implemented properly for the move in question
 boolean isWinner(int gameRole)
          isWinner() checks whether the given gameRole is in the array retruned by getWinner().
protected abstract  GameMove[] listLegalMoves()
          listLegalMoves() returns the legal moves for this game.
static AbstractGame loadFromFile(String fileLocation)
          just a convenience function
 boolean makeMove(GameMove move)
          If the move is successfully carried out, the function returns true, false otherwise.
 int numberOfMoves()
           
 int numberOfPlayers()
          numberOfPlayers() returns the number of game roles in the GamePlay.
protected abstract  boolean popMove()
          popMove undoes the last move by altering the game board to the stage before the last move happened.
protected abstract  boolean pushMove(GameMove move)
          pushMove takes a GameMove and alters the game according to to the move.
 boolean redoMove()
          returns true only if last move previously taken back is successfully reapplied.
 boolean removeObserver(GameObserver observer)
           
protected  void resetLegalMoves()
          forces a recalculation of getLegalMoves() with listLegalMoves(); needed if the extending class alters the game status without calling makeMove(), redoMove() or undoLastMove() and the move history and redo list is to be maintained
protected  void resetLists()
          resetList() forces a recalculation of getLegalMoves() and also resets the move list and the redo list.
 void saveToFile(String fileLocation)
          just a convenience function
 GamePlay spawnChild(GameMove move)
          spawnChild() creates a clone of the current game and advances the game by the given GameMove.
 String toString()
          overridden to provide useful information about the game
 boolean undoLastMove()
          If the last move is successfully taken back, this method returns true, false otherwise.
 boolean undoMoves(int n)
          calls undoLastMove() either n times or as many times as there are numberOfMoves(), whichever is smaller
 
Methods inherited from class java.lang.Object
equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 
Methods inherited from interface com.antelmann.game.GamePlay
getWinner, nextPlayer
 

Constructor Detail

AbstractGame

public AbstractGame(String name,
                    int numberOfPlayers)
Method Detail

addObserver

public boolean addObserver(GameObserver observer)
observer is called on makeMove(GameMove); cloned games will point to the same set of observers.


removeObserver

public boolean removeObserver(GameObserver observer)

getObservers

public GameObserver[] getObservers()

listLegalMoves

protected abstract GameMove[] listLegalMoves()
listLegalMoves() returns the legal moves for this game. This function is used by the final method getLegalMoves(), which is a wrapper around this method to avoid the overhead of generating the legal moves over and over again when called multiple times (as calculating legal moves is commonly expensive). Note that implementations of listLegalMoves() must not check for gameOver(), unless gameOver() is overridden not to check for listLegalMoves(). The same applies to isLegalMove().


pushMove

protected abstract boolean pushMove(GameMove move)
pushMove takes a GameMove and alters the game according to to the move.

Returns:
true only if the move was put on the board successfully.

popMove

protected abstract boolean popMove()
popMove undoes the last move by altering the game board to the stage before the last move happened.

Returns:
true only if the move was taken back successfully.

getGameName

public String getGameName()
Description copied from interface: GamePlay
returns the name of the game for display in titles (as toString() may be used to display something else)

Specified by:
getGameName in interface GamePlay
Returns:
the name of this game which is supposed to be a qualified identifier

isWinner

public boolean isWinner(int gameRole)
                 throws GameRuntimeException
isWinner() checks whether the given gameRole is in the array retruned by getWinner(). If getWinner() returns null, a GameRuntimeException is thrown.

Throws:
GameRuntimeException
See Also:
GamePlay.getWinner()

getLastPlayer

public int getLastPlayer()
                  throws GameRuntimeException
getLastPlayer() is a convenience function which simply looks up the last move and then returns the playerRole that played it

Throws:
GameRuntimeException - if no move has been made, yet.

gameOver

public boolean gameOver()
This convenience function gameOver() simply checks whether there are any legal moves left; consequently, unless this function is overridden, listLegalMoves() must not check for gameOver().


getLastMove

public GameMove getLastMove()
getLastMove() is a convenience function which returns the last element of the GameMove[] from getMoveHistory() in case the array has any elements in it; null is returned otherwise.


getLegalMoves

public final GameMove[] getLegalMoves()
Instead of overriding this (final) function, implement listLegalMoves() instead. This function serves as an optimization to ensure that if called more than once on the same game, this function will only have to compile the list of legal moves once. This function never returns null; if no legal moves are avaliable, it returns an array with 0 elements. If the method needs to recalculate the legal moves by calling listLegalMoves(), it is done so in a synchronized fashion.

Specified by:
getLegalMoves in interface GamePlay
See Also:
GamePlay.isLegalMove(GameMove)

resetLegalMoves

protected final void resetLegalMoves()
forces a recalculation of getLegalMoves() with listLegalMoves(); needed if the extending class alters the game status without calling makeMove(), redoMove() or undoLastMove() and the move history and redo list is to be maintained


clearRedoList

protected final void clearRedoList()
may be called by the subclass if certain events alter the game status so that the given redo moves cannot be applied anymore


resetLists

protected void resetLists()
resetList() forces a recalculation of getLegalMoves() and also resets the move list and the redo list. This is provided to allow an extending class to account for a situation where the game is altered to an extend where neither the move listory, the redo list, nor the the legal moves apply anymore.


isLegalMove

public boolean isLegalMove(GameMove move)
this implementation checks whether the move is contained in the array returned by getLegalMoves(); thus this method relies on GameMove.equals() being implemented properly for the move in question

Specified by:
isLegalMove in interface GamePlay
See Also:
GamePlay.getLegalMoves()

getLegalMoves

public final GameMove[] getLegalMoves(int playerRole)
getLegalMoves(playerRole) returns the subset of getLegalMoves() where player == move.getPlayer().


makeMove

public boolean makeMove(GameMove move)
Description copied from interface: GamePlay
If the move is successfully carried out, the function returns true, false otherwise. This function should work with any legal moves as returned by getLegalMoves().

Specified by:
makeMove in interface GamePlay

redoMove

public boolean redoMove()
Description copied from interface: GamePlay
returns true only if last move previously taken back is successfully reapplied.

Specified by:
redoMove in interface GamePlay

getNumberOfRedoMoves

public final int getNumberOfRedoMoves()

undoMoves

public boolean undoMoves(int n)
calls undoLastMove() either n times or as many times as there are numberOfMoves(), whichever is smaller


undoLastMove

public boolean undoLastMove()
Description copied from interface: GamePlay
If the last move is successfully taken back, this method returns true, false otherwise. If there are no moves to be taken back, the method also returns false. Undoing moves may not be supported by a game implementation, in which case this method would simply always return false.

Specified by:
undoLastMove in interface GamePlay

numberOfMoves

public final int numberOfMoves()

numberOfPlayers

public int numberOfPlayers()
Description copied from interface: GamePlay
numberOfPlayers() returns the number of game roles in the GamePlay. Each role in the game is represented by an integer so that (0 <= game_role < numberOfPlayers()). The association to actual Player objects is then done by AutoPlay objects.

Specified by:
numberOfPlayers in interface GamePlay
See Also:
AutoPlay, Player

getResult

public double getResult(int playerRole)
                 throws GameRuntimeException
a default implementation for convenience which may suit most games that do not involve betting or any form of measuring how 'big' the win was.

Specified by:
getResult in interface GamePlay
Returns:
1 if game is won, -1 if game is lost and 0 if no winners are present
Throws:
GameRuntimeException - if the game is still in progress

getMoveHistory

public final GameMove[] getMoveHistory()
Description copied from interface: GamePlay
returns an array containing all moves that have been applied to the current game status; the last move that was applied is the last move in the array at index (getMoveHistory().length-1)

Specified by:
getMoveHistory in interface GamePlay

getRedoList

public final GameMove[] getRedoList()
Description copied from interface: GamePlay
returns an array containing all moves that have been taken back and could be reapplied; the GameMove at the index 0 is the next object that can be reapplied.

Specified by:
getRedoList in interface GamePlay

spawnChild

public GamePlay spawnChild(GameMove move)
                    throws GameRuntimeException
spawnChild() creates a clone of the current game and advances the game by the given GameMove. Registered GameObserver objects are notified. The purpose of this function is to have a separate game instance that can be used by a Player to do whatever with it while determining heuristics. Note that the proper functionality of this method relies on the inheriting class to properly implement the clone() method to ensure a deep copy if the subclass has non-primitive members.

Specified by:
spawnChild in interface GamePlay
Throws:
GameRuntimeException - if the given move is not legal or cannot be performed because the game is not cloneable
See Also:
GameMove, clone()

clone

public Object clone()
             throws CloneNotSupportedException
Any inheriting class with non-primitive members must override this clone() method to provide a full deep copy of the object, which is essential for spawnChild() to work correctly. Ay overriding of this method should still begin with a call to super.clone(), though. Also, note that this clone() method does not clone the embedded GameMove objects, i.e. those are expected not to change (except for their heuristics, which shouldn't affect game functionality) - or the subclass will have to take care of this.

Specified by:
clone in interface GamePlay
Overrides:
clone in class Object
Throws:
CloneNotSupportedException
See Also:
spawnChild(GameMove)

saveToFile

public void saveToFile(String fileLocation)
just a convenience function


loadFromFile

public static AbstractGame loadFromFile(String fileLocation)
just a convenience function


toString

public String toString()
overridden to provide useful information about the game

Overrides:
toString in class Object


(c) 2001-2006 Holger Antelmann - all rights reserved (contact: info@antelmann.com)
see www.antelmann.com/developer for further details and available downloads