Skip to content

Commit

Permalink
chore: remove a bunch of ataxx stuff from isolation::Move
Browse files Browse the repository at this point in the history
  • Loading branch information
raklaptudirm committed Dec 12, 2024
1 parent 7306504 commit 7243494
Showing 1 changed file with 30 additions and 64 deletions.
94 changes: 30 additions & 64 deletions games/src/isolation/move.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use thiserror::Error;
use super::Square;
use crate::interface::{MoveType, RepresentableType, TypeParseError};

/// Move represents an Ataxx move which can be played on the Board.
/// Move represents an Isolation move which can be played on the Board.
#[derive(Copy, Clone, PartialEq, Eq, Default)]
pub struct Move(u16);

Expand Down Expand Up @@ -54,67 +54,48 @@ impl Move {
const PAWN_OFFSET: u16 = 0;
const TILE_OFFSET: u16 = Move::PAWN_OFFSET + Move::PAWN_WIDTH;

/// NULL Move represents an invalid move.
pub const NULL: Move = Move(1 << 15);

/// new_single returns a new singular Move, where a piece is cloned to its
/// target Square. For a singular Move, [`Move::source`] and [`Move::target`]
/// are equal since the source Square is irrelevant to the Move.
/// ```
/// use tetka_games::ataxx::*;
///
/// let mov = Move::new_single(Square::A1);
///
/// assert_eq!(mov.source(), mov.target());
/// assert_eq!(mov.target(), Square::A1);
/// ```
#[inline(always)]
pub fn new_single(square: Square) -> Move {
Move::new(square, square)
}

/// new returns a new jump Move from the given source Square to the given
/// target Square. These Squares can be recovered with the [`Move::source`] and
/// [`Move::target`] methods respectively.
/// new returns a new jump Move from the given pawn Square to the given
/// tile Square. These Squares can be recovered with the [`Move::pawn`] and
/// [`Move::tile`] methods respectively.
/// ```
/// use tetka_games::ataxx::*;
/// use tetka_games::isolation::*;
///
/// let mov = Move::new(Square::A1, Square::A3);
///
/// assert_eq!(mov.source(), Square::A1);
/// assert_eq!(mov.target(), Square::A3);
/// assert_eq!(mov.pawn(), Square::A1);
/// assert_eq!(mov.tile(), Square::A3);
/// ```
#[inline(always)]
#[rustfmt::skip]
pub fn new(source: Square, target: Square) -> Move {
pub fn new(pawn: Square, tile: Square) -> Move {
Move(
(source as u16) << Move::PAWN_OFFSET |
(target as u16) << Move::TILE_OFFSET
(pawn as u16) << Move::PAWN_OFFSET |
(tile as u16) << Move::TILE_OFFSET
)
}

/// Source returns the source Square of the moving piece. This is equal to the
/// target Square if the given Move is of singular type.
/// Source returns the pawn Square of the moving piece. This is equal to the
/// tile Square if the given Move is of singular type.
/// ```
/// use tetka_games::ataxx::*;
/// use tetka_games::isolation::*;
///
/// let mov = Move::new(Square::A1, Square::A3);
///
/// assert_eq!(mov.source(), Square::A1);
/// assert_eq!(mov.pawn(), Square::A1);
/// ```
pub fn pawn(self) -> Square {
unsafe {
Square::unsafe_from((self.0 >> Move::PAWN_OFFSET) & Move::PAWN_MASK)
}
}

/// Target returns the target Square of the moving piece.
/// Target returns the tile Square of the moving piece.
/// ```
/// use tetka_games::ataxx::*;
/// use tetka_games::isolation::*;
///
/// let mov = Move::new(Square::A1, Square::A3);
///
/// assert_eq!(mov.target(), Square::A3);
/// assert_eq!(mov.tile(), Square::A3);
/// ```
pub fn tile(self) -> Square {
unsafe {
Expand All @@ -127,58 +108,43 @@ impl Move {
pub enum MoveParseError {
#[error("length of move string should be 2 or 4, not {0}")]
BadLength(usize),
#[error("bad source square string \"{0}\"")]
#[error("bad pawn square string \"{0}\"")]
BadSquare(#[from] TypeParseError),
}

impl FromStr for Move {
type Err = MoveParseError;

/// from_str converts the given string representation of a Move into a [Move].
/// The formats supported are '0000' for a [Move::PASS], `<target>` for a
/// singular Move, and `<source><target>` for a jump Move. For how `<source>`
/// and `<target>` are parsed, take a look at
/// [`Square::FromStr`](Square::from_str). This function can be treated as the
/// inverse of the [`fmt::Display`] trait for [Move].
/// The format supported is `<pawn><tile>`. For how `<pawn>` and `<tile>` are
/// parsed, take a look at [`Square::FromStr`](Square::from_str). This function
/// can be treated as the inverse of the [`fmt::Display`] trait for [Move].
/// ```
/// use tetka_games::ataxx::*;
/// use tetka_games::isolation::*;
/// use std::str::FromStr;
///
/// let pass = Move::PASS;
/// let sing = Move::new_single(Square::A1);
/// let jump = Move::new(Square::A1, Square::A3);
///
/// assert_eq!(Move::from_str(&pass.to_string()).unwrap(), pass);
/// assert_eq!(Move::from_str(&sing.to_string()).unwrap(), sing);
/// assert_eq!(Move::from_str(&jump.to_string()).unwrap(), jump);
/// ```
fn from_str(s: &str) -> Result<Self, Self::Err> {
if s.len() != 2 && s.len() != 4 {
if s.len() != 4 {
return Err(MoveParseError::BadLength(s.len()));
}

let source = &s[..2];
let source = Square::from_str(source)?;

if s.len() < 4 {
return Ok(Move::new_single(source));
}

let target = &s[2..];
let target = Square::from_str(target)?;
let pawn = Square::from_str(&s[..2])?;
let tile = Square::from_str(&s[2..])?;

Ok(Move::new(source, target))
Ok(Move::new(pawn, tile))
}
}

impl fmt::Display for Move {
/// Display formats the given Move in a human-readable manner. The format used
/// for displaying jump moves is `<source><target>`, while a singular Move is
/// formatted as `<target>`. For the formatting of `<source>` and `<target>`,
/// refer to `Square::Display`. [`Move::NULL`] is formatted as `null`, while
/// [`Move::PASS`] is formatted as `0000`.
/// for displaying jump moves is `<pawn><tile>`, while a singular Move is
/// formatted as `<tile>`. For the formatting of `<pawn>` and `<tile>`,
/// refer to `Square::Display`. [`Move::NULL`] is formatted as `null`.
/// ```
/// use tetka_games::ataxx::*;
/// use tetka_games::isolation::*;
///
/// let null = Move::NULL;
/// let pass = Move::PASS;
Expand Down

0 comments on commit 7243494

Please sign in to comment.