///|
/// The side a piece belongs to.
pub(all) enum Color {
White
Black
} derive(Eq, @debug.Debug)
///|
pub extend Color with Eq::{equal, not_equal}
///|
pub extend Color with @debug.Debug::{to_repr}
///|
pub extend Color with Show::{to_string, output}
///|
pub impl Show for Color with fn output(self, logger) {
logger.write_string(Color::name(self))
}
///|
/// The lower-case name of the colour.
pub fn Color::name(self : Color) -> String {
match self {
White => "white"
Black => "black"
}
}
///|
/// The storage index of the colour, `0` for white and `1` for black.
pub fn Color::index(self : Color) -> Int32 {
match self {
White => 0
Black => 1
}
}
///|
/// The opposite colour.
pub fn Color::opposite(self : Color) -> Color {
match self {
White => Black
Black => White
}
}
///|
/// The `w`/`b` character used by FEN and PGN.
pub fn Color::fen_char(self : Color) -> Char {
match self {
White => 'w'
Black => 'b'
}
}
///|
/// Reads the `w`/`b` character used by FEN and PGN.
pub fn Color::from_fen_char(c : Char) -> Color? {
match c {
'w' => Some(White)
'b' => Some(Black)
_ => None
}
}
///|
/// The kind of a chess piece, independent of its colour.
pub(all) enum PieceKind {
Pawn
Knight
Bishop
Rook
Queen
King
} derive(Eq, @debug.Debug)
///|
pub extend PieceKind with Eq::{equal, not_equal}
///|
pub extend PieceKind with @debug.Debug::{to_repr}
///|
pub extend PieceKind with Show::{to_string, output}
///|
pub impl Show for PieceKind with fn output(self, logger) {
logger.write_string(PieceKind::name(self))
}
///|
/// The lower-case English name of the piece kind.
pub fn PieceKind::name(self : PieceKind) -> String {
match self {
Pawn => "pawn"
Knight => "knight"
Bishop => "bishop"
Rook => "rook"
Queen => "queen"
King => "king"
}
}
///|
/// The storage index of the piece kind, `0` for a pawn and `5` for a king.
pub fn PieceKind::index(self : PieceKind) -> Int32 {
match self {
Pawn => 0
Knight => 1
Bishop => 2
Rook => 3
Queen => 4
King => 5
}
}
///|
/// Maps a storage index in `0..=5` back to a piece kind.
pub fn PieceKind::from_index(index : Int32) -> PieceKind? {
match index {
0 => Some(Pawn)
1 => Some(Knight)
2 => Some(Bishop)
3 => Some(Rook)
4 => Some(Queen)
5 => Some(King)
_ => None
}
}
///|
/// The lower-case piece letter used by FEN and SAN.
pub fn PieceKind::fen_char(self : PieceKind) -> Char {
match self {
Pawn => 'p'
Knight => 'n'
Bishop => 'b'
Rook => 'r'
Queen => 'q'
King => 'k'
}
}
///|
/// Reads a FEN piece letter, accepting either case.
pub fn PieceKind::from_fen_char(c : Char) -> PieceKind? {
match c {
'p' | 'P' => Some(Pawn)
'n' | 'N' => Some(Knight)
'b' | 'B' => Some(Bishop)
'r' | 'R' => Some(Rook)
'q' | 'Q' => Some(Queen)
'k' | 'K' => Some(King)
_ => None
}
}
///|
/// A coloured piece.
pub(all) struct Piece {
color : Color
kind : PieceKind
} derive(Eq, @debug.Debug)
///|
pub extend Piece with Eq::{equal, not_equal}
///|
pub extend Piece with @debug.Debug::{to_repr}
///|
pub extend Piece with Show::{to_string, output}
///|
pub impl Show for Piece with fn output(self, logger) {
logger.write_string(self.color.name() + " " + self.kind.name())
}
///|
pub fn Piece::new(color : Color, kind : PieceKind) -> Piece {
{ color, kind, }
}
///|
pub fn Piece::color(self : Piece) -> Color {
self.color
}
///|
pub fn Piece::kind(self : Piece) -> PieceKind {
self.kind
}
///|
/// The FEN letter of the piece, upper-case for white and lower-case for black.
pub fn Piece::fen_char(self : Piece) -> Char {
let c = self.kind.fen_char()
match self.color {
White => (c.to_int() - 32).to_char().unwrap()
Black => c
}
}
///|
/// Reads a FEN piece letter, deriving the colour from the letter's case.
pub fn Piece::from_fen_char(c : Char) -> Piece? {
match PieceKind::from_fen_char(c) {
Some(kind) => {
let color = if c >= 'A' && c <= 'Z' { White } else { Black }
Some(Piece::new(color, kind))
}
None => None
}
}