Make en_passant_square an Option<u8>
This commit is contained in:
@@ -121,7 +121,7 @@ impl Board {
|
|||||||
pieces,
|
pieces,
|
||||||
all_occupancies,
|
all_occupancies,
|
||||||
enemy_occupancies,
|
enemy_occupancies,
|
||||||
self.state,
|
self.state.get_en_passant_target_square(),
|
||||||
color,
|
color,
|
||||||
),
|
),
|
||||||
Kind::Knight => knight_pseudo_moves(pieces, own_occupancies),
|
Kind::Knight => knight_pseudo_moves(pieces, own_occupancies),
|
||||||
|
|||||||
11
src/fen.rs
11
src/fen.rs
@@ -101,7 +101,7 @@ fn castling_ability(castling: &str) -> Result<u8, FenError> {
|
|||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
fn en_passant_target_square(square: &str) -> Result<u8, FenError> {
|
fn en_passant_target_square(square: &str) -> Result<Option<u8>, FenError> {
|
||||||
let mut sqr = square.chars();
|
let mut sqr = square.chars();
|
||||||
|
|
||||||
let mut files: HashMap<char, u8> = HashMap::new();
|
let mut files: HashMap<char, u8> = HashMap::new();
|
||||||
@@ -120,14 +120,15 @@ fn en_passant_target_square(square: &str) -> Result<u8, FenError> {
|
|||||||
|
|
||||||
match sqr.next() {
|
match sqr.next() {
|
||||||
Some(file) if files.contains_key(&file) => match sqr.next() {
|
Some(file) if files.contains_key(&file) => match sqr.next() {
|
||||||
Some(rank) if ranks.contains_key(&rank) => Ok(ranks.get(&rank).expect("Invalid rank")
|
Some(rank) if ranks.contains_key(&rank) => Ok(Some(
|
||||||
* 8
|
ranks.get(&rank).expect("Invalid rank") * 8
|
||||||
+ files.get(&file).expect("Invalid file")),
|
+ files.get(&file).expect("Invalid file"),
|
||||||
|
)),
|
||||||
Some(_) | None => Err(FenError::from(
|
Some(_) | None => Err(FenError::from(
|
||||||
"Not a valid rank (3 or 6) for an en passant target square",
|
"Not a valid rank (3 or 6) for an en passant target square",
|
||||||
)),
|
)),
|
||||||
},
|
},
|
||||||
Some('-') => Ok(0),
|
Some('-') => Ok(None),
|
||||||
Some(_) | None => Err(FenError::from("Not a file (a..h) or dash (-) character")),
|
Some(_) | None => Err(FenError::from("Not a file (a..h) or dash (-) character")),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
10
src/game.rs
10
src/game.rs
@@ -35,7 +35,7 @@ impl Default for Game {
|
|||||||
pub struct State {
|
pub struct State {
|
||||||
side_to_move: Color,
|
side_to_move: Color,
|
||||||
castling_ability: u8,
|
castling_ability: u8,
|
||||||
en_passant_target_square: u8,
|
en_passant_target_square: Option<u8>,
|
||||||
halfmove_clock: u8,
|
halfmove_clock: u8,
|
||||||
fullmove_counter: u8,
|
fullmove_counter: u8,
|
||||||
}
|
}
|
||||||
@@ -45,7 +45,7 @@ impl State {
|
|||||||
Self {
|
Self {
|
||||||
side_to_move: Color::White,
|
side_to_move: Color::White,
|
||||||
castling_ability: 0b1111,
|
castling_ability: 0b1111,
|
||||||
en_passant_target_square: 0,
|
en_passant_target_square: None,
|
||||||
halfmove_clock: 0,
|
halfmove_clock: 0,
|
||||||
fullmove_counter: 1,
|
fullmove_counter: 1,
|
||||||
}
|
}
|
||||||
@@ -54,7 +54,7 @@ impl State {
|
|||||||
pub const fn load_state(
|
pub const fn load_state(
|
||||||
side_to_move: Color,
|
side_to_move: Color,
|
||||||
castling_ability: u8,
|
castling_ability: u8,
|
||||||
en_passant_target_square: u8,
|
en_passant_target_square: Option<u8>,
|
||||||
halfmove_clock: u8,
|
halfmove_clock: u8,
|
||||||
fullmove_counter: u8,
|
fullmove_counter: u8,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
@@ -67,7 +67,7 @@ impl State {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const fn get_en_passant_target_square(&self) -> u8 {
|
pub const fn get_en_passant_target_square(&self) -> Option<u8> {
|
||||||
self.en_passant_target_square
|
self.en_passant_target_square
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -78,7 +78,7 @@ impl fmt::Display for State {
|
|||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
writeln!(f,
|
writeln!(f,
|
||||||
"side_to_move: {:?}\ncastling_ability: {:b}\nen_passant_target_square: {:b}\nhalfmove_clock: {}\nfullmove_counter: {}\n",
|
"side_to_move: {:?}\ncastling_ability: {:b}\nen_passant_target_square: {:b}\nhalfmove_clock: {}\nfullmove_counter: {}\n",
|
||||||
self.side_to_move, self.castling_ability, 1_u64 << self.en_passant_target_square, self.halfmove_clock, self.fullmove_counter)
|
self.side_to_move, self.castling_ability, 1_u64 << self.en_passant_target_square.unwrap_or(0), self.halfmove_clock, self.fullmove_counter)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ use crate::attack::{
|
|||||||
get_rook_attacks,
|
get_rook_attacks,
|
||||||
};
|
};
|
||||||
use crate::board::Color;
|
use crate::board::Color;
|
||||||
use crate::game::State;
|
|
||||||
use u64 as Bitboard;
|
use u64 as Bitboard;
|
||||||
|
|
||||||
const NOT_A_FILE: Bitboard = 0xfefefefefefefefe;
|
const NOT_A_FILE: Bitboard = 0xfefefefefefefefe;
|
||||||
@@ -27,17 +26,25 @@ pub fn pawn_pseudo_moves(
|
|||||||
pawns: Bitboard,
|
pawns: Bitboard,
|
||||||
all_occupancies: Bitboard,
|
all_occupancies: Bitboard,
|
||||||
enemy_occupancies: Bitboard,
|
enemy_occupancies: Bitboard,
|
||||||
state: State,
|
en_passant_square: Option<u8>,
|
||||||
color: Color,
|
color: Color,
|
||||||
) -> Vec<Move> {
|
) -> Vec<Move> {
|
||||||
let mut moves: Vec<Move> = vec![];
|
let mut moves: Vec<Move> = vec![];
|
||||||
match color {
|
match color {
|
||||||
Color::White => {
|
Color::White => {
|
||||||
moves.extend(white_pawn_quiet_moves(pawns, all_occupancies));
|
moves.extend(white_pawn_quiet_moves(pawns, all_occupancies));
|
||||||
moves.extend(white_pawn_capture_moves(pawns, enemy_occupancies, state));
|
moves.extend(white_pawn_capture_moves(
|
||||||
|
pawns,
|
||||||
|
enemy_occupancies,
|
||||||
|
en_passant_square,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
Color::Black => {
|
Color::Black => {
|
||||||
moves.extend(black_pawn_capture_moves(pawns, enemy_occupancies, state));
|
moves.extend(black_pawn_capture_moves(
|
||||||
|
pawns,
|
||||||
|
enemy_occupancies,
|
||||||
|
en_passant_square,
|
||||||
|
));
|
||||||
moves.extend(black_pawn_quiet_moves(pawns, all_occupancies));
|
moves.extend(black_pawn_quiet_moves(pawns, all_occupancies));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -91,7 +98,7 @@ fn black_pawn_quiet_moves(pawns: Bitboard, occupancies: Bitboard) -> Vec<Move> {
|
|||||||
fn white_pawn_capture_moves(
|
fn white_pawn_capture_moves(
|
||||||
pawns: Bitboard,
|
pawns: Bitboard,
|
||||||
enemy_occupancies: Bitboard,
|
enemy_occupancies: Bitboard,
|
||||||
state: State,
|
en_passant_square: Option<u8>,
|
||||||
) -> Vec<Move> {
|
) -> Vec<Move> {
|
||||||
let mut moves: Vec<Move> = vec![];
|
let mut moves: Vec<Move> = vec![];
|
||||||
let mut w_pawns_capture_east = pawns & ((enemy_occupancies >> 9) & NOT_H_FILE);
|
let mut w_pawns_capture_east = pawns & ((enemy_occupancies >> 9) & NOT_H_FILE);
|
||||||
@@ -110,19 +117,18 @@ fn white_pawn_capture_moves(
|
|||||||
w_pawns_capture_west &= w_pawns_capture_west - 1;
|
w_pawns_capture_west &= w_pawns_capture_west - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
let epts = state.get_en_passant_target_square();
|
if let Some(en_passant_square) = en_passant_square {
|
||||||
if epts != 0 {
|
let attacked_from = get_pawn_attacks(en_passant_square as usize, Color::Black);
|
||||||
let attacked_from = get_pawn_attacks(epts as usize, Color::Black);
|
|
||||||
let result = attacked_from & pawns;
|
let result = attacked_from & pawns;
|
||||||
moves.push(Move::new(result.trailing_zeros(), epts as u32));
|
moves.push(Move::new(result.trailing_zeros(), en_passant_square as u32));
|
||||||
}
|
};
|
||||||
moves
|
moves
|
||||||
}
|
}
|
||||||
|
|
||||||
fn black_pawn_capture_moves(
|
fn black_pawn_capture_moves(
|
||||||
pawns: Bitboard,
|
pawns: Bitboard,
|
||||||
enemy_occupancies: Bitboard,
|
enemy_occupancies: Bitboard,
|
||||||
state: State,
|
en_passant_square: Option<u8>,
|
||||||
) -> Vec<Move> {
|
) -> Vec<Move> {
|
||||||
let mut moves: Vec<Move> = vec![];
|
let mut moves: Vec<Move> = vec![];
|
||||||
let mut b_pawns_capture_east = pawns & ((enemy_occupancies << 7) & NOT_H_FILE);
|
let mut b_pawns_capture_east = pawns & ((enemy_occupancies << 7) & NOT_H_FILE);
|
||||||
@@ -142,12 +148,11 @@ fn black_pawn_capture_moves(
|
|||||||
b_pawns_capture_west &= b_pawns_capture_west - 1;
|
b_pawns_capture_west &= b_pawns_capture_west - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
let epts = state.get_en_passant_target_square();
|
if let Some(en_passant_square) = en_passant_square {
|
||||||
if epts != 0 {
|
let attacked_from = get_pawn_attacks(en_passant_square as usize, Color::White);
|
||||||
let attacked_from = get_pawn_attacks(epts as usize, Color::White);
|
|
||||||
let result = attacked_from & pawns;
|
let result = attacked_from & pawns;
|
||||||
moves.push(Move::new(result.trailing_zeros(), epts as u32));
|
moves.push(Move::new(result.trailing_zeros(), en_passant_square as u32));
|
||||||
}
|
};
|
||||||
moves
|
moves
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -190,7 +195,6 @@ pub fn bishop_pseudo_moves(
|
|||||||
bishops &= bishops - 1;
|
bishops &= bishops - 1;
|
||||||
}
|
}
|
||||||
moves
|
moves
|
||||||
// moves arkoudaki se agapo polu! to gataki sou
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn rook_pseudo_moves(
|
pub fn rook_pseudo_moves(
|
||||||
|
|||||||
Reference in New Issue
Block a user