Help us shape the future of Go! Take the 2026 Go Developer Survey

bgfparser

package module
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Nov 4, 2025 License: MIT Imports: 11 Imported by: 2

README ΒΆ

BGFParser

A Go package for parsing BGBlitz backgammon data files, including SMILE-encoded binary formats.

Overview

BGFParser is a comprehensive library for reading and analyzing backgammon data from BGBlitz, a popular backgammon analysis software. The package supports two file formats:

  • TXT files: Human-readable position files containing board states, evaluations, and analysis
  • BGF files: Binary match files using compressed JSON (with optional SMILE encoding)

Features

TXT Parser
  • βœ… Parse board positions with checker locations
  • βœ… Extract player names and scores
  • βœ… Read match information (length, Crawford state)
  • βœ… Parse position identifiers (Position-ID, Match-ID, XGID)
  • βœ… Extract dice rolls and cube information
  • βœ… Parse move evaluations with equity and statistics
  • βœ… Read cube decisions (Double/Take, Double/Pass, No Double)
  • βœ… Support for multiple languages (English, French)
  • βœ… Pip count extraction
BGF Parser
  • βœ… Full SMILE encoding/decoding support
    • Complete match data extraction
    • Player names, ratings, and statistics
    • Move-by-move analysis with equity calculations
    • Cube decisions and match equity
    • Performance ratings and error analysis
    • All nested objects and arrays
Web-Ready API πŸ†•
  • βœ… Parse from files, HTTP uploads, memory buffers, or any io.Reader
  • βœ… JSON serializable structures for easy API responses
  • βœ… No file system required - parse directly from uploaded data
  • βœ… Database-ready structures with JSON tags

Installation

go get github.com/kevung/bgfparser

Quick Start

Parse from File
package main

import (
    "fmt"
    "log"

    "github.com/kevung/bgfparser"
)

func main() {
    // Parse a position file
    position, err := bgfparser.ParseTXT("game_position.txt")
    if err != nil {
        log.Fatal(err)
    }
    
    // Access position data
    fmt.Printf("Players: %s vs %s\n", position.PlayerX, position.PlayerO)
    fmt.Printf("Score: %d-%d\n", position.ScoreX, position.ScoreO)
    fmt.Printf("On Roll: %s with %d-%d\n", 
        position.OnRoll, position.Dice[0], position.Dice[1])
    
    // Check evaluations
    if len(position.Evaluations) > 0 {
        best := position.Evaluations[0]
        fmt.Printf("Best move: %s (Equity: %.3f)\n", 
            best.Move, best.Equity)
    }
}
Parse from HTTP Upload πŸ†•
import (
    "net/http"
    "encoding/json"
    "github.com/kevung/bgfparser"
)

func uploadHandler(w http.ResponseWriter, r *http.Request) {
    // Get uploaded file
    file, _, err := r.FormFile("bgffile")
    if err != nil {
        http.Error(w, err.Error(), http.StatusBadRequest)
        return
    }
    defer file.Close()
    
    // Parse directly from upload (no temp file needed!)
    match, err := bgfparser.ParseBGFFromReader(file)
    if err != nil {
        http.Error(w, err.Error(), http.StatusBadRequest)
        return
    }
    
    // Return JSON response
    w.Header().Set("Content-Type", "application/json")
    json.NewEncoder(w).Encode(match)
}
Parse from Memory πŸ†•
import (
    "bytes"
    "github.com/kevung/bgfparser"
)

func parseFromMemory(data []byte) (*bgfparser.Match, error) {
    reader := bytes.NewReader(data)
    return bgfparser.ParseBGFFromReader(reader)
}
Export to JSON πŸ†•
// Parse any file
pos, _ := bgfparser.ParseTXT("position.txt")

// Get JSON output
jsonData, err := pos.ToJSON()
if err != nil {
    panic(err)
}

fmt.Println(string(jsonData))

Web Server Example πŸ†•

A complete web server is provided in examples/web_server/:

cd examples/web_server
go run main.go

Then visit http://localhost:8080 to upload and analyze BGF/TXT files through a web interface.

API Overview

