Files
minimax/rust/minimax/src/game/action.rs
2025-11-01 11:13:34 -07:00

71 lines
1.6 KiB
Rust

use rand::Rng;
use rhai::{CustomType, EvalAltResult, TypeBuilder};
use std::fmt::Display;
use super::{Board, Symb};
#[derive(Debug, Clone, Copy)]
pub struct PlayerAction {
pub symb: Symb,
pub pos: usize,
}
impl Display for PlayerAction {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{} at {}", self.symb, self.pos)
}
}
impl PlayerAction {
pub fn new_random<R: Rng>(rng: &mut R, board: &Board) -> Self {
let n = board.size();
let pos = rng.gen_range(0..n);
let symb = Symb::new_random(rng);
PlayerAction { symb, pos }
}
}
impl CustomType for PlayerAction {
fn build(mut builder: TypeBuilder<Self>) {
builder
.with_name("Action")
.with_fn(
"Action",
|symb: &str, pos: i64| -> Result<Self, Box<EvalAltResult>> {
let symb = match Symb::from_str(symb) {
Some(x) => x,
None => return Err(format!("Invalid symbol {symb:?}").into()),
};
Ok(Self {
symb,
pos: pos as usize,
})
},
)
.with_fn(
"Action",
|symb: i64, pos: i64| -> Result<Self, Box<EvalAltResult>> {
let symb = symb.to_string();
let symb = match Symb::from_str(&symb) {
Some(x) => x,
None => return Err(format!("Invalid symbol {symb:?}").into()),
};
Ok(Self {
symb,
pos: pos as usize,
})
},
)
.with_fn("to_string", |s: &mut Self| -> String {
format!("Action {{{} at {}}}", s.symb, s.pos)
})
.with_fn("to_debug", |s: &mut Self| -> String {
format!("Action {{{} at {}}}", s.symb, s.pos)
})
.with_get("symb", |s: &mut Self| s.symb.to_string())
.with_get("pos", |s: &mut Self| s.pos);
}
}