Top Banner
Design Patterns for Games Stephen Wong Dung Nguyen Rice University
23

Design Patterns for Games

Feb 25, 2016

Download

Documents

hamal

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 Presentation
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Design Patterns for Games

Design Patterns for Games

Stephen WongDung Nguyen

Rice University

Page 2: Design Patterns for Games

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

Page 3: Design Patterns for Games

Something Different…

It’s not really about TicTacToe…– It’s a vehicle to teach something BIGGER.

Abstraction Design Process Fundamental Principles

Page 4: Design Patterns for Games

What’s in a Game?

X X

O

OController

ModelRules

PlayersStrategies

ViewButtons, etc.Display outputsadapter

adapter

Install adapters

Page 5: Design Patterns for Games

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!

Page 6: Design Patterns for Games

The Rules of the GameIBoardModel

IBoardStatusVisitor

makeMove(player, row, col), chkMoveCmd)IUndoMove , bdStatusVstr)

ICheckMoveCmdvalidMoveCase()invalidMoveCase()

player1WonCase(…)player0WonCase(…)

noWinnerCase(…)drawCase(…)IUndoMove

apply(…)

commandshost/visitor

Object execute(bdStatusVstr, param)

// other methods

Page 7: Design Patterns for Games

State DiagramInvalid Move State

Valid Move State

Non-Terminal State(no winner yet)

Terminal States

Player #0 Wins

Draw Game

Player #1 Wins

Page 8: Design Patterns for Games

ABoardStatestate

State Design Pattern

TicTacToeBoard

Player1WonPlayer0Won DrawGame

ATerminalState NonTerminalState

IBoardModelexecute(IBoardStatusVisitor v, …)

v.player0WonCase(…)

state.execute(v, …)

v.player1WonCase(…) v.drawCase(…)

v.noWinnerCase(…)

Page 9: Design Patterns for Games

Playing the GameComputerPlayertakeTurn(…)

INextMoveStrategyPoint getNextMove(…)

Random AlphaBetaMinMax

The next move process is decoupledfrom the rules of the game!

Page 10: Design Patterns for Games

FacadeAPlayer

takeTurn(…)

IBoardModelmakeMove(…)

TurnControl IView

IRequestor

Page 11: Design Patterns for Games

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

Page 12: Design Patterns for Games

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);

}

Page 13: Design Patterns for Games

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

Page 14: Design Patterns for Games

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!

Page 15: Design Patterns for Games

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.

Page 16: Design Patterns for Games

IBoardLambda

Mapping AbstractionIBoardModel

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.

Page 17: Design Patterns for Games

Min-Max AbstractionINextMoveStrategy

MinMax accFac:IAccFactoryAAccum 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();

Page 18: Design Patterns for Games

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?

Page 19: Design Patterns for Games

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!

Page 20: Design Patterns for Games

Player Management

Event-loop for turn-taking

Call-back techniques for asynchronous processing

Abstract players

Page 21: Design Patterns for Games

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

Page 22: Design Patterns for Games

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