File-Based Parsing
// Parse TXT position file
pos, err := bgfparser.ParseTXT("position.txt")

// Parse BGF match file
match, err := bgfparser.ParseBGF("match.bgf")
Web-Ready Parsing (io.Reader) πŸ†•
// Parse from any io.Reader source
match, err := bgfparser.ParseBGFFromReader(reader)
pos, err := bgfparser.ParseTXTFromReader(reader)

// Works with:
// - HTTP file uploads (multipart.File)
// - Memory buffers (bytes.Reader)
// - Network streams (net.Conn)
// - Any io.Reader implementation
JSON Export πŸ†•
### Export to JSON πŸ†•

```go
// Export to JSON
jsonData, err := match.ToJSON()
jsonData, err := pos.ToJSON()

Command-Line Tools

The package includes several CLI tools for parsing BGF and TXT files:

Building the Tools
# Build all tools
go build -o bin/parse_txt ./examples/parse_txt/
go build -o bin/parse_bgf ./examples/parse_bgf/
go build -o bin/batch_parse ./examples/batch_parse/
go build -o bin/web_server ./examples/web_server/

# Or build individually
cd examples/parse_txt && go build
cd examples/parse_bgf && go build
cd examples/batch_parse && go build
cd examples/web_server && go build
parse_txt - Parse TXT Position Files

Parse and display information from a BGBlitz TXT position file.

# Usage
./bin/parse_txt <filename.txt>

# Example
./bin/parse_txt tmp/blunder21_EN.txt

# Output shows:
# - Player names and scores
# - Match length and Crawford status
# - Position on roll and dice
# - Cube value and owner
# - Move evaluations with equity
# - Cube decisions
# - XGID and Position IDs
parse_bgf - Parse BGF Match Files

Parse and display information from a BGBlitz BGF binary match file.

# Usage
./bin/parse_bgf <filename.bgf>

# Example
./bin/parse_bgf tmp/TachiAI_V_player_Nov_2__2025__16_55.bgf

# Output shows:
# - File format and version
# - Compression status
# - SMILE encoding detection
# - Match metadata (players, dates, scores)
# - Number of decoded fields
# - Game data (if available)
batch_parse - Process Multiple Files

Parse all BGF and TXT files in a directory.

# Usage
./bin/batch_parse <directory>

# Example
./bin/batch_parse tmp/

# Processes:
# - All .txt files (position data)
# - All .bgf files (match data)
# - Shows summary for each file
web_server - Web Interface

Run a web server with upload interface for analyzing BGF and TXT files.

# Start server
./bin/web_server

# Or run directly
cd examples/web_server && go run main.go

# Server starts on http://localhost:8080
# Upload BGF/TXT files through web interface
# Get JSON responses with parsed data

API Endpoints:

  • POST /upload/bgf - Upload and parse BGF file
  • POST /upload/txt - Upload and parse TXT file
  • GET /health - Health check
Running Without Building

You can also run tools directly with go run:

# Parse TXT file
go run examples/parse_txt/main.go tmp/blunder21_EN.txt

# Parse BGF file
go run examples/parse_bgf/main.go tmp/match.bgf

# Batch process directory
go run examples/batch_parse/main.go tmp/

# Start web server
go run examples/web_server/main.go

Use Cases

  • Web Applications: Parse uploaded BGF/TXT files in HTTP handlers
  • REST APIs: Provide backgammon position analysis endpoints
  • Database Storage: Import positions and matches into SQL/NoSQL databases
  • Batch Processing: Analyze collections of match/position files
  • Match Servers: Real-time position analysis services
  • Statistical Analysis: Extract move quality, equity, and win rates

Documentation


## Data Types

### Position

Represents a backgammon position with complete state:

```go
type Position struct {
    Board       [26]int           // Checker positions (0=unused, 1-24=points, 25=bar)
    PlayerX     string            // Player X name
    PlayerO     string            // Player O name
    ScoreX      int               // Player X score
    ScoreO      int               // Player O score
    MatchLength int               // Match length in points
    Crawford    bool              // Crawford rule active
    PositionID  string            // BGBlitz Position-ID
    MatchID     string            // BGBlitz Match-ID
    XGID        string            // XG format ID
    OnRoll      string            // "X" or "O"
    Dice        [2]int            // Current dice roll
    CubeValue   int               // Doubling cube value
    CubeOwner   string            // "", "X", or "O"
    OnBar       map[string]int    // Checkers on bar
    PipCount    map[string]int    // Pip counts
    Evaluations []Evaluation      // Move evaluations
    CubeDecision *CubeDecision    // Cube decision analysis
}
Evaluation

