littlewing 0.8.0

A chess engine rated at 2050+ ELO, compatible with both UCI and XBoard protocols, with a nice CLI, and a documented library.
Documentation
use crate::common::*;
use crate::color::*;
use crate::piece::*;
use crate::square::*;

const PAWN_OPENING: [Score; 64] = [
   0,    0,    0,    0,    0,    0,    0,    0,
  67,   67,   66,   67,   67,   59,   62,   63,
   3,  -21,    8,   43,   28,   -8,   16,   -6,
 -25,  -16,  -10,    7,    8,   -9,    2,  -17,
 -20,  -11,  -23,   -0,    0,   -6,   -6,  -26,
 -25,   -5,  -20,   -7,   -3,   13,   36,  -12,
 -35,  -16,  -32,  -27,  -16,    2,   20,  -35,
   0,    0,    0,    0,    0,    0,    0,    0,
];

const PAWN_ENDGAME: [Score; 64] = [
   0,    0,    0,    0,    0,    0,    0,    0,
 117,  117,   97,   87,   88,   97,  117,  114,
  72,   60,   81,   77,   77,   37,   76,   66,
  54,   48,   18,    5,  -14,    6,   33,   43,
  37,   29,   15,    8,   -9,    8,   28,   31,
  29,   13,  -14,   -5,  -13,  -21,   -9,   21,
  24,   23,    6,   21,    7,  -11,   13,    3,
   0,    0,    0,    0,    0,    0,    0,    0,
];

const KNIGHT_OPENING: [Score; 64] = [
-116,  -61,   -1,   -0,   20,  -32,  -12, -111,
 -54,  -24,   -2,   22,   24,    8,  -13,  -59,
 -11,   31,   25,   60,   48,   61,   23,  -11,
  29,   17,   28,   53,   24,   55,    6,   -7,
   0,    9,   26,    6,   29,    5,   21,   -9,
 -10,    9,    1,   20,   37,    2,   16,  -20,
 -40,  -21,    8,    4,    2,   20,  -11,  -24,
 -73,  -15,  -13,   -3,  -11,   -7,  -20,  -31,
];

const KNIGHT_ENDGAME: [Score; 64] = [
-104,  -63,  -20,  -14,  -24,  -11,  -17,  -99,
   4,   17,    6,  -11,    1,   -2,  -29,  -19,
 -13,   -5,   17,   15,    9,   -2,    3,  -23,
  -3,   19,   19,   -2,   16,   -7,   37,    3,
  -8,  -18,   -3,   24,   16,   29,    8,  -24,
 -31,  -28,  -17,   -9,  -28,  -10,  -58,  -15,
 -50,  -25,  -32,  -12,  -16,  -25,    2,  -35,
 -66,  -62,  -74,  -40,  -47,  -46,  -71,  -61,
];

const BISHOP_OPENING: [Score; 64] = [
 -35,   -9,  -11,   -8,  -14,  -40,   -9,  -43,
 -47,   -4,  -14,  -14,    4,  -18,  -36,  -71,
 -14,   17,    1,    7,    9,   17,    0,   11,
  -1,  -10,   17,   23,   10,   19,  -15,  -29,
   3,   23,  -19,    7,   18,   -8,   -6,  -11,
  -5,   20,    8,   -2,   -5,    9,   10,  -20,
  22,   -7,    3,  -10,    2,   11,    5,   -0,
 -51,  -38,  -16,  -13,  -40,  -26,  -10,  -44,
];

const BISHOP_ENDGAME: [Score; 64] = [
 -34,   -2,   16,    6,  -10,   14,  -14,  -20,
   5,   20,   16,   -0,   10,    9,   -3,    1,
   9,  -10,    1,   14,    5,    4,   17,    1,
 -12,   26,    3,  -12,   -2,    5,   23,   -3,
 -14,   -9,   29,   -8,   -3,   14,  -24,   20,
   9,  -12,  -14,   13,   -5,  -37,  -19,   -2,
 -43,  -52,  -28,  -16,  -23,  -22,  -20,  -28,
 -39,   -5,  -29,  -31,   -8,  -11,  -19,  -10,
];

const ROOK_OPENING: [Score; 64] = [
  46,   51,   45,   33,   30,   27,   18,   26,
  28,   25,   30,   33,   42,   63,   32,   34,
  12,   -3,    5,   17,   34,   14,   -8,  -12,
 -27,  -25,   -6,   -9,    4,   -3,  -26,   -9,
 -30,  -14,  -21,  -25,  -15,  -29,  -24,  -26,
 -30,  -23,  -27,  -20,  -21,  -21,  -10,  -29,
 -20,  -27,  -22,  -14,  -12,    1,  -11,   -3,
 -17,   -2,   -3,    2,    9,  -13,  -15,  -22,
];

