Skip to content

Commit

Permalink
feat: expose more nim utils
Browse files Browse the repository at this point in the history
  • Loading branch information
LeoDog896 committed Nov 2, 2024
1 parent 337211e commit 4135443
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 4 deletions.
4 changes: 3 additions & 1 deletion crates/game-solver/src/player.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,9 @@ impl TwoPlayer for PartizanPlayer {}

/// Represents a player in a zero-sum (2-player) game,
/// where the game is impartial. That is,
/// the only difference between players is who goes first.
/// the only difference between players is who goes first,
/// and the only thing that defines a game is its 'state':
/// both players need to have the same winning criteria for this player to be used.
#[derive(PartialEq, Eq, Debug, Clone, Copy, Hash)]
pub enum ImpartialPlayer {
/// The player that will play on the current game state,
Expand Down
27 changes: 24 additions & 3 deletions crates/nimnim/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
use std::ops::Add;
use std::{collections::HashSet, ops::Add};

#[derive(PartialEq, PartialOrd, Eq, Ord, Debug)]
struct Nimber(usize);
/// A nimber is the size of a heap in a single-stack nim game.
///
/// Nim is crucial for loop-free* impartial combinatorial game theory analysis.
///
/// *This structure does not define utilities for loopy nimbers.
#[derive(Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)]
pub struct Nimber(pub usize);

impl Add for Nimber {
type Output = Nimber;
Expand All @@ -13,6 +18,22 @@ impl Add for Nimber {
}
}

/// Returns Some(minimum excluded value of `list`), or `None` iff `list.is_empty()`
pub fn mex(list: &[Nimber]) -> Option<Nimber> {
let mut mex: Option<Nimber> = None;
let mut set: HashSet<Nimber> = HashSet::with_capacity(list.len());

for item in list {
if set.insert(*item) {
if item > &mex.unwrap_or(Nimber(0)) {
mex = Some(*item)
}
}
}

mex
}

#[cfg(test)]
mod tests {
use crate::Nimber;
Expand Down

0 comments on commit 4135443

Please sign in to comment.