83 lines
2.2 KiB
Rust
83 lines
2.2 KiB
Rust
use crate::game::{Action, Controllable, Game};
|
|
use crate::playfield::{Matrix, PlayField};
|
|
use crate::tetromino::{Tetromino, TetrominoType};
|
|
use rand::rngs::SmallRng;
|
|
|
|
pub mod genetic;
|
|
pub mod qlearning;
|
|
|
|
#[derive(Hash, PartialEq, Eq, Clone, Debug)]
|
|
pub struct State {
|
|
matrix: Matrix,
|
|
active_piece: Option<Tetromino>,
|
|
held_piece: Option<TetrominoType>,
|
|
line_clears: u32,
|
|
}
|
|
|
|
impl From<Game> for State {
|
|
fn from(game: Game) -> Self {
|
|
(&game).into()
|
|
}
|
|
}
|
|
|
|
impl From<&Game> for State {
|
|
fn from(game: &Game) -> Self {
|
|
let mut state: State = game.playfield().clone().into();
|
|
state.line_clears = game.line_clears;
|
|
state
|
|
}
|
|
}
|
|
|
|
impl From<PlayField> for State {
|
|
fn from(playfield: PlayField) -> Self {
|
|
Self {
|
|
matrix: playfield.field().clone(),
|
|
active_piece: playfield.active_piece,
|
|
held_piece: playfield.hold_piece().map(|t| t.clone()),
|
|
line_clears: 0,
|
|
}
|
|
}
|
|
}
|
|
|
|
pub trait Actor {
|
|
fn get_action(&self, rng: &mut SmallRng, game: &Game, legal_actions: &[Action]) -> Action;
|
|
|
|
fn dbg(&self);
|
|
}
|
|
|
|
pub trait Predictable {
|
|
fn get_next_state(&self, action: Action) -> Self;
|
|
}
|
|
|
|
impl Predictable for Game {
|
|
/// Expensive, performs a full clone.
|
|
fn get_next_state(&self, action: Action) -> Self {
|
|
let mut game = self.clone();
|
|
match action {
|
|
Action::Nothing => (),
|
|
Action::MoveLeft => game.move_left(),
|
|
Action::MoveRight => game.move_right(),
|
|
Action::SoftDrop => game.move_down(),
|
|
Action::HardDrop => game.hard_drop(),
|
|
Action::Hold => game.hold(),
|
|
Action::RotateLeft => game.rotate_left(),
|
|
Action::RotateRight => game.rotate_right(),
|
|
};
|
|
|
|
game
|
|
}
|
|
}
|
|
|
|
pub fn apply_action_to_game(action: Action, game: &mut Game) {
|
|
match action {
|
|
Action::Nothing => (),
|
|
Action::MoveLeft => game.move_left(),
|
|
Action::MoveRight => game.move_right(),
|
|
Action::SoftDrop => game.move_down(),
|
|
Action::HardDrop => game.hard_drop(),
|
|
Action::Hold => game.hold(),
|
|
Action::RotateLeft => game.rotate_left(),
|
|
Action::RotateRight => game.rotate_right(),
|
|
}
|
|
}
|