|
| |||||||||||||||
|
|
Start of topic | Skip to actions
Lab 11 - Games For TwoIntroductionThe game of Tic-Tac-Toe is a often used as an example for two-person games where each player takes turn to place a game piece on a two dimensional game board. The discussion of such a game serves to illustrate the notion game trees, and in particular, the min-max principle: how to compute the values of the game tree nodes and select the best next move. Even though these algorithms are initially described in high-level abstract terms, this is not reflected in their standard implementations. Traditional Tic-Tac-Toe code from
The Best Little Tic-Tac-Toe Game in TexasAs one can see from the demo, the program is not really about playing Tic-Tac-Toe but is about using a 2-pesron game design as a vehicle to learn BIGGER concepts in computing:
/** This class represents an abstract player of the game.
* The players are represented as a circular linked list.
*/
public abstract class APlayer {
private IRequestor requestor;
private int player;
private APlayer nextPlayer = this;
/** The constructor for the class.
* @param requestor The requestor that the player uses to request moves of the board.
* @param player The player number of this player.
*/
public APlayer(IRequestor requestor, int player) {
this.requestor = requestor;
this.player = player;
}
/** Tells this player to take its turn. */
public abstract void takeTurn();
/** other methods elided... */
}
/* This class represents a concrete computer player. */
public class ComputerPlayer extends APlayer {
private INextMoveStrategy nextMoveStrategy;
private IModel model;
/** The constructor for the class.
* @param requestor The requestor that this player will use to communicate with the model.
* @param player This player's player number.
* @param model A reference to the IModel. Needed to call the getNextMove() method
* of the INextMoveStrategy.
* @param nextMoveStrategy The strategy used to calculate this player's next move.
*/
public ComputerPlayer(IRequestor requestor, int player, IModel model, INextMoveStrategy nextMoveStrategy) {
super(requestor, player);
this.model = model;
this.nextMoveStrategy = nextMoveStrategy;
System.out.println("ComputerPlayer is using " + nextMoveStrategy);
}
/** Used by the TurnControl to tell this player to take its turn.
* When the computer takes its turn, it will calculate its next move and
* then request that move of the model.
* If the computer makes and invalid move, the computer will print an error
* message to the screen and then it will take its turn again.
*/
public void takeTurn() {
System.out.print("Computer player "+ getPlayer() +" ("+ this +") takes turn...");
final Point p = nextMoveStrategy.getNextMove(model, getPlayer());
System.out.println("and moves to "+ p);
getRequestor().setTokenAt (p.y, p.x, getPlayer(), new IRejectCommand() {
// ANONYMOUS COMMAND!
public void execute() {
System.out.println("ComputerPlayer: The move at ("+p.x+", "+p.y+") is invalid.");
takeTurn();
}
});
}
}
When a player is instantiated, it is given an IRequestor to communicate with the model. As shown in ComputerPlayer.takeTurn(), the computer player gets the best next move from the next move strategy and then asks the requestor ( getRequestor() ) to set the game token at the best move's position, passing to the requestor an anonymous IRejectCommand, in case the move is illegal. This situation may happen if the next move strategy is a totally random move.
The IRejectCommand has only one method called execute()
/** A basic command that is executed when a move request has been rejected by the model.
*/
public interface IRejectCommand {
/** This method is called by the model when a move is rejected. */
public abstract void execute();
}
The IRequestor has only one method called setTokenAt(...)
/** This interface encapsulates the request mechanism used by an APlayer to try
* to make a move to a given (row, col) by a given player.
* This is the public (client) end of a "Facade" design pattern that hides the
* internal workings of the model.
*/
public interface IRequestor {
/** Requests to the model that a given player's token be placed on the
* internal board at (row, col).
* An IRejectCommand is supplied that should be executed if the request is rejected.
*/
public abstract void setTokenAt(int row, int col, int player, IRejectCommand rejectCommand);
}
A player gets its requestor at construction time. Who creates the concrete requestor and passes it to the player? The GameModel via its getPlayers() method! The GameModel has access to the board model, the turn control manager, and the view administrator. By creating an IRequestor as an anonymous inner class, the GameModel can thus set up the appropriate context for a player to make a request for a move without knowing anything about the board, the view, and the turn control!
In this lab you are to work with others to try to implement theIRequestor anonymous inner class that is stubbed out the GameModel code. This is part of the upcoming homework 11.
Topic Actions: Edit | Attach | Printable | Raw View | Backlinks: Web, All Webs | History: r14 < r13 < r12 < r11 < r10 | More topic actions
Webs: Main | TWiki | Africa | CPSX | EmbeddedSystems | Gpce | Houston | International | K12 | MetaOCaml | MulticoreOCR | ProgrammingLanguages | RAP | RIDL | Sandbox | SpeechClub | Teaching | Texbot | WG211 Web Actions: | ||||||||||||||
This work is licensed under a Creative Commons Attribution 2.5 License. Please follow our citation guidelines.