|
@@ -16,7 +16,6 @@ pub struct SearchControl<'a> {
|
|
|
|
|
|
pub enum SearchResult {
|
|
pub enum SearchResult {
|
|
Finished(Move, PosValue),
|
|
Finished(Move, PosValue),
|
|
- Mate(Move, i32),
|
|
|
|
Cancelled(Option<(Move, PosValue)>),
|
|
Cancelled(Option<(Move, PosValue)>),
|
|
Invalid
|
|
Invalid
|
|
}
|
|
}
|
|
@@ -91,11 +90,11 @@ pub fn search(game: &mut Game, sc: &mut SearchControl, hash: &mut Cache, depth:
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
- if val >= MAX_VALUE {
|
|
|
|
- // mate in 1
|
|
|
|
|
|
+ if val >= mate() {
|
|
|
|
+ // mate in 1 --- can't get better than that
|
|
info!("yay mate!");
|
|
info!("yay mate!");
|
|
game.undo_move(undo);
|
|
game.undo_move(undo);
|
|
- return SearchResult::Mate(mov, 1);
|
|
|
|
|
|
+ return SearchResult::Finished(mov, val);
|
|
}
|
|
}
|
|
|
|
|
|
//info!("searched {} -> {}", mov.to_string(), val);
|
|
//info!("searched {} -> {}", mov.to_string(), val);
|
|
@@ -114,7 +113,7 @@ pub fn search(game: &mut Game, sc: &mut SearchControl, hash: &mut Cache, depth:
|
|
|
|
|
|
//info!("movvalues: {:?}", valued_moves.iter().map(|mv| mv.0.to_string() + " - " + &mv.1.to_string()).collect::<Vec<String>>());
|
|
//info!("movvalues: {:?}", valued_moves.iter().map(|mv| mv.0.to_string() + " - " + &mv.1.to_string()).collect::<Vec<String>>());
|
|
|
|
|
|
- valued_moves.sort_by_key(|mv| (mv.1 * 1000.0f32) as i64);
|
|
|
|
|
|
+ valued_moves.sort_by_key(|mv| mv.1);
|
|
|
|
|
|
//info!("best movvalues: {:?}", valued_moves.iter().map(|mv| mv.0.to_string() + " - " + &mv.1.to_string()).collect::<Vec<String>>());
|
|
//info!("best movvalues: {:?}", valued_moves.iter().map(|mv| mv.0.to_string() + " - " + &mv.1.to_string()).collect::<Vec<String>>());
|
|
|
|
|
|
@@ -125,11 +124,11 @@ pub fn search(game: &mut Game, sc: &mut SearchControl, hash: &mut Cache, depth:
|
|
//info!("bestmove value {}", -min_val);
|
|
//info!("bestmove value {}", -min_val);
|
|
let chosen_mov = best_moves[(rng.next_u64() % best_moves.len() as u64) as usize];
|
|
let chosen_mov = best_moves[(rng.next_u64() % best_moves.len() as u64) as usize];
|
|
if cancelled {
|
|
if cancelled {
|
|
- return SearchResult::Cancelled(Some((chosen_mov.0, chosen_mov.1)));
|
|
|
|
|
|
+ return SearchResult::Cancelled(Some((chosen_mov.0, -chosen_mov.1)));
|
|
}
|
|
}
|
|
else {
|
|
else {
|
|
hash.cache(game, CacheEntry::new_value(depth, chosen_mov.1));
|
|
hash.cache(game, CacheEntry::new_value(depth, chosen_mov.1));
|
|
- return SearchResult::Finished(chosen_mov.0, chosen_mov.1);
|
|
|
|
|
|
+ return SearchResult::Finished(chosen_mov.0, -chosen_mov.1);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
else {
|
|
@@ -139,12 +138,7 @@ pub fn search(game: &mut Game, sc: &mut SearchControl, hash: &mut Cache, depth:
|
|
|
|
|
|
fn negamax(game: &mut Game, sc: &mut SearchControl, hash: &mut Cache, mut alpha: PosValue, beta: PosValue, depth: i32) -> (PosValue, bool) {
|
|
fn negamax(game: &mut Game, sc: &mut SearchControl, hash: &mut Cache, mut alpha: PosValue, beta: PosValue, depth: i32) -> (PosValue, bool) {
|
|
if depth == 0 {
|
|
if depth == 0 {
|
|
- return (quiescence_search(game, sc, alpha, beta, 7), false);
|
|
|
|
- let eval = evaluate(game);
|
|
|
|
- if eval != 0.0f32 {
|
|
|
|
- //info!("eval: {}", eval);
|
|
|
|
- }
|
|
|
|
- //return eval;
|
|
|
|
|
|
+ return (quiescence_search(game, sc, alpha, beta, 9), false);
|
|
}
|
|
}
|
|
|
|
|
|
sc.nodes += 1;
|
|
sc.nodes += 1;
|
|
@@ -165,7 +159,7 @@ fn negamax(game: &mut Game, sc: &mut SearchControl, hash: &mut Cache, mut alpha:
|
|
if moves.len() == 0 {
|
|
if moves.len() == 0 {
|
|
if is_check(game, game.turn) {
|
|
if is_check(game, game.turn) {
|
|
// mate
|
|
// mate
|
|
- return (MIN_VALUE, false);
|
|
|
|
|
|
+ return (-mate(), false);
|
|
}
|
|
}
|
|
else {
|
|
else {
|
|
// stalemate
|
|
// stalemate
|
|
@@ -178,6 +172,12 @@ fn negamax(game: &mut Game, sc: &mut SearchControl, hash: &mut Cache, mut alpha:
|
|
let (mut val, ret) = negamax(game, sc, hash, -beta, -alpha, depth - 1);
|
|
let (mut val, ret) = negamax(game, sc, hash, -beta, -alpha, depth - 1);
|
|
val = -val;
|
|
val = -val;
|
|
|
|
|
|
|
|
+ if let Some(turns) = is_mate_in_p1(val) {
|
|
|
|
+ if turns < 0 {
|
|
|
|
+ val = mate_in_p1(turns - 1);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
if ret {
|
|
if ret {
|
|
game.undo_move(undo);
|
|
game.undo_move(undo);
|
|
return (alpha, ret)
|
|
return (alpha, ret)
|
|
@@ -192,7 +192,6 @@ fn negamax(game: &mut Game, sc: &mut SearchControl, hash: &mut Cache, mut alpha:
|
|
}
|
|
}
|
|
//info!(" -> negamaxed {} -> {}", mov.to_string(), depth - 1);
|
|
//info!(" -> negamaxed {} -> {}", mov.to_string(), depth - 1);
|
|
if val > best {
|
|
if val > best {
|
|
-
|
|
|
|
best = val;
|
|
best = val;
|
|
//best_move = mov;
|
|
//best_move = mov;
|
|
}
|
|
}
|
|
@@ -201,7 +200,7 @@ fn negamax(game: &mut Game, sc: &mut SearchControl, hash: &mut Cache, mut alpha:
|
|
|
|
|
|
|
|
|
|
//info!("best alpha {}", best);
|
|
//info!("best alpha {}", best);
|
|
- return ((alpha as f64 * 0.99) as _, false);
|
|
|
|
|
|
+ return (alpha, false);
|
|
}
|
|
}
|
|
|
|
|
|
fn quiescence_search(game: &mut Game, sc: &mut SearchControl, mut alpha: PosValue, beta: PosValue, depth: i32) -> PosValue {
|
|
fn quiescence_search(game: &mut Game, sc: &mut SearchControl, mut alpha: PosValue, beta: PosValue, depth: i32) -> PosValue {
|