farkle

package module
v0.0.0-...-12c3208 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 28, 2024 License: GPL-3.0 Imports: 16 Imported by: 0

README

go-farkle

Solver for optimal play in the Farkle dice game

How to run

Solve the game
cd cmd/solve-farkle
go build
./solve-farkle -logtostderr -num_players 2 -db 2player.db
Play the game using optimal solution
cd cmd/play-farkle
go build
./play-farkle -num_players 2 -db ../solve-farkle/2player.db

Solution size

Scores are capped at 12,750 (255 * 50) to make the game play finite.

  • 2 player: 99,488,250 states, 1.5 GiB
  • 3 player: 25,369,503,750 states, 567 GiB
  • 4 player: 6.4692235e+12 states, 188 TiB

Documentation

Index

Constants

View Source
const MaxNumDice = 6

Variables

This section is empty.

Functions

func CalculateScore

func CalculateScore(held Roll) uint8

func GetRollID

func GetRollID(roll Roll) uint16

func IsFarkle

func IsFarkle(roll Roll) bool

func IsValidHold

func IsValidHold(roll, held Roll) bool

func IterGameStates

func IterGameStates(numPlayers int, path string) (iter.Seq2[uint64, GameState], error)

Return an iterator over all game states in the given file.

func SaveGameStates

func SaveGameStates(states iter.Seq2[uint64, GameState], path string) error

Save all game states from the given iterator to a file.

func SortedGameStates

func SortedGameStates(numPlayers int, workDir string) iter.Seq2[uint64, GameState]

Return an iterator over all distinct game states and their depth in the game tree. Game states are sorted by depth in descending order such that end game states are enumerated before early game states.

func UpdateAll

func UpdateAll(db DB, states iter.Seq2[uint64, GameState], chkpntPath string)

Recalculate the value of all states in the given iterator, updating the value of each state in the database.

Types

type Action

type Action struct {
	HeldDiceID      uint16
	ContinueRolling bool
}

Action is the choice made by a player after rolling. A zero Action is a Farkle.

func SelectAction

func SelectAction(state GameState, rollID uint16, db DB) (Action, [maxNumPlayers]float64)

Find the action that maximizes current player win probability.

func (Action) String

func (a Action) String() string

type DB

type DB interface {
	// The number of game players.
	NumPlayers() int
	// Store the result for a game state in the database.
	Put(gsId int, pWin [maxNumPlayers]float64)
	// Retrieve a stored result for the given game state.
	Get(gsID int) [maxNumPlayers]float64
	io.Closer
}

type FileDB

type FileDB struct {
	// contains filtered or unexported fields
}

DB that stores results in a memory-mapped flat file.

func NewFileDB

func NewFileDB(path string, numPlayers int) (*FileDB, error)

func (*FileDB) Close

func (db *FileDB) Close() error

func (*FileDB) Get

func (db *FileDB) Get(gsID int) [maxNumPlayers]float64

func (*FileDB) NumPlayers

func (db *FileDB) NumPlayers() int

func (*FileDB) Put

func (db *FileDB) Put(gsID int, pWin [maxNumPlayers]float64)

type GameState

type GameState struct {
	ScoreThisRound uint8
	NumDiceToRoll  uint8
	NumPlayers     uint8
	PlayerScores   [maxNumPlayers]uint8
}

State of the game. The current player is always player 0. Game states can be partially ordered since scores can only go up during game play.

func ApplyAction

func ApplyAction(state GameState, action Action) GameState

func GameStateFromBytes

func GameStateFromBytes(buf []byte) GameState

func GameStateFromID

func GameStateFromID(numPlayers, id int) GameState

func NewGameState

func NewGameState(numPlayers int) GameState

func (GameState) CurrentPlayerHasWon

func (gs GameState) CurrentPlayerHasWon() bool

Current player has certainly won if they stop now. This is used as an optimization to avoid further traversing the tree, since there is no reason for the player to continue.

func (GameState) CurrentPlayerScore

func (gs GameState) CurrentPlayerScore() uint8

Score of the current player.

func (GameState) HighestScore

func (gs GameState) HighestScore() uint8

Highest score of any player.

func (GameState) ID

func (gs GameState) ID() int

A unique ID for this game state within the set of all possible games with a certain number of players.

func (GameState) IsGameOver

func (gs GameState) IsGameOver() bool

Whether the game is over, i.e. this is a terminal game state.

func (GameState) SerializeTo

func (gs GameState) SerializeTo(buf []byte) int

func (GameState) String

func (gs GameState) String() string

type Roll

type Roll [numSides + 1]uint8

Roll represents an unordered roll of N dice. A roll can hold 1 - maxNumDice dice. Extra entries are at the end of the roll with the value -1.

func CombineRolls

func CombineRolls(rolls ...Roll) Roll

func NewRandomRoll

func NewRandomRoll(numDice int) Roll

func NewRoll

func NewRoll(dice ...uint8) Roll

func RepeatedRoll

func RepeatedRoll(die uint8, n uint8) Roll

func SubtractRolls

func SubtractRolls(a, b Roll) Roll

func (Roll) Dice

func (r Roll) Dice() []uint8

The dice in this roll, sorted in ascending order.

func (Roll) NumDice

func (r Roll) NumDice() uint8

The number of dice in this roll, in the range 0 - maxNumDice.

func (Roll) String

func (r Roll) String() string

type Trick

type Trick struct {
	Type TrickType
	Dice Roll
}

func (Trick) Score

func (t Trick) Score() uint8

type TrickType

type TrickType int
const (
	Single1 TrickType = iota
	Single5
	Three1s
	Three2s
	Three3s
	Three4s
	Three5s
	Three6s
	FourOfAKind
	FiveOfAKind
	SixOfAKind
	Straight
	ThreePairs
	FourOfAKindPlusPair
	TwoTriplets
)

type WeightedRoll

type WeightedRoll struct {
	Roll
	ID   uint16
	Prob float64
}

WeightedRoll represents an unordered set of rolled dice, and the probability of realizing that combination.

Directories

Path Synopsis
cmd
play-farkle command
solve-farkle command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL