feat: make en-passant moves
This commit is contained in:
parent
a4efad3c14
commit
4efb48244f
20
src/lib.rs
20
src/lib.rs
@ -168,7 +168,7 @@ impl Square {
|
|||||||
'f' => 5,
|
'f' => 5,
|
||||||
'g' => 6,
|
'g' => 6,
|
||||||
'h' => 7,
|
'h' => 7,
|
||||||
_ => {return Err(SquareError::InvalidCharacter(bytes[0] as char))}
|
_ => return Err(SquareError::InvalidCharacter(bytes[0] as char)),
|
||||||
};
|
};
|
||||||
if let Some(row) = (bytes[1] as char).to_digit(10) {
|
if let Some(row) = (bytes[1] as char).to_digit(10) {
|
||||||
Square::from_row_col(row as usize - 1, col as usize)
|
Square::from_row_col(row as usize - 1, col as usize)
|
||||||
@ -187,7 +187,10 @@ mod tests {
|
|||||||
let test_cases = [("a1", 0), ("a8", 56), ("h1", 7), ("h8", 63)];
|
let test_cases = [("a1", 0), ("a8", 56), ("h1", 7), ("h8", 63)];
|
||||||
for (sqr, idx) in test_cases {
|
for (sqr, idx) in test_cases {
|
||||||
assert_eq!(Square::try_from(idx).unwrap().to_algebraic(), sqr);
|
assert_eq!(Square::try_from(idx).unwrap().to_algebraic(), sqr);
|
||||||
assert_eq!(Square::from_algebraic(sqr).unwrap(), Square::try_from(idx).unwrap());
|
assert_eq!(
|
||||||
|
Square::from_algebraic(sqr).unwrap(),
|
||||||
|
Square::try_from(idx).unwrap()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -339,6 +342,10 @@ pub struct BoardState {
|
|||||||
turn: Color,
|
turn: Color,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Piece missing where there should be one.
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct NoPieceError;
|
||||||
|
|
||||||
impl BoardState {
|
impl BoardState {
|
||||||
/// Get mutable reference to a player.
|
/// Get mutable reference to a player.
|
||||||
fn pl_mut(&mut self, col: Color) -> &mut Player {
|
fn pl_mut(&mut self, col: Color) -> &mut Player {
|
||||||
@ -352,12 +359,17 @@ impl BoardState {
|
|||||||
*self.mail.sq_mut(idx) = Some(pc);
|
*self.mail.sq_mut(idx) = Some(pc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Delete the piece in a location, if it exists.
|
/// Delete the piece in a location.
|
||||||
fn del_piece(&mut self, idx: Square) {
|
///
|
||||||
|
/// Returns an error if there is no piece in the location.
|
||||||
|
fn del_piece(&mut self, idx: Square) -> Result<(), NoPieceError> {
|
||||||
if let Some(pc) = *self.mail.sq_mut(idx) {
|
if let Some(pc) = *self.mail.sq_mut(idx) {
|
||||||
let pl = self.pl_mut(pc.col);
|
let pl = self.pl_mut(pc.col);
|
||||||
pl.board(pc.into()).off_idx(idx);
|
pl.board(pc.into()).off_idx(idx);
|
||||||
*self.mail.sq_mut(idx) = None;
|
*self.mail.sq_mut(idx) = None;
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(NoPieceError)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,7 +98,7 @@ impl Move {
|
|||||||
pc_asserts!(pc_src, self);
|
pc_asserts!(pc_src, self);
|
||||||
debug_assert_eq!(pc_src.pc, Piece::Pawn);
|
debug_assert_eq!(pc_src.pc, Piece::Pawn);
|
||||||
|
|
||||||
node.pos.del_piece(self.src);
|
node.pos.del_piece(self.src).expect("Move source should have piece.");
|
||||||
node.pos.set_piece(
|
node.pos.set_piece(
|
||||||
self.dest,
|
self.dest,
|
||||||
ColPiece {
|
ColPiece {
|
||||||
@ -127,12 +127,22 @@ impl Move {
|
|||||||
Color::Black => { self.src.0 - BOARD_WIDTH },
|
Color::Black => { self.src.0 - BOARD_WIDTH },
|
||||||
};
|
};
|
||||||
node.pos.ep_square = Some(
|
node.pos.ep_square = Some(
|
||||||
// TODO: fix the en passant targetsquare
|
|
||||||
Square::try_from(new_idx)
|
Square::try_from(new_idx)
|
||||||
.expect("En-passant target should be valid."),
|
.expect("En-passant target should be valid."),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
node.pos.ep_square = None;
|
node.pos.ep_square = None;
|
||||||
|
if pc_dest.is_none() && src_col != dest_col {
|
||||||
|
// we took en passant
|
||||||
|
debug_assert!(src_row.abs_diff(dest_row) == 1);
|
||||||
|
debug_assert_eq!(self.dest, old_pos.ep_square.unwrap());
|
||||||
|
// square to actually capture at
|
||||||
|
let ep_capture = Square::try_from(match pc_src.col {
|
||||||
|
Color::White => { self.dest.0 - BOARD_WIDTH },
|
||||||
|
Color::Black => { self.dest.0 + BOARD_WIDTH },
|
||||||
|
}).expect("En-passant capture square should be valid.");
|
||||||
|
node.pos.del_piece(ep_capture).expect("En-passant capture square should have piece.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
node.pos.half_moves += 1;
|
node.pos.half_moves += 1;
|
||||||
@ -168,7 +178,7 @@ impl Move {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
node.pos.del_piece(self.src);
|
node.pos.del_piece(self.src).expect("Move source should have piece.");
|
||||||
node.pos.set_piece(self.dest, pc_src);
|
node.pos.set_piece(self.dest, pc_src);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -331,6 +341,17 @@ mod tests {
|
|||||||
("b2b1q", "4k1N1/8/8/8/8/8/8/1q2K3 w - - 0 2"),
|
("b2b1q", "4k1N1/8/8/8/8/8/8/1q2K3 w - - 0 2"),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
// en passant test
|
||||||
|
(
|
||||||
|
"k7/4p3/8/3P4/3p4/8/4P3/K7 w - - 0 1",
|
||||||
|
vec![
|
||||||
|
("e2e4", "k7/4p3/8/3P4/3pP3/8/8/K7 b - e3 0 1"),
|
||||||
|
("d4e3", "k7/4p3/8/3P4/8/4p3/8/K7 w - - 0 2"),
|
||||||
|
("a1b1", "k7/4p3/8/3P4/8/4p3/8/1K6 b - - 1 2"),
|
||||||
|
("e7e5", "k7/8/8/3Pp3/8/4p3/8/1K6 w - e6 0 3"),
|
||||||
|
("d5e6", "k7/8/4P3/8/8/4p3/8/1K6 b - - 0 3"),
|
||||||
|
],
|
||||||
|
),
|
||||||
];
|
];
|
||||||
|
|
||||||
for (i, test_case) in test_cases.iter().enumerate() {
|
for (i, test_case) in test_cases.iter().enumerate() {
|
||||||
|
Loading…
Reference in New Issue
Block a user