chiark / gitweb /
clamp onto table
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 30 Aug 2020 10:28:32 +0000 (11:28 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 30 Aug 2020 10:28:32 +0000 (11:28 +0100)
src/api.rs
src/error.rs
src/gamestate.rs

index 50ef5f7a42113f29f1fef13db2b98b1743431642..a3224a9c2d81b2f16d3851175288ba6df74b6f70 100644 (file)
@@ -212,7 +212,9 @@ impl ApiPieceOp for ApiPieceMove {
         _lens: &dyn Lens)
         -> (PieceUpdateOp<()>, Vec<LogEntry>) {
     let pc = gs.pieces.byid_mut(piece).unwrap();
-
+    if let (_,true) = self.0.clamped(gs.table_size) {
+      throw!(GameError::PosOffTable);
+    }
     pc.pos = self.0;
     let update = PieceUpdateOp::Move(self.0);
     (update, vec![])
index f7d562c58256a464464156b244bc14321c8e6709..8aa36586ccdbdaa4d1a860f31ff25519ccd8a033 100644 (file)
@@ -8,6 +8,7 @@ pub enum GameError {
   PieceGone,
   PieceHeld,
   FaceNotFound,
+  PosOffTable,
   InternalErrorSVG(#[from] SVGProcessingError),
 }
 
index a9ca08aae4f51d1e4b92ab9dc8bf0ce2a2162e33..f860430a6c45d74d6419ebc009217ca614638cf8 100644 (file)
@@ -144,6 +144,31 @@ impl Display for ZCoord {
   }
 }
 
+pub trait ClampTable : Sized {
+  fn clamped(self, range: Self) -> (Self, bool);
+}
+
+impl ClampTable for Coord {
+  fn clamped(self, range: Coord) -> (Coord, bool) {
+    if self < 0     { return (0,     true) }
+    if self > range { return (range, true) }
+    return (self, false)
+  }
+}
+
+impl ClampTable for Pos {
+  fn clamped(self, range: Pos) -> (Pos, bool) {
+    let mut output = ArrayVec::new();
+    let mut did = false;
+    for (npos, tdid) in self.iter().zip(range.iter())
+      .map(|(&pos, &rng)| pos.clamped(rng)) {
+      output.push(npos);
+      did |= tdid;
+    }
+    (output.into_inner().unwrap(), did)
+  }
+}
+
 // ---------- game state - rendering etc. ----------
 
 impl PieceState {