most basic best move search
This commit is contained in:
parent
af2178abad
commit
9d527634eb
7 changed files with 105 additions and 4 deletions
18
src/eval/basic.rs
Normal file
18
src/eval/basic.rs
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
use crate::board::{Board, Color, PieceType};
|
||||||
|
|
||||||
|
pub fn evaluate_board(board: &Board) -> i32 {
|
||||||
|
let mut score = 0_i32;
|
||||||
|
score += board.pieces[PieceType::Pawn as usize][Color::White as usize].count_ones() as i32 * 100;
|
||||||
|
score += board.pieces[PieceType::Knight as usize][Color::White as usize].count_ones() as i32 * 300;
|
||||||
|
score += board.pieces[PieceType::Bishop as usize][Color::White as usize].count_ones() as i32 * 300;
|
||||||
|
score += board.pieces[PieceType::Rook as usize][Color::White as usize].count_ones() as i32 * 500;
|
||||||
|
score += board.pieces[PieceType::Queen as usize][Color::White as usize].count_ones() as i32 * 900;
|
||||||
|
score += board.pieces[PieceType::King as usize][Color::White as usize].count_ones() as i32 * 10000;
|
||||||
|
score -= board.pieces[PieceType::Pawn as usize][Color::Black as usize].count_ones() as i32 * 100;
|
||||||
|
score -= board.pieces[PieceType::Knight as usize][Color::Black as usize].count_ones() as i32 * 300;
|
||||||
|
score -= board.pieces[PieceType::Bishop as usize][Color::Black as usize].count_ones() as i32 * 300;
|
||||||
|
score -= board.pieces[PieceType::Rook as usize][Color::Black as usize].count_ones() as i32 * 500;
|
||||||
|
score -= board.pieces[PieceType::Queen as usize][Color::Black as usize].count_ones() as i32 * 900;
|
||||||
|
score -= board.pieces[PieceType::King as usize][Color::Black as usize].count_ones() as i32 * 10000;
|
||||||
|
score
|
||||||
|
}
|
||||||
1
src/eval/mod.rs
Normal file
1
src/eval/mod.rs
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
pub mod basic;
|
||||||
|
|
@ -2,5 +2,7 @@ pub mod board;
|
||||||
pub mod r#move;
|
pub mod r#move;
|
||||||
pub mod square;
|
pub mod square;
|
||||||
pub mod movegen;
|
pub mod movegen;
|
||||||
mod display;
|
pub mod eval;
|
||||||
mod parsing;
|
pub mod display;
|
||||||
|
pub mod parsing;
|
||||||
|
pub mod search;
|
||||||
|
|
|
||||||
11
src/main.rs
11
src/main.rs
|
|
@ -2,8 +2,15 @@ use chess_engine::board::Board;
|
||||||
use chess_engine::movegen::generate_pseudo_legal_moves;
|
use chess_engine::movegen::generate_pseudo_legal_moves;
|
||||||
use chess_engine::movegen::legal_check::is_king_attacked;
|
use chess_engine::movegen::legal_check::is_king_attacked;
|
||||||
use chess_engine::r#move::*;
|
use chess_engine::r#move::*;
|
||||||
|
use chess_engine::search::minimax;
|
||||||
|
use chess_engine::search::minimax::minimax;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
let mut board = Board::from_fen("rnb1kbnr/pppppppp/8/8/8/4q3/PPPPPPPP/RNBQKBNR w KQkq - 0 1");
|
||||||
|
let (opt_move, _) = minimax(&mut board, 5);
|
||||||
|
if let Some(mv) = opt_move {
|
||||||
|
println!("Found best move: {}", mv)
|
||||||
|
} else {
|
||||||
|
println!("No moves found")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
17
src/move.rs
17
src/move.rs
|
|
@ -1,4 +1,5 @@
|
||||||
use std::slice;
|
use std::slice;
|
||||||
|
use std::ops::{Index, IndexMut};
|
||||||
use crate::square::Square;
|
use crate::square::Square;
|
||||||
use crate::board::PieceType;
|
use crate::board::PieceType;
|
||||||
use crate::square::SQUARES;
|
use crate::square::SQUARES;
|
||||||
|
|
@ -103,6 +104,22 @@ impl MoveList {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Index<usize> for MoveList {
|
||||||
|
type Output = Move;
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn index(&self, index: usize) -> &Self::Output {
|
||||||
|
&self.moves[..self.count][index]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IndexMut<usize> for MoveList {
|
||||||
|
#[inline(always)]
|
||||||
|
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
|
||||||
|
&mut self.moves[..self.count][index]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct UndoMove {
|
pub struct UndoMove {
|
||||||
pub mv: Move,
|
pub mv: Move,
|
||||||
pub captured_piece: Option<PieceType>,
|
pub captured_piece: Option<PieceType>,
|
||||||
|
|
|
||||||
55
src/search/minimax.rs
Normal file
55
src/search/minimax.rs
Normal file
|
|
@ -0,0 +1,55 @@
|
||||||
|
use crate::board::{Board, Color}; // <-- Assuming you have a Color enum (e.g., Color::White, Color::Black)
|
||||||
|
use crate::eval::basic::evaluate_board;
|
||||||
|
use crate::movegen::generate_pseudo_legal_moves;
|
||||||
|
use crate::movegen::legal_check::is_king_attacked;
|
||||||
|
use crate::r#move::{Move, MoveList};
|
||||||
|
|
||||||
|
|
||||||
|
fn evaluate_board_relative(board: &Board) -> i32 {
|
||||||
|
let static_eval = evaluate_board(board);
|
||||||
|
match board.side_to_move {
|
||||||
|
Color::White => static_eval,
|
||||||
|
Color::Black => -static_eval,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn minimax(board: &mut Board, depth: u8) -> (Option<Move>, i32) {
|
||||||
|
if depth == 0 {
|
||||||
|
return (None, evaluate_board_relative(board));
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut list = MoveList::new();
|
||||||
|
generate_pseudo_legal_moves(board, &mut list);
|
||||||
|
let mut best_move: Option<Move> = None;
|
||||||
|
let mut best_score: i32 = -i32::MAX;
|
||||||
|
let mut legal_moves_found = false;
|
||||||
|
|
||||||
|
for mv in list.iter() {
|
||||||
|
let undo_mv = board.make_move(*mv);
|
||||||
|
let is_illegal = is_king_attacked(board);
|
||||||
|
if is_illegal {
|
||||||
|
board.undo_move(undo_mv);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
legal_moves_found = true;
|
||||||
|
let (_, score) = minimax(board, depth - 1);
|
||||||
|
let current_score = -score;
|
||||||
|
|
||||||
|
if current_score > best_score {
|
||||||
|
best_score = current_score;
|
||||||
|
best_move = Some(*mv);
|
||||||
|
}
|
||||||
|
|
||||||
|
board.undo_move(undo_mv);
|
||||||
|
}
|
||||||
|
|
||||||
|
if !legal_moves_found {
|
||||||
|
if is_king_attacked(board) {
|
||||||
|
return (None, -i32::MAX);
|
||||||
|
} else {
|
||||||
|
return (None, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
(best_move, best_score)
|
||||||
|
}
|
||||||
1
src/search/mod.rs
Normal file
1
src/search/mod.rs
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
pub mod minimax;
|
||||||
Loading…
Add table
Add a link
Reference in a new issue