Guide AI by heuristic evaluation; "best first search"

This commit is contained in:
tali 2022-12-22 16:18:40 -05:00
parent 5313580b2e
commit 7ddc748d35
1 changed files with 39 additions and 10 deletions

View File

@ -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
}