Guide AI by heuristic evaluation; "best first search"
This commit is contained in:
parent
5313580b2e
commit
7ddc748d35
|
@ -1,6 +1,6 @@
|
||||||
//! AI engine.
|
//! AI engine.
|
||||||
|
|
||||||
use crate::find;
|
use crate::{eval, find};
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
use core::{future::Future, pin::Pin, task::Poll};
|
use core::{future::Future, pin::Pin, task::Poll};
|
||||||
use mino::srs::{Piece, PieceType};
|
use mino::srs::{Piece, PieceType};
|
||||||
|
@ -15,6 +15,20 @@ pub struct Ai {
|
||||||
cur_mat: MatBuf,
|
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 {
|
impl Ai {
|
||||||
// TODO: personality config
|
// TODO: personality config
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
|
@ -50,18 +64,33 @@ impl Ai {
|
||||||
}
|
}
|
||||||
|
|
||||||
let ty = self.root_previews[depth];
|
let ty = self.root_previews[depth];
|
||||||
let loc = {
|
let locs = find::find_locations(&self.cur_mat, ty, find::cap::All);
|
||||||
let mut fl = find::find_locations(&self.cur_mat, ty, find::cap::All);
|
let pcs = locs.map(|loc| Piece { ty, loc });
|
||||||
match fl.nth(0) {
|
|
||||||
Some(loc) => loc,
|
let mut rate_mat: MatBuf = MatBuf::new();
|
||||||
None => return true, // game over
|
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 };
|
self.path.push(pc);
|
||||||
piece.cells().fill(&mut self.cur_mat);
|
self.cur_mat.copy_from(&best_mat);
|
||||||
self.path.push(piece);
|
|
||||||
|
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue