Turn-Based Games
1 Basic turn-based game interfaces
gen:  turn-based-game
sides
next-side
valid-move-choice?
valid-move-choices
play-move-choice
winning-state?
gen:  turn-based-game/  standard-initial-state
standard-initial-state
standard-initial-side
2 User interfaces for playing turn-based games
2.1 
gen:  turn-based-game/  gui
display-game-state
display-end-state
start-turn
handle-mouse
handle-key
2.2 
start
3 Playing against the computer
3.1 
computer/  n-ahead
3.2 
computer/  score-explore-random
3.3 
start/  computer
7.7

Turn-Based Games

1 Basic turn-based game interfaces

generic interface

gen:turn-based-game

A TBG is an instance of gen:turn-based-game. This is meant to be a dictionary of game-related methods. It is NOT meant to be the state of the game.

Each instance defines its own types for Side, GameState, and MoveChoice, which are used by the methods to keep track of players and turns, what state the game is in, and possible choices a player could make on a given turn.

procedure

(sides tbg game-state)  (listof Side)

  tbg : TBG
  game-state : GameState
Returns the set of sides that are currently in the game. Order in the result list does not matter.

procedure

(next-side tbg game-state side)  Side

  tbg : TBG
  game-state : GameState
  side : Side
Returns the side to play once side’s turn is over. This should be called after side’s turn is over and game-state has been updated with side’s move choice.

procedure

(valid-move-choice? tbg    
  game-state    
  side    
  move-choice)  Boolean
  tbg : TBG
  game-state : GameState
  side : Side
  move-choice : MoveChoice
Determines whether the given move-choice is a valid legal move according to the rules of the game. If it is legal, valid-move-choice? returns true, otherwise it returns false.

procedure

(valid-move-choices tbg game-state side)

  (sequenceof MoveChoice)
  tbg : TBG
  game-state : GameState
  side : Side
Returns a sequence which will enumerate all possible legal moves within the rules of the game.

NOTE: This sequence may or may not be finite, so if you’re relying on using it to iterate through all the elements, check with known-finite? first.

procedure

(play-move-choice tbg    
  game-state    
  side    
  move-choice)  GameState
  tbg : TBG
  game-state : GameState
  side : Side
  move-choice : MoveChoice
Returns the game state after side plays the given move-choice for their turn. This should not mutate the original game state, but return a new one.

procedure

(winning-state? tbg game-state side)  Boolean

  tbg : TBG
  game-state : GameState
  side : Side
Determines whether the given side has won in the given game-state according to the rules of the game.

This interface includes two more methods:

procedure

(standard-initial-state tbg)  GameState

  tbg : TBGI
Produces the standard initial game state for the given turn-based game.

procedure

(standard-initial-side tbg)  Side

  tbg : TBGI
Produces the standard starting side for the given turn-based game, that is, the side that starts the game with their turn.

2 User interfaces for playing turn-based games

generic interface

gen:turn-based-game/gui

In order to be used for a user interface like the start function, turn-based games must implement the gen:turn-based-game/gui interface in addition to gen:turn-based-game. A TBGG is an instance of both of these interfaces. A TBGGI is a TBGG that also specifies initial states with gen:turn-based-game/standard-initial-state. Again, instances of these are meant to be dictionaries of game-related methods, not the state of the game.

Each instance should define its own type for TurnState, in addition to the types Side, GameState, and MoveChoice. The TurnState type keeps track of any state that a player could build up before making a final MoveChoice for their turn.
The key and mouse handlers should return HandlerResults according to the data definition below.

procedure

(display-game-state tbg    
  game-state    
  side    
  turn-state)  Image
  tbg : TBGG
  game-state : GameState
  side : Side
  turn-state : TurnState

procedure

