voronoi_go/lib.rs
1//! Core rules implementation for Voronoi Go. Machine translated from the original
2//! implementation playable at [voronoigo.com].
3//!
4//! [voronoigo.com]: https://voronoigo.com
5//!
6//! This small section of docs was written by a human, but the rest can be assumed to
7//! be machine-written unless stated otherwise. All of the code was also written
8//! by a machine but reviewed by a human and verified against output from the
9//! original implementation. For more information and support for using this implementation
10//! in non-rust languages, visit [the repo]. For questions left unanswered by these docs,
11//! you can also join [the discord] and ask there. I am happy to help you out.
12//!
13//! [the repo]: https://github.com/csun/voronoi-go-rs
14//! [the discord]: https://discord.gg/4ren7UAFeb
15//!
16//! You'll mainly want to interact with the [`Game`] struct to play moves, calculate
17//! territory, compute cuttability, etc. Code sample:
18//! ```
19//! use voronoi_go::{Game, Point};
20//!
21//! // A board nine stones across is 18 units wide: coordinates are stone radii.
22//! let mut game = Game::new(18.0);
23//!
24//! game.try_move(Point::new(4.0, 4.0))?; // black
25//! game.try_move(Point::new(14.0, 14.0))?; // white
26//!
27//! assert_eq!(game.stones().len(), 2);
28//!
29//! // Territory is area, and the two shares sum to the whole board.
30//! let area = game.territory();
31//! assert!((area.black() + area.white() - 18.0 * 18.0).abs() < 1e-9);
32//!
33//! // Undo restores the previous state bit for bit.
34//! game.undo_move();
35//! assert_eq!(game.stones().len(), 1);
36//! # Ok::<(), voronoi_go::StonePlayError>(())
37//! ```
38//!
39//! # Feature flags
40//!
41//! Both are on by default but are optional.
42//!
43//! - **`svg`** — [`Game::dump_svg`] and [`AliveZone::to_svg`], which write a
44//! standalone board image. Items behind it are labelled on [docs.rs].
45//! - **`serde`** — `Serialize`/`Deserialize` on the public data types. Required by the engine binary and the Python bindings.
46//!
47//! [docs.rs]: https://docs.rs/voronoi-go
48
49// `doc_cfg` is nightly-only, and `docsrs` is set only by docs.rs and by
50// `cargo docs-rs`. Every other build never sees the attribute, so this costs a
51// stable build nothing while giving a reader feature labels where they look.
52#![cfg_attr(docsrs, feature(doc_cfg))]
53
54pub mod alive_zone;
55// The segment arena, the shapes and the shared-start index. Internal: nothing a
56// consumer of the rules needs, and publishing it would freeze the one structure
57// `docs/design.md` most wants free to change. The three names that leak through
58// `ZoneError` are re-exported below.
59pub(crate) mod clipping;
60mod color;
61pub mod connectivity;
62mod constants;
63mod delta;
64pub mod game;
65pub mod geometry;
66mod point;
67#[cfg(feature = "serde")]
68#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
69mod serde_support;
70mod stone;
71#[cfg(feature = "svg")]
72#[cfg_attr(docsrs, doc(cfg(feature = "svg")))]
73mod svg;
74pub mod voronoi;
75
76pub use alive_zone::{AliveZone, DeadZoneError, ZoneError};
77// Named by `ZoneError`'s variants, so they have to be reachable even though the
78// module they come from is not.
79pub use clipping::{SegId, ShapeId, StructureError};
80pub use color::{Color, PerColor};
81pub use connectivity::{BoardEdge, Connectivity, CutError, CutKind};
82pub use constants::{EPSILON, STONE_DIAMETER, STONE_RADIUS};
83pub use delta::GameDelta;
84pub use game::{BoardError, Commit, DeltaError, Game, GameOverError, GameStatus, StonePlayError};
85pub use point::{Point, PointKey};
86pub use stone::{Stone, StoneId};
87pub use voronoi::{Voronoi, VoronoiGroup};