Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
[package]
name = "magpie"
version = "0.11.2"
authors = ["Emil Englesson <englesson.emil@gmail.com>"]
edition = "2024"
description = "High-performance Othello library built with bitboards"
repository = "https://github.com/LimeEng/magpie/"
Expand All @@ -10,15 +9,17 @@ keywords = ["othello", "reversi", "bitboard"]
categories = ["algorithms", "game-engines"]
build = "build/build.rs"

exclude = [
".github/**"
]
exclude = [".github/**"]

[features]
default = []
serde = ["dep:serde"]

[dependencies]
serde = { version = "1.0", optional = true, features = ["derive"] }

[dev-dependencies]
criterion = "0.5"
criterion = "0.8"
indoc = "2.0"
paste = "1.0"
quickcheck = "1.0"
Expand Down
16 changes: 8 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,20 @@ Magpie is a high-performance library for the classic board game [Othello](https:

### Key Features

- **Built with bitboards**: Uses bitboards for extremely fast board operations
- **Zero dependencies**: Core functionality has no external dependencies
- **Optional Serde support**: Serialization available through an optional feature flag
- **Built with bitboards**, allowing for extremely fast board operations
- Core functionality has **zero dependencies**
- **Optional Serde support**

Furthermore, the library offers two abstraction levels:
Magpie offers two abstraction levels:

- **Game API**: Ensures rule compliance, tracks turns, and maintains board consistency
- **Board API**: Provides raw board operations without validation, when performance is critical.
- **Game API**: rule-checked, turn-aware game logic and state management
- **Board API**: lower-level, unchecked board operations for maximum performance.

## Installation

```sh
cargo add magpie
# If serialization with Serde is desired, activate the serde feature flag.
# Serde support is available through the serde feature flag.
cargo add magpie -F serde
```

Expand All @@ -36,4 +36,4 @@ Curious to play? One example features a functional Othello game with a random AI

Benchmarks are [described here](/benches)

Simply run `cargo bench` to run all benchmarks.
Run the benchmarks with `cargo bench`.
9 changes: 7 additions & 2 deletions benches/README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
# Benchmarks

Simply run `cargo bench` to run all benchmarks.
Run the benchmarks with `cargo bench`.

- [Clone](#clone)
- [Legal moves](#legal-moves)
- [Place stone](#place-stone)
- [Legal move check](#legal-move-check)
- [Individual bitboard extraction](#individual-bitboard-extraction)
- [Legal moves extraction](#legal-moves-extraction)

## Clone

Simply measures the performance when cloning the standard opening position of Othello.
Measures the performance when cloning the standard opening position of Othello.

## Legal moves

Expand Down Expand Up @@ -55,6 +56,10 @@ Playing E5 as black will flip 19 white stones.

Measures the performance of checking if playing E5 as black is legal given the same board configuration as used in the [play benchmark](#play).

## Individual bitboard extraction

Measures the performance of extracting each position of a bitboard, as a bitboard, given the same board configuration used in the [legal moves benchmark](#legal-moves).

## Legal moves extraction

Measures the performance of extracting all individual legal moves as black given the same board configuration used in the [legal moves benchmark](#legal-moves).
3 changes: 2 additions & 1 deletion benches/othello_board.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use criterion::{Criterion, black_box, criterion_group, criterion_main};
use criterion::{Criterion, criterion_group, criterion_main};
use magpie::othello::{Bitboard, Board, Position, Stone};
use std::hint::black_box;

fn bench_clone(c: &mut Criterion) {
let board = Board::standard();
Expand Down
41 changes: 21 additions & 20 deletions examples/serde.rs
Original file line number Diff line number Diff line change
@@ -1,27 +1,28 @@
use magpie::othello::{Board, Stone};
use serde::{Deserialize, Serialize};
use serde_json::Result;
use magpie::othello::{Bitboard, Board, Game, Position, Stone};
use serde::{Serialize, de::DeserializeOwned};
use std::fmt::Debug;

#[derive(Debug, Serialize, Deserialize)]
struct Game {
board: Board,
next_player: Stone,
}

fn main() -> Result<()> {
let board = Board::standard();
// In Othello, black moves first
let next_player = Stone::Black;
fn main() -> Result<(), serde_json::Error> {
print_serde(&Game::new())?;
print_serde(&Board::standard())?;
print_serde(&Stone::Black)?;
print_serde(&Bitboard::FILLED)?;
print_serde(&Position::try_from("A1").unwrap())?;

let game = Game { board, next_player };
Ok(())
}

// Serialize to JSON
let json = serde_json::to_string_pretty(&game)?;
fn print_serde<T>(value: &T) -> Result<(), serde_json::Error>
where
T: Serialize + DeserializeOwned + Debug,
{
let json = serde_json::to_string_pretty(&value)?;
let value: T = serde_json::from_str(&json)?;
println!("-----[ Deserialized ]-----");
println!("{value:#?}");
println!("-----[ Serialized ]-----");
println!("{json}");

// Deserialize from JSON
let game: Game = serde_json::from_str(&json)?;
println!("{game:?}");
println!("==========================");

Ok(())
}