feat: promotion moves
This commit is contained in:
parent
8804c0e1c4
commit
98b4f116d6
@ -34,7 +34,7 @@ impl From<Color> for char {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||
enum Piece {
|
||||
Rook,
|
||||
Bishop,
|
||||
@ -157,7 +157,7 @@ impl Square {
|
||||
}
|
||||
|
||||
/// Convert typical human-readable form (e.g. `e4`) to square index.
|
||||
fn from_algebraic(value: String) -> Result<Self, SquareError> {
|
||||
fn from_algebraic(value: &str) -> Result<Self, SquareError> {
|
||||
let bytes = value.as_bytes();
|
||||
let col = match bytes[0] as char {
|
||||
'a' => 0,
|
||||
@ -187,7 +187,7 @@ mod tests {
|
||||
let test_cases = [("a1", 0), ("a8", 56), ("h1", 7), ("h8", 63)];
|
||||
for (sqr, idx) in test_cases {
|
||||
assert_eq!(Square::try_from(idx).unwrap().to_algebraic(), sqr);
|
||||
assert_eq!(Square::from_algebraic(sqr.to_string()).unwrap(), Square::try_from(idx).unwrap());
|
||||
assert_eq!(Square::from_algebraic(sqr).unwrap(), Square::try_from(idx).unwrap());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
//! Move generation.
|
||||
|
||||
use crate::fen::{FromFen, ToFen, START_POSITION};
|
||||
use crate::{BoardState, Color, Piece, Square, BOARD_HEIGHT, BOARD_WIDTH, N_SQUARES};
|
||||
use crate::{BoardState, ColPiece, Color, Piece, Square, BOARD_HEIGHT, BOARD_WIDTH, N_SQUARES};
|
||||
use std::rc::Rc;
|
||||
|
||||
/// Game tree node.
|
||||
@ -32,6 +32,17 @@ enum PromotePiece {
|
||||
Queen,
|
||||
}
|
||||
|
||||
impl From<PromotePiece> for Piece {
|
||||
fn from(value: PromotePiece) -> Self {
|
||||
match value {
|
||||
PromotePiece::Rook => Piece::Rook,
|
||||
PromotePiece::Bishop => Piece::Bishop,
|
||||
PromotePiece::Knight => Piece::Knight,
|
||||
PromotePiece::Queen => Piece::Queen,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Move data common to all move types.
|
||||
struct MoveData {
|
||||
src: Square,
|
||||
@ -61,16 +72,46 @@ impl Move {
|
||||
prev: Some(Rc::new(old_node)),
|
||||
pos: old_pos,
|
||||
};
|
||||
node.pos.turn = node.pos.turn.flip();
|
||||
if node.pos.turn == Color::White {
|
||||
|
||||
if old_pos.turn == Color::Black {
|
||||
node.pos.full_moves += 1;
|
||||
}
|
||||
|
||||
/// Get the piece at the source square.
|
||||
macro_rules! pc_src {
|
||||
($data: ident) => {
|
||||
node.pos
|
||||
.get_piece($data.src)
|
||||
.expect("Move source should have a piece")
|
||||
};
|
||||
}
|
||||
/// Perform sanity checks.
|
||||
macro_rules! pc_asserts {
|
||||
($pc_src: ident, $data: ident) => {
|
||||
debug_assert_eq!($pc_src.col, node.pos.turn, "Moving piece on wrong turn.");
|
||||
debug_assert_ne!($data.src, $data.dest, "Moving piece to itself.");
|
||||
};
|
||||
}
|
||||
|
||||
match self {
|
||||
Move::Promotion(data, piece) => todo!(),
|
||||
Move::Promotion(data, to_piece) => {
|
||||
let pc_src = pc_src!(data);
|
||||
pc_asserts!(pc_src, data);
|
||||
debug_assert_eq!(pc_src.pc, Piece::Pawn);
|
||||
|
||||
node.pos.del_piece(data.src);
|
||||
node.pos.set_piece(
|
||||
data.dest,
|
||||
ColPiece {
|
||||
pc: Piece::from(to_piece),
|
||||
col: pc_src.col,
|
||||
},
|
||||
);
|
||||
}
|
||||
Move::Castle(data) => todo!(),
|
||||
Move::Normal(data) => {
|
||||
let pc_src = node.pos.get_piece(data.src).unwrap();
|
||||
let pc_src = pc_src!(data);
|
||||
pc_asserts!(pc_src, data);
|
||||
if matches!(pc_src.pc, Piece::Pawn) {
|
||||
// pawn moves are irreversible
|
||||
node.pos.half_moves = 0;
|
||||
@ -129,6 +170,8 @@ impl Move {
|
||||
Move::EnPassant(data) => todo!(),
|
||||
}
|
||||
|
||||
node.pos.turn = node.pos.turn.flip();
|
||||
|
||||
node
|
||||
}
|
||||
}
|
||||
@ -229,11 +272,14 @@ mod tests {
|
||||
|
||||
// make move
|
||||
println!("Starting test case {i}, make move.");
|
||||
let mut node = Node {pos: BoardState::from_fen(start_pos.to_string()).unwrap(), prev: None};
|
||||
let mut node = Node {
|
||||
pos: BoardState::from_fen(start_pos.to_string()).unwrap(),
|
||||
prev: None,
|
||||
};
|
||||
for (src, dest, expect_fen) in moves {
|
||||
println!("Moving {src} to {dest}.");
|
||||
let idx_src = Square::from_algebraic(src.to_string()).unwrap();
|
||||
let idx_dest = Square::from_algebraic(dest.to_string()).unwrap();
|
||||
let idx_src = Square::from_algebraic(src).unwrap();
|
||||
let idx_dest = Square::from_algebraic(dest).unwrap();
|
||||
let mv = Move::Normal(MoveData {
|
||||
src: idx_src,
|
||||
dest: idx_dest,
|
||||
|
Loading…
Reference in New Issue
Block a user