Veggerby.Boards.Go
0.1.0-prerelease0212
dotnet add package Veggerby.Boards.Go --version 0.1.0-prerelease0212
NuGet\Install-Package Veggerby.Boards.Go -Version 0.1.0-prerelease0212
<PackageReference Include="Veggerby.Boards.Go" Version="0.1.0-prerelease0212" />
<PackageVersion Include="Veggerby.Boards.Go" Version="0.1.0-prerelease0212" />
<PackageReference Include="Veggerby.Boards.Go" />
paket add Veggerby.Boards.Go --version 0.1.0-prerelease0212
#r "nuget: Veggerby.Boards.Go, 0.1.0-prerelease0212"
#:package Veggerby.Boards.Go@0.1.0-prerelease0212
#addin nuget:?package=Veggerby.Boards.Go&version=0.1.0-prerelease0212&prerelease
#tool nuget:?package=Veggerby.Boards.Go&version=0.1.0-prerelease0212&prerelease
Veggerby.Boards.Go
Go (Weiqi/Baduk) module for Veggerby.Boards providing complete stone placement, capture mechanics, ko rule, and territory scoring built atop the immutable deterministic core engine.
Depends on
Veggerby.Boards. Use when you want a ready Go ruleset or a foundation for Go variants.
Install
dotnet add package Veggerby.Boards.Go
Overview
This module provides a complete, deterministic implementation of Go (Weiqi/Baduk) with:
- Board topology for standard sizes (9×9, 13×13, 19×19)
- Stone placement with liberty and suicide validation
- Capture mechanics with group detection
- Simple ko rule enforcement
- Pass turns with two-consecutive-pass game termination
- Area scoring (stones + territory)
Quick Start
using Veggerby.Boards.Go;
// Create a 19×19 Go game (default size)
var builder = new GoGameBuilder(size: 19);
var progress = builder.Compile();
// Get players and an available stone
var blackPlayer = progress.Game.GetPlayer("black");
var whitePlayer = progress.Game.GetPlayer("white");
var tile = progress.Game.GetTile("tile-4-4"); // D4 in Go notation
// Find an available stone for black
var blackStone = progress.State.GetStates<PieceState>()
.Where(ps => ps.Artifact.Owner?.Id == "black" && ps.Tile == null)
.Select(ps => ps.Artifact)
.Cast<Piece>()
.First();
// Place a stone
progress = progress.HandleEvent(new PlaceStoneGameEvent(blackStone, tile));
// Pass turn
progress = progress.HandleEvent(new PassTurnGameEvent());
// Check if game is over (after two consecutive passes)
if (progress.IsGameOver())
{
var outcome = progress.GetOutcome() as GoOutcomeState;
Console.WriteLine($"Game ended. Score - Black: {outcome.BlackScore}, White: {outcome.WhiteScore}");
}
Key Concepts
GoStateExtras
The module uses GoStateExtras to track:
- KoTileId: The tile position where ko rule is currently active (prevents immediate recapture)
- BoardSize: The board dimension (9, 13, or 19)
Events & Mutators
| Event | Mutator | Description |
|---|---|---|
PlaceStoneGameEvent |
PlaceStoneStateMutator |
Places a stone, handles captures, validates suicide rule, enforces ko |
PassTurnGameEvent |
PassTurnStateMutator |
Passes turn, increments pass streak, ends game after two consecutive passes |
Group Detection & Liberties
The GroupScanner performs iterative flood-fill to:
- Identify connected stone groups
- Count liberties (empty adjacent intersections)
- Detect which groups have zero liberties (captured)
Capture Mechanics
When a stone is placed:
- Check opponent groups for zero liberties → remove captured stones
- Check own group for zero liberties (suicide) → reject placement unless it captures opponent stones
Ko Rule
Simple ko prevents immediately recapturing a single stone:
- After a single-stone capture, the capturing position is marked in
KoTileId - Next move cannot place a stone at that position
- Ko restriction clears when any other move is made or a turn is passed
Pass Mechanics
PassTurnGameEventincrements the consecutive pass counter (TurnState.PassStreak)- After two consecutive passes,
PassTurnStateMutatorappendsGameEndedState - Any stone placement resets the pass streak to zero
Scoring
GoScoring.AreaScore computes final score using area scoring:
- Stones: Each stone on the board counts as 1 point
- Territory: Empty intersections surrounded by one color count for that color
- Result: Returns
GoOutcomeStatewith black and white scores
Territory assignment uses flood-fill: if an empty region touches only one color, it belongs to that color.
Phases
The Go module uses a single "play" phase:
AddGamePhase("play")
.If<NullGameStateCondition>() // Always active
.Then()
.All()
.ForEvent<PlaceStoneGameEvent>()
.Then()
.Do<PlaceStoneStateMutator>()
.ForEvent<PassTurnGameEvent>()
.Then()
.Do<PassTurnStateMutator>();
Testing
Run the module tests:
cd test/Veggerby.Boards.Tests
dotnet test --filter "FullyQualifiedName~Go"
Test Coverage (29/29 passing, 100% success rate):
- Stone placement validation (empty intersection required)
- Single and multi-stone capture mechanics
- Suicide rule enforcement (with and without capture)
- Ko rule: immediate recapture blocking, ko clearing via pass, ko clearing via play elsewhere
- Snapback scenarios (multi-stone captures don't trigger ko)
- Pass counting and double-pass termination
- Area scoring with territory assignment
Known Limitations
- Superko: Only simple ko is enforced; positional superko (full-board repetition) is not detected
- Territory vs Area Scoring: Only area scoring is implemented; Chinese rules are assumed
- Handicap Stones: No built-in handicap placement helper
- Dead Stone Adjudication: No automatic detection of dead groups; players must play out all captures
Extending This Module
Common extension scenarios:
Adding Handicap Placement
public class GoGameBuilderWithHandicap : GoGameBuilder
{
public GoGameBuilderWithHandicap(int size, int handicap) : base(size)
{
// After Build(), place handicap stones on star points
// WithPiece("black-stone-1").OnTile("tile-4-4");
// ...
}
}
Implementing Territory Scoring Variant
public static class GoScoringVariants
{
public static GoOutcomeState TerritoryScore(GameState state, GoStateExtras extras)
{
// Count only territory (empty intersections), not stones
// Implement Japanese-style scoring
}
}
Adding Time Controls
public sealed record GoTimeControlExtras(
TimeSpan BlackTime,
TimeSpan WhiteTime,
int ByoYomiPeriods
);
// Add time tracking mutators that validate time usage
References
- Core Documentation: See /docs/core-concepts.md for engine fundamentals
- Phase Patterns: See /docs/phase-based-design.md for phase design guidelines
- Game Termination: See /docs/game-termination.md for outcome patterns
- Go Rules: Sensei's Library for comprehensive Go rules reference
Versioning
Semantic versioning aligned with repository releases. Breaking rule or API changes bump MAJOR.
Contributing
Open issues & PRs at https://github.com/veggerby/Veggerby.Boards. Follow contributor guidelines.
License
MIT License. See root LICENSE.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Veggerby.Algorithm (>= 1.0.0)
- Veggerby.Boards (>= 0.1.0-prerelease0212)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.1.0-prerelease0212 | 76 | 4/13/2026 |
| 0.1.0-prerelease0211 | 78 | 2/8/2026 |
| 0.1.0-prerelease0210 | 75 | 1/26/2026 |
| 0.1.0-prerelease0209 | 73 | 1/12/2026 |
| 0.1.0-prerelease0208 | 70 | 1/11/2026 |
| 0.1.0-prerelease0207 | 75 | 1/11/2026 |
| 0.1.0-prerelease0206 | 77 | 1/11/2026 |
| 0.1.0-prerelease0205 | 73 | 1/10/2026 |
| 0.1.0-prerelease0204 | 82 | 1/9/2026 |
| 0.1.0-prerelease0203 | 75 | 1/9/2026 |
| 0.1.0-prerelease0202 | 80 | 1/9/2026 |
| 0.1.0-prerelease0201 | 79 | 1/8/2026 |
| 0.1.0-prerelease0200 | 76 | 1/8/2026 |
| 0.1.0-prerelease0199 | 78 | 1/7/2026 |
| 0.1.0-prerelease0198 | 84 | 1/6/2026 |
| 0.1.0-prerelease0197 | 74 | 1/6/2026 |
| 0.1.0-prerelease0196 | 75 | 1/6/2026 |
| 0.1.0-prerelease0195 | 77 | 1/5/2026 |
| 0.1.0-prerelease0194 | 76 | 1/4/2026 |
| 0.1.0-prerelease0193 | 264 | 12/17/2025 |