68 lines
1.8 KiB
Rust
68 lines
1.8 KiB
Rust
use mino::Mat;
|
|
|
|
mod basic;
|
|
mod downstacking;
|
|
|
|
pub use basic::{i_deps, max_height, row_trans};
|
|
pub use downstacking::mystery_mdse;
|
|
|
|
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
|
|
pub struct Features(pub usize, pub [i32; 4]);
|
|
|
|
/// Computes the feature vector for the given matrix. These are the underlying values
|
|
/// used to calculate the heuristic rating.
|
|
pub fn features(mat: &Mat, pcnt: usize) -> Features {
|
|
Features(
|
|
pcnt,
|
|
[
|
|
max_height(mat),
|
|
i_deps(mat),
|
|
row_trans(mat),
|
|
mystery_mdse(mat),
|
|
],
|
|
)
|
|
}
|
|
|
|
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
|
|
pub struct Weights(pub [i32; 4]);
|
|
|
|
impl Weights {
|
|
/// Default weights (determined experimentally).
|
|
pub const DEFAULT: Self = Self([
|
|
512, // max_height
|
|
1024, // i_deps
|
|
0, // FIXME: row_trans
|
|
1024, // mdse
|
|
]);
|
|
|
|
/// Constant penalty given to the number of pieces placed. Each element of the weight
|
|
/// vector is effectively a ratio to this constant, i.e. if this were to be doubled,
|
|
/// then all of the weights should be doubled as well to produce an identical
|
|
/// heuristic.
|
|
pub const PER_PIECE: i32 = 1024;
|
|
}
|
|
|
|
impl Default for Weights {
|
|
fn default() -> Self {
|
|
Self::DEFAULT
|
|
}
|
|
}
|
|
|
|
impl Features {
|
|
/// Applies the given weights vector to the features. Returns the heuristic score.
|
|
#[inline]
|
|
pub fn evaluate(&self, weights: &Weights) -> i32 {
|
|
let pcnt = self.0 as i32;
|
|
let ft = &self.1;
|
|
let wt = &weights.0;
|
|
|
|
let mut score = Weights::PER_PIECE * pcnt;
|
|
score += wt[0] * ft[0];
|
|
score += wt[1] * ft[1];
|
|
score += wt[2] * ft[2];
|
|
score += wt[3] * ft[3];
|
|
// TODO(?) quadratic weights, e.g. score += wt[i] * f[j]^2
|
|
score
|
|
}
|
|
}
|