Create initial AI engine core
This commit is contained in:
parent
dfd8d9f399
commit
90dcc2555a
|
@ -0,0 +1,88 @@
|
||||||
|
//! AI engine.
|
||||||
|
|
||||||
|
use crate::find;
|
||||||
|
use alloc::vec::Vec;
|
||||||
|
use core::{future::Future, pin::Pin, task::Poll};
|
||||||
|
use mino::srs::{Piece, PieceType};
|
||||||
|
use mino::{Mat, MatBuf};
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
#[non_exhaustive]
|
||||||
|
pub struct Ai {
|
||||||
|
root_matrix: MatBuf,
|
||||||
|
root_previews: Vec<PieceType>,
|
||||||
|
path: Vec<Piece>,
|
||||||
|
cur_mat: MatBuf,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Ai {
|
||||||
|
// TODO: personality config
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
root_matrix: MatBuf::new(),
|
||||||
|
root_previews: Vec::with_capacity(8),
|
||||||
|
path: Vec::with_capacity(8),
|
||||||
|
cur_mat: MatBuf::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn start(
|
||||||
|
&mut self,
|
||||||
|
init_mat: &Mat,
|
||||||
|
init_previews: &[PieceType],
|
||||||
|
init_hold: Option<PieceType>,
|
||||||
|
) {
|
||||||
|
// init root node
|
||||||
|
self.root_matrix.copy_from(init_mat);
|
||||||
|
self.root_previews.clear();
|
||||||
|
self.root_previews.extend_from_slice(init_previews);
|
||||||
|
self.root_previews.extend(init_hold); // TODO: actual hold logic
|
||||||
|
|
||||||
|
// init search state
|
||||||
|
self.path.clear();
|
||||||
|
self.cur_mat.copy_from(&self.root_matrix);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn think_1_cycle(&mut self) -> bool {
|
||||||
|
let depth = self.path.len();
|
||||||
|
if depth >= self.root_previews.len() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 piece = Piece { ty, loc };
|
||||||
|
piece.cells().fill(&mut self.cur_mat);
|
||||||
|
self.path.push(piece);
|
||||||
|
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn suggestion(&self) -> Vec<Piece> {
|
||||||
|
self.path.clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Think<'a>(&'a mut Ai);
|
||||||
|
|
||||||
|
impl Future for Think<'_> {
|
||||||
|
type Output = ();
|
||||||
|
|
||||||
|
fn poll(mut self: Pin<&mut Self>, _cx: &mut core::task::Context<'_>) -> Poll<Self::Output> {
|
||||||
|
let ai: &mut Ai = &mut self.0;
|
||||||
|
|
||||||
|
if ai.think_1_cycle() {
|
||||||
|
// TODO: if <limits reached> then return Poll::Ready)
|
||||||
|
Poll::Pending
|
||||||
|
} else {
|
||||||
|
Poll::Ready(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,9 +2,11 @@
|
||||||
|
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
|
|
||||||
|
pub mod ai;
|
||||||
pub mod find;
|
pub mod find;
|
||||||
|
|
||||||
#[cfg(feature = "io")]
|
#[cfg(feature = "io")]
|
||||||
pub mod io;
|
pub mod io;
|
||||||
|
|
||||||
|
pub use ai::Ai;
|
||||||
pub use find::find_locations;
|
pub use find::find_locations;
|
||||||
|
|
Loading…
Reference in New Issue