gamestore

package
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Sep 1, 2026 License: MIT Imports: 10 Imported by: 0

Documentation

Overview

Package gamestore keeps games on disk: finished games worth replaying, games interrupted part way through, and correspondence games waiting for the opponent's next move code.

Each game is its own file, named by its identifier, because these are written one at a time and a single shared file would make two twixtui processes contend over unrelated games. The game itself is stored as an encoded game.Record, so a file that has been edited or truncated is refused when it is loaded rather than quietly producing a different position.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func NewID

func NewID() string

NewID returns a short random identifier.

func ValidateID

func ValidateID(id string) error

ValidateID rejects an identifier that could escape the store's directory or collide with a shell pattern.

Types

type Kind

type Kind string

Kind says how a game is being played, which decides where it can be resumed.

const (
	// Hotseat is two players taking turns at this keyboard.
	Hotseat Kind = "hotseat"
	// VersusBot is one player against the built-in opponent.
	VersusBot Kind = "bot"
	// Remote is a live game over a network connection.
	Remote Kind = "remote"
	// Correspondence is a game played by exchanging move codes.
	Correspondence Kind = "correspondence"
	// Imported is a record read in from elsewhere with "game import". The
	// record format carries no names and no kind, so nobody on this machine is
	// known to have played it: it is kept to be shown and replayed, and a
	// listing that offers games to carry on with should leave it alone.
	Imported Kind = "imported"
)

The kinds of game that can be stored.

type Saved

type Saved struct {
	ID      string    `json:"id"`
	Kind    Kind      `json:"kind"`
	Created time.Time `json:"created"`
	Updated time.Time `json:"updated"`

	// Player is the local profile's name, and Side the axis it plays.
	Player string `json:"player"`
	Side   string `json:"side"`
	// Opponent is the other player: a profile name, a bot tier, or a remote name.
	Opponent string `json:"opponent"`

	// Record is an encoded game.Record, which carries its own integrity checks.
	Record string `json:"record"`

	// Finished is set once the game has a result, so a listing can separate
	// games that are waiting for a move from games that are over.
	Finished bool `json:"finished"`
}

Saved is one stored game.

func (Saved) Describe

func (s Saved) Describe() string

Describe renders a one-line summary for a listing.

func (Saved) Game

func (s Saved) Game() (*game.Game, error)

Game rebuilds the position, refusing a record that has been altered.

type Store

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

Store is the collection of stored games in one directory.

func Open

func Open(dir string) (*Store, error)

Open prepares the store. The directory is created on the first write rather than here, so listing games on a fresh install does not leave empty directories behind.

func (*Store) Delete

func (s *Store) Delete(id string) error

Delete removes a game.

func (*Store) Dir

func (s *Store) Dir() string

Dir returns the directory games are kept in.

func (*Store) Get

func (s *Store) Get(id string) (Saved, error)

Get reads one game.

func (*Store) List

func (s *Store) List() []Saved

List returns every stored game, most recently updated first. A file that cannot be read is skipped rather than failing the whole listing, so one damaged game does not hide the rest.

func (*Store) OfKind

func (s *Store) OfKind(k Kind) []Saved

OfKind returns the stored games of one kind, most recently updated first.

func (*Store) Put

func (s *Store) Put(sv Saved) error

Put writes a game, replacing any earlier version of it. Updated is stamped here so that a caller cannot forget to.

A finished game is final. Once a result has been recorded the game is over, it has been rated, and there is nothing left to play; reopening it and storing the position it had before the result would contradict the rating log and lose the result. Such a write is refused here rather than in the caller, because the store is the one place every writer passes through.

func (*Store) Resolve

func (s *Store) Resolve(prefix string) (Saved, error)

Resolve turns a possibly abbreviated identifier into exactly one game, which is what lets a player type the first few characters they can see on screen.

func (*Store) Unfinished

func (s *Store) Unfinished() []Saved

Unfinished returns the stored games still waiting for a move.

Jump to

Keyboard shortcuts

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