From ee61528891d4043d0c95de3c9b78b30af1899c9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Wed, 19 Nov 2025 20:16:48 +0100 Subject: [PATCH 01/49] added file and module structure for bitboard::movegen.rs --- engine/src/bitboard.rs | 1 + engine/src/bitboard/movegen.rs | 0 2 files changed, 1 insertion(+) create mode 100644 engine/src/bitboard/movegen.rs diff --git a/engine/src/bitboard.rs b/engine/src/bitboard.rs index 1486484..177e4a5 100644 --- a/engine/src/bitboard.rs +++ b/engine/src/bitboard.rs @@ -5,5 +5,6 @@ mod checkinfo; mod attacks; mod bitmove; mod movebuffer; +mod movegen; pub mod board; \ No newline at end of file diff --git a/engine/src/bitboard/movegen.rs b/engine/src/bitboard/movegen.rs new file mode 100644 index 0000000..e69de29 From d172afc50c5841cdea165277371a6d24c30ff919 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Wed, 19 Nov 2025 20:32:12 +0100 Subject: [PATCH 02/49] re-added missing code for check tests from past branch --- engine/src/bitboard/board.rs | 19 +++++++- engine/src/bitboard/legality.rs | 79 +++++++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+), 1 deletion(-) diff --git a/engine/src/bitboard/board.rs b/engine/src/bitboard/board.rs index 11a85ce..483f1c4 100644 --- a/engine/src/bitboard/board.rs +++ b/engine/src/bitboard/board.rs @@ -64,7 +64,7 @@ impl Board { for (i, c) in coming_up.chars().enumerate() { if pieces.contains(&c) { - // board.place_piece(row*8 + col, c); + board.place_piece(row*8 + col, c); col += 1; } else if ('1'..='8').contains(&c) { @@ -179,4 +179,21 @@ impl Board { } } + pub fn place_piece(&mut self, sq: i32, piece: char) { + match piece { + 'p' => {self.bitboards[6] |= 1 << sq} + 'n' => {self.bitboards[7] |= 1 << sq} + 'b' => {self.bitboards[8] |= 1 << sq} + 'r' => {self.bitboards[9] |= 1 << sq} + 'q' => {self.bitboards[10] |= 1 << sq} + 'k' => {self.bitboards[11] |= 1 << sq} + 'P' => {self.bitboards[0] |= 1 << sq} + 'N' => {self.bitboards[1] |= 1 << sq} + 'B' => {self.bitboards[2] |= 1 << sq} + 'R' => {self.bitboards[3] |= 1 << sq} + 'Q' => {self.bitboards[4] |= 1 << sq} + 'K' => {self.bitboards[5] |= 1 << sq} + _ => () + } + } } \ No newline at end of file diff --git a/engine/src/bitboard/legality.rs b/engine/src/bitboard/legality.rs index 7d12e57..f42fdc1 100644 --- a/engine/src/bitboard/legality.rs +++ b/engine/src/bitboard/legality.rs @@ -1,8 +1,56 @@ use super::board::Board; use super::attackmaps::RAY_TABLE; +use super::checkinfo::CheckInfo; +use super::attacks::get_raycast_from_square_in_direction; impl Board { + pub fn check_test(&self) -> CheckInfo { + let mut check_info: CheckInfo = CheckInfo::new(); + let offset: usize = 6 * self.side_to_move as usize; + let king: u64 = self.bitboards[5 + offset]; + let king_sq = king.trailing_zeros() as usize; + let occupancy = self.occupancy[2]; + + // queen-rook checks (+) + let attacker_mask = self.bitboards[10 - offset] | self.bitboards[9 - offset]; + + for dir in [0, 2, 4, 6] { + let threat_mask: u64 = get_raycast_from_square_in_direction(occupancy, king_sq, dir); + if threat_mask & attacker_mask != 0 { + check_info.add_checker(threat_mask); + } + } + + // queen-bishop checks (x) + let attacker_mask = self.bitboards[10 - offset] | self.bitboards[8 - offset]; + + for dir in [1, 3, 5, 7] { + let threat_mask = get_raycast_from_square_in_direction(occupancy, king_sq, dir); + if threat_mask & attacker_mask != 0 { + check_info.add_checker(threat_mask); + } + } + + // knight checks (L) + let attacker_mask = self.bitboards[7 - offset]; + let threat_mask = self.get_pseudo_knight_moves(king_sq as u32); + let checker = threat_mask & attacker_mask; + if checker != 0 { + check_info.add_checker(checker); + } + + // pawn checks (v) + let attacker_mask = self.bitboards[6 - offset]; + let threat_mask = self.get_pseudo_pawn_captures(king_sq as u32); + let checker = threat_mask & attacker_mask; + if checker != 0 { + check_info.add_checker(checker); + } + + return check_info; + } + pub(in super) fn calc_pinned_squares(&mut self) { self.pinned_squares = [4; 64]; self.pin_mask = 0u64; @@ -45,4 +93,35 @@ impl Board { } } +} + +// <----- TESTS -----> + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn check_test_test() { + + let fens = [ + "rnb1k1nr/pppppppp/4q3/8/1b6/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1", // no check + "rnb1k1nr/pppppppp/4q3/8/1b1P4/8/PPP1PPPP/RNBQKBNR w KQkq d3 0 1", // single check + "rnb1k1nr/ppp1p2p/3pq1p1/8/1b1P1P2/8/PPP2PPP/RNBQKBNR w KQkq - 0 1" // double check + ]; + let expected_results = [ + CheckInfo { check_count: 0, move_mask: 0xFFFF_FFFF_FFFF_FFFF }, + CheckInfo { check_count: 1, move_mask: 0x0000_0000_0204_0800 }, + CheckInfo { check_count: 2, move_mask: 0x0000_0000_0000_0000 } + ]; + + for test_nr in 0..3 { + let fen = fens[test_nr]; + let board = Board::build(fen); + let check_test_actual = board.check_test(); + assert_eq!(check_test_actual.check_count, expected_results[test_nr].check_count); + assert_eq!(check_test_actual.move_mask, expected_results[test_nr].move_mask); + } + + } } \ No newline at end of file From 48272d6d70ebbb44c5e6dad8ea4536f7fec011a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Wed, 19 Nov 2025 20:35:46 +0100 Subject: [PATCH 03/49] added skeleton for main move generation method to bitboard::movegen --- engine/src/bitboard/movegen.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/engine/src/bitboard/movegen.rs b/engine/src/bitboard/movegen.rs index e69de29..345821e 100644 --- a/engine/src/bitboard/movegen.rs +++ b/engine/src/bitboard/movegen.rs @@ -0,0 +1,19 @@ +use super::board::Board; +use super::movebuffer::MoveBuffer; + +impl Board { + + pub fn collect_moves(&mut self, buffer: &mut MoveBuffer, temp_buffer: &mut MoveBuffer) -> bool { + buffer.clear(); + self.calc_pinned_squares(); + let check_info = self.check_test(); + + match check_info.check_count { + // 0 => self.collect_all_moves(), + // 1 => self.collect_moves_single_check(), + // 2 => self.collect_king_evasion(), + _ => panic!("More than 2 checking pieces found as the same time!") + } + return check_info.check_count > 0; + } +} \ No newline at end of file From 3f7cc2df4dfa2db1325353f01fda9ffbbb2cd73f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Wed, 19 Nov 2025 20:39:00 +0100 Subject: [PATCH 04/49] added file and module structure for bitboard::movegen::pawns --- engine/src/bitboard/movegen.rs | 2 ++ engine/src/bitboard/movegen/pawns.rs | 0 2 files changed, 2 insertions(+) create mode 100644 engine/src/bitboard/movegen/pawns.rs diff --git a/engine/src/bitboard/movegen.rs b/engine/src/bitboard/movegen.rs index 345821e..aa5ff96 100644 --- a/engine/src/bitboard/movegen.rs +++ b/engine/src/bitboard/movegen.rs @@ -1,3 +1,5 @@ +mod pawns; + use super::board::Board; use super::movebuffer::MoveBuffer; diff --git a/engine/src/bitboard/movegen/pawns.rs b/engine/src/bitboard/movegen/pawns.rs new file mode 100644 index 0000000..e69de29 From a2f261778bdce392e94fa62fe70944c6c86a9a2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Wed, 19 Nov 2025 20:47:44 +0100 Subject: [PATCH 05/49] implemented move generation method for pawn quiet moves --- engine/src/bitboard/legality.rs | 7 +++++ engine/src/bitboard/movegen.rs | 1 + engine/src/bitboard/movegen/pawns.rs | 38 ++++++++++++++++++++++++++++ 3 files changed, 46 insertions(+) diff --git a/engine/src/bitboard/legality.rs b/engine/src/bitboard/legality.rs index f42fdc1..f81973e 100644 --- a/engine/src/bitboard/legality.rs +++ b/engine/src/bitboard/legality.rs @@ -93,6 +93,13 @@ impl Board { } } + #[inline] + pub(in super) fn get_pin_masked_moves(&self, moves: u64, sq: u32) -> u64 { + let sq: usize = sq as usize; + if self.pinned_squares[sq] == 4 { return moves; } + let dir: u8 = self.pinned_squares[sq]; + return moves & (RAY_TABLE[sq][dir as usize] | RAY_TABLE[sq][4 + dir as usize]); + } } // <----- TESTS -----> diff --git a/engine/src/bitboard/movegen.rs b/engine/src/bitboard/movegen.rs index aa5ff96..4dbb76e 100644 --- a/engine/src/bitboard/movegen.rs +++ b/engine/src/bitboard/movegen.rs @@ -2,6 +2,7 @@ mod pawns; use super::board::Board; use super::movebuffer::MoveBuffer; +use super::bitmove::BitMove; impl Board { diff --git a/engine/src/bitboard/movegen/pawns.rs b/engine/src/bitboard/movegen/pawns.rs index e69de29..30d2000 100644 --- a/engine/src/bitboard/movegen/pawns.rs +++ b/engine/src/bitboard/movegen/pawns.rs @@ -0,0 +1,38 @@ +use super::*; + +impl Board { + + fn add_pawn_quiets(&self, buffer: &mut MoveBuffer, move_mask: u64) { + let offset: u8 = self.side_to_move * 6; + let mut pawns: u64 = self.bitboards[offset as usize]; + while pawns != 0 { + let next_sq = pawns.trailing_zeros(); + pawns &= !(1 << next_sq); + + let mut quiets: u64 = self.get_pseudo_pawn_moves(next_sq) & move_mask; + quiets = self.get_pin_masked_moves(quiets, next_sq); + while quiets != 0 { + let to_sq = quiets.trailing_zeros(); + + if (self.side_to_move == 0 && quiets.trailing_zeros() / 8 == 7) + || (self.side_to_move == 1 && quiets.trailing_zeros() / 8 == 0) { + for piece_type in [3, 2, 1, 0] { + buffer.add(BitMove::quiet( + next_sq as u8, + to_sq as u8, + Some(piece_type) + )); + } + } + else { + buffer.add(BitMove::quiet( + next_sq as u8, + to_sq as u8, + None + )); + } + quiets &= !(1 << to_sq); + } + } + } +} \ No newline at end of file From a4c63f19e54bc6d381f4dd8eaedebd0f65132245 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Wed, 19 Nov 2025 20:52:28 +0100 Subject: [PATCH 06/49] implemented move generation method for pawn capture moves --- engine/src/bitboard/movegen/pawns.rs | 36 ++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/engine/src/bitboard/movegen/pawns.rs b/engine/src/bitboard/movegen/pawns.rs index 30d2000..3cb7037 100644 --- a/engine/src/bitboard/movegen/pawns.rs +++ b/engine/src/bitboard/movegen/pawns.rs @@ -35,4 +35,40 @@ impl Board { } } } + fn add_pawn_captures(&self, buffer: &mut MoveBuffer, move_mask: u64) { + let offset = 6 * self.side_to_move as usize; + let mut pawns: u64 = self.bitboards[offset]; + let opponents = self.occupancy[1 - self.side_to_move as usize]; + while pawns != 0 { + let next_sq: u32 = pawns.trailing_zeros(); + pawns &= !(1 << next_sq); + + let mut attacks: u64 = self.get_pseudo_pawn_captures(next_sq) & move_mask; + attacks = self.get_pin_masked_moves(attacks, next_sq); + attacks &= opponents; + + while attacks != 0 { + let to_sq = attacks.trailing_zeros(); + + if (self.side_to_move == 0 && attacks.trailing_zeros() / 8 == 7) + || (self.side_to_move == 1 && attacks.trailing_zeros() / 8 == 0) { + for piece_type in [3, 2, 1, 0] { + buffer.add(BitMove::capture( + next_sq as u8, + to_sq as u8, + Some(piece_type) + )); + } + } + else { + buffer.add(BitMove::capture( + next_sq as u8, + to_sq as u8, + None + )); + } + attacks &= !(1 << to_sq); + } + } + } } \ No newline at end of file From d66787f51d169dbdc83c6c19690fdd8242e265f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Wed, 19 Nov 2025 20:54:01 +0100 Subject: [PATCH 07/49] implemented method to collect both quiet and capture moves for pawns --- engine/src/bitboard/movegen/pawns.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/engine/src/bitboard/movegen/pawns.rs b/engine/src/bitboard/movegen/pawns.rs index 3cb7037..f31b3f7 100644 --- a/engine/src/bitboard/movegen/pawns.rs +++ b/engine/src/bitboard/movegen/pawns.rs @@ -71,4 +71,8 @@ impl Board { } } } + fn add_pawn_moves(&self, capture_buffer: &mut MoveBuffer, quiet_buffer: &mut MoveBuffer, move_mask: u64) { + self.add_pawn_captures(capture_buffer, move_mask); + self.add_pawn_quiets(quiet_buffer, move_mask); + } } \ No newline at end of file From 372d86b4511b941864e586707cfa5d1121ca10ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Wed, 19 Nov 2025 20:58:56 +0100 Subject: [PATCH 08/49] changed signature utility functions utils::pop_lsb and utils::pop_msb to reduce unnecessary type conversions --- engine/src/bitboard/movegen/pawns.rs | 8 ++++---- engine/src/bitboard/utils.rs | 12 ++++++------ 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/engine/src/bitboard/movegen/pawns.rs b/engine/src/bitboard/movegen/pawns.rs index f31b3f7..1f0c6e3 100644 --- a/engine/src/bitboard/movegen/pawns.rs +++ b/engine/src/bitboard/movegen/pawns.rs @@ -1,3 +1,5 @@ +use crate::bitboard::utils::pop_lsb; + use super::*; impl Board { @@ -6,8 +8,7 @@ impl Board { let offset: u8 = self.side_to_move * 6; let mut pawns: u64 = self.bitboards[offset as usize]; while pawns != 0 { - let next_sq = pawns.trailing_zeros(); - pawns &= !(1 << next_sq); + let next_sq = pop_lsb(&mut pawns); let mut quiets: u64 = self.get_pseudo_pawn_moves(next_sq) & move_mask; quiets = self.get_pin_masked_moves(quiets, next_sq); @@ -40,8 +41,7 @@ impl Board { let mut pawns: u64 = self.bitboards[offset]; let opponents = self.occupancy[1 - self.side_to_move as usize]; while pawns != 0 { - let next_sq: u32 = pawns.trailing_zeros(); - pawns &= !(1 << next_sq); + let next_sq = pop_lsb(&mut pawns); let mut attacks: u64 = self.get_pseudo_pawn_captures(next_sq) & move_mask; attacks = self.get_pin_masked_moves(attacks, next_sq); diff --git a/engine/src/bitboard/utils.rs b/engine/src/bitboard/utils.rs index f7f83fe..81cc68f 100644 --- a/engine/src/bitboard/utils.rs +++ b/engine/src/bitboard/utils.rs @@ -1,13 +1,13 @@ #[inline(always)] -pub fn pop_lsb(value: &mut u64) -> usize { - let idx = value.trailing_zeros() as usize; +pub fn pop_lsb(value: &mut u64) -> u32 { + let idx = value.trailing_zeros(); *value &= !(1 << idx); return idx; } #[inline(always)] -pub fn pop_msb(value: &mut u64) -> usize { - let idx = 63 - value.leading_zeros() as usize; +pub fn pop_msb(value: &mut u64) -> u32 { + let idx = 63 - value.leading_zeros(); *value &= !(1 << idx); return idx; } @@ -72,7 +72,7 @@ mod tests { 0xBEAC_DBE0_903A_AC00, 0x01E8_C895_A6F0_0000 ]; - let expected_values: [usize; 6] = [63, 0, 4, 2, 10, 20]; + let expected_values: [u32; 6] = [63, 0, 4, 2, 10, 20]; // tests for index in 0..6 { @@ -92,7 +92,7 @@ mod tests { 0x0000_C1C3_201C_0DB1, 0x0000_0203_0DE4_E944 ]; - let expected_values: [usize; 6] = [63, 0, 61, 57, 47, 41]; + let expected_values: [u32; 6] = [63, 0, 61, 57, 47, 41]; // tests for index in 0..6 { From 2e82a52f2754a6bf180c010308c9fcd2718164f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Wed, 19 Nov 2025 21:03:27 +0100 Subject: [PATCH 09/49] added file and module structure for bitboard::movegen::knights --- engine/src/bitboard/movegen.rs | 1 + engine/src/bitboard/movegen/knights.rs | 1 + 2 files changed, 2 insertions(+) create mode 100644 engine/src/bitboard/movegen/knights.rs diff --git a/engine/src/bitboard/movegen.rs b/engine/src/bitboard/movegen.rs index 4dbb76e..b83278a 100644 --- a/engine/src/bitboard/movegen.rs +++ b/engine/src/bitboard/movegen.rs @@ -1,4 +1,5 @@ mod pawns; +mod knights; use super::board::Board; use super::movebuffer::MoveBuffer; diff --git a/engine/src/bitboard/movegen/knights.rs b/engine/src/bitboard/movegen/knights.rs new file mode 100644 index 0000000..9148c04 --- /dev/null +++ b/engine/src/bitboard/movegen/knights.rs @@ -0,0 +1 @@ +use super::*; \ No newline at end of file From 40e2c50209247a1c50b202bc304d26f9f43eb851 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Wed, 19 Nov 2025 21:05:58 +0100 Subject: [PATCH 10/49] implemeneted general move generation method for knight moves --- engine/src/bitboard/movegen.rs | 1 + engine/src/bitboard/movegen/knights.rs | 37 +++++++++++++++++++++++++- engine/src/bitboard/movegen/pawns.rs | 2 -- 3 files changed, 37 insertions(+), 3 deletions(-) diff --git a/engine/src/bitboard/movegen.rs b/engine/src/bitboard/movegen.rs index b83278a..0fb7857 100644 --- a/engine/src/bitboard/movegen.rs +++ b/engine/src/bitboard/movegen.rs @@ -4,6 +4,7 @@ mod knights; use super::board::Board; use super::movebuffer::MoveBuffer; use super::bitmove::BitMove; +use super::utils::*; impl Board { diff --git a/engine/src/bitboard/movegen/knights.rs b/engine/src/bitboard/movegen/knights.rs index 9148c04..43b6b24 100644 --- a/engine/src/bitboard/movegen/knights.rs +++ b/engine/src/bitboard/movegen/knights.rs @@ -1 +1,36 @@ -use super::*; \ No newline at end of file +use super::*; + +impl Board { + + fn add_knight_moves(&self, capture_buffer: &mut MoveBuffer, quiet_buffer: &mut MoveBuffer, move_mask: u64) { + let piece_index = 1 + self.side_to_move * 6; + let mut knights = self.bitboards[piece_index as usize]; + let empty = !self.occupancy[2]; + let opponents = self.occupancy[1 - self.side_to_move as usize]; + while knights != 0 { + let from_sq = pop_lsb(&mut knights); + let raw_move_map = self.get_pseudo_knight_moves(from_sq) & move_mask; + let move_map = self.get_pin_masked_moves(raw_move_map, from_sq); + + let mut quiet_map = move_map & empty; + let mut capture_map = move_map & opponents; + + while quiet_map != 0 { + let to_sq = pop_lsb(&mut quiet_map); + quiet_buffer.add(BitMove::quiet( + from_sq as u8, + to_sq as u8, + None + )); + } + while capture_map != 0 { + let to_sq = pop_lsb(&mut capture_map); + capture_buffer.add(BitMove::capture( + from_sq as u8, + to_sq as u8, + None + )); + } + } + } +} \ No newline at end of file diff --git a/engine/src/bitboard/movegen/pawns.rs b/engine/src/bitboard/movegen/pawns.rs index 1f0c6e3..6e9e1dc 100644 --- a/engine/src/bitboard/movegen/pawns.rs +++ b/engine/src/bitboard/movegen/pawns.rs @@ -1,5 +1,3 @@ -use crate::bitboard::utils::pop_lsb; - use super::*; impl Board { From 2d646f0ad0421ebd11dcecd7be92c57c4b7abc83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Wed, 19 Nov 2025 21:07:18 +0100 Subject: [PATCH 11/49] implemented move generation method for knight capture moves --- engine/src/bitboard/movegen/knights.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/engine/src/bitboard/movegen/knights.rs b/engine/src/bitboard/movegen/knights.rs index 43b6b24..db4a105 100644 --- a/engine/src/bitboard/movegen/knights.rs +++ b/engine/src/bitboard/movegen/knights.rs @@ -33,4 +33,23 @@ impl Board { } } } + fn add_knight_captures(&self, buffer: &mut MoveBuffer, move_mask: u64) { + let offset = 6 * self.side_to_move as usize; + let mut knights: u64 = self.bitboards[1 + offset]; + let opponents = self.occupancy[1 - self.side_to_move as usize]; + while knights != 0 { + let next_sq: u32 = pop_lsb(&mut knights); + let mut attacks: u64 = self.get_pseudo_knight_moves(next_sq) & opponents & move_mask; + attacks = self.get_pin_masked_moves(attacks, next_sq); + + while attacks != 0 { + let to_sq = pop_lsb(&mut attacks); + buffer.add(BitMove::capture( + next_sq as u8, + to_sq as u8, + None + )); + } + } + } } \ No newline at end of file From 06cb2b88c2d61d9b2ee0b25be0db00e82917cbd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Wed, 19 Nov 2025 21:08:45 +0100 Subject: [PATCH 12/49] added file and module structure for bitboard::movegen::bishops --- engine/src/bitboard/movegen.rs | 1 + engine/src/bitboard/movegen/bishops.rs | 1 + 2 files changed, 2 insertions(+) create mode 100644 engine/src/bitboard/movegen/bishops.rs diff --git a/engine/src/bitboard/movegen.rs b/engine/src/bitboard/movegen.rs index 0fb7857..1aba161 100644 --- a/engine/src/bitboard/movegen.rs +++ b/engine/src/bitboard/movegen.rs @@ -1,5 +1,6 @@ mod pawns; mod knights; +mod bishops; use super::board::Board; use super::movebuffer::MoveBuffer; diff --git a/engine/src/bitboard/movegen/bishops.rs b/engine/src/bitboard/movegen/bishops.rs new file mode 100644 index 0000000..9148c04 --- /dev/null +++ b/engine/src/bitboard/movegen/bishops.rs @@ -0,0 +1 @@ +use super::*; \ No newline at end of file From 8165749845ec36fe74d2967995d51504af713f65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Wed, 19 Nov 2025 21:11:39 +0100 Subject: [PATCH 13/49] implemented general move generation method for bishops --- engine/src/bitboard/movegen/bishops.rs | 37 +++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/engine/src/bitboard/movegen/bishops.rs b/engine/src/bitboard/movegen/bishops.rs index 9148c04..c05a964 100644 --- a/engine/src/bitboard/movegen/bishops.rs +++ b/engine/src/bitboard/movegen/bishops.rs @@ -1 +1,36 @@ -use super::*; \ No newline at end of file +use super::*; + +impl Board { + + fn add_bishop_moves(&self, capture_buffer: &mut MoveBuffer, quiet_buffer: &mut MoveBuffer, move_mask: u64) { + let piece_index = 2 + self.side_to_move * 6; + let mut bishops = self.bitboards[piece_index as usize]; + let empty = !self.occupancy[2]; + let opponents = self.occupancy[1 - self.side_to_move as usize]; + while bishops != 0 { + let from_sq = pop_lsb(&mut bishops); + let raw_move_map = self.get_pseudo_bishop_moves(from_sq) & move_mask; + let move_map = self.get_pin_masked_moves(raw_move_map, from_sq); + + let mut quiet_map = move_map & empty; + let mut capture_map = move_map & opponents; + + while quiet_map != 0 { + let to_sq = pop_lsb(&mut quiet_map); + quiet_buffer.add(BitMove::quiet( + from_sq as u8, + to_sq as u8, + None + )); + } + while capture_map != 0 { + let to_sq = pop_lsb(&mut capture_map); + capture_buffer.add(BitMove::capture( + from_sq as u8, + to_sq as u8, + None + )); + } + } + } +} \ No newline at end of file From 35cb1eeb738ccab727bc48c8178724e12b117512 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Wed, 19 Nov 2025 21:13:05 +0100 Subject: [PATCH 14/49] implemented move generation method for bishop capture moves --- engine/src/bitboard/movegen/bishops.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/engine/src/bitboard/movegen/bishops.rs b/engine/src/bitboard/movegen/bishops.rs index c05a964..00f681b 100644 --- a/engine/src/bitboard/movegen/bishops.rs +++ b/engine/src/bitboard/movegen/bishops.rs @@ -33,4 +33,23 @@ impl Board { } } } + fn add_bishop_captures(&self, buffer: &mut MoveBuffer, move_mask: u64) { + let offset = 6 * self.side_to_move as usize; + let mut bishops: u64 = self.bitboards[2 + offset]; + let opponents = self.occupancy[1 - self.side_to_move as usize]; + while bishops != 0 { + let next_sq: u32 = pop_lsb(&mut bishops); + let mut attacks: u64 = self.get_pseudo_bishop_moves(next_sq) & opponents & move_mask; + attacks = self.get_pin_masked_moves(attacks, next_sq); + + while attacks != 0 { + let to_sq = pop_lsb(&mut attacks); + buffer.add(BitMove::capture( + next_sq as u8, + to_sq as u8, + None + )); + } + } + } } \ No newline at end of file From 9fb3d15beda85d5bffadf5fd4736d74c296247e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Thu, 20 Nov 2025 12:14:31 +0100 Subject: [PATCH 15/49] added file and module structure for bitboard::movegen::rooks --- engine/src/bitboard/movegen.rs | 1 + engine/src/bitboard/movegen/rooks.rs | 1 + 2 files changed, 2 insertions(+) create mode 100644 engine/src/bitboard/movegen/rooks.rs diff --git a/engine/src/bitboard/movegen.rs b/engine/src/bitboard/movegen.rs index 1aba161..0664d7c 100644 --- a/engine/src/bitboard/movegen.rs +++ b/engine/src/bitboard/movegen.rs @@ -1,6 +1,7 @@ mod pawns; mod knights; mod bishops; +mod rooks; use super::board::Board; use super::movebuffer::MoveBuffer; diff --git a/engine/src/bitboard/movegen/rooks.rs b/engine/src/bitboard/movegen/rooks.rs new file mode 100644 index 0000000..9148c04 --- /dev/null +++ b/engine/src/bitboard/movegen/rooks.rs @@ -0,0 +1 @@ +use super::*; \ No newline at end of file From e896aba4ec4aa50707495ca258b877a20ac86cd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Thu, 20 Nov 2025 12:18:25 +0100 Subject: [PATCH 16/49] implemented general move generation method for rooks --- engine/src/bitboard/movegen/rooks.rs | 37 +++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/engine/src/bitboard/movegen/rooks.rs b/engine/src/bitboard/movegen/rooks.rs index 9148c04..f81f129 100644 --- a/engine/src/bitboard/movegen/rooks.rs +++ b/engine/src/bitboard/movegen/rooks.rs @@ -1 +1,36 @@ -use super::*; \ No newline at end of file +use super::*; + +impl Board { + + fn add_rook_moves(&self, capture_buffer: &mut MoveBuffer, quiet_buffer: &mut MoveBuffer, move_mask: u64) { + let piece_index = 3 + self.side_to_move * 6; + let mut rooks = self.bitboards[piece_index as usize]; + let empty = !self.occupancy[2]; + let opponents = self.occupancy[1 - self.side_to_move as usize]; + while rooks != 0 { + let from_sq = pop_lsb(&mut rooks); + let raw_move_map = self.get_pseudo_rook_moves(from_sq) & move_mask; + let move_map = self.get_pin_masked_moves(raw_move_map, from_sq); + + let mut quiet_map = move_map & empty; + let mut capture_map = move_map & opponents; + + while quiet_map != 0 { + let to_sq = pop_lsb(&mut quiet_map); + quiet_buffer.add(BitMove::quiet( + from_sq as u8, + to_sq as u8, + None + )); + } + while capture_map != 0 { + let to_sq = pop_lsb(&mut capture_map); + capture_buffer.add(BitMove::capture( + from_sq as u8, + to_sq as u8, + None + )); + } + } + } +} \ No newline at end of file From 0dd9a3d0473aedb83e093b9be9e5f89961d9a9e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Thu, 20 Nov 2025 12:23:14 +0100 Subject: [PATCH 17/49] implemented move generation method for rook capture moves --- engine/src/bitboard/movegen/rooks.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/engine/src/bitboard/movegen/rooks.rs b/engine/src/bitboard/movegen/rooks.rs index f81f129..b908911 100644 --- a/engine/src/bitboard/movegen/rooks.rs +++ b/engine/src/bitboard/movegen/rooks.rs @@ -33,4 +33,23 @@ impl Board { } } } + fn add_rook_captures(&self, buffer: &mut MoveBuffer, move_mask: u64) { + let offset = 6 * self.side_to_move as usize; + let mut rooks: u64 = self.bitboards[3 + offset]; + let opponents = self.occupancy[1 - self.side_to_move as usize]; + while rooks != 0 { + let next_sq: u32 = pop_lsb(&mut rooks); + let mut attacks: u64 = self.get_pseudo_rook_moves(next_sq) & opponents & move_mask; + attacks = self.get_pin_masked_moves(attacks, next_sq); + + while attacks != 0 { + let to_sq = pop_lsb(&mut attacks); + buffer.add(BitMove::capture( + next_sq as u8, + to_sq as u8, + None + )); + } + } + } } \ No newline at end of file From a51d5e26525e9dc32b4a83b8f10eb9f8e2f88e4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Thu, 20 Nov 2025 12:24:40 +0100 Subject: [PATCH 18/49] added file and module structure for bitboard::movegen::queens --- engine/src/bitboard/movegen.rs | 1 + engine/src/bitboard/movegen/queens.rs | 1 + 2 files changed, 2 insertions(+) create mode 100644 engine/src/bitboard/movegen/queens.rs diff --git a/engine/src/bitboard/movegen.rs b/engine/src/bitboard/movegen.rs index 0664d7c..effeacc 100644 --- a/engine/src/bitboard/movegen.rs +++ b/engine/src/bitboard/movegen.rs @@ -2,6 +2,7 @@ mod pawns; mod knights; mod bishops; mod rooks; +mod queens; use super::board::Board; use super::movebuffer::MoveBuffer; diff --git a/engine/src/bitboard/movegen/queens.rs b/engine/src/bitboard/movegen/queens.rs new file mode 100644 index 0000000..9148c04 --- /dev/null +++ b/engine/src/bitboard/movegen/queens.rs @@ -0,0 +1 @@ +use super::*; \ No newline at end of file From 9fa298ed5185e73e4662917360232735e2832cda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Thu, 20 Nov 2025 12:26:16 +0100 Subject: [PATCH 19/49] implemented general move generation method for queens --- engine/src/bitboard/movegen/queens.rs | 37 ++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/engine/src/bitboard/movegen/queens.rs b/engine/src/bitboard/movegen/queens.rs index 9148c04..95951a8 100644 --- a/engine/src/bitboard/movegen/queens.rs +++ b/engine/src/bitboard/movegen/queens.rs @@ -1 +1,36 @@ -use super::*; \ No newline at end of file +use super::*; + +impl Board { + + fn add_queen_moves(&self, capture_buffer: &mut MoveBuffer, quiet_buffer: &mut MoveBuffer, move_mask: u64) { + let piece_index = 4 + self.side_to_move * 6; + let mut queens = self.bitboards[piece_index as usize]; + let empty = !self.occupancy[2]; + let opponents = self.occupancy[1 - self.side_to_move as usize]; + while queens != 0 { + let from_sq = pop_lsb(&mut queens); + let raw_move_map = self.get_pseudo_queen_moves(from_sq) & move_mask; + let move_map = self.get_pin_masked_moves(raw_move_map, from_sq); + + let mut quiet_map = move_map & empty; + let mut capture_map = move_map & opponents; + + while quiet_map != 0 { + let to_sq = pop_lsb(&mut quiet_map); + quiet_buffer.add(BitMove::quiet( + from_sq as u8, + to_sq as u8, + None + )); + } + while capture_map != 0 { + let to_sq = pop_lsb(&mut capture_map); + capture_buffer.add(BitMove::capture( + from_sq as u8, + to_sq as u8, + None + )); + } + } + } +} \ No newline at end of file From c2abc08206180b2259ed159ab34cbc408e7151b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Thu, 20 Nov 2025 12:27:31 +0100 Subject: [PATCH 20/49] implemented move generation method for queen capture moves --- engine/src/bitboard/movegen/queens.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/engine/src/bitboard/movegen/queens.rs b/engine/src/bitboard/movegen/queens.rs index 95951a8..6fdf4bd 100644 --- a/engine/src/bitboard/movegen/queens.rs +++ b/engine/src/bitboard/movegen/queens.rs @@ -33,4 +33,23 @@ impl Board { } } } + fn add_queen_captures(&self, buffer: &mut MoveBuffer, move_mask: u64) { + let offset = 6 * self.side_to_move as usize; + let mut queens: u64 = self.bitboards[4 + offset]; + let opponents = self.occupancy[1 - self.side_to_move as usize]; + while queens != 0 { + let next_sq: u32 = pop_lsb(&mut queens); + let mut attacks: u64 = self.get_pseudo_queen_moves(next_sq) & opponents & move_mask; + attacks = self.get_pin_masked_moves(attacks, next_sq); + + while attacks != 0 { + let to_sq = pop_lsb(&mut attacks); + buffer.add(BitMove::capture( + next_sq as u8, + to_sq as u8, + None + )); + } + } + } } \ No newline at end of file From e9f76634883e91ef64ea0a7ad3c544ec9ac10b26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Thu, 20 Nov 2025 12:28:46 +0100 Subject: [PATCH 21/49] added file and module structure for bitboard::movegen::kings --- engine/src/bitboard/movegen.rs | 1 + engine/src/bitboard/movegen/kings.rs | 1 + 2 files changed, 2 insertions(+) create mode 100644 engine/src/bitboard/movegen/kings.rs diff --git a/engine/src/bitboard/movegen.rs b/engine/src/bitboard/movegen.rs index effeacc..8f5a34a 100644 --- a/engine/src/bitboard/movegen.rs +++ b/engine/src/bitboard/movegen.rs @@ -3,6 +3,7 @@ mod knights; mod bishops; mod rooks; mod queens; +mod kings; use super::board::Board; use super::movebuffer::MoveBuffer; diff --git a/engine/src/bitboard/movegen/kings.rs b/engine/src/bitboard/movegen/kings.rs new file mode 100644 index 0000000..9148c04 --- /dev/null +++ b/engine/src/bitboard/movegen/kings.rs @@ -0,0 +1 @@ +use super::*; \ No newline at end of file From 21d26902f068b87c6537e88fafda7bba34285e5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Thu, 20 Nov 2025 12:33:58 +0100 Subject: [PATCH 22/49] implemented general move generation methdod for kings --- engine/src/bitboard/movegen/kings.rs | 36 +++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/engine/src/bitboard/movegen/kings.rs b/engine/src/bitboard/movegen/kings.rs index 9148c04..101ca04 100644 --- a/engine/src/bitboard/movegen/kings.rs +++ b/engine/src/bitboard/movegen/kings.rs @@ -1 +1,35 @@ -use super::*; \ No newline at end of file +use super::*; + +impl Board { + + fn add_king_moves(&self, capture_buffer: &mut MoveBuffer, quiet_buffer: &mut MoveBuffer, move_mask: u64) { + let piece_index = 5 + self.side_to_move * 6; + let mut kings = self.bitboards[piece_index as usize]; + let empty = !self.occupancy[2]; + let opponents = self.occupancy[1 - self.side_to_move as usize]; + while kings != 0 { + let from_sq = pop_lsb(&mut kings); + let move_map = self.get_pseudo_king_moves(from_sq) & move_mask; + + let mut quiet_map = move_map & empty; + let mut capture_map = move_map & opponents; + + while quiet_map != 0 { + let to_sq = pop_lsb(&mut quiet_map); + quiet_buffer.add(BitMove::quiet( + from_sq as u8, + to_sq as u8, + None + )); + } + while capture_map != 0 { + let to_sq = pop_lsb(&mut capture_map); + capture_buffer.add(BitMove::capture( + from_sq as u8, + to_sq as u8, + None + )); + } + } + } +} \ No newline at end of file From 5b3e84dab0d14efe7ed7f3f98eaf75c48dedb2e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Thu, 20 Nov 2025 12:35:46 +0100 Subject: [PATCH 23/49] implemented move generation method or king capture moves --- engine/src/bitboard/movegen/kings.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/engine/src/bitboard/movegen/kings.rs b/engine/src/bitboard/movegen/kings.rs index 101ca04..883d082 100644 --- a/engine/src/bitboard/movegen/kings.rs +++ b/engine/src/bitboard/movegen/kings.rs @@ -32,4 +32,23 @@ impl Board { } } } + fn add_king_captures(&self, buffer: &mut MoveBuffer, move_mask: u64) { + let offset = 6 * self.side_to_move as usize; + let mut kings: u64 = self.bitboards[5 + offset]; + let opponents = self.occupancy[1 - self.side_to_move as usize]; + while kings != 0 { + let next_sq: u32 = pop_lsb(&mut kings); + let mut attacks: u64 = self.get_pseudo_king_moves(next_sq) & opponents & move_mask; + attacks = self.get_pin_masked_moves(attacks, next_sq); + + while attacks != 0 { + let to_sq = pop_lsb(&mut attacks); + buffer.add(BitMove::capture( + next_sq as u8, + to_sq as u8, + None + )); + } + } + } } \ No newline at end of file From 08ba7ee436ae1bcc212b21fa29264e70847495c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Thu, 20 Nov 2025 12:41:20 +0100 Subject: [PATCH 24/49] implemented move generation method for castling moves --- engine/src/bitboard/attacks.rs | 25 ++++++++++++++++++++ engine/src/bitboard/movegen/kings.rs | 34 ++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/engine/src/bitboard/attacks.rs b/engine/src/bitboard/attacks.rs index a348d96..27c54e0 100644 --- a/engine/src/bitboard/attacks.rs +++ b/engine/src/bitboard/attacks.rs @@ -71,6 +71,31 @@ impl Board { pub fn get_pseudo_queen_moves(&self, sq: u32) -> u64 { return self.get_pseudo_bishop_moves(sq) | self.get_pseudo_rook_moves(sq); } + + #[inline] + pub fn is_square_attacked(&self, king_sq: u32) -> bool { + let offset: usize = 6 * self.side_to_move as usize; + + // rook-queen checks (+) + let mut threat_mask: u64 = self.get_pseudo_rook_moves(king_sq); + let mut attacker_mask: u64 = self.bitboards[10 - offset] | self.bitboards[9 - offset]; + if threat_mask & attacker_mask != 0 { return true; } + + // bishop-queen checks (x) + threat_mask = self.get_pseudo_bishop_moves(king_sq); + attacker_mask = self.bitboards[10 - offset] | self.bitboards[8 - offset]; + if threat_mask & attacker_mask != 0 { return true; } + + // knight checks (L) + threat_mask = KNIGHT_ATTACK_MAP[king_sq as usize]; + attacker_mask = self.bitboards[7 - offset]; + if threat_mask & attacker_mask != 0 { return true; } + + // pawn checks (v) + threat_mask = PAWN_ATTACK_MAP[king_sq as usize][self.side_to_move as usize]; + attacker_mask = self.bitboards[6 - offset]; + return threat_mask & attacker_mask != 0; + } } #[inline(always)] diff --git a/engine/src/bitboard/movegen/kings.rs b/engine/src/bitboard/movegen/kings.rs index 883d082..18315e4 100644 --- a/engine/src/bitboard/movegen/kings.rs +++ b/engine/src/bitboard/movegen/kings.rs @@ -51,4 +51,38 @@ impl Board { } } } + fn add_king_castles(&self, buffer: &mut MoveBuffer, move_mask: u64) { + if self.castling_rights & (0b11 << (2 - 2 * self.side_to_move)) == 0 { + return; + } + + let offset = 5 + 6 * self.side_to_move as u8; + let castle_offset = 2 - 2 * self.side_to_move as u8; + let castling_rights = self.castling_rights & 3 << castle_offset; + let occupied = self.occupancy[2]; + let king_sq = self.bitboards[offset as usize].trailing_zeros(); + + let queenside_mask = 0b111 << (king_sq - 3); + let kingside_mask = 0b11 << (king_sq + 1); + + if (castling_rights & 1 << castle_offset) != 0 + && queenside_mask & occupied == 0 + && !move_mask & 0b11 << (king_sq - 2) == 0 + && !self.is_square_attacked(king_sq - 2) { + buffer.add(BitMove::castle( + king_sq as u8, + (king_sq - 2) as u8 + )); + } + if (castling_rights & 2 << castle_offset) != 0 + && kingside_mask & occupied == 0 + && !move_mask & 0b11 << (king_sq + 1) == 0 + && !self.is_square_attacked(king_sq + 2) { + buffer.add(BitMove::castle( + king_sq as u8, + (king_sq + 2) as u8 + )); + } + + } } \ No newline at end of file From 33ca535547244128714321dec217e372ea0ad350 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Thu, 20 Nov 2025 20:21:28 +0100 Subject: [PATCH 25/49] added LUT ROOK_MOVE_MASK in bitboard::attackmaps for king safety checks --- engine/src/bitboard/attackmaps.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/engine/src/bitboard/attackmaps.rs b/engine/src/bitboard/attackmaps.rs index f7fe35f..51b150c 100644 --- a/engine/src/bitboard/attackmaps.rs +++ b/engine/src/bitboard/attackmaps.rs @@ -94,6 +94,17 @@ pub static RAY_TABLE: Lazy<[[u64; 8]; 64]> = Lazy::new(|| { return table; }); +pub static ROOK_MOVE_MASK: Lazy<[u64; 64]> = Lazy::new(|| { + let mut table = [0u64; 64]; + + for sq in 0..64 { + for dir in [0, 2, 4, 6] { + table[sq] |= RAY_TABLE[sq][dir]; + } + } + table +}); + // <----- TESTS -----> From 71ea2a05d0185c15fa6f0ed3c48a9920967cac0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Thu, 20 Nov 2025 20:22:08 +0100 Subject: [PATCH 26/49] added LUT BISHOP_MOVE_MASK in bitboard::attackmaps for king safety checks --- engine/src/bitboard/attackmaps.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/engine/src/bitboard/attackmaps.rs b/engine/src/bitboard/attackmaps.rs index 51b150c..f581113 100644 --- a/engine/src/bitboard/attackmaps.rs +++ b/engine/src/bitboard/attackmaps.rs @@ -105,6 +105,17 @@ pub static ROOK_MOVE_MASK: Lazy<[u64; 64]> = Lazy::new(|| { table }); +pub static BISHOP_MOVE_MASK: Lazy<[u64; 64]> = Lazy::new(|| { + let mut table = [0u64; 64]; + + for sq in 0..64 { + for dir in [1, 3, 5, 7] { + table[sq] |= RAY_TABLE[sq][dir]; + } + } + table +}); + // <----- TESTS -----> From d8eae9177b79153f01dbec6d66224dd82d7462aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Thu, 20 Nov 2025 20:23:40 +0100 Subject: [PATCH 27/49] added LUT KING_SAFETY_ROOK_MASK in bitboard::attackmaps for king safety checks --- engine/src/bitboard/attackmaps.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/engine/src/bitboard/attackmaps.rs b/engine/src/bitboard/attackmaps.rs index f581113..016719d 100644 --- a/engine/src/bitboard/attackmaps.rs +++ b/engine/src/bitboard/attackmaps.rs @@ -94,6 +94,7 @@ pub static RAY_TABLE: Lazy<[[u64; 8]; 64]> = Lazy::new(|| { return table; }); +// ROOK_MOVE_MASK[] pub static ROOK_MOVE_MASK: Lazy<[u64; 64]> = Lazy::new(|| { let mut table = [0u64; 64]; @@ -105,6 +106,7 @@ pub static ROOK_MOVE_MASK: Lazy<[u64; 64]> = Lazy::new(|| { table }); +// BISHOP_MOVE_MASK[] pub static BISHOP_MOVE_MASK: Lazy<[u64; 64]> = Lazy::new(|| { let mut table = [0u64; 64]; @@ -116,6 +118,22 @@ pub static BISHOP_MOVE_MASK: Lazy<[u64; 64]> = Lazy::new(|| { table }); +pub static KING_SAFETY_ROOK_MASK: Lazy<[u64; 64]> = Lazy::new(|| { + let mut table = [0u64; 64]; + + for sq in 0..64 { + let mut mask = KING_ATTACK_MAP[sq]; + + while mask != 0 { + let next_sq = mask.trailing_zeros(); + table[sq] |= ROOK_MOVE_MASK[next_sq as usize]; + mask &= !(1 << next_sq); + } + } + + table +}); + // <----- TESTS -----> From 8c0fa09f1ea755f33eded79cfe4f919895627490 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Thu, 20 Nov 2025 20:25:14 +0100 Subject: [PATCH 28/49] added LUT KING_SAFETY_BISHOP_MASK in bitboard::attackmaps for king safety checks --- engine/src/bitboard/attackmaps.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/engine/src/bitboard/attackmaps.rs b/engine/src/bitboard/attackmaps.rs index 016719d..b99a4db 100644 --- a/engine/src/bitboard/attackmaps.rs +++ b/engine/src/bitboard/attackmaps.rs @@ -118,6 +118,7 @@ pub static BISHOP_MOVE_MASK: Lazy<[u64; 64]> = Lazy::new(|| { table }); +// KING_SAFETY_ROOK_MASK[] pub static KING_SAFETY_ROOK_MASK: Lazy<[u64; 64]> = Lazy::new(|| { let mut table = [0u64; 64]; @@ -134,6 +135,23 @@ pub static KING_SAFETY_ROOK_MASK: Lazy<[u64; 64]> = Lazy::new(|| { table }); +// KING_SAFETY_BISHOP_MASK[] +pub static KING_SAFETY_BISHOP_MASK: Lazy<[u64; 64]> = Lazy::new(|| { + let mut table = [0u64; 64]; + + for sq in 0..64 { + let mut mask = KING_ATTACK_MAP[sq]; + + while mask != 0 { + let next_sq = mask.trailing_zeros(); + table[sq] |= BISHOP_MOVE_MASK[next_sq as usize]; + mask &= !(1 << next_sq); + } + } + + table +}); + // <----- TESTS -----> From 1bbe33f3aa50ebd50f45a521645a19d294e2c00a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Thu, 20 Nov 2025 20:28:16 +0100 Subject: [PATCH 29/49] added method get_pseudo_bishop_moves_ignore_king in bitboard::attacks for king safety checks --- engine/src/bitboard/attacks.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/engine/src/bitboard/attacks.rs b/engine/src/bitboard/attacks.rs index 27c54e0..cd547d4 100644 --- a/engine/src/bitboard/attacks.rs +++ b/engine/src/bitboard/attacks.rs @@ -72,6 +72,21 @@ impl Board { return self.get_pseudo_bishop_moves(sq) | self.get_pseudo_rook_moves(sq); } + #[inline] + pub fn get_pseudo_bishop_moves_ignore_king(&self, sq: u32) -> u64 { + let mut moves = 0u64; + let sq = sq as usize; + let king = self.bitboards[5 + 6*self.side_to_move as usize]; + let occupancy = self.occupancy[2] & !king; + moves |= get_raycast_from_square_in_direction(occupancy, sq, 1); + moves |= get_raycast_from_square_in_direction(occupancy, sq, 3); + moves |= get_raycast_from_square_in_direction(occupancy, sq, 5); + moves |= get_raycast_from_square_in_direction(occupancy, sq, 7); + + return moves; + } + + #[inline] pub fn is_square_attacked(&self, king_sq: u32) -> bool { let offset: usize = 6 * self.side_to_move as usize; From 47a22dbbaa3d5d21005718702fcd0d6d0331d78a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Thu, 20 Nov 2025 20:29:27 +0100 Subject: [PATCH 30/49] added method get_pseudo_rook_moves_ignore_king in bitboard::attacks for king safety checks --- engine/src/bitboard/attacks.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/engine/src/bitboard/attacks.rs b/engine/src/bitboard/attacks.rs index cd547d4..2e1e655 100644 --- a/engine/src/bitboard/attacks.rs +++ b/engine/src/bitboard/attacks.rs @@ -85,7 +85,19 @@ impl Board { return moves; } + #[inline] + pub fn get_pseudo_rook_moves_ignore_king(&self, sq: u32) -> u64 { + let mut moves: u64 = 0u64; + let sq = sq as usize; + let king = self.bitboards[5 + 6*self.side_to_move as usize]; + let occupancy = self.occupancy[2] & !king; + moves |= get_raycast_from_square_in_direction(occupancy, sq, 0); + moves |= get_raycast_from_square_in_direction(occupancy, sq, 2); + moves |= get_raycast_from_square_in_direction(occupancy, sq, 4); + moves |= get_raycast_from_square_in_direction(occupancy, sq, 6); + return moves; + } #[inline] pub fn is_square_attacked(&self, king_sq: u32) -> bool { From dba7aca2cfada34d44a8cf9f7fce6390df347dc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Thu, 20 Nov 2025 20:35:44 +0100 Subject: [PATCH 31/49] added method get_safe_king_squares to bitboard::attacks for king safety checks --- engine/src/bitboard/attacks.rs | 55 ++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/engine/src/bitboard/attacks.rs b/engine/src/bitboard/attacks.rs index 2e1e655..63b0c32 100644 --- a/engine/src/bitboard/attacks.rs +++ b/engine/src/bitboard/attacks.rs @@ -5,6 +5,8 @@ impl Board { const RANK_2: u64 = 0x0000_0000_0000_FF00; const RANK_7: u64 = 0x00FF_0000_0000_0000; + const A_FILE: u64 = 0x0101_0101_0101_0101; + const H_FILE: u64 = 0x8080_8080_8080_8080; pub fn get_pseudo_pawn_moves(&self, sq: u32) -> u64 { let pawn: u64 = 1 << sq; @@ -123,6 +125,59 @@ impl Board { attacker_mask = self.bitboards[6 - offset]; return threat_mask & attacker_mask != 0; } + pub fn get_safe_king_squares(&self) -> u64 { + let offset: usize = 6 * (1 - self.side_to_move as usize); + let king_sq = self.bitboards[11 - offset].trailing_zeros() as usize; + let bishop_mask = KING_SAFETY_BISHOP_MASK[king_sq]; + let rook_mask = KING_SAFETY_ROOK_MASK[king_sq]; + let mut attack_map: u64 = 0u64; + + let mut board: u64 = self.bitboards[offset]; + if self.side_to_move() == 0 { + attack_map |= (board >> 9 & !Self::H_FILE) | (board >> 7 & !Self::A_FILE); + } + else { + attack_map |= (board << 9 & !Self::A_FILE) | (board << 7 & !Self::H_FILE); + } + + board = self.bitboards[offset + 1]; + while board != 0 { + let piece_sq: u32 = board.trailing_zeros(); + board &= !(1 << piece_sq); + + attack_map |= self.get_pseudo_knight_moves(piece_sq); + } + + board = self.bitboards[offset + 2] & bishop_mask; + while board != 0 { + let piece_sq: u32 = board.trailing_zeros(); + board &= !(1 << piece_sq); + + attack_map |= self.get_pseudo_bishop_moves_ignore_king(piece_sq); + } + + board = self.bitboards[offset + 3] & rook_mask; + while board != 0 { + let piece_sq: u32 = board.trailing_zeros(); + board &= !(1 << piece_sq); + + attack_map |= self.get_pseudo_rook_moves_ignore_king(piece_sq); + } + + board = self.bitboards[offset + 4] & (bishop_mask | rook_mask); + while board != 0 { + let piece_sq: u32 = board.trailing_zeros(); + board &= !(1 << piece_sq); + + attack_map |= self.get_pseudo_rook_moves_ignore_king(piece_sq) | self.get_pseudo_bishop_moves_ignore_king(piece_sq); + } + + board = self.bitboards[offset + 5]; + let piece_sq: u32 = board.trailing_zeros(); + attack_map |= self.get_pseudo_king_moves(piece_sq); + + return !attack_map; + } } #[inline(always)] From 9b43c9ce9a9db5756a5d4b432d43d8bf6b36c1c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Thu, 20 Nov 2025 20:39:47 +0100 Subject: [PATCH 32/49] implemented method collect_all_moves in bitboard::movegen used in move generation --- engine/src/bitboard/movegen.rs | 19 ++++++++++++++++++- engine/src/bitboard/movegen/bishops.rs | 4 ++-- engine/src/bitboard/movegen/kings.rs | 6 +++--- engine/src/bitboard/movegen/knights.rs | 4 ++-- engine/src/bitboard/movegen/pawns.rs | 6 +++--- engine/src/bitboard/movegen/queens.rs | 4 ++-- engine/src/bitboard/movegen/rooks.rs | 4 ++-- 7 files changed, 32 insertions(+), 15 deletions(-) diff --git a/engine/src/bitboard/movegen.rs b/engine/src/bitboard/movegen.rs index 8f5a34a..76bc395 100644 --- a/engine/src/bitboard/movegen.rs +++ b/engine/src/bitboard/movegen.rs @@ -12,17 +12,34 @@ use super::utils::*; impl Board { + const NO_FILTER: u64 = 0xFFFF_FFFF_FFFF_FFFF; + pub fn collect_moves(&mut self, buffer: &mut MoveBuffer, temp_buffer: &mut MoveBuffer) -> bool { buffer.clear(); self.calc_pinned_squares(); let check_info = self.check_test(); match check_info.check_count { - // 0 => self.collect_all_moves(), + 0 => self.collect_all_moves(buffer, temp_buffer), // 1 => self.collect_moves_single_check(), // 2 => self.collect_king_evasion(), _ => panic!("More than 2 checking pieces found as the same time!") } return check_info.check_count > 0; } + + pub(in super) fn collect_all_moves(&self, buffer: &mut MoveBuffer, temp_buffer: &mut MoveBuffer) { + let safe_squares = self.get_safe_king_squares(); + + self.add_pawn_moves(buffer, temp_buffer, Self::NO_FILTER); + self.add_knight_moves(buffer, temp_buffer, Self::NO_FILTER); + self.add_bishop_moves(buffer, temp_buffer, Self::NO_FILTER); + self.add_rook_moves(buffer, temp_buffer, Self::NO_FILTER); + self.add_queen_moves(buffer, temp_buffer, Self::NO_FILTER); + self.add_king_moves(buffer, temp_buffer, safe_squares); + self.add_king_castles(buffer, safe_squares); + + buffer.append(temp_buffer); + temp_buffer.clear(); + } } \ No newline at end of file diff --git a/engine/src/bitboard/movegen/bishops.rs b/engine/src/bitboard/movegen/bishops.rs index 00f681b..3d41916 100644 --- a/engine/src/bitboard/movegen/bishops.rs +++ b/engine/src/bitboard/movegen/bishops.rs @@ -2,7 +2,7 @@ use super::*; impl Board { - fn add_bishop_moves(&self, capture_buffer: &mut MoveBuffer, quiet_buffer: &mut MoveBuffer, move_mask: u64) { + pub fn add_bishop_moves(&self, capture_buffer: &mut MoveBuffer, quiet_buffer: &mut MoveBuffer, move_mask: u64) { let piece_index = 2 + self.side_to_move * 6; let mut bishops = self.bitboards[piece_index as usize]; let empty = !self.occupancy[2]; @@ -33,7 +33,7 @@ impl Board { } } } - fn add_bishop_captures(&self, buffer: &mut MoveBuffer, move_mask: u64) { + pub fn add_bishop_captures(&self, buffer: &mut MoveBuffer, move_mask: u64) { let offset = 6 * self.side_to_move as usize; let mut bishops: u64 = self.bitboards[2 + offset]; let opponents = self.occupancy[1 - self.side_to_move as usize]; diff --git a/engine/src/bitboard/movegen/kings.rs b/engine/src/bitboard/movegen/kings.rs index 18315e4..60e7daf 100644 --- a/engine/src/bitboard/movegen/kings.rs +++ b/engine/src/bitboard/movegen/kings.rs @@ -2,7 +2,7 @@ use super::*; impl Board { - fn add_king_moves(&self, capture_buffer: &mut MoveBuffer, quiet_buffer: &mut MoveBuffer, move_mask: u64) { + pub fn add_king_moves(&self, capture_buffer: &mut MoveBuffer, quiet_buffer: &mut MoveBuffer, move_mask: u64) { let piece_index = 5 + self.side_to_move * 6; let mut kings = self.bitboards[piece_index as usize]; let empty = !self.occupancy[2]; @@ -32,7 +32,7 @@ impl Board { } } } - fn add_king_captures(&self, buffer: &mut MoveBuffer, move_mask: u64) { + pub fn add_king_captures(&self, buffer: &mut MoveBuffer, move_mask: u64) { let offset = 6 * self.side_to_move as usize; let mut kings: u64 = self.bitboards[5 + offset]; let opponents = self.occupancy[1 - self.side_to_move as usize]; @@ -51,7 +51,7 @@ impl Board { } } } - fn add_king_castles(&self, buffer: &mut MoveBuffer, move_mask: u64) { + pub fn add_king_castles(&self, buffer: &mut MoveBuffer, move_mask: u64) { if self.castling_rights & (0b11 << (2 - 2 * self.side_to_move)) == 0 { return; } diff --git a/engine/src/bitboard/movegen/knights.rs b/engine/src/bitboard/movegen/knights.rs index db4a105..4c0efce 100644 --- a/engine/src/bitboard/movegen/knights.rs +++ b/engine/src/bitboard/movegen/knights.rs @@ -2,7 +2,7 @@ use super::*; impl Board { - fn add_knight_moves(&self, capture_buffer: &mut MoveBuffer, quiet_buffer: &mut MoveBuffer, move_mask: u64) { + pub fn add_knight_moves(&self, capture_buffer: &mut MoveBuffer, quiet_buffer: &mut MoveBuffer, move_mask: u64) { let piece_index = 1 + self.side_to_move * 6; let mut knights = self.bitboards[piece_index as usize]; let empty = !self.occupancy[2]; @@ -33,7 +33,7 @@ impl Board { } } } - fn add_knight_captures(&self, buffer: &mut MoveBuffer, move_mask: u64) { + pub fn add_knight_captures(&self, buffer: &mut MoveBuffer, move_mask: u64) { let offset = 6 * self.side_to_move as usize; let mut knights: u64 = self.bitboards[1 + offset]; let opponents = self.occupancy[1 - self.side_to_move as usize]; diff --git a/engine/src/bitboard/movegen/pawns.rs b/engine/src/bitboard/movegen/pawns.rs index 6e9e1dc..9fc7571 100644 --- a/engine/src/bitboard/movegen/pawns.rs +++ b/engine/src/bitboard/movegen/pawns.rs @@ -2,7 +2,7 @@ use super::*; impl Board { - fn add_pawn_quiets(&self, buffer: &mut MoveBuffer, move_mask: u64) { + pub fn add_pawn_quiets(&self, buffer: &mut MoveBuffer, move_mask: u64) { let offset: u8 = self.side_to_move * 6; let mut pawns: u64 = self.bitboards[offset as usize]; while pawns != 0 { @@ -34,7 +34,7 @@ impl Board { } } } - fn add_pawn_captures(&self, buffer: &mut MoveBuffer, move_mask: u64) { + pub fn add_pawn_captures(&self, buffer: &mut MoveBuffer, move_mask: u64) { let offset = 6 * self.side_to_move as usize; let mut pawns: u64 = self.bitboards[offset]; let opponents = self.occupancy[1 - self.side_to_move as usize]; @@ -69,7 +69,7 @@ impl Board { } } } - fn add_pawn_moves(&self, capture_buffer: &mut MoveBuffer, quiet_buffer: &mut MoveBuffer, move_mask: u64) { + pub fn add_pawn_moves(&self, capture_buffer: &mut MoveBuffer, quiet_buffer: &mut MoveBuffer, move_mask: u64) { self.add_pawn_captures(capture_buffer, move_mask); self.add_pawn_quiets(quiet_buffer, move_mask); } diff --git a/engine/src/bitboard/movegen/queens.rs b/engine/src/bitboard/movegen/queens.rs index 6fdf4bd..960f49a 100644 --- a/engine/src/bitboard/movegen/queens.rs +++ b/engine/src/bitboard/movegen/queens.rs @@ -2,7 +2,7 @@ use super::*; impl Board { - fn add_queen_moves(&self, capture_buffer: &mut MoveBuffer, quiet_buffer: &mut MoveBuffer, move_mask: u64) { + pub fn add_queen_moves(&self, capture_buffer: &mut MoveBuffer, quiet_buffer: &mut MoveBuffer, move_mask: u64) { let piece_index = 4 + self.side_to_move * 6; let mut queens = self.bitboards[piece_index as usize]; let empty = !self.occupancy[2]; @@ -33,7 +33,7 @@ impl Board { } } } - fn add_queen_captures(&self, buffer: &mut MoveBuffer, move_mask: u64) { + pub fn add_queen_captures(&self, buffer: &mut MoveBuffer, move_mask: u64) { let offset = 6 * self.side_to_move as usize; let mut queens: u64 = self.bitboards[4 + offset]; let opponents = self.occupancy[1 - self.side_to_move as usize]; diff --git a/engine/src/bitboard/movegen/rooks.rs b/engine/src/bitboard/movegen/rooks.rs index b908911..749e2d8 100644 --- a/engine/src/bitboard/movegen/rooks.rs +++ b/engine/src/bitboard/movegen/rooks.rs @@ -2,7 +2,7 @@ use super::*; impl Board { - fn add_rook_moves(&self, capture_buffer: &mut MoveBuffer, quiet_buffer: &mut MoveBuffer, move_mask: u64) { + pub fn add_rook_moves(&self, capture_buffer: &mut MoveBuffer, quiet_buffer: &mut MoveBuffer, move_mask: u64) { let piece_index = 3 + self.side_to_move * 6; let mut rooks = self.bitboards[piece_index as usize]; let empty = !self.occupancy[2]; @@ -33,7 +33,7 @@ impl Board { } } } - fn add_rook_captures(&self, buffer: &mut MoveBuffer, move_mask: u64) { + pub fn add_rook_captures(&self, buffer: &mut MoveBuffer, move_mask: u64) { let offset = 6 * self.side_to_move as usize; let mut rooks: u64 = self.bitboards[3 + offset]; let opponents = self.occupancy[1 - self.side_to_move as usize]; From fad1a6d51b4644b6a58d7ca02b2ec9adbb5ddf60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Thu, 20 Nov 2025 20:42:44 +0100 Subject: [PATCH 33/49] implemented method collect_moves_single_check in bitboard::movegen used in move generation --- engine/src/bitboard/movegen.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/engine/src/bitboard/movegen.rs b/engine/src/bitboard/movegen.rs index 76bc395..5e5ca3c 100644 --- a/engine/src/bitboard/movegen.rs +++ b/engine/src/bitboard/movegen.rs @@ -8,6 +8,7 @@ mod kings; use super::board::Board; use super::movebuffer::MoveBuffer; use super::bitmove::BitMove; +use super::checkinfo::CheckInfo; use super::utils::*; impl Board { @@ -39,6 +40,19 @@ impl Board { self.add_king_moves(buffer, temp_buffer, safe_squares); self.add_king_castles(buffer, safe_squares); + buffer.append(temp_buffer); + temp_buffer.clear(); + } + pub(in super) fn collect_moves_single_check(&self, buffer: &mut MoveBuffer, temp_buffer: &mut MoveBuffer, check_info: &CheckInfo) { + let safe_squares = self.get_safe_king_squares(); + + self.add_pawn_moves(buffer, temp_buffer, check_info.move_mask); + self.add_knight_moves(buffer, temp_buffer, check_info.move_mask); + self.add_bishop_moves(buffer, temp_buffer, check_info.move_mask); + self.add_rook_moves(buffer, temp_buffer, check_info.move_mask); + self.add_queen_moves(buffer, temp_buffer, check_info.move_mask); + self.add_king_moves(buffer, temp_buffer, safe_squares); + buffer.append(temp_buffer); temp_buffer.clear(); } From f3d316d3e3b43794e48c9a0259c2d258206f0276 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Thu, 20 Nov 2025 20:43:35 +0100 Subject: [PATCH 34/49] implemented method collect_king_evasion in bitboard::movegen used in move generation --- engine/src/bitboard/movegen.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/engine/src/bitboard/movegen.rs b/engine/src/bitboard/movegen.rs index 5e5ca3c..2e5e6a7 100644 --- a/engine/src/bitboard/movegen.rs +++ b/engine/src/bitboard/movegen.rs @@ -56,4 +56,12 @@ impl Board { buffer.append(temp_buffer); temp_buffer.clear(); } + pub(in super) fn collect_king_evasion(&self, buffer: &mut MoveBuffer, temp_buffer: &mut MoveBuffer) { + let safe_squares = self.get_safe_king_squares(); + + self.add_king_moves(buffer, temp_buffer, safe_squares); + + buffer.append(&temp_buffer); + temp_buffer.clear(); + } } \ No newline at end of file From 84121fbeba83228511f828d01ca7af188efae527 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Thu, 20 Nov 2025 20:45:26 +0100 Subject: [PATCH 35/49] allowed use of move generation methods in case of check --- engine/src/bitboard/movegen.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/engine/src/bitboard/movegen.rs b/engine/src/bitboard/movegen.rs index 2e5e6a7..b702f4a 100644 --- a/engine/src/bitboard/movegen.rs +++ b/engine/src/bitboard/movegen.rs @@ -22,8 +22,8 @@ impl Board { match check_info.check_count { 0 => self.collect_all_moves(buffer, temp_buffer), - // 1 => self.collect_moves_single_check(), - // 2 => self.collect_king_evasion(), + 1 => self.collect_moves_single_check(buffer, temp_buffer, &check_info), + 2 => self.collect_king_evasion(buffer, temp_buffer), _ => panic!("More than 2 checking pieces found as the same time!") } return check_info.check_count > 0; From 775083fde7ef482efcae5b5703088e517aaf1f3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Thu, 20 Nov 2025 21:11:41 +0100 Subject: [PATCH 36/49] fixed wrong promotion_piece indexes being saved in bitboard::movegen::pawns --- engine/src/bitboard/movegen/pawns.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/engine/src/bitboard/movegen/pawns.rs b/engine/src/bitboard/movegen/pawns.rs index 9fc7571..444b387 100644 --- a/engine/src/bitboard/movegen/pawns.rs +++ b/engine/src/bitboard/movegen/pawns.rs @@ -15,7 +15,7 @@ impl Board { if (self.side_to_move == 0 && quiets.trailing_zeros() / 8 == 7) || (self.side_to_move == 1 && quiets.trailing_zeros() / 8 == 0) { - for piece_type in [3, 2, 1, 0] { + for piece_type in [4, 3, 2, 1] { buffer.add(BitMove::quiet( next_sq as u8, to_sq as u8, @@ -50,7 +50,7 @@ impl Board { if (self.side_to_move == 0 && attacks.trailing_zeros() / 8 == 7) || (self.side_to_move == 1 && attacks.trailing_zeros() / 8 == 0) { - for piece_type in [3, 2, 1, 0] { + for piece_type in [4, 3, 2, 1] { buffer.add(BitMove::capture( next_sq as u8, to_sq as u8, From 82a6bd8449ca616ebe05904c81123f3c3805ab87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Fri, 21 Nov 2025 12:40:24 +0100 Subject: [PATCH 37/49] implemented constructor for enum MoveType from in-engine move_type index --- engine/src/movetype.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/engine/src/movetype.rs b/engine/src/movetype.rs index 3c531dd..d024084 100644 --- a/engine/src/movetype.rs +++ b/engine/src/movetype.rs @@ -9,3 +9,14 @@ pub enum MoveType { EnPassant, } +impl MoveType { + pub fn from_index(idx: u8) -> Self { + return match idx { + 0 => Self::Quiet, + 1 => Self::Capture, + 2 => Self::Castle, + 3 => Self::EnPassant, + _ => panic!("invalid move_type index! should NEVER appear") + } + } +} \ No newline at end of file From 5e65bcf5ef4e83bfe76202474a17e183dba708d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Fri, 21 Nov 2025 12:55:18 +0100 Subject: [PATCH 38/49] changed method from_index for enum MoveType to from_bitmovetype --- engine/src/bitboard.rs | 4 ++-- engine/src/movetype.rs | 13 +++++++------ 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/engine/src/bitboard.rs b/engine/src/bitboard.rs index 177e4a5..9779d93 100644 --- a/engine/src/bitboard.rs +++ b/engine/src/bitboard.rs @@ -3,8 +3,8 @@ mod utils; mod legality; mod checkinfo; mod attacks; -mod bitmove; mod movebuffer; mod movegen; -pub mod board; \ No newline at end of file +pub mod board; +pub(in super) mod bitmove; \ No newline at end of file diff --git a/engine/src/movetype.rs b/engine/src/movetype.rs index d024084..d332780 100644 --- a/engine/src/movetype.rs +++ b/engine/src/movetype.rs @@ -1,5 +1,6 @@ use serde::Deserialize; use serde::Serialize; +use super::bitboard::bitmove::BitMoveType; #[derive(Serialize, Deserialize)] pub enum MoveType { @@ -10,12 +11,12 @@ pub enum MoveType { } impl MoveType { - pub fn from_index(idx: u8) -> Self { - return match idx { - 0 => Self::Quiet, - 1 => Self::Capture, - 2 => Self::Castle, - 3 => Self::EnPassant, + pub fn from_bitmovetype(move_type: BitMoveType) -> Self { + return match move_type { + BitMoveType::Quiet => Self::Quiet, + BitMoveType::Capture => Self::Capture, + BitMoveType::Castle => Self::Castle, + BitMoveType::EnPassant => Self::EnPassant, _ => panic!("invalid move_type index! should NEVER appear") } } From d649afdcfdbb086ce1fa6fe88aae93764d59d796 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Fri, 21 Nov 2025 12:57:38 +0100 Subject: [PATCH 39/49] limited visibility of method from_bitmovetype from enum MoveType to pub(in super) --- engine/src/movetype.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engine/src/movetype.rs b/engine/src/movetype.rs index d332780..e9740ae 100644 --- a/engine/src/movetype.rs +++ b/engine/src/movetype.rs @@ -11,7 +11,7 @@ pub enum MoveType { } impl MoveType { - pub fn from_bitmovetype(move_type: BitMoveType) -> Self { + pub(in super) fn from_bitmovetype(move_type: BitMoveType) -> Self { return match move_type { BitMoveType::Quiet => Self::Quiet, BitMoveType::Capture => Self::Capture, From b137e6ceab0bcfa6dcb65f09a5acf4f4f47962b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Fri, 21 Nov 2025 13:01:38 +0100 Subject: [PATCH 40/49] implemented constructor by piece_index for enum PieceType --- engine/src/piecetype.rs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/engine/src/piecetype.rs b/engine/src/piecetype.rs index b79d341..550fac0 100644 --- a/engine/src/piecetype.rs +++ b/engine/src/piecetype.rs @@ -16,3 +16,23 @@ pub enum PieceType { BlackKing, } +impl PieceType { + + pub(in super) fn from_index(idx: u8) -> Self { + return match idx { + 0 => PieceType::WhitePawn, + 1 => PieceType::WhiteKnight, + 2 => PieceType::WhiteBishop, + 3 => PieceType::WhiteRook, + 4 => PieceType::WhiteQueen, + 5 => PieceType::WhiteKing, + 6 => PieceType::BlackPawn, + 7 => PieceType::BlackKnight, + 8 => PieceType::BlackBishop, + 9 => PieceType::BlackRook, + 10 => PieceType::BlackQueen, + 11 => PieceType::BlackKing, + _ => panic!("invalid piece index! should NEVER appear") + } + } +} \ No newline at end of file From 5d108602eacae816e75fe4016710688fde80a95c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Fri, 21 Nov 2025 13:08:53 +0100 Subject: [PATCH 41/49] implemented constructor by square_index for struct BoardSquare --- engine/src/boardsquare.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/engine/src/boardsquare.rs b/engine/src/boardsquare.rs index 2587406..dbfb5fa 100644 --- a/engine/src/boardsquare.rs +++ b/engine/src/boardsquare.rs @@ -27,5 +27,19 @@ impl BoardSquare { } return Self { x: x, y: y }; } + + pub(in super) fn from_index(idx: u8) -> Self { + let file = idx % 8; + let rank = idx / 8; + + #[cfg(debug_assertions)] + { + if !(0..8).contains(&rank) { + println!("Warning: internal engine issue, given index is not on the board!"); + } + } + + return Self {x: file as usize, y: rank as usize}; + } } From 821746d7cfa58f4c5056c6c662378f87c310ed2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Fri, 21 Nov 2025 13:29:01 +0100 Subject: [PATCH 42/49] changed implementation of ChessMove from struct to enum --- engine/src/chessmove.rs | 84 ++++++++++++++++++++++++++--------------- 1 file changed, 54 insertions(+), 30 deletions(-) diff --git a/engine/src/chessmove.rs b/engine/src/chessmove.rs index ae46a6a..e38ad7f 100644 --- a/engine/src/chessmove.rs +++ b/engine/src/chessmove.rs @@ -1,12 +1,10 @@ -use crate::piecetype; - use super::boardsquare::BoardSquare; use super::movetype::MoveType; use super::piecetype::PieceType; use serde::{Deserialize, Serialize}; #[derive(Serialize, Deserialize)] -pub struct ChessMove { +/*pub struct ChessMove { pub move_type: MoveType, pub piece_type: PieceType, pub from_square: BoardSquare, @@ -14,6 +12,36 @@ pub struct ChessMove { pub rook_from: BoardSquare, pub rook_to: BoardSquare, pub promotion_piece: Option, +}*/ +pub enum ChessMove { + Quiet { + piece_type: PieceType, + from_square: BoardSquare, + to_square: BoardSquare, + promotion_piece: Option + }, + Capture { + piece_type: PieceType, + from_square: BoardSquare, + to_square: BoardSquare, + captured_piece: PieceType, + promotion_piece: Option + }, + Castle { + king_type: PieceType, + king_from: BoardSquare, + king_to: BoardSquare, + rook_type: PieceType, + rook_from: BoardSquare, + rook_to: BoardSquare + }, + EnPassant { + pawn_type: PieceType, + from_square: BoardSquare, + to_square: BoardSquare, + captured_piece: PieceType, + captured_from: BoardSquare + } } impl ChessMove { @@ -23,14 +51,11 @@ impl ChessMove { to_square: BoardSquare, promotion_piece: Option, ) -> Self { - return Self { - move_type: MoveType::Quiet, - piece_type: piece_type, - from_square: from_square, - to_square: to_square, - rook_from: BoardSquare::new(), - rook_to: BoardSquare::new(), - promotion_piece: promotion_piece, + return Self::Quiet { + piece_type, + from_square, + to_square, + promotion_piece }; } @@ -38,34 +63,33 @@ impl ChessMove { piece_type: PieceType, from_square: BoardSquare, to_square: BoardSquare, + captured_piece: PieceType, promotion_piece: Option, ) -> Self { - return Self { - move_type: MoveType::Capture, - piece_type: piece_type, - from_square: from_square, - to_square: to_square, - rook_from: BoardSquare::new(), - rook_to: BoardSquare::new(), - promotion_piece: promotion_piece, + return Self::Capture { + piece_type, + from_square, + to_square, + captured_piece, + promotion_piece }; } pub fn castle( - piece_type: PieceType, - from_square: BoardSquare, - to_square: BoardSquare, + king_type: PieceType, + king_from: BoardSquare, + king_to: BoardSquare, + rook_type: PieceType, rook_from: BoardSquare, rook_to: BoardSquare, ) -> Self { - return Self { - move_type: MoveType::Quiet, - piece_type: piece_type, - from_square: from_square, - to_square: to_square, - rook_from: rook_from, - rook_to: rook_to, - promotion_piece: None, + return Self::Castle { + king_type, + king_from, + king_to, + rook_type, + rook_from, + rook_to }; } } From f841fba0805ab955e32b010683bde26ca002faf9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Fri, 21 Nov 2025 13:55:07 +0100 Subject: [PATCH 43/49] implemented constructor from_bitmove for enum ChessMove --- engine/src/chessmove.rs | 63 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 62 insertions(+), 1 deletion(-) diff --git a/engine/src/chessmove.rs b/engine/src/chessmove.rs index e38ad7f..aa5017e 100644 --- a/engine/src/chessmove.rs +++ b/engine/src/chessmove.rs @@ -1,5 +1,6 @@ +use crate::{bitboard::{bitmove::{BitMove, BitMoveType}, board::Board}, movetype::MoveType, piecetype}; + use super::boardsquare::BoardSquare; -use super::movetype::MoveType; use super::piecetype::PieceType; use serde::{Deserialize, Serialize}; @@ -92,4 +93,64 @@ impl ChessMove { rook_to }; } + + pub(in super) fn from_bitmove(bitmove: &BitMove, board: Board) -> Self { + match bitmove.move_type() { + BitMoveType::Quiet => { + let from_square_index = bitmove.from_square(); + let piece_type = PieceType::from_index(board.piece_board(from_square_index)); + let from_square = BoardSquare::from_index(from_square_index); + let to_square = BoardSquare::from_index(bitmove.to_square()); + let promotion_piece = match bitmove.promotion_piece() { + Some(piece) => Some(PieceType::from_index(piece)), + None => None + }; + + return ChessMove::Quiet { piece_type, from_square, to_square, promotion_piece } + }, + BitMoveType::Capture => { + let from_square_index = bitmove.from_square(); + let to_square_index = bitmove.to_square(); + let piece_type = PieceType::from_index(board.piece_board(from_square_index)); + let from_square = BoardSquare::from_index(from_square_index); + let to_square = BoardSquare::from_index(to_square_index); + let captured_piece = PieceType::from_index(board.piece_board(to_square_index)); + let promotion_piece = match bitmove.promotion_piece() { + Some(piece) => Some(PieceType::from_index(piece)), + None => None + }; + + return ChessMove::Capture { piece_type, from_square, to_square, captured_piece, promotion_piece } + }, + BitMoveType::Castle => { + let from_square_index = bitmove.from_square(); + let to_square_index = bitmove.to_square(); + let king_type = PieceType::from_index(board.piece_board(from_square_index)); + let king_from = BoardSquare::from_index(from_square_index); + let king_to = BoardSquare::from_index(to_square_index); + let promotion_piece = match bitmove.promotion_piece() { + Some(piece) => Some(PieceType::from_index(piece)), + None => None + }; + let rook_type = if bitmove.from_square() < 32 { PieceType::WhiteRook } else { PieceType::BlackRook }; + let rook_from_index = if bitmove.to_square() > bitmove.from_square() { + bitmove.from_square() + 3 + } else { + bitmove.from_square() - 4 + }; + let rook_from = BoardSquare::from_index(rook_from_index); + let rook_to_index = if bitmove.to_square() > bitmove.from_square() { + bitmove.from_square() + 1 + } else { + bitmove.from_square() - 1 + }; + let rook_to = BoardSquare::from_index(rook_to_index); + + return ChessMove::Castle { king_type, king_from, king_to, rook_type, rook_from, rook_to } + }, + BitMoveType::EnPassant => { + panic!("ChessMove::from_bitmove was left unimplemented"); + } + } + } } From e1d51fe29128cfbe9b6943dc2c5c1d0e48543b2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Fri, 21 Nov 2025 14:04:37 +0100 Subject: [PATCH 44/49] implemented conversion method to_bitmovetype for enum MoveType --- engine/src/movetype.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/engine/src/movetype.rs b/engine/src/movetype.rs index e9740ae..c7fa6d9 100644 --- a/engine/src/movetype.rs +++ b/engine/src/movetype.rs @@ -20,4 +20,12 @@ impl MoveType { _ => panic!("invalid move_type index! should NEVER appear") } } + pub(in super) fn to_bitmoveType(&self) -> BitMoveType { + return match self { + &MoveType::Quiet => BitMoveType::Quiet, + &MoveType::Capture => BitMoveType::Capture, + &MoveType::Castle => BitMoveType::Castle, + &MoveType::EnPassant => BitMoveType::EnPassant + }; + } } \ No newline at end of file From f29298731bb1438dd4332a5c745fe115688e05bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Fri, 21 Nov 2025 14:07:27 +0100 Subject: [PATCH 45/49] implemented conversion method to_index for enum PieceType --- engine/src/piecetype.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/engine/src/piecetype.rs b/engine/src/piecetype.rs index 550fac0..92a7e7b 100644 --- a/engine/src/piecetype.rs +++ b/engine/src/piecetype.rs @@ -35,4 +35,20 @@ impl PieceType { _ => panic!("invalid piece index! should NEVER appear") } } + pub(in super) fn to_index(&self) -> u8 { + return match self { + &PieceType::WhitePawn => 0, + &PieceType::WhiteKnight => 1, + &PieceType::WhiteBishop => 2, + &PieceType::WhiteRook => 3, + &PieceType::WhiteQueen => 4, + &PieceType::WhiteKing => 5, + &PieceType::BlackPawn => 6, + &PieceType::BlackKnight => 7, + &PieceType::BlackBishop => 8, + &PieceType::BlackRook => 9, + &PieceType::BlackQueen => 10, + &PieceType::BlackKing => 11 + } + } } \ No newline at end of file From c414485891b32a5d8b98856206d1dd027e05ae20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Fri, 21 Nov 2025 14:09:02 +0100 Subject: [PATCH 46/49] implemented conversion method to_index for struct BoardSquare --- engine/src/boardsquare.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/engine/src/boardsquare.rs b/engine/src/boardsquare.rs index dbfb5fa..2e0b57f 100644 --- a/engine/src/boardsquare.rs +++ b/engine/src/boardsquare.rs @@ -41,5 +41,8 @@ impl BoardSquare { return Self {x: file as usize, y: rank as usize}; } + pub(in super) fn to_index(&self) -> u8 { + return (8 * self.y + self.x) as u8; + } } From a4982c0fd310cde1b5df5619be7eedf16d1344b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Fri, 21 Nov 2025 14:18:23 +0100 Subject: [PATCH 47/49] implemented conversion method to_bitmove for enum ChessMove --- engine/src/chessmove.rs | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/engine/src/chessmove.rs b/engine/src/chessmove.rs index aa5017e..aa3d507 100644 --- a/engine/src/chessmove.rs +++ b/engine/src/chessmove.rs @@ -153,4 +153,40 @@ impl ChessMove { } } } + pub(in super) fn to_bitmove(&self) -> BitMove { + let bitmove = match self { + ChessMove::Quiet { piece_type, from_square, to_square, promotion_piece } => { + let promotion_piece = match promotion_piece { + Some(piece) => Some(piece.to_index()), + None => None + }; + return BitMove::quiet( + from_square.to_index(), + to_square.to_index(), + promotion_piece + ); + }, + ChessMove::Capture { piece_type, from_square, to_square, captured_piece, promotion_piece } => { + let promotion_piece = match promotion_piece { + Some(piece) => Some(piece.to_index()), + None => None + }; + return BitMove::capture( + from_square.to_index(), + to_square.to_index(), + promotion_piece + ); + }, + ChessMove::Castle { king_type, king_from, king_to, rook_type, rook_from, rook_to } => { + return BitMove::castle( + king_from.to_index(), + king_to.to_index() + ); + }, + ChessMove::EnPassant { pawn_type, from_square, to_square, captured_piece, captured_from } => { + panic!("ChessMove::to_bitmove was left unimplemented"); + } + }; + return bitmove; + } } From ebcc44709261ea313387966f02849f0ed315ec0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Varga=20D=C3=A1vid=20Lajos?= Date: Fri, 21 Nov 2025 14:19:33 +0100 Subject: [PATCH 48/49] removed unused imports from chessmove.rs --- engine/src/chessmove.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engine/src/chessmove.rs b/engine/src/chessmove.rs index aa3d507..4fa1319 100644 --- a/engine/src/chessmove.rs +++ b/engine/src/chessmove.rs @@ -1,4 +1,4 @@ -use crate::{bitboard::{bitmove::{BitMove, BitMoveType}, board::Board}, movetype::MoveType, piecetype}; +use crate::{bitboard::{bitmove::{BitMove, BitMoveType}, board::Board}}; use super::boardsquare::BoardSquare; use super::piecetype::PieceType; From 5ccca3ab8e4955258bed934b7932c13414650dea Mon Sep 17 00:00:00 2001 From: htom Date: Mon, 24 Nov 2025 13:14:38 +0100 Subject: [PATCH 49/49] added resign event and deleting finished matches --- server/Cargo.lock | 1080 +++++++++++++++++++++++++++++++++++++ server/src/connection.rs | 89 ++- server/src/matchmaking.rs | 6 +- 3 files changed, 1158 insertions(+), 17 deletions(-) create mode 100644 server/Cargo.lock diff --git a/server/Cargo.lock b/server/Cargo.lock new file mode 100644 index 0000000..d799894 --- /dev/null +++ b/server/Cargo.lock @@ -0,0 +1,1080 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "anyhow" +version = "1.0.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" + +[[package]] +name = "bitflags" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "bumpalo" +version = "3.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3" + +[[package]] +name = "cfg-if" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + +[[package]] +name = "crypto-common" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "data-encoding" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476" + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", +] + +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "engine" +version = "0.1.0" +dependencies = [ + "once_cell", + "serde", + "serde_json", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "form_urlencoded" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "futures-core" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" + +[[package]] +name = "futures-macro" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-sink" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" + +[[package]] +name = "futures-task" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" + +[[package]] +name = "futures-util" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +dependencies = [ + "futures-core", + "futures-macro", + "futures-sink", + "futures-task", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "getrandom" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasip2", +] + +[[package]] +name = "http" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "httparse" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" + +[[package]] +name = "icu_collections" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" +dependencies = [ + "displaydoc", + "potential_utf", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locale_core" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_normalizer" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599" +dependencies = [ + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" + +[[package]] +name = "icu_properties" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e93fcd3157766c0c8da2f8cff6ce651a31f0810eaa1c51ec363ef790bbb5fb99" +dependencies = [ + "icu_collections", + "icu_locale_core", + "icu_properties_data", + "icu_provider", + "zerotrie", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02845b3647bb045f1100ecd6480ff52f34c35f82d9880e029d329c21d1054899" + +[[package]] +name = "icu_provider" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614" +dependencies = [ + "displaydoc", + "icu_locale_core", + "writeable", + "yoke", + "zerofrom", + "zerotrie", + "zerovec", +] + +[[package]] +name = "idna" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + +[[package]] +name = "itoa" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" + +[[package]] +name = "js-sys" +version = "0.3.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b011eec8cc36da2aab2d5cff675ec18454fad408585853910a202391cf9f8e65" +dependencies = [ + "once_cell", + "wasm-bindgen", +] + +[[package]] +name = "libc" +version = "0.2.177" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976" + +[[package]] +name = "litemap" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" + +[[package]] +name = "lock_api" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" +dependencies = [ + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" + +[[package]] +name = "memchr" +version = "2.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" + +[[package]] +name = "mio" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69d83b0086dc8ecf3ce9ae2874b2d1290252e2a30720bea58a5c6639b0092873" +dependencies = [ + "libc", + "wasi", + "windows-sys 0.61.2", +] + +[[package]] +name = "once_cell" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + +[[package]] +name = "parking_lot" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-link", +] + +[[package]] +name = "percent-encoding" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" + +[[package]] +name = "pin-project-lite" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "potential_utf" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" +dependencies = [ + "zerovec", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "proc-macro2" +version = "1.0.103" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" +dependencies = [ + "rand_chacha 0.9.0", + "rand_core 0.9.3", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.3", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.16", +] + +[[package]] +name = "rand_core" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" +dependencies = [ + "getrandom 0.3.4", +] + +[[package]] +name = "redox_syscall" +version = "0.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" +dependencies = [ + "bitflags", +] + +[[package]] +name = "rustversion" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" + +[[package]] +name = "ryu" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.145" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", + "serde_core", +] + +[[package]] +name = "server" +version = "0.1.0" +dependencies = [ + "anyhow", + "engine", + "futures-util", + "rand 0.9.2", + "serde", + "serde_json", + "tokio", + "tokio-tungstenite", + "tungstenite", + "url", + "uuid", +] + +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7664a098b8e616bdfcc2dc0e9ac44eb231eedf41db4e9fe95d8d32ec728dedad" +dependencies = [ + "libc", +] + +[[package]] +name = "slab" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" + +[[package]] +name = "smallvec" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" + +[[package]] +name = "socket2" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881" +dependencies = [ + "libc", + "windows-sys 0.60.2", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" + +[[package]] +name = "syn" +version = "2.0.111" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "390cc9a294ab71bdb1aa2e99d13be9c753cd2d7bd6560c77118597410c4d2e87" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "synstructure" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tinystr" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869" +dependencies = [ + "displaydoc", + "zerovec", +] + +[[package]] +name = "tokio" +version = "1.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff360e02eab121e0bc37a2d3b4d4dc622e6eda3a8e5253d5435ecf5bd4c68408" +dependencies = [ + "bytes", + "libc", + "mio", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "windows-sys 0.61.2", +] + +[[package]] +name = "tokio-macros" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tokio-tungstenite" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c83b561d025642014097b66e6c1bb422783339e0909e4429cde4749d1990bc38" +dependencies = [ + "futures-util", + "log", + "tokio", + "tungstenite", +] + +[[package]] +name = "tungstenite" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ef1a641ea34f399a848dea702823bbecfb4c486f911735368f1f137cb8257e1" +dependencies = [ + "byteorder", + "bytes", + "data-encoding", + "http", + "httparse", + "log", + "rand 0.8.5", + "sha1", + "thiserror", + "url", + "utf-8", +] + +[[package]] +name = "typenum" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" + +[[package]] +name = "unicode-ident" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" + +[[package]] +name = "url" +version = "2.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08bc136a29a3d1758e07a9cca267be308aeebf5cfd5a10f3f67ab2097683ef5b" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", + "serde", +] + +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + +[[package]] +name = "uuid" +version = "1.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f87b8aa10b915a06587d0dec516c282ff295b475d94abf425d62b57710070a2" +dependencies = [ + "getrandom 0.3.4", + "js-sys", + "serde", + "wasm-bindgen", +] + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "wasip2" +version = "1.0.1+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" +dependencies = [ + "wit-bindgen", +] + +[[package]] +name = "wasm-bindgen" +version = "0.2.105" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da95793dfc411fbbd93f5be7715b0578ec61fe87cb1a42b12eb625caa5c5ea60" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.105" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04264334509e04a7bf8690f2384ef5265f05143a4bff3889ab7a3269adab59c2" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.105" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "420bc339d9f322e562942d52e115d57e950d12d88983a14c79b86859ee6c7ebc" +dependencies = [ + "bumpalo", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.105" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76f218a38c84bcb33c25ec7059b07847d465ce0e0a76b995e134a45adcb6af76" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-sys" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-targets" +version = "0.53.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" +dependencies = [ + "windows-link", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" + +[[package]] +name = "windows_i686_gnu" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" + +[[package]] +name = "windows_i686_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" + +[[package]] +name = "wit-bindgen" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" + +[[package]] +name = "writeable" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" + +[[package]] +name = "yoke" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954" +dependencies = [ + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "zerocopy" +version = "0.8.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43fa6694ed34d6e57407afbccdeecfa268c470a7d2a5b0cf49ce9fcc345afb90" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c640b22cd9817fae95be82f0d2f90b11f7605f6c319d16705c459b27ac2cbc26" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "zerofrom" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "zerotrie" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", +] + +[[package]] +name = "zerovec" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/server/src/connection.rs b/server/src/connection.rs index 6b7b9d7..2afd928 100644 --- a/server/src/connection.rs +++ b/server/src/connection.rs @@ -1,9 +1,11 @@ use crate::connection::ClientEvent::*; +use crate::matchmaking; use engine::chessmove::ChessMove; use engine::gameend::GameEnd::{self, *}; use engine::{get_available_moves, is_game_over}; use futures_util::{SinkExt, StreamExt}; use serde::{Deserialize, Serialize}; +use std::char::from_u32_unchecked; use std::collections::{HashMap, VecDeque}; use std::sync::Arc; use tokio::net::TcpStream; @@ -17,6 +19,10 @@ pub type ConnectionMap = Arc>>; pub type MatchMap = Arc>>; pub type WaitingQueue = Arc>>; +pub async fn clean_up_match(matches: &MatchMap, match_id: &Uuid) { + matches.lock().await.remove(&match_id); +} + // Helper functions to create new instances pub fn new_connection_map() -> ConnectionMap { Arc::new(Mutex::new(HashMap::new())) @@ -61,6 +67,9 @@ pub enum ServerMessage2 { color: String, opponent_name: String, }, + Ok { + response: Result<(), String>, + }, } #[derive(Serialize, Deserialize)] @@ -74,11 +83,6 @@ enum ClientEvent { RequestLegalMoves { fen: String }, } -#[derive(Serialize, Deserialize, Debug)] -pub struct EventResponse { - pub response: Result<(), String>, -} - #[derive(Debug)] pub struct PlayerConnection { pub id: Uuid, @@ -191,8 +195,6 @@ pub async fn handle_connection( let client_data: ClientEvent = serde_json::from_str(text) .expect("Failed to convert data into json at handle_connection"); - //println!("client: {:?}", client_data); - match client_data { Join { username } => { { @@ -202,11 +204,7 @@ pub async fn handle_connection( } //respone to client - let response: EventResponse = EventResponse { - response: core::result::Result::Ok(()), - }; - - println!("response: {:?}", response); + let response = ServerMessage2::Ok { response: Ok(()) }; let mut conn_map = connections.lock().await; let _ = send_message_to_player_connection( @@ -257,9 +255,11 @@ pub async fn handle_connection( .await; { - match engine::is_game_over( + let is_game_end = engine::is_game_over( &matches.lock().await.get(&match_id).unwrap().board_state, - ) { + ); + + match is_game_end { Some(res) => { let message = ServerMessage2::GameEnd { winner: res }; let _ = broadcast_to_match( @@ -269,6 +269,7 @@ pub async fn handle_connection( &serde_json::to_string(&message).unwrap(), ) .await; + clean_up_match(&matches, &match_id); } None => { println!("No winner match continues.") @@ -286,8 +287,64 @@ pub async fn handle_connection( println!("Sent moves to player: {}", player_id); } Resign => { - // TODO: set game over and turn on game end ui, then delete the match - println!("Resigned!"); + let (fuck, fuck_id): (ServerMessage2, &Uuid) = { + let matches = matches.lock().await; + + let curr_match = matches + .get( + &connections + .lock() + .await + .get(&player_id) + .unwrap() + .current_match + .unwrap(), + ) + .unwrap(); + + if player_id == curr_match.player_white { + ( + ServerMessage2::GameEnd { + winner: GameEnd::BlackWon("Resigned".to_string()), + }, + &connections + .lock() + .await + .get(&player_id) + .unwrap() + .current_match + .unwrap(), + ) + } else { + ( + ServerMessage2::GameEnd { + winner: GameEnd::WhiteWon("Resigned".to_string()), + }, + &connections + .lock() + .await + .get(&player_id) + .unwrap() + .current_match + .unwrap(), + ) + } + }; + + broadcast_to_match( + &connections, + &matches, + connections + .lock() + .await + .get(&player_id) + .unwrap() + .current_match + .unwrap(), + &serde_json::to_string(&fuck).unwrap(), + ) + .await; + clean_up_match(&matches, fuck_id); } _ => { println!("Not known client event"); diff --git a/server/src/matchmaking.rs b/server/src/matchmaking.rs index daa5c10..0bf5cfa 100644 --- a/server/src/matchmaking.rs +++ b/server/src/matchmaking.rs @@ -1,5 +1,5 @@ use crate::connection::ServerMessage2; -use crate::connection::{ConnectionMap, GameMatch, MatchMap, WaitingQueue, broadcast_to_match}; +use crate::connection::{ConnectionMap, GameMatch, MatchMap, WaitingQueue}; use rand::random; use uuid::Uuid; @@ -25,6 +25,10 @@ impl MatchmakingSystem { } } + pub async fn clean_up(&self, match_id: Uuid) { + self.matches.lock().await.remove(&match_id); + } + async fn try_create_match(&self) { let mut queue = self.waiting_queue.lock().await;