File size: 2,252 Bytes
3014f14
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum Color {
    White = 0,
    Black = 1,
}

impl Color {
    pub fn flip(&self) -> Self {
        match self {
            Color::White => Color::Black,
            Color::Black => Color::White,
        }
    }
}

#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum PieceType {
    Pawn = 1,
    Knight = 2,
    Bishop = 3,
    Rook = 4,
    Queen = 5,
    King = 6,
    None = 0,
}

#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum Square {
    A1 = 0,  B1, C1, D1, E1, F1, G1, H1,
    A2, B2, C2, D2, E2, F2, G2, H2,
    A3, B3, C3, D3, E3, F3, G3, H3,
    A4, B4, C4, D4, E4, F4, G4, H4,
    A5, B5, C5, D5, E5, F5, G5, H5,
    A6, B6, C6, D6, E6, F6, G6, H6,
    A7, B7, C7, D7, E7, F7, G7, H7,
    A8, B8, C8, D8, E8, F8, G8, H8,
    None = 64,
}

impl Square {
    pub fn from_u8(val: u8) -> Self {
        if val < 64 { unsafe { std::mem::transmute(val) } } else { Square::None }
    }
}

pub struct CastlingRights;
impl CastlingRights {
    pub const WHITE_OO: u8 = 1;
    pub const WHITE_OOO: u8 = 2;
    pub const BLACK_OO: u8 = 4;
    pub const BLACK_OOO: u8 = 8;
    pub const ANY_WHITE: u8 = Self::WHITE_OO | Self::WHITE_OOO;
    pub const ANY_BLACK: u8 = Self::BLACK_OO | Self::BLACK_OOO;
}

#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct Move {
    data: u16,
}

impl Move {
    pub const NONE: Move = Move { data: 0 };
    
    pub fn new(from: Square, to: Square, promo: PieceType) -> Self {
        let p_bits = match promo {
            PieceType::Knight => 1,
            PieceType::Bishop => 2,
            PieceType::Rook => 3,
            PieceType::Queen => 4,
            _ => 0,
        };
        Move {
            data: (from as u16) | ((to as u16) << 6) | (p_bits << 12),
        }
    }

    pub fn from(&self) -> Square {
        Square::from_u8((self.data & 0x3F) as u8)
    }

    pub fn to(&self) -> Square {
        Square::from_u8(((self.data >> 6) & 0x3F) as u8)
    }

    pub fn promotion(&self) -> PieceType {
        match (self.data >> 12) & 0x7 {
            1 => PieceType::Knight,
            2 => PieceType::Bishop,
            3 => PieceType::Rook,
            4 => PieceType::Queen,
            _ => PieceType::None,
        }
    }
}