Design Patterns for Games Stephen Wong Dung Nguyen

  • Slides: 19
Download presentation
Design Patterns for Games Stephen Wong Dung Nguyen Rice University

Design Patterns for Games Stephen Wong Dung Nguyen Rice University

Let’s Play a Game v v Sun’s Tic-Tac-Toe What can we learn from this?

Let’s Play a Game v v Sun’s Tic-Tac-Toe What can we learn from this? – Arrays – For-loops – Nested Conditionals v What aren’t we learning? – Delineation of concepts from implementation – Abstraction – Design

Something Different… v It’s not really about Tic. Tac. Toe… – It’s a vehicle

Something Different… v It’s not really about Tic. Tac. Toe… – It’s a vehicle to teach something BIGGER. Abstraction v Design Process v Fundamental Principles v

What’s in a Game? Model X Rules Strategies Players adapter View adapter Buttons, etc.

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

Game Model v Rules of the Game – Board configurations – Legal moves v

Game Model v Rules of the Game – Board configurations – Legal moves v Next Move Strategies Abstract these components! – Random – Min-Max – Etc. v Player Management Decouple these components! – Turn taking – Win/lose/draw notification – Fault handling

The Rules of the Game IBoard. Model IUndo. Move make. Move(player, row, col), chk.

The Rules of the Game IBoard. Model IUndo. Move make. Move(player, row, col), chk. Move. Cmd), bd. Status. Vstr) Object execute(bd. Status. Vstr, param) // other methods commands host/visitor ICheck. Move. Cmd valid. Move. Case() invalid. Move. Case() IUndo. Move apply(…) IBoard. Status. Visitor player 0 Won. Case(…) player 1 Won. Case(…) draw. Case(…) no. Winner. Case(…)

State Diagram Invalid Move State Valid Move State Non-Terminal State (no winner yet) Terminal

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

State Design Pattern IBoard. Model execute(IBoard. Status. Visitor v, …) Tic. Tac. Toe. Board

State Design Pattern IBoard. Model execute(IBoard. Status. Visitor v, …) Tic. Tac. Toe. Board state. execute(v, …) state ABoard. State v. no. Winner. Case(…) ATerminal. State Player 0 Won v. player 0 Won. Case(…) Player 1 Won Non. Terminal. State Draw. Game v. player 1 Won. Case(…) v. draw. Case(…)

Playing the Game Computer. Player INext. Move. Strategy take. Turn(…) Point get. Next. Move(…)

Playing the Game Computer. Player INext. Move. Strategy take. Turn(…) Point get. Next. Move(…) Random Min. Max Alpha. Beta The next move process is decoupled from the rules of the game!

Min-Max Principle V(s) = ·For terminal state · +1, if s is a winning

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 Application of · -1, if s is a losing state for that player a process ·For non-terminal state over a set! · 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.

Mapping and Lambda v Math/FP: Map( , S) = { (x) | x S}

Mapping and Lambda v Math/FP: Map( , S) = { (x) | x S} Both accumulators are abstractly equivalent! v Express our algorithm in terms of mapping, not iteration: – min(…) map( , min-accum) – max(…) map( , max-accum) v Backtracking is automatically handled by mapping.

Mapping Abstraction IBoard. Model IUndo. Move make. Move(player, row, col), chk. Move. Cmd), bd.

Mapping Abstraction IBoard. Model IUndo. Move make. Move(player, row, col), chk. Move. Cmd), bd. Status. Vstr) Object execute(bd. Status. Vstr, param) void map(player, lambda, param) Controls Called on all valid continuation of Called when there moves. mapping are no valid moves. command IBoard. Lambda boolean apply(board, param, row, col, cell-val) void no. Apply(board, param)

INext. Move. Strategy Min-Max Abstraction Min. Max acc. Fac: IAcc. Factory AAccum make. Acc(player)

INext. Move. Strategy Min-Max Abstraction Min. Max acc. Fac: IAcc. Factory AAccum make. Acc(player) Point get. Next. Move(model, player) min. Max. Eval: IBoard. Lambda boolean apply(…) void no. Apply(…) AAccum acc = acc. Fac. make. Acc(player); model. get. Board. Model(). map(min. Max. Eval, acc); return acc. get. Move();

private IBoard. Lambda min. Max. Eval = new IBoard. Lambda() { Try a test

private IBoard. Lambda min. Max. Eval = new IBoard. Lambda() { Try a test move. public boolean apply(board, acc, row, col, cell-value) { to be mapped over IUndo. Move undo = host. make. Move( row, Update col, acc. get. Player(), valid. Mv. Vstr, the available states. Called by map on new IBoard. Status. Visitor() { accumulator each valid (row, col) Update player 0 Won. Case(. . . ) {…} accumulator What to do in Update each situation {…} player 1 Won. Case(…) accumulator draw. Case(…) {…} Declarative style programming! no. Winner. Case(…) { AAccumulator next. Acc = acc. make. Opposite(); Undohost. map(next. Acc. get. Player(), the move. min. Max. Eval, next. Acc); acc. update. Best(row, col, next. Acc. get. Val()); return null; } }); undo. apply(valid. Undo); return acc. is. Not. Done(); } Stop mapping?

Just a new accumulator! Alpha-Beta Pruning Override the creation of the next level’s {accumulator

Just a new accumulator! Alpha-Beta Pruning Override the creation of the next level’s {accumulator public class Alpha. Acc extends Max. Accumulator for the opposite player as an public AAccumulator make. Opposite() { anonymous inner class. return new Beta. Acc() { Stop mapping if pruning condition is met. gives the Inner class { this. model. Player = Alpha. Acc. this. model. Player; } scoping we need! public boolean is. Not. Done() { return Alpha. Acc. this. get. Val() < this. get. Val(); } }; } Abstraction isolates the essence and provides extensibility }

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

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

Design Patterns In Action MVC separates model from view v Commands and Visitors isolate

Design Patterns In Action MVC separates model from view v Commands and Visitors isolate rules from behaviors v State pattern models game behavior v Calculating the next move is a Strategy v Design patterns express abstractions

Concepts in Action Abstract functions – lambda’s v Higher order functions – Mapping v

Concepts in Action Abstract functions – lambda’s v Higher order functions – Mapping v Declarative programming v Invariant: Min-Max Principle v Variant: v – Full depth-first search – Alpha-beta pruning

More Information… v Design Pattern for Games: http: //www. exciton. cs. rice. edu/research/SIGCSE 02

More Information… v Design Pattern for Games: http: //www. exciton. cs. rice. edu/research/SIGCSE 02 v Patterns for Decoupling Data Structures and Algorithms: http: //www. exciton. cs. rice. edu/research/SIGCSE 02