use wasm_bindgen::prelude::*; use crate::core::models::{GameState, CardDatabase}; use crate::core::mcts::{SearchHorizon, EvalMode}; #[wasm_bindgen] pub struct WasmEngine { state: GameState, db: CardDatabase, } #[wasm_bindgen] impl WasmEngine { #[wasm_bindgen(constructor)] pub fn new(card_db_json: &str) -> Result { let db = CardDatabase::from_json(card_db_json) .map_err(|e| JsError::new(&format!("Failed to parse card DB: {}", e)))?; Ok(WasmEngine { state: GameState::default(), db, }) } pub fn init_game(&mut self, p0_deck: Vec, p1_deck: Vec, p0_energy: Vec, p1_energy: Vec, p0_lives: Vec, p1_lives: Vec, seed: Option ) { self.state.initialize_game_with_seed( p0_deck.into_iter().map(|x| x as u16).collect(), p1_deck.into_iter().map(|x| x as u16).collect(), p0_energy.into_iter().map(|x| x as u16).collect(), p1_energy.into_iter().map(|x| x as u16).collect(), p0_lives.into_iter().map(|x| x as u16).collect(), p1_lives.into_iter().map(|x| x as u16).collect(), seed ); } pub fn step(&mut self, action_id: i32) -> Result<(), JsError> { self.state.step(&self.db, action_id) .map_err(|e| JsError::new(&e.to_string())) } pub fn get_state_json(&self) -> Result { serde_json::to_string(&self.state) .map_err(|e| JsError::new(&e.to_string())) } pub fn get_legal_actions(&mut self) -> Vec { self.state.get_legal_action_ids(&self.db) } pub fn ai_suggest(&mut self, sims: usize) -> Result { let suggestions = self.state.get_mcts_suggestions(&self.db, sims, SearchHorizon::GameEnd, EvalMode::Normal); if let Some((action, _, _)) = suggestions.first() { Ok(*action) } else { Ok(0) } } }