GameTheory.jl

GameTheory.jl is a Julia package about algorithms and data structures for Game Theory.

Installation

To install the package, enter the Pkg mode by pressing ] and run

add GameTheory

Usage

Once installed, the GameTheory package can be used by typing

using GameTheory

Creating a game

The Base type Player can be created by passing a payoff matrix:

player1 = Player([3 1; 0 2])
2×2 Player{2, Int64}:
 3  1
 0  2

Here the rows of the payoff matrix correspond to player 1's own actions and the columns to the opponent's actions.

A 2-player NormalFormGame can be created either by passing Player instances,

player2 = Player([2 0; 1 3])
g = NormalFormGame((player1, player2))
2×2 NormalFormGame{2, Int64}:
 (3, 2)  (1, 1)
 (0, 0)  (2, 3)

or by passing an array of tuples representing payoff profiles:

g = NormalFormGame([(3, 2) (1, 1)
                    (0, 0) (2, 3)])
2×2 NormalFormGame{2, Int64}:
 (3, 2)  (1, 1)
 (0, 0)  (2, 3)

or by passing a payoff matrix directly:

payoff_bimatrix = Array{Int}(undef, 2, 2, 2)
payoff_bimatrix[1, 1, :] = [3, 2]
payoff_bimatrix[1, 2, :] = [1, 1]
payoff_bimatrix[2, 1, :] = [0, 0]
payoff_bimatrix[2, 2, :] = [2, 3]
g = NormalFormGame(payoff_bimatrix)
2×2 NormalFormGame{2, Int64}:
 (3, 2)  (1, 1)
 (0, 0)  (2, 3)

Payoff array conventions

Each player's payoff_array is indexed with the player's own action first: for player i in an N-player game, the first axis corresponds to player i's own actions, and the j-th axis, j = 2, ..., N, to the actions of player i+j-1 (modulo N). In the 2-player game g constructed above,

player1.payoff_array[1, 2] == 1 && player2.payoff_array[2, 1] == 1
true

both give the payoffs under the action profile in which player 1 plays action 1 and player 2 plays action 2 — each player's array is indexed with that player's own action first. Similarly, in a 3-player game, g.players[2].payoff_array[a2, a3, a1] is player 2's payoff under the action profile (a1, a2, a3).

Computing Nash equilibria

After constructing a NormalFormGame, we can find its Nash equilibria by using methods of GameTheory. For example, pure_nash finds all pure-action Nash equilibria by enumeration:

pure_nash(g)
2-element Vector{Tuple{Int64, Int64}}:
 (1, 1)
 (2, 2)

The game also has a mixed-action Nash equilibrium: vertex_enumeration finds all Nash equilibria of a two-player nondegenerate game, pure and mixed:

vertex_enumeration(g)
3-element Vector{Tuple{Vector{Float64}, Vector{Float64}}}:
 ([1.0, 0.0], [1.0, 0.0])
 ([0.0, 1.0], [0.0, 1.0])
 ([0.75, 0.25], [0.25, 0.75])

See Computing Nash Equilibria for the other solvers available.

Notebooks

Some notebooks for demonstration are available:

Library Outline