chess/
piece.rs

1use std::fmt;
2
3use super::Color;
4
5/// Represent a chess piece.
6#[derive(Copy, Clone, Eq, PartialEq, PartialOrd, Debug)]
7pub enum Piece {
8    Pawn,
9    Knight,
10    Bishop,
11    Rook,
12    Queen,
13    King,
14}
15
16/// Numbers of [`Piece`].
17pub const NUM_PIECES: usize = 6;
18
19/// An array representing each [`Piece`] type, in order of ascending value.
20pub const ALL_PIECES: [Piece; NUM_PIECES] = [
21    Piece::Pawn,
22    Piece::Knight,
23    Piece::Bishop,
24    Piece::Rook,
25    Piece::Queen,
26    Piece::King,
27];
28
29// /// Number of promotion.
30// pub const NUM_PROMOTION_PIECES: usize = 4;
31
32// /// Enumerate all [`Piece`] in which a [`Piece::Pawn`] can be promoted.
33// pub const PROMOTION_PIECES: [Piece; 4] = [Piece::Queen, Piece::Rook, Piece::Bishop, Piece::Knight];
34
35impl Piece {
36    /// Convert the [`Piece`] to a [`usize`].
37    #[inline]
38    pub fn to_index(&self) -> usize {
39        *self as usize
40    }
41
42    /// Convert a piece with a [`Color`] to a string.
43    ///
44    /// > **Note**: White pieces are uppercase, black pieces are lowercase.
45    ///
46    /// ```
47    /// use chess::{Piece, Color};
48    ///
49    /// assert_eq!(Piece::King.to_string(Color::White), "K");
50    /// assert_eq!(Piece::Knight.to_string(Color::Black), "n");
51    /// ```
52    #[inline]
53    pub fn to_string(&self, color: Color) -> String {
54        let piece = format!("{}", self);
55        match color {
56            Color::White => piece.to_uppercase(),
57            Color::Black => piece,
58        }
59    }
60}
61
62impl fmt::Display for Piece {
63    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
64        write!(
65            f,
66            "{}",
67            match self {
68                Piece::Pawn => "p",
69                Piece::Knight => "n",
70                Piece::Bishop => "b",
71                Piece::Rook => "r",
72                Piece::Queen => "q",
73                Piece::King => "k",
74            }
75        )
76    }
77}
78
79#[cfg(test)]
80mod tests {
81    use super::*;
82
83    #[test]
84    fn to_index() {
85        assert_eq!(Piece::Pawn.to_index(), 0);
86        assert_eq!(Piece::Knight.to_index(), 1);
87        assert_eq!(Piece::Bishop.to_index(), 2);
88        assert_eq!(Piece::Rook.to_index(), 3);
89        assert_eq!(Piece::Queen.to_index(), 4);
90        assert_eq!(Piece::King.to_index(), 5);
91    }
92
93    #[test]
94    fn to_string_per_color() {
95        assert_eq!(Piece::Pawn.to_string(Color::White), "P");
96        assert_eq!(Piece::Knight.to_string(Color::White), "N");
97        assert_eq!(Piece::Bishop.to_string(Color::White), "B");
98        assert_eq!(Piece::Rook.to_string(Color::White), "R");
99        assert_eq!(Piece::Queen.to_string(Color::White), "Q");
100        assert_eq!(Piece::King.to_string(Color::White), "K");
101
102        assert_eq!(Piece::Pawn.to_string(Color::Black), "p");
103        assert_eq!(Piece::Knight.to_string(Color::Black), "n");
104        assert_eq!(Piece::Bishop.to_string(Color::Black), "b");
105        assert_eq!(Piece::Rook.to_string(Color::Black), "r");
106        assert_eq!(Piece::Queen.to_string(Color::Black), "q");
107        assert_eq!(Piece::King.to_string(Color::Black), "k");
108    }
109
110    #[test]
111    fn fmt() {
112        assert_eq!(format!("{}", Piece::Pawn), "p".to_string());
113        assert_eq!(format!("{}", Piece::Knight), "n".to_string());
114        assert_eq!(format!("{}", Piece::Bishop), "b".to_string());
115        assert_eq!(format!("{}", Piece::Rook), "r".to_string());
116        assert_eq!(format!("{}", Piece::Queen), "q".to_string());
117        assert_eq!(format!("{}", Piece::King), "k".to_string());
118    }
119}