const ROOK_ENDGAME: [Score; 64] = [
  -6,    5,    5,   -3,   16,   17,   12,  -18,
   0,   12,   11,    9,   17,   11,   18,    1,
  10,   21,    5,   -2,    9,   -2,   32,    7,
  30,   19,   17,   22,   25,   26,   27,   16,
  22,   15,    9,   11,   32,   31,   24,  -10,
   8,   10,   -5,    1,   18,    8,    6,   13,
   7,    6,  -15,  -15,  -13,  -40,   -1,   -0,
  -4,   13,   10,  -16,  -11,    2,   10,  -23,
];

const QUEEN_OPENING: [Score; 64] = [
 -12,   44,   33,   21,   41,   49,   50,   43,
 -30,  -62,   -1,   10,   25,   54,   18,   45,
  -4,  -22,  -13,   -9,   24,   64,   62,   40,
 -25,  -21,  -22,  -16,    0,   13,   -6,   14,
  -6,  -24,  -24,  -16,  -19,  -16,    3,    0,
  -6,   -4,  -10,  -11,  -12,   -4,   15,   -3,
 -33,   -9,   12,    7,    1,   15,    5,    2,
   9,    3,   -3,   10,    4,  -10,  -35,  -19,
];

const QUEEN_ENDGAME: [Score; 64] = [
   8,   -7,   18,   13,   28,   37,   13,    8,
  -9,   24,   28,   36,   21,   36,   23,   16,
   2,   10,   22,   40,   23,   38,   27,   18,
  28,   29,   30,   35,   32,   23,   25,   19,
 -22,   15,   31,   30,   17,   22,   -1,   14,
 -19,  -21,    1,   -2,  -12,   -8,   -5,    3,
   0,   -4,  -60,  -42,  -31,  -42,  -31,  -22,
 -46,  -46,  -32,  -33,  -54,  -45,  -52,  -27,
];

const KING_OPENING: [Score; 64] = [
 -20,  -35,  -15,  -38,  -41,  -23,  -26,  -10,
 -20,   12,   19,    4,   10,   11,    4,  -14,
   2,   21,   22,   14,   12,   25,   19,    0,
  -7,   17,   21,   18,   12,  -18,   17,   -4,
 -30,   -7,   10,   13,   16,  -15,  -24,  -34,
 -36,  -28,   -5,    4,   -3,    1,  -17,  -51,
 -26,  -26,  -17,  -28,  -22,   -7,    1,   13,
 -41,   -4,   -7,  -59,   -4,  -32,   38,   37,
];

const KING_ENDGAME: [Score; 64] = [
 -27,  -14,   -7,    7,    5,    5,   -2,  -27,
  -8,   14,   24,   27,   42,   22,   28,    3,
  -9,   29,   31,   45,   53,   31,   32,   11,
 -11,   20,   25,   43,   42,   50,   27,    4,
 -23,   -3,   15,   36,   39,   41,   15,  -15,
 -26,  -16,    3,   24,   25,   16,   -3,  -15,
 -10,  -23,  -20,    7,   20,   -1,  -18,  -30,
 -29,  -27,  -23,  -13,  -45,  -20,  -49,  -60,
];

const PIECES_OPENING: [[Score; 64]; 6] = [
    PAWN_OPENING,
    KNIGHT_OPENING,
    BISHOP_OPENING,
    ROOK_OPENING,
    QUEEN_OPENING,
    KING_OPENING
];

const PIECES_ENDGAME: [[Score; 64]; 6] = [
    PAWN_ENDGAME,
    KNIGHT_ENDGAME,
    BISHOP_ENDGAME,
    ROOK_ENDGAME,
    QUEEN_ENDGAME,
    KING_ENDGAME,
];

lazy_static! {
    pub static ref PST: [[[Score; 2]; 64]; 14] = {
        let mut pst_values = [[[0; 2]; 64]; 14];

        for c in 0..2 {
            for p in 0..6 {
                for s in 0..64 {
                    let square = (s as Square).flip((c as Color) ^ 1);
                    let piece = (c as Color) | PIECES[p];

                    let score = PIECES_OPENING[p][s];
                    pst_values[piece as usize][square as usize][0] = score;

                    let score = PIECES_ENDGAME[p][s];
                    pst_values[piece as usize][square as usize][1] = score;
                }
            }
        }

        pst_values
    };
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_pst() {
        let white_score = PST[WHITE_KNIGHT as usize][A1.flip(WHITE) as usize][0];
        let black_score = PST[BLACK_KNIGHT as usize][A1.flip(BLACK) as usize][0];
        assert!(white_score < 0);
        assert_eq!(white_score, black_score);
    }
}