Skip to main content

backgammon/
lib.rs

1/*
2 * BSD 2-Clause License
3 *
4 * Copyright (c) 2020-2026, Carlo Strub <cs@carlostrub.ch>
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright notice, this
10 *    list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright notice,
13 *    this list of conditions and the following disclaimer in the documentation
14 *    and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28//! [![status-badge](https://ci.codeberg.org/api/badges/15563/status.svg)](https://ci.codeberg.org/repos/15563)
29//!
30//! # Backgammon: The Oldest Board Game in the World
31//! This crate provides a pure, canonical implementation of the game
32//! [*Backgammon.*](https://en.wikipedia.org/wiki/Backgammon)
33//!
34//! <img src="https://upload.wikimedia.org/wikipedia/commons/3/30/Backgammon_lg.png" height="100">
35//!
36//! ## Supported Doubling Cube Rules
37//! The following doubling cube [`rules`](`crate::rules::Rules`) are supported:
38//!
39//! * Murphy
40//! * Jacobi
41//! * Crawford
42//! * Holland
43//!
44//! ## Recommended Use for AI Agents
45//! For a correct and tournament-legal implementation, AI agents should interact with the `Match`
46//! struct rather than the `Game` struct directly.
47//! use backgammon::prelude::*;
48//!
49//! AI Agent Setup: Always define the match context first
50//! ```
51//! use backgammon::prelude::*;
52//!
53//! fn setup_agent_environment() -> Match {
54//! let mut m = Match::new();
55//! m.set_points(13).unwrap();
56//! m.set_crawford(true).unwrap();
57//! m
58//! }
59//! ```
60//!
61//! - **Why `Match`?**: It manages the Doubling Cube, Match Points, and rules like Jacoby or
62//!   Crawford which are essential for calculating "Match Equity" (the probability of winning the
63//!   whole match).
64//! - **Statelessness**: This crate is stateless. Agents must persist the `Match` object between
65//!   turns.
66//!
67//! ### Difference between Game and Match Structs
68//! | Feature | Game Struct | Match Struct |
69//! |---------|-------------|--------------|
70//! | Checker Movement | Yes | Yes (via current game) |
71//! | Dice Rolling | Yes | Yes |
72//! | Doubling Cube | No | Yes |
73//! | Match Score | No | Yes |
74//! | Tournament Rules | No | Yes (Crawford, etc.) |
75//!
76//! ## Examples
77//! ### Creating a Match
78//! To create a new backgammon match, load the prelude module and define a mutable match:
79//! ```
80//! use backgammon::prelude::*;
81//!
82//! let mut m = Match::new();
83//!
84//! ```
85//! Depending on the style of tournament, it is possible to set any number of
86//! [`rules`](`crate::rules::Rules`):
87//! ```
88//! use backgammon::prelude::*;
89//!
90//! fn play_match() -> Result<(), Error> {
91//!
92//! let mut m = Match::new();
93//! m.set_points(13)?;
94//! m.set_jacobi(true)?;
95//!
96//! Ok(())
97//! }
98//! ```
99//! ### The first roll
100//! In a physical game, both players roll with one die. Then, the higher roll defines the first
101//! player.
102//! ```
103//! use backgammon::prelude::*;
104//!
105//! fn play_match() -> Result<(), Error> {
106//!
107//! let mut m = Match::new();
108//! m.roll(Player::Nobody)?;
109//!
110//! Ok(())
111//! }
112//! ```
113//!
114//! ### Playing an Example Backgammon Match
115//! To see this library in action, run the included example:
116//! ```console
117//! cargo run --example backgammon_tui
118//! ```
119//! For more examples, have a look at the [examples](https://codeberg.org/Backgammon/backgammon/src/branch/main/examples)
120//! directory.
121//!
122//! ## Design Philosophy
123//! This library is designed to provide stateless Backgammon gameplay functionality. Because it does
124//! not track or store game states itself, you can easily implement wrappers that use this library
125//! along with an external database to manage and persist game states.
126//!
127//! ## Discussions and Support
128//! Remember that the APIs are not stable yet. Any support is very welcome. Please open an
129//! [Issue](https://codeberg.org/Backgammon/backgammon/issues) to discuss features or ask for help.
130
131#![warn(future_incompatible)]
132#![deny(
133    rustdoc::broken_intra_doc_links,
134    rustdoc::invalid_codeblock_attributes,
135    rustdoc::invalid_html_tags,
136    rustdoc::missing_crate_level_docs,
137    missing_debug_implementations,
138    missing_docs,
139    rustdoc::private_intra_doc_links,
140    single_use_lifetimes,
141    trivial_casts,
142    trivial_numeric_casts,
143    unreachable_pub,
144    unsafe_code,
145    unused_extern_crates,
146    unused_import_braces,
147    unused_qualifications,
148    unused_results,
149    unused_variables,
150    variant_size_differences
151)] // be tough on code quality
152
153pub use error::Error;
154pub use game::Game;
155pub use r#match::{Match, MatchState};
156
157/// Implements all possible Backgammon errors.
158pub mod error;
159/// Implements a Backgammon game.
160pub mod game;
161/// Implements a Backgammon match.
162pub mod r#match;
163/// Implements the board, the dice, the cube, and all other Backgammon rules.
164///
165/// _Caveat:_ Unless you know what you are doing, you should not use this module directly. Only
166/// use the [Match struct](./struct.Match.html) in your implementation.
167pub mod rules;
168/// Implements statistics.
169pub mod stats;
170
171/// Implements the AI Agent API. Useful for training neural networks.
172pub mod ai;
173
174/// Implements the FIBS rating algorithm.
175pub mod rating;
176
177/// Provides commonly used types and structures for ease of use in external modules. It is
178/// recommended to always use the prelude module for convenience.
179pub mod prelude {
180    pub use crate::game::GameOutcome;
181    pub use crate::game::GameState;
182    pub use crate::rules::prelude::*;
183    pub use crate::stats::Stats;
184    pub use crate::{Error, Game, Match, MatchState};
185}