96 lines
2.9 KiB
Rust
96 lines
2.9 KiB
Rust
use crate::geo_utils::GeoUtils;
|
|
use serde::{Deserialize, Serialize};
|
|
use std::collections::HashMap;
|
|
|
|
#[derive(Debug, Clone, Deserialize, Serialize)]
|
|
pub struct Player {
|
|
pub username: String,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Deserialize, Serialize)]
|
|
pub struct Team {
|
|
pub name: String,
|
|
pub color: String,
|
|
pub players: Vec<Player>,
|
|
pub scores: HashMap<String, i32>, // neighborhood to number of valid changes
|
|
}
|
|
|
|
#[derive(Debug, Clone, Deserialize, Serialize)]
|
|
pub struct Game {
|
|
pub code: String,
|
|
pub teams: Vec<Team>,
|
|
pub start_time: String,
|
|
pub end_time: String,
|
|
pub territories: HashMap<String, Territory>, // territory name/id to struct
|
|
}
|
|
|
|
impl Game {
|
|
fn build_territories(&mut self, geoutils: &GeoUtils) {
|
|
let territory_json = geoutils.get_feature_collection_copy();
|
|
for feature in &territory_json.features {
|
|
let name = feature.property("S_HOOD").unwrap_or_default();
|
|
let name = name.as_str().unwrap_or("unknown");
|
|
let t: Territory = Territory {
|
|
territory_name: String::from(name),
|
|
claiming_team: None,
|
|
claiming_score: 0,
|
|
};
|
|
self.territories.insert(name.to_string(), t);
|
|
}
|
|
}
|
|
|
|
pub fn new(code: String, teams: Vec<Team>, start_time: String, end_time: String) -> Self {
|
|
let geoutils = GeoUtils::new();
|
|
let mut game = Game {
|
|
code: code,
|
|
teams: teams,
|
|
start_time: start_time,
|
|
end_time: end_time,
|
|
territories: HashMap::new(),
|
|
};
|
|
game.build_territories(&geoutils);
|
|
game
|
|
}
|
|
|
|
pub fn update_territories(&mut self) {
|
|
for (_, territory) in &mut self.territories {
|
|
let mut max_team: (Option<Team>, i32) = (None, 0);
|
|
for team in &self.teams {
|
|
let score = team.scores.get(&territory.territory_name).unwrap_or(&0);
|
|
if *score > max_team.1 {
|
|
max_team = (Some(team.clone()), *score);
|
|
} else if *score > 0 && *score == max_team.1 {
|
|
// Tie doesn't count
|
|
max_team = (None, max_team.1);
|
|
}
|
|
}
|
|
territory.claiming_team = max_team.0;
|
|
territory.claiming_score = max_team.1;
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone, Deserialize, Serialize)]
|
|
pub struct Territory {
|
|
pub territory_name: String,
|
|
pub claiming_team: Option<Team>,
|
|
pub claiming_score: i32,
|
|
}
|
|
|
|
impl Team {
|
|
pub fn add_scores(&mut self, scores: &HashMap<String, i32>) {
|
|
for (territory, score) in scores {
|
|
self.scores
|
|
.entry(territory.to_string())
|
|
.and_modify(|s| *s += score)
|
|
.or_insert(*score);
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone, Deserialize, Serialize)]
|
|
pub struct TeamLegend {
|
|
pub name: String,
|
|
pub color: String,
|
|
}
|