You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
147 lines
3.5 KiB
147 lines
3.5 KiB
use rhai::{
|
|
serde::{from_dynamic, to_dynamic},
|
|
Dynamic, Func, AST,
|
|
};
|
|
use uuid::Uuid;
|
|
|
|
use std::collections::HashMap;
|
|
|
|
use super::config::{Config, Pile};
|
|
|
|
mod engine;
|
|
use engine::setup_engine;
|
|
mod functions;
|
|
use functions::Functions;
|
|
mod types;
|
|
pub use types::{CardId, CardIdx, PileKind};
|
|
use types::{Data, Player, RhaiResult};
|
|
|
|
pub struct RunningGame {
|
|
#[allow(unused)] // TODO Remove
|
|
name: String,
|
|
pub piles: HashMap<String, Pile>,
|
|
pub player_piles: Vec<HashMap<String, Pile>>,
|
|
functions: Functions,
|
|
current_player: Player,
|
|
data: HashMap<String, serde_json::Value>,
|
|
pub players: HashMap<Uuid, u32>,
|
|
}
|
|
|
|
// TODO add errors
|
|
|
|
impl RunningGame {
|
|
fn get_fns(ast: &AST) -> Vec<String> {
|
|
ast.iter_functions()
|
|
.map(|(_, _, name, _, _)| name.to_string())
|
|
.collect()
|
|
}
|
|
|
|
pub fn compile(path: std::path::PathBuf) -> RhaiResult<(AST, Vec<String>)> {
|
|
let e = setup_engine();
|
|
let ast = e.compile_file(path)?;
|
|
let fns = Self::get_fns(&ast);
|
|
Ok((ast, fns))
|
|
}
|
|
|
|
pub fn new(
|
|
name: String,
|
|
ast: AST,
|
|
fns: &[String],
|
|
conf: &Config,
|
|
current_players: &[Uuid],
|
|
) -> Self {
|
|
// log::info!("Fns: {:?}", fns);
|
|
let functions = Functions::new(fns, ast.clone(), &name);
|
|
let engine = setup_engine();
|
|
let setup = Func::<(Dynamic,), Dynamic>::create_from_ast(engine, ast, "setup");
|
|
|
|
let piles = conf.piles.clone();
|
|
let player_piles = vec![conf.player_piles.clone(); current_players.len()];
|
|
let Data {
|
|
piles,
|
|
player_piles,
|
|
players: _,
|
|
other,
|
|
} = from_dynamic(
|
|
&setup(
|
|
to_dynamic(Data::new(piles, player_piles, current_players.len() as u32)).unwrap(),
|
|
)
|
|
.unwrap(),
|
|
)
|
|
.unwrap();
|
|
let mut players = HashMap::new();
|
|
for (i, player) in current_players.iter().enumerate() {
|
|
players.insert(player.clone(), i as u32);
|
|
}
|
|
log::info!("Players in game {}: {:?}", name, players);
|
|
Self {
|
|
name,
|
|
piles,
|
|
player_piles,
|
|
functions,
|
|
current_player: Player::new(0, current_players.len() as u32),
|
|
data: other,
|
|
players,
|
|
}
|
|
// Self {setup: Box::new(Func::<(Vec<Pile>, Vec<Vec<Pile>>), ()>::create_from_ast(engine, ast, "setup"))}
|
|
}
|
|
|
|
pub fn get_player_for_uuid(&self, user: &Uuid) -> Option<u32> {
|
|
self.players.get(user).copied()
|
|
}
|
|
|
|
pub fn get_current_player(&self) -> u32 {
|
|
self.current_player.num
|
|
}
|
|
|
|
fn data_as_dynamic(&self) -> RhaiResult<Dynamic> {
|
|
to_dynamic(Data {
|
|
piles: self.piles.clone(),
|
|
player_piles: self.player_piles.clone(),
|
|
players: self.current_player.max,
|
|
other: self.data.clone(),
|
|
})
|
|
}
|
|
|
|
fn save_data(&mut self, d: &Dynamic) -> RhaiResult<()> {
|
|
let d: Data = from_dynamic(d)?;
|
|
self.data = d.other;
|
|
self.piles = d.piles;
|
|
self.player_piles = d.player_piles;
|
|
Ok(())
|
|
}
|
|
|
|
pub fn on_click(&mut self, card: CardId, player: u32) {
|
|
let action_author = Player::new(player, self.current_player.max);
|
|
let data = self.data_as_dynamic().unwrap();
|
|
let arr = self
|
|
.functions
|
|
.on_click(data, card, action_author, self.current_player)
|
|
.unwrap();
|
|
self.save_data(&arr[0]).unwrap();
|
|
let turn_end: bool = arr[1].clone().cast();
|
|
if turn_end {
|
|
self.turn_end()
|
|
}
|
|
}
|
|
|
|
fn turn_end(&mut self) {
|
|
let data = self.data_as_dynamic().unwrap();
|
|
let mut arr = self.functions.turn_end(data, self.current_player).unwrap();
|
|
self.save_data(&arr[0]).unwrap();
|
|
self.current_player = arr.remove(1).cast();
|
|
self.turn_start();
|
|
}
|
|
|
|
fn turn_start(&mut self) {
|
|
let data = self.data_as_dynamic().unwrap();
|
|
let data = self
|
|
.functions
|
|
.turn_start(data, self.current_player)
|
|
.transpose()
|
|
.unwrap();
|
|
if let Some(data) = data {
|
|
self.save_data(&data).unwrap();
|
|
}
|
|
}
|
|
}
|
|
|