From 4acad1bab17806dfd6243be2245274d5ef54c9f0 Mon Sep 17 00:00:00 2001 From: ntr Date: Thu, 28 Feb 2019 15:14:08 +1100 Subject: [PATCH] outcomes --- server/src/game.rs | 23 +++++-- server/src/instance.rs | 137 ++++++++++++++++++++++++++++++++++++++--- server/src/mob.rs | 9 +++ server/src/player.rs | 17 +++++ 4 files changed, 171 insertions(+), 15 deletions(-) diff --git a/server/src/game.rs b/server/src/game.rs index 34dabb13..d90b23db 100644 --- a/server/src/game.rs +++ b/server/src/game.rs @@ -19,6 +19,7 @@ pub type Log = Vec; #[derive(Debug,Clone,Serialize,Deserialize)] pub struct Team { pub id: Uuid, + pub bot: bool, cryps: Vec, } @@ -27,9 +28,15 @@ impl Team { return Team { id: account, cryps: vec![], + bot: false, }; } + pub fn set_bot(&mut self) -> &mut Team { + self.bot = true; + self + } + fn skills_required(&self) -> usize { let required = self.cryps.iter() .filter(|c| !c.is_ko()) @@ -190,7 +197,7 @@ impl Game { && self.teams.iter().all(|t| t.cryps.len() == self.team_size) } - fn start(&mut self) -> &mut Game { + pub fn start(&mut self) -> &mut Game { self.log.push("Game starting...".to_string()); self.skill_phase_start(); @@ -210,17 +217,21 @@ impl Game { if self.is_pve { self.pve_add_skills(); + if self.skill_phase_finished() { + self.resolve_phase_start(); + } } self } fn pve_add_skills(&mut self) -> &mut Game { - { - let mob_team_id = Uuid::nil(); - let mobs = self.team_by_id(mob_team_id).clone(); + for mobs in self.teams + .clone() + .into_iter() + .filter(|t| t.bot) { - let player_team = self.teams.iter().find(|t| t.id != mob_team_id).unwrap().clone(); + let player_team = self.teams.iter().find(|t| t.id != mobs.id).unwrap().clone(); for mob in mobs.cryps.iter() { let skill = mob.mob_select_skill(); @@ -244,7 +255,7 @@ impl Game { target = find_target(); } - match self.add_skill(mob_team_id, mob.id, Some(target.id), s) { + match self.add_skill(mobs.id, mob.id, Some(target.id), s) { Ok(_) => (), Err(e) => println!("{:?} could not add pve skill", e), } diff --git a/server/src/instance.rs b/server/src/instance.rs index 932b4ee6..fb755096 100644 --- a/server/src/instance.rs +++ b/server/src/instance.rs @@ -13,14 +13,14 @@ use rpc::{InstanceJoinParams, InstanceReadyParams}; use account::Account; use player::{Player, player_create, player_get}; use cryp::{Cryp, cryp_get}; -use mob::{generate_mob}; -use game::{Game, game_get, game_instance_new, game_instance_join}; +use mob::{instance_mobs}; +use game::{Game, Team, game_get, game_instance_new, game_instance_join}; #[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)] enum InstancePhase { Open, Vbox, - Combat, + Games, Finished, } @@ -28,7 +28,7 @@ enum InstancePhase { struct Round { player_ids: Vec, game_id: Option, - winner_id: Option, + outcome: Option<(Uuid, Uuid)>, } #[derive(Debug,Clone,Serialize,Deserialize)] @@ -57,7 +57,7 @@ impl Instance { self.pve = true; self.players = iter::repeat_with(|| { let bot_id = Uuid::new_v4(); - let cryps = iter::repeat_with(|| generate_mob(1).set_account(bot_id)).take(3).collect::>(); + let cryps = instance_mobs(bot_id); Player::new(bot_id, self.id, cryps).set_bot(true) }) .take(15) @@ -93,10 +93,70 @@ impl Instance { self.generate_rounds(); self.phase = InstancePhase::Vbox; + self.vbox_phase_start() + } + + fn vbox_phase_start(&mut self) -> &mut Instance { + // match self.rounds.last() { + // Some(r) => { + // for round in r { + // { + // let winner = self.players.iter_mut().find(|p| p.account == round.outcome.unwrap().0).unwrap(); + // winner.add_win(); + // } + // { + // let loser = self.players.iter_mut().find(|p| p.account == round.outcome.unwrap().1).unwrap(); + // loser.add_loss(); + // } + // } + // } + // None => (), + // } + + self.bot_vbox_phase(); + self } - fn progress(&mut self) -> &mut Instance { + fn vbox_phase_finished(&self) -> bool { + self.players.iter().all(|p| p.ready) + } + + // requires no input + // just do it + fn games_phase_start(&mut self) -> &mut Instance { + if self.phase != InstancePhase::Vbox { + panic!("instance not in vbox phase"); + } + assert!(self.vbox_phase_finished()); + + self.phase = InstancePhase::Games; + + self.bot_games_phase(); + + self + } + + fn games_phase_finished(&self) -> bool { + match self.rounds.last() { + Some(r) => r.iter().all(|g| g.game_id.is_some() && g.outcome.is_some()), + None => true, + } + } + + fn bot_vbox_phase(&mut self) -> &mut Instance { + for bot in self.players.iter_mut().filter(|p| p.bot) { + bot.set_ready(true); + } + + self + } + + fn bot_games_phase(&mut self) -> &mut Instance { + if self.phase != InstancePhase::Games { + panic!("instance not in games phase"); + } + if self.pve { let r = self.rounds.len() - 1; for mut round in self.rounds[r].iter_mut() { @@ -104,7 +164,33 @@ impl Instance { .iter() .filter(|p| round.player_ids.contains(&p.id) && p.bot) .count() == 2 { - // play bot game + println!("should play a game between {:?}", round.player_ids); + let a = self.players.clone().into_iter().find(|p| p.id == round.player_ids[0]).unwrap(); + let b = self.players.clone().into_iter().find(|p| p.id == round.player_ids[1]).unwrap(); + + let mut game = Game::new(); + game + .set_pve(true) + .set_team_num(2) + .set_team_size(3); + + // add the players + let mut a_team = Team::new(a.id); + a_team.set_cryps(a.cryps); + a_team.set_bot(); + + let mut b_team = Team::new(b.id); + b_team.set_cryps(b.cryps); + b_team.set_bot(); + + game + .team_add(a_team).unwrap() + .team_add(b_team).unwrap(); + + game.start(); + + round.game_id = Some(game.id); + round.outcome = Some((game.winner().unwrap().id, Uuid::new_v4())); } } } @@ -127,13 +213,14 @@ impl Instance { // only set up for even player numbers atm // no byes let np = matched_players.len(); - let current_round = matched_players[0..(np / 2) - 1] + println!("{:?} players in instance", np); + let current_round = matched_players[0..(np / 2)] .iter() .enumerate() .map(|(i, id)| Round { player_ids: vec![*id, matched_players[np - (i + 1)]], game_id: None, - winner_id: None, + outcome: None, }) .collect::>(); @@ -282,3 +369,35 @@ pub fn instance_ready(params: InstanceReadyParams, tx: &mut Transaction, account return Ok(game); } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn instance_pve_test() { + let mut instance = Instance::new().add_bots(); + + let player_id = Uuid::new_v4(); + let cryps = instance_mobs(player_id); + let player = Player::new(player_id, instance.id, cryps).set_bot(true); + + instance.add_player(player); + assert!(instance.can_start()); + + instance.start(); + assert_eq!(instance.rounds[0].len(), 8); + + { + let player = instance.players.iter_mut().find(|p| p.account == player_id).unwrap(); + player.set_ready(true); + } + + assert!(instance.vbox_phase_finished()); + instance.games_phase_start(); + + println!("{:?}", instance.rounds); + + assert!(instance.games_phase_finished()); + } +} \ No newline at end of file diff --git a/server/src/mob.rs b/server/src/mob.rs index a90adab8..43b09e78 100644 --- a/server/src/mob.rs +++ b/server/src/mob.rs @@ -39,6 +39,15 @@ fn quick_game(mob_lvl: u8, team_size: usize) -> Vec { .collect::>() } +pub fn instance_mobs(team_id: Uuid) -> Vec { + iter::repeat_with(|| + generate_mob(1) + .set_account(team_id) + .learn(Skill::Attack)) + .take(3) + .collect::>() +} + fn zone_3v2_attack(player_lvl: u8) -> Vec { let x = Cryp::new() .named(&"hench".to_string()) diff --git a/server/src/player.rs b/server/src/player.rs index 2c50c0b1..a7e87f0a 100644 --- a/server/src/player.rs +++ b/server/src/player.rs @@ -28,6 +28,7 @@ pub struct Player { pub score: Score, pub cryps: Vec, pub bot: bool, + pub ready: bool, } impl Player { @@ -40,6 +41,7 @@ impl Player { score: Score { wins: 0, losses: 0 }, cryps, bot: false, + ready: false, } } @@ -47,6 +49,21 @@ impl Player { self.bot = bot; self } + + pub fn set_ready(&mut self, ready: bool) -> &mut Player { + self.ready = ready; + self + } + + pub fn add_win(&mut self) -> &mut Player { + self.score.wins += 1; + self + } + + pub fn add_loss(&mut self) -> &mut Player { + self.score.losses += 1; + self + } } pub fn player_get(tx: &mut Transaction, account_id: Uuid, instance_id: Uuid) -> Result {