From 7ddc748d350bd2358e5a8e03ca0f7a30c3141798 Mon Sep 17 00:00:00 2001 From: tali Date: Thu, 22 Dec 2022 16:18:40 -0500 Subject: [PATCH] Guide AI by heuristic evaluation; "best first search" --- fish/src/ai.rs | 49 +++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 39 insertions(+), 10 deletions(-) diff --git a/fish/src/ai.rs b/fish/src/ai.rs index 425e9b4..9c0a524 100644 --- a/fish/src/ai.rs +++ b/fish/src/ai.rs @@ -1,6 +1,6 @@ //! AI engine. -use crate::find; +use crate::{eval, find}; use alloc::vec::Vec; use core::{future::Future, pin::Pin, task::Poll}; use mino::srs::{Piece, PieceType}; @@ -15,6 +15,20 @@ pub struct Ai { cur_mat: MatBuf, } +fn evaluate(mat: &Mat, depth: usize) -> i32 { + let w_height = 5; + let w_ideps = 10; + let w_mdse = 10; + let w_pc = 10; + + let mut rating = 0; + rating += eval::max_height(mat) * w_height; + rating += eval::i_deps(mat) * w_ideps; + rating += eval::mystery_mdse(mat) * w_mdse; + rating += (depth as i32) * w_pc; + rating +} + impl Ai { // TODO: personality config pub fn new() -> Self { @@ -50,18 +64,33 @@ impl Ai { } let ty = self.root_previews[depth]; - let loc = { - let mut fl = find::find_locations(&self.cur_mat, ty, find::cap::All); - match fl.nth(0) { - Some(loc) => loc, - None => return true, // game over + let locs = find::find_locations(&self.cur_mat, ty, find::cap::All); + let pcs = locs.map(|loc| Piece { ty, loc }); + + let mut rate_mat: MatBuf = MatBuf::new(); + let mut best_mat: MatBuf = MatBuf::new(); + let mut best: Option<(i32, Piece)> = None; + + for pc in pcs { + rate_mat.copy_from(&self.cur_mat); + pc.cells().fill(&mut rate_mat); + rate_mat.clear_lines(); + let rating = evaluate(&rate_mat, depth); + + let best_rating = best.clone().map_or(i32::MAX, |(r, _)| r); + if rating < best_rating { + best = Some((rating, pc)); + best_mat.copy_from(&rate_mat); } + } + + let pc = match best { + Some((_, pc)) => pc, + None => return true, // no locations; game over }; - let piece = Piece { ty, loc }; - piece.cells().fill(&mut self.cur_mat); - self.path.push(piece); - + self.path.push(pc); + self.cur_mat.copy_from(&best_mat); false }