make things fall into smoke better
3 files changed, 59 insertions(+), 20 deletions(-)

M sand.el
M sand.tests.el
M todo.org
M sand.el +19 -19
@@ 386,6 386,10 @@ Each item in MESSAGES is a different lin
     (cond
      ((eq drop-to-cell 'black-hole)
       (sand//delete from-row from-column))
+     ((seq-contains '(smoke smoke1) drop-to-cell)
+      (setf (sand//at to-row to-column)
+            this-cell)
+      (sand//delete from-row from-column))
      ((and this-cell
            drop-to-cell
            (or (eq this-cell 'antimatter)

          
@@ 411,25 415,21 @@ Each item in MESSAGES is a different lin
 
 (defun sand//can-drop-to (from-thing to-thing)
   "See if FROM-THING can drop into a spot occupied by TO-THING."
-  (and from-thing
-       (sand//affected-by-gravity from-thing)
-
-       ;;antimatter doesn't react with antimatter
-       (not (and (equal from-thing 'antimatter)
-                 (equal to-thing 'antimatter)))
-
-       ;;antimatter can't take out fixed items, but can get swallowed up by black-holes.
-       (if (equal from-thing 'antimatter)
-           (or (not (sand//is-fixed to-thing))
-               (equal to-thing 'black-hole))
-         t)
-
-       ;;from-thing can move into the spot of to-thing
-       (or (not to-thing)
-           (seq-contains-p sand//consuming-items to-thing)
-           (seq-contains-p sand//consuming-items from-thing)
-           (and (eq from-thing 'rock)
-                (seq-contains-p '(sand glass) to-thing)))))
+  (cond
+   ((not from-thing) nil)
+   ((not (sand//affected-by-gravity from-thing)) nil)
+   ((not to-thing) t)
+   ((equal from-thing 'antimatter)
+    ;;antimatter doesn't react with antimatter
+    (and (not (equal to-thing 'antimatter))
+         (or (not (sand//is-fixed to-thing))
+             (seq-contains-p '(black-hole smoke smoke1) to-thing))
+         ;;explicitly return t
+         t))
+   ((seq-contains-p sand//consuming-items to-thing) t)
+   ((seq-contains-p sand//consuming-items from-thing) t)
+   ((eq from-thing 'rock)
+    (seq-contains-p '(sand glass) to-thing))))
 
 (defun sand//direction-to-drop (row column)
   "Figure out the direction that a cell at (ROW, COLUMN) should drop.

          
M sand.tests.el +38 -0
@@ 34,6 34,10 @@ BODY is the body code."
   (should-not (sand//can-drop-to 'antimatter 'angle-left))
   (should-not (sand//can-drop-to 'antimatter 'angle-right)))
 
+(ert-deftest can-drop-to/into-smoke ()
+  (should (sand//can-drop-to 'antimatter 'smoke))
+  (should (sand//can-drop-to 'antimatter 'smoke1)))
+
 (ert-deftest direction-to-drop/balloon ()
   (sand//with-new-board
    (setf (sand//at 0 3) 'balloon)

          
@@ 75,6 79,17 @@ BODY is the body code."
    (should (equal [-1 -1]
                   (sand//direction-to-drop 4 3)))))
 
+(ert-deftest direction-to-drop/antimatter/smoke ()
+  (sand//with-new-board
+   (setf (sand//at 3 3) 'smoke)
+   (setf (sand//at 2 3) 'antimatter)
+   (should (equal [1 0]
+                  (sand//direction-to-drop 2 3)))
+
+   (setf (sand//at 3 3) 'smoke1)
+   (should (equal [1 0]
+                  (sand//direction-to-drop 2 3)))))
+
 (ert-deftest tick-cell/bare-balloon ()
   (sand//with-new-board
    (setf (sand//at 5 5) 'balloon)

          
@@ 205,6 220,20 @@ Like this:
 
    (should (sand//at 2 1))))
 
+(ert-deftest tick-cell/balloon-under-antimatter-under-antimatter ()
+  (sand//with-new-board
+   (setf (sand//at 4 3) 'antimatter)
+   (setf (sand//at 5 3) 'antimatter)
+   (setf (sand//at 6 3) 'balloon)
+
+   (sand//tick-cell 6 3)
+   (should-not (sand//at 6 3))
+   (should (equal 'smoke1
+                  (sand//at 5 3)))
+
+   (sand//tick-cell 4 3)
+   (should (equal 'antimatter
+                  (sand//at 5 3)))))
 
 (ert-deftest add-angle-row/left ()
   (sand//with-new-board

          
@@ 222,6 251,15 @@ Like this:
            (setf non-nil (1+ non-nil)))))
      (should (equal non-nil 3)))))
 
+(ert-deftest move-sand/into-smoke ()
+  (sand//with-new-board
+   (setf (sand//at 4 5) 'antimatter)
+   (setf (sand//at 5 5) 'smoke)
+   (sand//move-sand 4 5 5 5)
+   (should-not (sand//at 4 5))
+   (should (equal 'antimatter
+                  (sand//at 5 5)))))
+
 (ert-deftest add-angle-row/right ()
   (sand//with-new-board
    (sand//add-diagonal-angles 5 10 4 nil)

          
M todo.org +2 -1
@@ 91,7 91,8 @@ CLOSED: [2022-12-30 Fri 15:28]
 * DONE balloon under angle-left/right should bounce balloons that way
 CLOSED: [2022-12-31 Sat 01:02]
 * TODO should a popping balloon make smoke? A small q?
-* TODO balloon under two antimatter bumps one antimatter to the side.
+* DONE balloon under two antimatter bumps one antimatter to the side.
+CLOSED: [2023-01-11 Wed 01:13]
 Like:
  *
  *   ->   *!