Move evaluation with equity and statistics:

type Evaluation struct {
    Rank    int      // Move rank (1 = best)
    Move    string   // Move notation
    Equity  float64  // Equity value
    Diff    float64  // Difference from best
    Win     float64  // Win probability
    WinG    float64  // Gammon win probability
    WinBG   float64  // Backgammon win probability
    LoseG   float64  // Gammon loss probability
    LoseBG  float64  // Backgammon loss probability
    IsBest  bool     // True if marked as best move
}
CubeDecision

Cube action analysis:

type CubeDecision struct {
    Action  string  // "Double/Take", "Double/Pass", or "No Double"
    MWC     float64 // Match Winning Chances
    MWCDiff float64 // Difference in MWC
    EMG     float64 // EMG (normalized equity)
    EMGDiff float64 // Difference in EMG
    IsBest  bool    // True if marked as best action
}
Match

BGF match file data:

type Match struct {
    Format     string                 // File format ("BGF")
    Version    string                 // Format version
    Compressed bool                   // Gzip compression used
    UseSmile   bool                   // SMILE encoding used
    Data       map[string]interface{} // Parsed match data
}

Examples

The package includes example programs in the examples/ directory:

1. parse_txt

Detailed parser for TXT position files showing all available data.

go run examples/parse_txt/main.go tmp/blunder21_EN.txt
2. parse_bgf

Parser for BGF match files with format detection.

go run examples/parse_bgf/main.go tmp/match.bgf
3. batch_parse

Batch processor for parsing all files in a directory.

go run examples/batch_parse/main.go tmp/
4. web_server πŸ†•

Complete web server with file upload interface.

cd examples/web_server
go run main.go
# Visit http://localhost:8080

File Format Details

TXT Format

Text files contain ASCII art representation of the board plus analysis:

 +13-14-15-16-17-18------19-20-21-22-23-24-+   O: TachiAI_V  161
 | X           O    |   | O     O        X |
 | X           O    |   | O     O        X |
 ...
 Position-ID: mGfwATDgc/ABMA    Match-ID: cAllAAAAAAAE
 XGID=-b----E-C---eE---b-d-b--B-:0:0:1:21:0:0:0:3:10
 
 TachiAI_V - 0 player - 0 in a 3 point match.
 player to move 2-1
 
 Evaluation
 ==========
 1) 13-11 24-23                0.473 / -0.289
    0.443  0.113  0.002  -  0.557  0.179  0.003 

The parser extracts:

  • Board state (visual representation)
  • Player information
  • Match state and score
  • Position identifiers
  • Move evaluations with equity values
  • Win/loss probabilities
  • Cube decisions
BGF Format

Binary files with two parts:

  1. Header (JSON, uncompressed):
{"format":"BGF","version":"1.0","compress":true,"useSmile":true}
  1. Data (gzip + SMILE encoded JSON):
    • Complete match data
    • All positions
    • Move history
    • Analysis results

Note: Full SMILE decoding support is implemented. The parser successfully decodes all SMILE-encoded BGF files including complete match data, move analysis, equity calculations, and performance statistics.

Project Structure

