1 / 23

Design Patterns for Games

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….

Download Presentation

Design Patterns for Games

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Design Patterns for Games Stephen Wong Dung Nguyen Rice University

  2. 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

  3. Something Different… • It’s not really about TicTacToe… • It’s a vehicle to teach something BIGGER. • Abstraction • Design Process • Fundamental Principles

  4. adapter adapter Install adapters What’s in a Game? Model View Rules Buttons, etc. Strategies Display outputs Players Controller

  5. Game Model Abstract these components! • 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!

  6. IUndoMove apply(…) The Rules of the Game IBoardModel , chkMoveCmd) , bdStatusVstr) makeMove(player, row, col) IUndoMove Object execute(bdStatusVstr, param) // other methods commands host/visitor ICheckMoveCmd validMoveCase() IBoardStatusVisitor invalidMoveCase() player0WonCase(…) player1WonCase(…) drawCase(…) noWinnerCase(…)

  7. State Diagram Invalid Move State Valid Move State Non-Terminal State (no winner yet) Terminal States Player #0 Wins Player #1 Wins Draw Game

  8. IBoardModel execute(IBoardStatusVisitor v, …) state TicTacToeBoard ABoardState ATerminalState NonTerminalState Player0Won Player1Won DrawGame State Design Pattern state.execute(v, …) v.noWinnerCase(…) v.player0WonCase(…) v.player1WonCase(…) v.drawCase(…)

  9. INextMoveStrategy Point getNextMove(…) Random MinMax AlphaBeta Playing the Game ComputerPlayer takeTurn(…) The next move process is decoupled from the rules of the game!

  10. APlayer takeTurn(…) IBoardModel makeMove(…) Facade IRequestor TurnControl IView

  11. 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(); }

  12. Selected APlayer factories Set of APlayer factories Player Factories Only displays the toString() of the factories. The factories are treated as Objects! IView GameModel private interface IMakePlayer { public APlayer create(int playerNo); }

  13. The Set of APlayer Factories Anonymous APlayer factory 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; } Factory method IView only cares about this!

  14. Min-Max Principle • V(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!

  15. 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.

  16. Mapping Abstraction IBoardModel , chkMoveCmd) , bdStatusVstr) makeMove(player, row, col) IUndoMove Object execute(bdStatusVstr, param) void map(player, lambda, param) Controls continuation of mapping command Called on all valid moves. Called when there are no valid moves. IBoardLambda boolean apply(board, param, row, col, cell-val) void noApply(board, param)

  17. INextMoveStrategy Min-Max Abstraction MinMax accFac:IAccFactory AAccum makeAcc(player) Point getNextMove(model, player) minMaxEval:IBoardLambda boolean apply(…) void noApply(…) AAccum acc = accFac.makeAcc(player); model.getBoardModel().map(minMaxEval, acc); return acc.getMove();

  18. 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(); • } Try a test move.  to be mapped over the available states. Update accumulator Called by map on each valid (row, col) Update accumulator What to do in each situation Update accumulator Declarative style programming! AAccumulator nextAcc = acc.makeOpposite(); host.map(nextAcc.getPlayer(), minMaxEval, nextAcc); acc.updateBest(row, col, nextAcc.getVal()); return null; } }); Undo the move. Stop mapping?

  19. Just a new accumulator! Alpha-Beta Pruning Override the creation of the next level’s accumulator public class AlphaAcc extends MaxAcc { public AAccumulator makeOpposite() { return new BetaAcc() { { this.modelPlayer = AlphaAcc.this.modelPlayer; }public boolean isNotDone() { return AlphaAcc.this.getVal() < this.getVal(); } }; }} Accumulator for the opposite player as an anonymous inner class. Stop mapping if pruning condition is met. Inner class gives the scoping we need! Abstraction isolates the essence and provides extensibility

  20. Player Management Abstract players Event-loop for turn-taking Call-back techniques for asynchronous processing

  21. 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

  22. 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 It’s more than just a game!

  23. More Information… • Nguyen and Wong, “Design Pattern for Games” (OOPSLA 2002) • Nguyen and Wong, “Patterns for Decoupling Data Structures and Algorithms” (SIGCSE 1999)

More Related