Skip to content
Counterfactual regret minimization algorithm for various heads up poker games
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.

Build Status

Counterfactual regret minimization in Go

Implementation of chance sampling counterfactual regret minimization in Go.


Install with

go get


The central struct is cfr.ComputingRoutine which holds GameState interface and global set of StrategyMap (keeping data necessary to compute nash equilibrium at the end)

To use it for your imperfect-information sum-zero strictly competitive two players game (like various kinds of poker) you need to provide implementation of GameState interface.

// GameState - state of the game interface
type GameState interface {
	Parent() GameState
	Act(action acting.Action) GameState
	InformationSet() InformationSet
	Actions() []acting.Action
	IsTerminal() bool
	CurrentActor() acting.Actor
	Evaluate() float32

Rhode Island Poker example

Example implementations of Rhode Island Poker and Kuhn Poker are included in repository. Here is how to compute Nash Equilibrium for Rhode Island Poker with limited card deck (reduced game size )

package main

import (

func main() {
	rhodeisland.MaxRaises = 3
	playerA := &rhodeisland.Player{Id: acting.PlayerA, Actions: nil, Card: nil, Stack: 1000.}
	playerB := &rhodeisland.Player{Id: acting.PlayerB, Actions: nil, Card: nil, Stack: 1000.}
	root := rhodeisland.Root(playerA, playerB, cards.CreateLimitedDeck(cards.C10, true))
	routine := cfr.CreateComputingRoutine(root)
	ne := routine.ComputeNashEquilibriumViaCFR(10000,  8) // 10k is too small for sure 
	for infSet := range ne.Value {
		fmt.Println(rhodeisland.PrettyPrintInformationSet(infSet), ne.Value[infSet])
You can’t perform that action at this time.