bgfparser/
β”œβ”€β”€ LICENSE              # MIT License
β”œβ”€β”€ README.md           # This file
β”œβ”€β”€ go.mod              # Go module definition
β”œβ”€β”€ types.go            # Core data types (JSON-serializable)
β”œβ”€β”€ txt_parser.go       # TXT format parser (file-based)
β”œβ”€β”€ bgf_parser.go       # BGF format parser (file-based)
β”œβ”€β”€ web.go              # Web-ready parsers (io.Reader) πŸ†•
β”œβ”€β”€ txt_parser_helpers.go # TXT parsing utilities πŸ†•
β”œβ”€β”€ doc/
β”‚   β”œβ”€β”€ API_REFERENCE.md     # Complete API reference
β”‚   β”œβ”€β”€ WEB_INTERFACE.md     # Web integration guide πŸ†•
β”‚   └── BGF_format.md        # BGF format specification
β”œβ”€β”€ examples/
β”‚   β”œβ”€β”€ parse_txt/      # TXT parser example
β”‚   β”œβ”€β”€ parse_bgf/      # BGF parser example
β”‚   β”œβ”€β”€ batch_parse/    # Batch processing example
β”‚   └── web_server/     # Web server example πŸ†•
└── tmp/                # Sample data files
    β”œβ”€β”€ *.txt           # Position files
    └── *.bgf           # Match files

Testing

Run the batch parser on the sample data:

# Build examples
go build -o bin/parse_txt ./examples/parse_txt/
go build -o bin/parse_bgf ./examples/parse_bgf/
go build -o bin/batch_parse ./examples/batch_parse/

# Test on sample data
./bin/batch_parse tmp/

Limitations and Future Work

Current Limitations
Planned Improvements
  • More comprehensive test suite
  • Performance optimizations for batch processing

Contributing

Contributions are welcome! Please feel free to submit pull requests or open issues for:

  • Bug fixes
  • Additional features
  • Documentation improvements
  • Test cases
  • Language support

License

This project is licensed under the MIT License - see the LICENSE file for details.

Acknowledgments

  • Frank Berger for creating BGBlitz, the backgammon analysis software
  • LeLuxNet for the SMILE decoder implementation

Support

For questions, issues, or suggestions:

  • Open an issue on GitHub
  • Check the doc/ directory for format specifications
  • Review the examples/ directory for usage patterns

Documentation ΒΆ

Overview ΒΆ

Package bgfparser provides parsers for BGBlitz backgammon data files.

BGBlitz is a backgammon analysis software that stores data in two formats:

  • TXT: Human-readable position files showing board state and analysis
  • BGF: Binary match files using JSON with gzip compression and SMILE encoding

This package can parse both formats and extract position data, evaluations, match information, and move analysis.

Index ΒΆ

Constants ΒΆ

This section is empty.

Variables ΒΆ

This section is empty.

Functions ΒΆ

This section is empty.

Types ΒΆ

type CubeDecision ΒΆ

type CubeDecision struct {
	Action  string  `json:"action"` // "Double/Take", "Double/Pass", "No Double"
	MWC     float64 `json:"mwc"`    // Match Winning Chances
	MWCDiff float64 `json:"mwc_diff"`
	EMG     float64 `json:"emg"` // EMG (Normalized equity)
	EMGDiff float64 `json:"emg_diff"`
	IsBest  bool    `json:"is_best"`
}

CubeDecision represents a cube decision analysis

type Evaluation ΒΆ

type Evaluation struct {
	Rank   int     `json:"rank"`
	Move   string  `json:"move"`
	Equity float64 `json:"equity"`
	Diff   float64 `json:"diff"`
	Win    float64 `json:"win"`
	WinG   float64 `json:"win_g"`
	WinBG  float64 `json:"win_bg"`
	LoseG  float64 `json:"lose_g"`
	LoseBG float64 `json:"lose_bg"`
	IsBest bool    `json:"is_best"`
}

Evaluation represents a move evaluation

type Match ΒΆ

type Match struct {
	Format   string `json:"format"`
	Version  string `json:"version"`
	Compress bool   `json:"compress"`
	UseSmile bool   `json:"useSmile"`

	// Match data will be populated from the JSON structure
	Data map[string]interface{} `json:"data,omitempty"`
}

Match represents a complete backgammon match from a BGF file

func ParseBGF ΒΆ

func ParseBGF(filename string) (*Match, error)

ParseBGF parses a BGBlitz BGF (binary match) file from disk This is a convenience wrapper around ParseBGFFromReader that handles file reading.

BGF files consist of: 1. A JSON header line with format info (uncompressed) 2. The rest of the file is gzipped JSON data (optionally SMILE encoded)

func ParseBGFFromReader ΒΆ

