chiark / gitweb /
hidden: implement permutation
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 7 Mar 2021 11:00:43 +0000 (11:00 +0000)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 7 Mar 2021 11:01:35 +0000 (11:01 +0000)
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
src/hidden.rs
src/prelude.rs

index 4a6b1e5cfedcdce9283912b907769f1ec2dedfb6..d64a9803ede1a63851f8fa56904d618492cb3835 100644 (file)
@@ -131,8 +131,8 @@ mod vpid {
 
   #[derive(Clone,Debug,Default,Serialize,Deserialize)]
   pub struct PerPlayerIdMap {
-    f: SecondarySlotMap<PieceId, VisiblePieceId>,
-    r: DenseSlotMap<VisiblePieceId, PieceId>,
+    pub(in super) f: SecondarySlotMap<PieceId, VisiblePieceId>,
+    pub(in super) r: DenseSlotMap<VisiblePieceId, PieceId>,
   }
 
   impl PerPlayerIdMap {
@@ -190,6 +190,11 @@ mod vpid {
   type NR = NotchRecord;
 
   impl NotchRecord {
+    fn piece(&self) -> Option<PieceId> { match self {
+      &NR::Piece(p) => Some(p),
+      &NR::Free(_) => None,
+    }}
+
     fn unwrap_free(&self) -> NotchPtr { match self {
       &NR::Free(ptr) => ptr,
       _ => panic!(),
@@ -385,6 +390,53 @@ mod vpid {
     // We choose a single permutation of the pieces in the
     // Occultation::notches.
 
+    let permu = {
+      let mut permu: Vec<_> =
+        occ.notches.table.iter()
+        .filter_map(NR::piece)
+        .collect();
+
+      let mut rng = thread_rng();
+      permu.shuffle(&mut rng);
+      permu
+    };
+
+    let new_notches = {
+      let mut permus = permu.iter();
+      let new_notches = occ.notches.table.iter().map(|nr| match nr {
+        &f@ NR::Free(_) => f,
+        NR::Piece(p) => NR::Piece(*permus.next().unwrap()),
+      })
+        .collect::<IndexVec<_,_>>();
+      permus.next().map(|x| panic!("{:?}", x));
+      new_notches
+    };
+
+    for gpl in gplayers.values_mut() {
+
+      // xxx don't do this for Visible, check occk
+
+      let mut fwd_updates = vec![];
+      for (old, new) in izip!(&occ.notches.table, &new_notches) {
+        if_chain! {
+          if let Some((old, new)) = zip_eq(old.piece(), new.piece()).next();
+          if let Some(vpid) = gpl.idmap.fwd(old);
+          then {
+            fwd_updates.push((new, vpid));
+            if let Some(e) = gpl.idmap.r.get_mut(vpid) {
+              *e = new;
+            }
+          }
+        }
+      }
+
+      for (new, vpid) in fwd_updates {
+        gpl.idmap.f.insert(new, vpid);
+      }
+
+    }
+    occ.notches.table = new_notches;
+    dbgc!(&occ);
   }
 }
 
index 7baa8932fcba31d1b0db3380a034531592844172..53c054d448758c2588ac592321078ee78f2f6c63 100644 (file)
@@ -63,7 +63,7 @@ pub use flexi_logger::LogSpecification;
 pub use fs2::FileExt;
 pub use if_chain::if_chain;
 pub use index_vec::{define_index_type, index_vec, IndexSlice, IndexVec};
-pub use itertools::{izip, EitherOrBoth, Itertools};
+pub use itertools::{izip, zip_eq, EitherOrBoth, Itertools};
 pub use lazy_static::lazy_static;
 pub use log::{debug, error, info, trace, warn};
 pub use log::{log, log_enabled};
@@ -77,6 +77,7 @@ pub use percent_encoding::NON_ALPHANUMERIC;
 pub use rand::distributions::Alphanumeric;
 pub use rand::thread_rng;
 pub use rand::Rng;
+pub use rand::prelude::SliceRandom;
 pub use regex::Regex;
 pub use serde::ser::SerializeTuple;
 pub use serde::{de::DeserializeOwned, Deserialize, Serialize};