Skip to content

Commit

Permalink
style: fmt
Browse files Browse the repository at this point in the history
  • Loading branch information
LeoDog896 committed Sep 23, 2024
1 parent c51060d commit d3a54eb
Show file tree
Hide file tree
Showing 11 changed files with 99 additions and 45 deletions.
25 changes: 13 additions & 12 deletions crates/game-solver/src/game.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,33 +15,34 @@ pub enum GameState<P: Player> {
}

/// Defines the 'state' the game is in.
///
///
/// Generally used by a game solver for better optimizations.
///
///
/// This is usually wrapped in an Option, as there are many games that do not classify
/// as being under 'Normal' or 'Misere.' (i.e. tic-tac-toe)
#[non_exhaustive]
pub enum StateType {
/// If a game is under 'normal play' convention, the last player to move wins.
/// There are no ties in this variant.
///
///
/// Learn more: <https://en.wikipedia.org/wiki/Normal_play_convention>
Normal,
/// If a game is under 'misere play' convention, the last player to move loses.
/// There are no ties in this variant.
///
///
/// Learn more: <https://en.wikipedia.org/wiki/Mis%C3%A8re#Mis%C3%A8re_game>
Misere
Misere,
}

impl StateType {
pub fn state<T>(&self, game: &T) -> GameState<T::Player>
where T: Game
where
T: Game,
{
if game.possible_moves().next().is_none() {
GameState::Win(match self {
Self::Misere => game.player(),
Self::Normal => game.player().previous()
Self::Normal => game.player().previous(),
})
} else {
GameState::Playable
Expand All @@ -50,9 +51,9 @@ impl StateType {
}

/// Represents a combinatorial game.
///
///
/// A game has three distinct variants per game:
///
///
/// - Game play type: Normal, Misere, Other
/// - Game partiality type: Impartial, Partizan
/// - Game player count: >0
Expand Down Expand Up @@ -88,7 +89,7 @@ pub trait Game: Clone {
fn possible_moves(&self) -> Self::Iter<'_>;

/// Returns a reachable game in one move.
///
///
/// Rather, this function asks if there exists some game in the possible games set
/// which has a resolvable, positive or negative, outcome.
fn find_immediately_resolvable_game(&self) -> Result<Option<Self>, Self::MoveError> {
Expand All @@ -105,10 +106,10 @@ pub trait Game: Clone {

/// Returns the current state of the game.
/// Used for verifying initialization and isn't commonly called.
///
///
/// If `Self::STATE_TYPE` isn't None,
/// the following implementation can be used:
///
///
/// ```ignore
/// fn state(&self) -> GameState<Self::Player> {
/// Self::STATE_TYPE.unwrap().state(self)
Expand Down
13 changes: 10 additions & 3 deletions crates/game-solver/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ fn negamax<T: Game<Player = impl TwoPlayer> + Eq + Hash>(
game: &T,
transposition_table: &mut dyn TranspositionTable<T>,
mut alpha: isize,
mut beta: isize
mut beta: isize,
) -> Result<isize, T::MoveError> {
match game.state() {
GameState::Playable => (),
Expand Down Expand Up @@ -165,7 +165,12 @@ type CollectedMoves<T> = Vec<Result<(<T as Game>::Move, isize), <T as Game>::Mov
///
/// A vector of tuples of the form `(move, score)`.
#[cfg(feature = "rayon")]
pub fn par_move_scores_with_hasher<T: Game<Player = impl TwoPlayer> + Eq + Hash + Sync + Send + 'static, S>(game: &T) -> CollectedMoves<T>
pub fn par_move_scores_with_hasher<
T: Game<Player = impl TwoPlayer> + Eq + Hash + Sync + Send + 'static,
S,
>(
game: &T,
) -> CollectedMoves<T>
where
T::Move: Sync + Send,
T::MoveError: Sync + Send,
Expand Down Expand Up @@ -203,7 +208,9 @@ where
///
/// A vector of tuples of the form `(move, score)`.
#[cfg(feature = "rayon")]
pub fn par_move_scores<T: Game<Player = impl TwoPlayer> + Eq + Hash + Sync + Send + 'static>(game: &T) -> CollectedMoves<T>
pub fn par_move_scores<T: Game<Player = impl TwoPlayer> + Eq + Hash + Sync + Send + 'static>(
game: &T,
) -> CollectedMoves<T>
where
T::Move: Sync + Send,
T::MoveError: Sync + Send,
Expand Down
4 changes: 2 additions & 2 deletions crates/game-solver/src/player.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,14 +63,14 @@ 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.
#[derive(PartialEq, Eq, Debug, Clone, Copy, Hash)]
pub enum ImpartialPlayer {
/// The player that will play on the current game state,
Next,
/// The player that has played previous to this game state
/// (or will play after Next).
Previous
Previous,
}

impl Player for ImpartialPlayer {
Expand Down
5 changes: 4 additions & 1 deletion crates/games/src/chomp/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ pub mod gui;
use anyhow::Error;
use array2d::Array2D;
use clap::Args;
use game_solver::{game::{Game, GameState, StateType}, player::ImpartialPlayer};
use game_solver::{
game::{Game, GameState, StateType},
player::ImpartialPlayer,
};
use serde::{Deserialize, Serialize};
use thiserror::Error;

Expand Down
65 changes: 46 additions & 19 deletions crates/games/src/domineering/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ pub mod gui;
use anyhow::Error;
use array2d::Array2D;
use clap::Args;
use game_solver::{game::{Game, GameState, StateType}, player::{PartizanPlayer, Player}};
use game_solver::{
game::{Game, GameState, StateType},
player::{PartizanPlayer, Player},
};
use serde::{Deserialize, Serialize};
use std::{
fmt::{Debug, Display, Formatter},
Expand All @@ -18,14 +21,14 @@ use crate::util::cli::move_failable;
#[derive(Clone, Hash, Eq, PartialEq, Debug, Copy)]
pub enum Orientation {
Horizontal,
Vertical
Vertical,
}

impl Orientation {
fn turn(&self) -> Orientation {
match *self {
Orientation::Horizontal => Orientation::Vertical,
Orientation::Vertical => Orientation::Horizontal
Orientation::Vertical => Orientation::Horizontal,
}
}
}
Expand Down Expand Up @@ -55,7 +58,7 @@ impl<const WIDTH: usize, const HEIGHT: usize> Domineering<WIDTH, HEIGHT> {
Self {
board: Array2D::filled_with(true, WIDTH, HEIGHT),
move_count: 0,
primary_orientation: orientation
primary_orientation: orientation,
}
}
}
Expand All @@ -78,7 +81,11 @@ impl Display for DomineeringMove {
}

impl<const WIDTH: usize, const HEIGHT: usize> Domineering<WIDTH, HEIGHT> {
fn place(&mut self, m: &DomineeringMove, orientation: Orientation) -> Result<(), DomineeringMoveError> {
fn place(
&mut self,
m: &DomineeringMove,
orientation: Orientation,
) -> Result<(), DomineeringMoveError> {
match orientation {
Orientation::Horizontal => {
if m.0 == WIDTH - 1 {
Expand All @@ -89,7 +96,7 @@ impl<const WIDTH: usize, const HEIGHT: usize> Domineering<WIDTH, HEIGHT> {
}
self.board.set(m.0, m.1, false).unwrap();
self.board.set(m.0 + 1, m.1, false).unwrap();
},
}
Orientation::Vertical => {
if m.1 == HEIGHT - 1 {
return Err(DomineeringMoveError::BlockingAdjacent(
Expand All @@ -101,7 +108,7 @@ impl<const WIDTH: usize, const HEIGHT: usize> Domineering<WIDTH, HEIGHT> {
self.board.set(m.0, m.1 + 1, false).unwrap();
}
};

Ok(())
}
}
Expand All @@ -124,11 +131,14 @@ impl<const WIDTH: usize, const HEIGHT: usize> Game for Domineering<WIDTH, HEIGHT

fn make_move(&mut self, m: &Self::Move) -> Result<(), Self::MoveError> {
if *self.board.get(m.0, m.1).unwrap() {
self.place(m, if self.player() == PartizanPlayer::Left {
self.primary_orientation
} else {
self.primary_orientation.turn()
})?;
self.place(
m,
if self.player() == PartizanPlayer::Left {
self.primary_orientation
} else {
self.primary_orientation.turn()
},
)?;

self.move_count += 1;
Ok(())
Expand Down Expand Up @@ -157,7 +167,7 @@ impl<const WIDTH: usize, const HEIGHT: usize> Game for Domineering<WIDTH, HEIGHT
}
}
}
},
}
Orientation::Vertical => {
for i in 0..HEIGHT - 1 {
for j in 0..WIDTH {
Expand Down Expand Up @@ -244,7 +254,9 @@ mod tests {
use super::*;

/// Get the winner of a generic configuration of domineering
fn winner<const WIDTH: usize, const HEIGHT: usize>(orientation: Orientation) -> Option<PartizanPlayer> {
fn winner<const WIDTH: usize, const HEIGHT: usize>(
orientation: Orientation,
) -> Option<PartizanPlayer> {
let game = Domineering::<WIDTH, HEIGHT>::new_orientation(orientation);
let mut move_scores = move_scores(&game, &mut HashMap::new())
.collect::<Result<Vec<_>, DomineeringMoveError>>()
Expand All @@ -265,11 +277,26 @@ mod tests {

#[test]
fn test_wins() {
assert_eq!(winner::<5, 5>(Orientation::Horizontal), Some(PartizanPlayer::Right));
assert_eq!(winner::<4, 4>(Orientation::Horizontal), Some(PartizanPlayer::Left));
assert_eq!(winner::<3, 3>(Orientation::Horizontal), Some(PartizanPlayer::Left));
assert_eq!(winner::<13, 2>(Orientation::Horizontal), Some(PartizanPlayer::Right));
assert_eq!(winner::<11, 2>(Orientation::Horizontal), Some(PartizanPlayer::Left));
assert_eq!(
winner::<5, 5>(Orientation::Horizontal),
Some(PartizanPlayer::Right)
);
assert_eq!(
winner::<4, 4>(Orientation::Horizontal),
Some(PartizanPlayer::Left)
);
assert_eq!(
winner::<3, 3>(Orientation::Horizontal),
Some(PartizanPlayer::Left)
);
assert_eq!(
winner::<13, 2>(Orientation::Horizontal),
Some(PartizanPlayer::Right)
);
assert_eq!(
winner::<11, 2>(Orientation::Horizontal),
Some(PartizanPlayer::Left)
);
}

#[test]
Expand Down
2 changes: 1 addition & 1 deletion crates/games/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ pub mod domineering;
pub mod nim;
pub mod order_and_chaos;
pub mod reversi;
pub mod tic_tac_toe;
pub mod sprouts;
pub mod tic_tac_toe;

use crate::{
chomp::ChompArgs, domineering::DomineeringArgs, nim::NimArgs,
Expand Down
5 changes: 4 additions & 1 deletion crates/games/src/nim/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@
pub mod gui;
use anyhow::Error;
use clap::Args;
use game_solver::{game::{Game, GameState, StateType}, player::ImpartialPlayer};
use game_solver::{
game::{Game, GameState, StateType},
player::ImpartialPlayer,
};
use serde::{Deserialize, Serialize};
use std::{fmt::Display, hash::Hash};
use thiserror::Error;
Expand Down
5 changes: 4 additions & 1 deletion crates/games/src/order_and_chaos/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ pub mod gui;
use anyhow::{anyhow, Error};
use array2d::Array2D;
use clap::Args;
use game_solver::{game::{Game, GameState, StateType}, player::PartizanPlayer};
use game_solver::{
game::{Game, GameState, StateType},
player::PartizanPlayer,
};
use serde::{Deserialize, Serialize};
use std::{
fmt::{Display, Formatter},
Expand Down
5 changes: 4 additions & 1 deletion crates/games/src/reversi/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ pub mod gui;
use anyhow::Error;
use array2d::Array2D;
use clap::Args;
use game_solver::{game::{Game, GameState, StateType}, player::{PartizanPlayer, Player}};
use game_solver::{
game::{Game, GameState, StateType},
player::{PartizanPlayer, Player},
};
use serde::{Deserialize, Serialize};
use std::fmt;
use std::hash::Hash;
Expand Down
5 changes: 4 additions & 1 deletion crates/games/src/tic_tac_toe/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@
pub mod gui;
use anyhow::{anyhow, Error};
use clap::Args;
use game_solver::{game::{Game, GameState, StateType}, player::{PartizanPlayer, Player}};
use game_solver::{
game::{Game, GameState, StateType},
player::{PartizanPlayer, Player},
};
use itertools::Itertools;
use ndarray::{iter::IndexedIter, ArrayD, Dim, Dimension, IntoDimension, IxDyn, IxDynImpl};
use serde::{Deserialize, Serialize};
Expand Down
10 changes: 7 additions & 3 deletions crates/games/src/util/cli/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,16 @@ use anyhow::{anyhow, Result};
use core::hash::Hash;
use game_solver::{
game::{Game, GameState},
par_move_scores, player::TwoPlayer,
par_move_scores,
player::TwoPlayer,
};
use std::fmt::{Debug, Display};

pub fn play<T: Game<Player = impl TwoPlayer + Debug> + Eq + Hash + Sync + Send + Display + 'static>(game: T)
where
pub fn play<
T: Game<Player = impl TwoPlayer + Debug> + Eq + Hash + Sync + Send + Display + 'static,
>(
game: T,
) where
T::Move: Sync + Send + Display,
T::MoveError: Sync + Send + Debug,
{
Expand Down

0 comments on commit d3a54eb

Please sign in to comment.