chiark / gitweb /
hidden: Occultation data structures
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 31 Jan 2021 23:08:52 +0000 (23:08 +0000)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Fri, 12 Feb 2021 01:38:24 +0000 (01:38 +0000)
Nothing really updates or uses these yet.

Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
src/hidden.rs
src/imports.rs

index b2288d46f9d42a8f395ac913c46b9eb3bfbb9814..7592236eed77dc6b18d6281822b777e8fdc57475 100644 (file)
@@ -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<OccId, Occultation>,
 }
 
 #[derive(Clone,Debug,Default,Serialize,Deserialize)]
+// kept in synch with Occultation::pieces
 pub struct PieceOccult {
-  // todo
+  active: Option<OccId>, // kept in synch with Occultation::occulter
+  passive: Option<OccId>, // 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<OccultView>,
+  defview: Option<OccultationKind>,
+  pieces: BTreeSet<PieceId>, // kept in synch with PieceOccult::passive
+}
+
+#[derive(Clone,Debug,Serialize,Deserialize)]
+pub struct OccultView {
+  players: Vec<PlayerId>,
+  occult: Option<OccultationKind>,
+}
+
+#[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<Ordering> {
+    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<OccultationKind> {
+  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<PieceId, VisiblePieceId>,
   r: DenseSlotMap<VisiblePieceId, PieceId>,
index f97558eed907e647e7e603cd32dab7eeaa61766c..6443dcb96dcdc6da76b57df29176ce9d4fc579d4 100644 (file)
@@ -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;