feat: basic basic search
This commit is contained in:
parent
5751215ffa
commit
7d0d81905e
@ -15,6 +15,7 @@ Copyright © 2024 dogeystamp <dogeystamp@disroot.org>
|
||||
|
||||
use chess_inator::fen::FromFen;
|
||||
use chess_inator::movegen::{FromUCIAlgebraic, Move, MoveGen, MoveGenType, ToUCIAlgebraic};
|
||||
use chess_inator::search::best_move;
|
||||
use chess_inator::Board;
|
||||
use std::io;
|
||||
|
||||
@ -87,8 +88,7 @@ fn cmd_position(mut tokens: std::str::SplitWhitespace<'_>) -> Board {
|
||||
|
||||
/// Play the game.
|
||||
fn cmd_go(mut _tokens: std::str::SplitWhitespace<'_>, board: &mut Board) {
|
||||
let mvs: Vec<_> = board.gen_moves(MoveGenType::Legal).into_iter().collect();
|
||||
let chosen = mvs.first();
|
||||
let chosen = best_move(board);
|
||||
match chosen {
|
||||
Some(mv) => println!("bestmove {}", mv.to_uci_algebraic()),
|
||||
None => println!("bestmove 0000"),
|
||||
|
@ -18,7 +18,7 @@ use crate::{Board, Color, N_PIECES};
|
||||
/// Signed centipawn type.
|
||||
///
|
||||
/// Positive is good for White, negative good for Black.
|
||||
type EvalInt = i16;
|
||||
pub type EvalInt = i16;
|
||||
|
||||
pub trait Eval {
|
||||
/// Evaluate a position and assign it a score.
|
||||
|
@ -19,6 +19,7 @@ use std::str::FromStr;
|
||||
pub mod eval;
|
||||
pub mod fen;
|
||||
pub mod movegen;
|
||||
pub mod search;
|
||||
|
||||
use crate::fen::{FromFen, ToFen, START_POSITION};
|
||||
|
||||
|
@ -96,7 +96,7 @@ pub struct AntiMove {
|
||||
|
||||
impl AntiMove {
|
||||
/// Undo the move.
|
||||
fn unmake(self, pos: &mut Board) {
|
||||
pub fn unmake(self, pos: &mut Board) {
|
||||
pos.move_piece(self.dest, self.src);
|
||||
pos.half_moves = self.half_moves;
|
||||
pos.castle = self.castle;
|
||||
|
69
src/search.rs
Normal file
69
src/search.rs
Normal file
@ -0,0 +1,69 @@
|
||||
/*
|
||||
|
||||
This file is part of chess_inator.
|
||||
|
||||
chess_inator is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.
|
||||
|
||||
chess_inator is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with chess_inator. If not, see https://www.gnu.org/licenses/.
|
||||
|
||||
Copyright © 2024 dogeystamp <dogeystamp@disroot.org>
|
||||
*/
|
||||
|
||||
//! Game-tree search.
|
||||
|
||||
use crate::eval::{Eval, EvalInt};
|
||||
use crate::movegen::{Move, MoveGen, MoveGenType};
|
||||
use crate::Board;
|
||||
use std::cmp::max;
|
||||
|
||||
/// Search the game tree to find the absolute (positive good) eval for the current player.
|
||||
fn minmax(board: &mut Board, depth: usize) -> EvalInt {
|
||||
if depth == 0 {
|
||||
let eval = board.eval();
|
||||
match board.turn {
|
||||
crate::Color::White => return eval,
|
||||
crate::Color::Black => return -eval,
|
||||
}
|
||||
}
|
||||
|
||||
let mvs: Vec<_> = board.gen_moves(MoveGenType::Legal).into_iter().collect();
|
||||
|
||||
let mut abs_best = EvalInt::MIN;
|
||||
|
||||
for mv in mvs {
|
||||
let anti_mv = mv.make(board);
|
||||
abs_best = max(abs_best, -minmax(board, depth - 1));
|
||||
anti_mv.unmake(board);
|
||||
}
|
||||
|
||||
abs_best
|
||||
}
|
||||
|
||||
/// Find the best move for a position (internal interface).
|
||||
fn search(board: &mut Board) -> Option<Move> {
|
||||
const DEPTH: usize = 4;
|
||||
let mvs: Vec<_> = board.gen_moves(MoveGenType::Legal).into_iter().collect();
|
||||
|
||||
// absolute eval value
|
||||
let mut best_eval = EvalInt::MIN;
|
||||
let mut best_mv: Option<Move> = None;
|
||||
|
||||
for mv in mvs {
|
||||
let anti_mv = mv.make(board);
|
||||
let abs_eval = -minmax(board, DEPTH);
|
||||
if abs_eval > best_eval {
|
||||
best_eval = abs_eval;
|
||||
best_mv = Some(mv);
|
||||
}
|
||||
anti_mv.unmake(board);
|
||||
}
|
||||
|
||||
best_mv
|
||||
}
|
||||
|
||||
/// Find the best move.
|
||||
pub fn best_move(board: &mut Board) -> Option<Move> {
|
||||
search(board)
|
||||
}
|
Loading…
Reference in New Issue
Block a user