From: Ian Jackson Date: Sun, 31 Jan 2021 23:08:52 +0000 (+0000) Subject: hidden: Occultation data structures X-Git-Tag: otter-0.4.0~551 X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=commitdiff_plain;h=d5a7be510aac689db399d15bc7acdac379a3de96;p=otter.git hidden: Occultation data structures Nothing really updates or uses these yet. Signed-off-by: Ian Jackson --- diff --git a/src/hidden.rs b/src/hidden.rs index b2288d46..7592236e 100644 --- a/src/hidden.rs +++ b/src/hidden.rs @@ -6,21 +6,107 @@ use crate::imports::*; use slotmap::secondary; +type OccK = OccultationKind; + +visible_slotmap_key!{ OccId(b'H') } + // ========== data structures ========== #[derive(Clone,Debug,Default,Serialize,Deserialize)] pub struct GameOccults { - // todo + occults: DenseSlotMap, } #[derive(Clone,Debug,Default,Serialize,Deserialize)] +// kept in synch with Occultation::pieces pub struct PieceOccult { - // todo + active: Option, // kept in synch with Occultation::occulter + passive: Option, // kept in synch with Occultation::pieces +} + +#[derive(Clone,Debug,Serialize,Deserialize)] +pub struct Occultation { + region: [Pos; 2], // automatically affect pieces here + occulter: PieceId, // kept in synch with PieceOccult::active + views: Vec, + defview: Option, + pieces: BTreeSet, // kept in synch with PieceOccult::passive +} + +#[derive(Clone,Debug,Serialize,Deserialize)] +pub struct OccultView { + players: Vec, + occult: Option, +} + +#[derive(Clone,Copy,Debug,Serialize,Deserialize)] +#[derive(Eq,PartialEq)] +pub enum OccultationKind { + Scrambled, + Displaced { within: Area }, + Invisible, +} + +impl PartialOrd for OccultationKind { + fn partial_cmp(&self, rhs: &Self) -> Option { + fn level(k: &OccK) -> u8 { use OccultationKind::*; match k { + Scrambled => 0, + Displaced{..} => 1, + Invisible => 2, + } } + + level(self).partial_cmp(&level(rhs)) + } +} + +trait OccOptExt { + fn at_all_visible(&self) -> bool; +} + +impl OccOptExt for Option { + fn at_all_visible(&self) -> bool { + match self { + None | + Some(OccK::Scrambled) | + Some(OccK::Displaced { .. }) + => false, + Some(OccK::Invisible) + => true, + } + } +} + +impl Occultation { + pub fn get_kind(&self, player: PlayerId) -> Option<&OccultationKind> { + let kind = self.views.iter().find_map(|view| { + if view.players.contains(&player) { return Some(view.occult.as_ref()); } + None + }).unwrap_or( + self.defview.as_ref() + ); + kind + } +} + +impl GameOccults { + #[throws(IE)] + fn by_id(&self, occid: OccId) -> &Occultation { + self.occults.get(occid).ok_or_else( + || internal_logic_error("piece missing"))? + } + + #[throws(IE)] + pub fn get_kind(&self, occid: OccId, player: PlayerId) + -> Option<&OccultationKind> { + let occ = self.by_id(occid)?; + let kind = occ.get_kind(player); + kind + } } // ========== PerPlayerIdMap ========== -#[derive(Default,Debug,Clone,Serialize,Deserialize)] +#[derive(Clone,Debug,Default,Serialize,Deserialize)] pub struct PerPlayerIdMap { f: SecondarySlotMap, r: DenseSlotMap, diff --git a/src/imports.rs b/src/imports.rs index f97558ee..6443dcb9 100644 --- a/src/imports.rs +++ b/src/imports.rs @@ -6,6 +6,7 @@ pub use std::borrow::Borrow; pub use std::borrow::Cow; pub use std::cmp::{self, max, min, Ordering}; pub use std::collections::VecDeque; +pub use std::collections::{btree_set, BTreeSet}; pub use std::collections::{hash_map, HashMap, HashSet}; pub use std::convert::{TryFrom, TryInto}; pub use std::env;