design patterns for games
DESCRIPTION
Design Patterns for Games. Stephen Wong Dung Nguyen Rice University. Let’s Play a Game. Sun’s Tic-Tac-Toe What can we learn from this? Arrays For-loops Nested Conditionals What aren’t we learning? Delineation of concepts from implementation Abstraction Design. Something Different…. - PowerPoint PPT PresentationTRANSCRIPT
Design Patterns for Games
Stephen Wong
Dung NguyenRice University
Let’s Play a Game
Sun’s Tic-Tac-Toe What can we learn from this?
– Arrays– For-loops– Nested Conditionals
What aren’t we learning?– Delineation of concepts from implementation– Abstraction– Design
Something Different…
It’s not really about TicTacToe…– It’s a vehicle to teach something BIGGER.
Abstraction Design Process Fundamental Principles
What’s in a Game?
X X
O
OController
ModelRules
PlayersStrategies
View
Buttons, etc.
Display outputsadapter
adapter
Install adapters
Game Model Rules of the Game
– Board configurations– Legal moves
Next Move Strategies– Random– Min-Max– Etc.
Player Management– Turn taking– Win/lose/draw notification– Fault handling
Decouple these components!
Abstractthese components!
The Rules of the Game
IBoardModel
IBoardStatusVisitor
makeMove(player, row, col), chkMoveCmd)IUndoMove , bdStatusVstr)
ICheckMoveCmdvalidMoveCase()invalidMoveCase()
player1WonCase(…)player0WonCase(…)
noWinnerCase(…)drawCase(…)IUndoMove
apply(…)
commandshost/visitor
Object execute(bdStatusVstr, param)
// other methods
State Diagram
Invalid Move State
Valid Move State
Non-Terminal State(no winner yet)
Terminal States
Player #0 Wins
Draw Game
Player #1 Wins
ABoardStatestate
State Design Pattern
TicTacToeBoard
Player1WonPlayer0Won DrawGame
ATerminalState NonTerminalState
IBoardModel
execute(IBoardStatusVisitor v, …)
v.player0WonCase(…)
state.execute(v, …)
v.player1WonCase(…) v.drawCase(…)
v.noWinnerCase(…)
Playing the GameComputerPlayer
takeTurn(…)
INextMoveStrategyPoint getNextMove(…)
Random AlphaBetaMinMax
The next move process is decoupledfrom the rules of the game!
FacadeAPlayer
takeTurn(…)
IBoardModel
makeMove(…)
TurnControl IView
IRequestor
What the player sees:
public interface IRequestor {
public abstract void setTokenAt(int row, int col, int player, IRejectCommand rejectCommand);
}
public interface IRejectCommand { public abstract void execute();}
Player FactoriesIView
GameModel
Set of APlayerfactories
Selected APlayerfactories
Only displays the toString()of the factories. The factories are treated as Objects!
private interface IMakePlayer {public APlayer create(int playerNo);
}
The Set of APlayer Factories
public Vector getPlayers() { Vector v = new Vector();
v.addElement(new IMakePlayer() {
public APlayer create(int playerNo) { return new HumanPlayer(requestor, playerNo, turnAdmin); } public String toString() { return "Human player"; } });
return v;}
Anonymous APlayer factory
IView only cares about this!
Factory method
Min-Max PrincipleV(s) = · For terminal state
· +1, if s is a winning state for that player· 0, if s is a draw state· -1, if s is a losing state for that player
· For non-terminal state· max{V(c) | c is a child valid move state of s} ,
if that player moves next· min{V(c) | c is a child valid move state of s},
if the other player moves next.
The best next move for a given player, m, is determined from max{V(c) | c S} where S is the set of available moves for that player. How max is computed is a variant.
Application of a process over a set!
Mapping and Lambda
Math/FP: Map(, S) = {(x) | x S}
Express our algorithm in terms of mapping, not iteration:–min(…) map(, min-accum)–max(…) map(, max-accum)
Both accumulators are abstractly equivalent!
Backtracking is automatically handled by mapping.
IBoardLambda
Mapping Abstraction
IBoardModel makeMove(player, row, col), chkMoveCmd)IUndoMove , bdStatusVstr)
command
Object execute(bdStatusVstr, param)
void map(player, lambda, param)
boolean apply(board, param, row, col, cell-val)
void noApply(board, param)
Controls continuation of mappingCalled when there are no valid moves.
Called on all valid moves.
Min-Max AbstractionINextMoveStrategy
MinMax accFac:IAccFactory
AAccum makeAcc(player)
minMaxEval:IBoardLambda
boolean apply(…)
void noApply(…)
Point getNextMove(model, player)
AAccum acc = accFac.makeAcc(player);model.getBoardModel().map(minMaxEval, acc);return acc.getMove();
private IBoardLambda minMaxEval = new IBoardLambda() {
public boolean apply(board, acc, row, col, cell-value) {
IUndoMove undo = host.makeMove(row, col, acc.getPlayer(), validMvVstr,new IBoardStatusVisitor() {
player0WonCase(...) {…}
player1WonCase(…) {…}
drawCase(…) {…}
noWinnerCase(…) {
undo.apply(validUndo); return acc.isNotDone();
}
UpdateaccumulatorUpdateaccumulator
Updateaccumulator
AAccumulator nextAcc = acc.makeOpposite(); host.map(nextAcc.getPlayer(), minMaxEval, nextAcc); acc.updateBest(row, col, nextAcc.getVal()); return null; } });
Try a test move.
Undo the move.
Declarative style programming!
to be mapped over the available states.
Called by map on each valid (row, col)
What to do in each situation
Stop mapping?
Alpha-Beta Pruningpublic class AlphaAcc extends MaxAcc { public AAccumulator makeOpposite() {
return new BetaAcc() {
{ this.modelPlayer = AlphaAcc.this.modelPlayer; }
public boolean isNotDone() { return AlphaAcc.this.getVal() < this.getVal(); } }; }}
Just a new accumulator!
Override the creation of the next level’s accumulator
Accumulator for the opposite player as an anonymous inner class.
Stop mapping if pruning condition is met.
Abstraction isolates the essence and provides extensibility
Inner class gives the scoping we need!
Player Management
Event-loop for turn-taking
Call-back techniques for asynchronous processing
Abstract players
Design Patterns In Action
MVC separates model from view Commands and Visitors isolate rules
from behaviors State pattern models game behavior Calculating the next move is a Strategy
Design patterns express abstractions
Concepts in Action
Abstract functions – lambda’s Higher order functions – Mapping Declarative programming Invariant: Min-Max Principle Variant:
– Full depth-first search– Alpha-beta pruning
More Information…
Design Pattern for Games:
http://www.exciton.cs.rice.edu/research/SIGCSE02
Patterns for Decoupling Data Structures and Algorithms:
http://www.exciton.cs.rice.edu/research/SIGCSE02