On this page:
outcomes
outcome-matrix
payoff-matrix
payoff-matrix/  sym
6.1.6.1 Game Operations
game-theory^
make-choice!
make-choice/  rounds!
get-own-choice
get-own-choice/  rounds
get-other-choice
get-other-choice/  rounds
chosen-action-profile
&group-choices
&group-choices/  rounds
6.1.6.2 Choice Variables
game-theory-vars^
get-choices
set!-choices
get-choices/  rounds
set!-choices/  rounds
6.1.6.3 Game Theory Unit
game-theory@

6.1.6 Game Theory🔗

 (require conscript/game-theory) package: conscript

This module provides functions for implementing two-player simultaneous-move games, such as the Prisoner’s Dilemma or other strategic interactions between paired participants.

The game theory framework manages choice storage and retrieval for participants in groups, tracking both single-round and multi-round games.

These functions require participants to be matched into groups first (see Matchmaking).

This module also provides all the bindings from conscript/game-theory-sig, conscript/game-theory-vars-sig and conscript/game-theory-unit.

A game form is a hash table that describes a two-player game. It has these keys:

  • 'actions1: a list of the actions of player 1, who chooses a row.

  • 'actions2: a list of the actions of player 2, who chooses a column.

  • 'outcomes1: a hash table that maps each action profile to the outcome for player 1. An action profile is a pair (cons action1 action2).

  • 'outcomes2: a hash table that maps each action profile to the outcome for player 2.

> (define prisoners-dilemma
    (hash 'actions1 '(cooperate defect)
          'actions2 '(cooperate defect)
          'outcomes1 (hash '(cooperate . cooperate) 3
                           '(cooperate . defect)    0
                           '(defect . cooperate)    5
                           '(defect . defect)       1)
          'outcomes2 (hash '(cooperate . cooperate) 3
                           '(cooperate . defect)    5
                           '(defect . cooperate)    0
                           '(defect . defect)       1)))

An outcome can be any value, such as a number of points, a grade, or a string.

procedure

(outcomes game-form action-profile) → any/c

  game-form : hash?
  action-profile : pair?
Returns the outcome for player 1 in the game form game-form when the players choose action-profile.

> (outcomes prisoners-dilemma '(defect . cooperate))

5

procedure

(outcome-matrix game-form) → xexpr?

  game-form : hash?
Returns an HTML table that shows game-form as a matrix. Each row is an action of player 1 and each column is an action of player 2. Each cell shows the outcomes for both players, with the outcome for player 1 first.

(defstep (show-game)
  @md{# The game
 
      @(outcome-matrix prisoners-dilemma)
 
      @button{Continue}})

procedure

(payoff-matrix game-form [utility1 utility2]) → xexpr?

  game-form : hash?
  utility1 : (-> pair? any/c) = identity
  utility2 : (-> pair? any/c) = identity
Like outcome-matrix, but each cell shows payoffs instead of outcomes. The payoff for player 1 is (utility1 action-profile), and the payoff for player 2 is (utility2 action-profile).

This function uses only the 'actions1 and 'actions2 keys of game-form.

procedure

(payoff-matrix/sym game-form [utility]) → xexpr?

  game-form : hash?
  utility : (-> pair? any/c) = identity
Like payoff-matrix, for a symmetric game in which both players have the same utility function. The utility function receives an action profile (cons own-action other-action) and returns the payoff for the player who chooses own-action.

This example shows the payoffs for players who value the total points of both players:

(define (total-points-utility action-profile)
  (define own-action (car action-profile))
  (define other-action (cdr action-profile))
  (+ (outcomes prisoners-dilemma (cons own-action other-action))
     (outcomes prisoners-dilemma (cons other-action own-action))))
 
(defstep (show-payoffs)
  @md{# Payoffs for players who value the total
 
      @(payoff-matrix/sym prisoners-dilemma total-points-utility)
 
      @button{Continue}})
6.1.6.1 Game Operations🔗

 (require conscript/game-theory-sig) package: conscript

Defines the game-theory^ signature containing the core game operations.

The bindings in this module are also provided by conscript/game-theory.

signature

game-theory^ : signature

The functions that game-theory@ defines when you invoke it (see Game Theory Unit). These functions assume that each group has two members.

procedure

(make-choice! choice) → void?

  choice : any/c

procedure

(make-choice/rounds! choice round) → void?

  choice : any/c
  round : any/c
Stores choice as the choice of the current participant in their current group. The make-choice/rounds! function stores it for the round round, which is usually a round number.

procedure

(get-own-choice) → any/c

procedure

(get-own-choice/rounds round) → any/c

  round : any/c
Returns the stored choice of the current participant in their current group, or #f if they have not made a choice.

procedure

(get-other-choice) → any/c

procedure

(get-other-choice/rounds round) → any/c

  round : any/c
Returns the stored choice of the other member of the current participant’s group, or #f if the other member has not made a choice.

Call these functions only after the current participant has made their own choice. If no member of the group has made a choice, they raise an exception.

procedure

(chosen-action-profile) → pair?

Returns the action profile of the current group in a game with one round, as a pair (cons own-choice other-choice). Either part is #f if that participant has not made a choice.

As with get-other-choice, call this function only after the current participant has made their own choice.

procedure

(&group-choices) → procedure?

procedure

(&group-choices/rounds round) → procedure?

  round : any/c
Returns a lens that focuses on the choices of the current group. Apply the lens to the value of the choice variable to get a hash table that maps each participant ID in the group to their choice, or #f if no member has made a choice.

For example, this expression counts how many members of the group have chosen in round 2:

(let ([group-choices ((&group-choices/rounds 2) (get-choices/rounds))])
  (if group-choices (hash-count group-choices) 0))
6.1.6.2 Choice Variables🔗

 (require conscript/game-theory-vars-sig)
  package: conscript

Defines the game-theory-vars^ signature for mutable game state variables.

The bindings in this module are also provided by conscript/game-theory.

signature

game-theory-vars^ : signature

The functions that game-theory@ uses to read and update the stored choices. Usually you define them with defbox.

procedure

(get-choices) → hash?

procedure

(set!-choices v) → void?

  v : hash?
Gets and sets the choices for games with one round. The value maps each group ID to a hash table, which maps the ID of each participant in that group to their choice.

procedure

(get-choices/rounds) → hash?

procedure

(set!-choices/rounds v) → void?

  v : hash?
Gets and sets the choices for games with more than one round. The value maps each group ID to a hash table, which maps each round to a hash table of participant IDs and choices.

6.1.6.3 Game Theory Unit🔗

 (require conscript/game-theory-unit) package: conscript

Provides the implementation unit for the game theory signature.

The bindings in this module are also provided by conscript/game-theory.

A unit that imports game-theory-vars^ and exports game-theory^.

The unit stores the choice of each participant in a group, and gets the choice of the other group member. To use it, you supply two study variables that hold the choices of all groups, and invoke game-theory@ with define-values/invoke-unit:

#lang conscript
 
(require conscript/game-theory)
 
(defvar/instance choices)
(defvar/instance choices/rounds)
 
(defbox choices)
(defbox choices/rounds)
 
(define-values/invoke-unit game-theory@
  (import game-theory-vars^)
  (export game-theory^))

The defbox forms define the functions that game-theory-vars^ names, and define-values/invoke-unit defines the functions that game-theory^ names, such as make-choice! and get-other-choice. See Tutorial: Advanced Study Composition with Units for an introduction to units and signatures.

Each choice variable must hold a hash table before the first choice is stored. Set it to (hash) if it is undefined?, for example in the action procedure of the first button of the study.