Skip to content

Commit

Permalink
feat: cool new piece_type macro
Browse files Browse the repository at this point in the history
  • Loading branch information
raklaptudirm committed Dec 26, 2024
1 parent 4c4c39c commit b537c28
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 138 deletions.
42 changes: 6 additions & 36 deletions games/src/ataxx/piece.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,42 +11,12 @@
// See the License for the specific language governing permissions and
// limitations under the License.

use crate::interface::ColoredPieceType;
use crate::interface::piece_type;
use crate::interface::representable_type;
use crate::interface::RepresentableType;
use crate::interface::{color_type, representable_type};

color_type!(
/// Color represents all the possible colors that an ataxx piece can have,
/// specifically, Black and White.
enum Color { Black "x", White "o", }
piece_type!(
Pieces: Piece "x"; Block "-";
Colors: Black "x" ("x"),
White "o" ("o");
);

representable_type!(
/// Piece represents the types of pieces in ataxx, namely Piece and Block.
enum Piece: u8 { Piece "x", Block "■", }
);

representable_type!(
/// Piece represents all the possible ataxx pieces.
enum ColoredPiece: u8 { Black "x", White "o", Block "-", }
);

impl ColoredPieceType for ColoredPiece {
type Piece = Piece;
type Color = Color;

fn piece(self) -> Piece {
match self {
ColoredPiece::Black | ColoredPiece::White => Piece::Piece,
ColoredPiece::Block => Piece::Block,
}
}

fn color(self) -> Color {
match self {
ColoredPiece::Black => Color::Black,
ColoredPiece::White => Color::White,
_ => panic!("Piece::color() called on Piece::Block"),
}
}
}
12 changes: 6 additions & 6 deletions games/src/ataxx/position.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,8 @@ impl PositionType for Position {
}

fn is_game_over(&self) -> bool {
let black = self.colored_piece_bb(ColoredPiece::Black);
let white = self.colored_piece_bb(ColoredPiece::White);
let black = self.colored_piece_bb(ColoredPiece::BlackPiece);
let white = self.colored_piece_bb(ColoredPiece::WhitePiece);
let block = self.colored_piece_bb(ColoredPiece::Block);

self.half_move_clock >= 100 || // Fifty-move rule
Expand All @@ -118,8 +118,8 @@ impl PositionType for Position {
return None;
}

let black = self.colored_piece_bb(ColoredPiece::Black);
let white = self.colored_piece_bb(ColoredPiece::White);
let black = self.colored_piece_bb(ColoredPiece::BlackPiece);
let white = self.colored_piece_bb(ColoredPiece::WhitePiece);
let block = self.colored_piece_bb(ColoredPiece::Block);

if black == BitBoard::EMPTY {
Expand Down Expand Up @@ -368,8 +368,8 @@ impl FromStr for Position {

// Calculate the Hash value for the Position.
position.checksum = Self::get_hash(
position.colored_piece_bb(ColoredPiece::Black),
position.colored_piece_bb(ColoredPiece::White),
position.colored_piece_bb(ColoredPiece::BlackPiece),
position.colored_piece_bb(ColoredPiece::WhitePiece),
position.side_to_move,
);

Expand Down
65 changes: 5 additions & 60 deletions games/src/chess/color.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,66 +11,11 @@
// See the License for the specific language governing permissions and
// limitations under the License.

use crate::interface::ColoredPieceType;
use crate::interface::RepresentableType;
use crate::interface::{color_type, representable_type};
use crate::interface::{piece_type, representable_type};

color_type!(
/// Color represents all the possible colors that an ataxx piece can have,
/// specifically, Black and White.
enum Color { White "w", Black "b", }
piece_type!(
Pieces: Pawn "p", Knight "n", Bishop "b", Rook "r", Queen "q", King "k";;
Colors: White "x" ("P", "N", "B", "R", "Q", "K"),
Black "o" ("p", "n", "b", "r", "q", "k");
);

representable_type!(
/// Piece represents the types of pieces in ataxx, namely Piece and Block.
enum Piece: u8 {
Pawn "p", Knight "n", Bishop "b", Rook "r", Queen "q", King "k",
}
);

representable_type!(
/// Piece represents all the possible ataxx pieces.
enum ColoredPiece: u8 {
WhitePawn "P", WhiteKnight "N", WhiteBishop "B",
WhiteRook "R", WhiteQueen "Q", WhiteKing "K",
BlackPawn "p", BlackKnight "n", BlackBishop "b",
BlackRook "r", BlackQueen "q", BlackKing "k",
}
);

impl ColoredPieceType for ColoredPiece {
type Piece = Piece;
type Color = Color;

fn piece(self) -> Piece {
match self {
ColoredPiece::BlackPawn | ColoredPiece::WhitePawn => Piece::Pawn,
ColoredPiece::BlackKnight | ColoredPiece::WhiteKnight => {
Piece::Knight
}
ColoredPiece::BlackBishop | ColoredPiece::WhiteBishop => {
Piece::Bishop
}
ColoredPiece::BlackRook | ColoredPiece::WhiteRook => Piece::Rook,
ColoredPiece::BlackQueen | ColoredPiece::WhiteQueen => Piece::Queen,
ColoredPiece::BlackKing | ColoredPiece::WhiteKing => Piece::King,
}
}

fn color(self) -> Color {
match self {
ColoredPiece::WhitePawn
| ColoredPiece::WhiteKnight
| ColoredPiece::WhiteBishop
| ColoredPiece::WhiteRook
| ColoredPiece::WhiteQueen
| ColoredPiece::WhiteKing => Color::White,
ColoredPiece::BlackPawn
| ColoredPiece::BlackKnight
| ColoredPiece::BlackBishop
| ColoredPiece::BlackRook
| ColoredPiece::BlackQueen
| ColoredPiece::BlackKing => Color::Black,
}
}
}
61 changes: 61 additions & 0 deletions games/src/interface/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,67 @@ pub enum TypeParseError {
RangeError(String),
}

macro_rules! piece_type {
(
Pieces: $($piece_variant:ident $piece_repr:literal),*;
$($other_variant:ident $other_repr:literal),*;
Colors: $color_1:ident $color_1_repr:literal ($($piece_1_repr:literal),*),
$color_2:ident $color_2_repr:literal ($($piece_2_repr:literal),*);
) => {
$crate::interface::color_type!(
enum Color { $color_1 $color_1_repr, $color_2 $color_2_repr, }
);

$crate::interface::representable_type!(
enum Piece: u8 {
$($piece_variant $piece_repr,)*
$($other_variant $other_repr,)*
}
);

paste::paste!(
$crate::interface::representable_type!(
enum ColoredPiece: u8 {
$([< $color_1 $piece_variant >] $piece_1_repr,)*
$([< $color_2 $piece_variant >] $piece_2_repr,)*
$($other_variant $other_repr,)*
}
);
);

impl $crate::interface::ColoredPieceType for ColoredPiece {
type Piece = Piece;
type Color = Color;

fn piece(self) -> Self::Piece {
paste::paste!(
match self {
$(
Self:: [< $color_1 $piece_variant >] |
Self:: [< $color_2 $piece_variant >]
=> Self::Piece::$piece_variant,
)*

$(Self:: $other_variant => Self::Piece::$other_variant)*
}
)
}

#[allow(unreachable_patterns)]
fn color(self) -> Self::Color {
paste::paste!(
match self {
$(Self:: [< $color_1 $piece_variant >])|* => Self::Color::$color_1,
$(Self:: [< $color_2 $piece_variant >])|* => Self::Color::$color_2,
_ => panic!("ColoredPiece::color() called on uncolored piece")
}
)
}
}
};
}
pub(crate) use piece_type;

macro_rules! square_type {
(enum $square:ident {
for $file:tt => $($file_variant:ident),* ;
Expand Down
41 changes: 5 additions & 36 deletions games/src/isolation/piece.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,42 +11,11 @@
// See the License for the specific language governing permissions and
// limitations under the License.

use crate::interface::ColoredPieceType;
use crate::interface::RepresentableType;
use crate::interface::{color_type, representable_type};
use crate::interface::{piece_type, representable_type};

color_type!(
/// Color represents all the possible colors that an ataxx piece can have,
/// specifically, Black and White.
enum Color { White "w", Black "b", }
piece_type!(
Pieces: Pawn "p"; Tile "-";
Colors: White "w" ("P"),
Black "b" ("p");
);

representable_type!(
/// Piece represents the types of pieces in ataxx, namely Piece and Block.
enum Piece: u8 { Pawn "p", Tile "-", }
);

representable_type!(
/// Piece represents all the possible ataxx pieces.
enum ColoredPiece: u8 { WhitePawn "P", BlackPawn "p", Tile "-", }
);

impl ColoredPieceType for ColoredPiece {
type Piece = Piece;
type Color = Color;

fn piece(self) -> Piece {
match self {
ColoredPiece::WhitePawn | ColoredPiece::BlackPawn => Piece::Pawn,
ColoredPiece::Tile => Piece::Tile,
}
}

fn color(self) -> Color {
match self {
ColoredPiece::WhitePawn => Color::White,
ColoredPiece::BlackPawn => Color::Black,
_ => panic!("Piece::color() called on Piece::Tile"),
}
}
}

0 comments on commit b537c28

Please sign in to comment.