func ParseBGFFromReader(reader io.Reader) (*Match, error)

ParseBGFFromReader parses a BGBlitz BGF file from an io.Reader This allows parsing BGF files from network streams, memory buffers, HTTP uploads, or any io.Reader source.

Example usage with HTTP upload:

func uploadHandler(w http.ResponseWriter, r *http.Request) {
    file, _, _ := r.FormFile("bgffile")
    defer file.Close()

    match, err := bgfparser.ParseBGFFromReader(file)
    if err != nil {
        http.Error(w, err.Error(), http.StatusBadRequest)
        return
    }

    w.Header().Set("Content-Type", "application/json")
    json.NewEncoder(w).Encode(match)
}

func (*Match) GetMatchInfo ΒΆ

func (m *Match) GetMatchInfo() map[string]interface{}

GetMatchInfo extracts basic match information from a parsed BGF file

func (*Match) String ΒΆ

func (m *Match) String() string

String returns a human-readable representation of the match

func (*Match) ToJSON ΒΆ

func (m *Match) ToJSON() ([]byte, error)

ToJSON serializes the Match to JSON

type ParseError ΒΆ

type ParseError struct {
	File    string
	Line    int
	Message string
}

ParseError represents an error during parsing

func (*ParseError) Error ΒΆ

func (e *ParseError) Error() string

type Position ΒΆ

type Position struct {
	// Board represents the checkers on each point (1-24), bar, and off
	// Points 1-24 for both players, positive for X, negative for O
	Board [26]int `json:"board"`

	// Player information
	PlayerX string `json:"player_x"`
	PlayerO string `json:"player_o"`
	ScoreX  int    `json:"score_x"`
	ScoreO  int    `json:"score_o"`

	// Match information
	MatchLength int  `json:"match_length"`
	Crawford    bool `json:"crawford"`

	// Position identifiers
	PositionID string `json:"position_id"` // BGBlitz Position-ID
	MatchID    string `json:"match_id"`    // BGBlitz Match-ID
	XGID       string `json:"xgid"`        // XG format ID

	// Current state
	OnRoll    string         `json:"on_roll"` // "X" or "O"
	Dice      [2]int         `json:"dice"`
	CubeValue int            `json:"cube_value"`
	CubeOwner string         `json:"cube_owner"` // "", "X", "O"
	OnBar     map[string]int `json:"on_bar"`
	PipCount  map[string]int `json:"pip_count"`

	// Evaluation data
	Evaluations  []Evaluation  `json:"evaluations,omitempty"`
	CubeDecision *CubeDecision `json:"cube_decision,omitempty"`
}

Position represents a backgammon position

func ParseTXT ΒΆ

func ParseTXT(filename string) (*Position, error)

ParseTXT parses a BGBlitz position text file from disk This is a convenience wrapper around ParseTXTFromReader that handles file reading.

func ParseTXTFromReader ΒΆ

func ParseTXTFromReader(reader io.Reader) (*Position, error)

ParseTXTFromReader parses a BGBlitz TXT position file from an io.Reader This allows parsing TXT files from network streams, memory buffers, HTTP uploads, or any io.Reader source.

Example usage with in-memory data:

data := []byte("... TXT content ...")
pos, err := bgfparser.ParseTXTFromReader(bytes.NewReader(data))

func (*Position) ToJSON ΒΆ

func (p *Position) ToJSON() ([]byte, error)

ToJSON serializes the Position to JSON

Directories ΒΆ

Path Synopsis
examples
batch_parse command
parse_bgf command
parse_txt command
web_server command
This example demonstrates how to use the bgfparser in HTTP handlers for uploading and analyzing BGF and TXT files via a web interface.
This example demonstrates how to use the bgfparser in HTTP handlers for uploading and analyzing BGF and TXT files via a web interface.
internal
smile
Licensed under the MIT License Original source: https://gitlab.com/LeLuxNet/X/-/blob/c09411c26dfb/encoding/smile/decode.go
Licensed under the MIT License Original source: https://gitlab.com/LeLuxNet/X/-/blob/c09411c26dfb/encoding/smile/decode.go

Jump to

Keyboard shortcuts

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