dzura/game/src/game/mod.rs
2024-08-18 18:36:45 -07:00

131 lines
4.1 KiB
Rust

use crate::{
//consts::*,
board::Board,
history::Play,
piece::Piece, util::Hex,
};
pub type Pool = [u8; 7];
pub struct Game {
pub complete:bool,
pub turn:u16,
pub board:Board,
pub pool:[Pool; 2],
pub history:Vec<Play>,
}
impl Game {
pub fn new() -> Self
{
Self {
complete:false,
turn:0,
board:Board::new(),
pool:[Pool::default(); 2],
history:Vec::new(),
}
}
pub fn init(&mut self)
{
self.board.init();
}
pub fn apply_history(&mut self, history:&Vec<Play>) -> Result<(),()>
{
self.init();
for play in history {
self.process(play)?;
}
Ok(())
}
pub fn process(&mut self, play:&Play) -> Result<(),()>
{
let player = (self.turn & 1) as u8;
//
// TODO:
// - Check for piece promotion.
// - Validate plays against move sets and specific rules.
// - Determine game state (check, checkmate).
//
// Move piece on board.
if if play.source == 0 {
if let Some(pid) = self.board.tiles[play.from as usize].piece {
if let Some(mut piece) = self.board.pieces[pid as usize] {
let mut swap = false;
if let Some(tid) = self.board.tiles[play.to as usize].piece {
if let Some(target) = &mut self.board.pieces[tid as usize] {
// Check for piece swap.
if piece.player == target.player {
swap = true;
target.tile = play.from;
// Check for target promotion.
let hex = Hex::from_tile(play.to);
if !target.promoted && Hex::is_back(hex.x, hex.y, target.player) {
println!("promotion {} {} ({}, {})", target.class, play.to, hex.x, hex.y);
target.promoted = true;
}
}
// Add captured piece to pool.
else {
self.pool[piece.player as usize][target.class as usize] += 1;
}
}
// Destroy piece if captured.
if !swap { self.board.pieces[tid as usize] = None; }
}
// Set tile/piece associations.
if swap {
self.board.tiles[play.from as usize].piece = self.board.tiles[play.to as usize].piece;
} else {
self.board.tiles[play.from as usize].piece = None;
}
self.board.tiles[play.to as usize].piece = Some(pid);
piece.tile = play.to;
self.board.pieces[pid as usize] = Some(piece);
// Check for piece promotion.
let hex = Hex::from_tile(play.from);
if !piece.promoted && Hex::is_back(hex.x, hex.y, piece.player) {
println!("promotion {} {} ({}, {})", piece.class, play.to, hex.x, hex.y);
if let Some(piece) = &mut self.board.pieces[pid as usize] {
piece.promoted = true;
}
}
true
} else { false }
} else { false }
}
// Place piece from pool.
else {
if self.pool[player as usize][play.from as usize] > 0 && self.board.tiles[play.to as usize].piece.is_none() {
self.pool[player as usize][play.from as usize] -= 1;
let piece = Piece::new(play.from, player);
self.board.set_piece(piece, play.to);
true
} else { false }
} {
self.turn += 1;
self.history.push(*play);
Ok(())
} else { Err(()) }
}
}