Create initial AI engine core

This commit is contained in:
tali 2022-12-16 13:31:33 -05:00
parent dfd8d9f399
commit 90dcc2555a
2 changed files with 90 additions and 0 deletions

88
fish/src/ai.rs Normal file
View File

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

View File

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