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;
|
||||
|
||||
pub mod ai;
|
||||
pub mod find;
|
||||
|
||||
#[cfg(feature = "io")]
|
||||
pub mod io;
|
||||
|
||||
pub use ai::Ai;
|
||||
pub use find::find_locations;
|
||||
|
|
Loading…
Reference in New Issue