(display-end-state tbg    
  game-state    
  side    
  winner)  Image
  tbg : TBGG
  game-state : GameState
  side : Side
  winner : (or/c #f Side)

procedure

(start-turn tbg)  TurnState

  tbg : TBGG
Determines the initial state that every player starts their turn with. The first mouse event or key event of a turn will use the result of this method as the starting turn-state.

procedure

(handle-mouse tbg    
  game-state    
  side    
  turn-state    
  mouse-posn    
  mouse-event)  HandlerResult
  tbg : TBGG
  game-state : GameState
  side : Side
  turn-state : TurnState
  mouse-posn : Posn
  mouse-event : MouseEvent
This method handles mouse events, including "move" for mouse movements, "button-down" and "button-up" for mouse clicks, "drag" for dragging movements, and "enter" and "leave" for when the mouse enters and leaves the game canvas.

Mouse scrolling motions are actually not handled as mouse events; they are handled as key events using handle-key.

When a mouse event happens, this method can either continue the turn with an updated turn-state using continue-turn, or finish the turn with a final MoveChoice, using finish-turn. If the mouse event is not relevant, it should continue the turn with the same turn-state as before.

For example, some games might require moving a piece by clicking on it and then clicking on the space to move it to. On the first click, the handle-mouse method should return (continue-turn piece-selection) where piece-selection is a TurnState representing which piece was clicked on to be moved. Then on the second click, the handle-mouse method should return (finish-turn move-choice) where move-choice is a MoveChoice representing which piece should be moved and where it should go. A rough sketch of the definition would look like this:

;; A Space represents the position of a space on the board.
 
;; A MoveChoice is a (move Space Space)
(struct move [from to])
;; representing moving a piece from the `from` space to the `to` space.
 
;; A TurnState is one of:
;;  - #false  ; beginning of turn
;;  - Space   ; the piece on this space has been selected to be moved
 
;; handle-mouse :
;; TBGG GameState Side TurnState Posn MouseEvent -> HandlerResult
(define (handle-mouse self game side turn-state posn mouse)
  (cond
    [(mouse=? "button-down" mouse)
     (cond [(false? turn-state)
            ;; this is the first click
            (if (piece-exists-at-space? game side (posn->space posn))
                ;; select the piece at this space to be moved
                (continue-turn (posn->space posn))
                ;; otherwise just a stray click on an empty space
                (continue-turn turn-state))]
           [else
            ;; there is already a piece selected; this is the second click
            (if (piece-can-move-here? game turn-state (posn->space posn))
                ;; this is a finished move choice
                (finish-turn (move turn-state (posn->space posn)))
                ;; otherwise this would be an invalid move
                ....)])]
    [else
     ;; the mouse event is not relevant
     (continue-turn turn-state)]))

procedure

(handle-key tbg    
  game-state    
  side    
  turn-state    
  key-event)  HandlerResult
  tbg : TBGG
  game-state : GameState
  side : Side
  turn-state : TurnState
  key-event : KeyEvent
This method handles key events. One-character strings like "a", "b", and "c" represent the "regular" keys like A, B, and C. This includes strings like " " for the Spacebar, "\r" for the Enter key, and "\t" for the Tab key.

Other keys are represented with multi-character strings, such as "left", "right", "up", and "down" for the arrow keys, and "shift" and "rshift" for the two shift keys.

Mouse scrolling motions are also handled as key events, with "wheel-up" representing scrolling up, "wheel-down" representing scrolling down, and "wheel-left" and "wheel-right" representing scrolling left and right.

Just like with handle-mouse, when a key event happens, this method can either continue the turn with an updated turn-state using continue-turn, or finish the turn with a final MoveChoice using finish-turn.

procedure

(start game-desc)  Void

  game-desc : TBGGI
Starts the turn-based game with its standard initial state.

3 Playing against the computer

A ComputerPlayer is an object that describes a strategy the computer will use to play a game. Some will be specific to a particular game, but some can be generic across all TBG instances, although for some they might be increbibly slow.

procedure

(computer/n-ahead n)  ComputerPlayer

  n : Natural
An automated turn-based-game player that only looks n moves ahead.

procedure

(computer/score-explore-random n p k)  ComputerPlayer

  n : Natural
  p : Natural
  k : Natural
An automated turn-based-game player that looks n moves ahead, and for each game state after that it randomly explores p different paths of k more moves ahead, scoring each game state according to the percentage of those paths that produce winning results.

procedure

(start/computer game-desc computer-players)  Void

  game-desc : TBGGI
  computer-players : (hash/c Side ComputerPlayer)
Starts the turn-based game with its standard initial state, with some of the sides played by the computer.