summary refs log tree commit diff
path: root/lib
diff options
context:
space:
mode:
authordozens2024-06-03 14:41:37 -0600
committerdozens2024-06-05 21:53:45 -0600
commit7776b2011a2585723078b275c838fd7332488d76 (patch)
treeddf78da1eb7c4a34e4771d6a2e5a74043597bfb5 /lib
parent7c07d6e6ececbf73e18a639e00b3690d4827e12a (diff)
feat: capturing cannot break a mill
refactors the way mill? is written to make it a little more versatile
Diffstat (limited to 'lib')
-rw-r--r--lib/index.fnl4
-rw-r--r--lib/mill.fnl55
-rw-r--r--lib/mill.test.fnl199
3 files changed, 132 insertions, 126 deletions
diff --git a/lib/index.fnl b/lib/index.fnl
index 7579a1d..6323160 100644
--- a/lib/index.fnl
+++ b/lib/index.fnl
@@ -2,7 +2,7 @@
 (local {: flip} (require :lib.flip))
 (local {: head} (require :lib.head))
 (local {: keys} (require :lib.keys))
-(local {: mill?} (require :lib.mill))
+(local {: mill-at?} (require :lib.mill))
 (local {: pprint} (require :lib.tableprint))
 (local {: slice} (require :lib.slice))
 (local {: tail} (require :lib.tail))
@@ -12,7 +12,7 @@
  : flip
  : head
  : keys
- : mill?
+ : mill-at?
  : pprint
  : slice
  : tail
diff --git a/lib/mill.fnl b/lib/mill.fnl
index e3b3337..14df2e7 100644
--- a/lib/mill.fnl
+++ b/lib/mill.fnl
@@ -1,45 +1,42 @@
 (local {: contains} (require :lib.contains))
 
-
 (fn get-candidates [all-mills next-move]
   "a list of mills that contain next-move"
   (icollect [_ mill (ipairs all-mills)] (if (contains mill next-move) mill)))
 
-(fn candidates->moves [candidates current-moves move player]
-  "a list of the candidate mills expressed as current moves"
-  (icollect [_ spaces (ipairs candidates)]
-    (icollect [_ space (ipairs spaces)] 
-              (if (= space move) :x (. current-moves space)))))
-
-(fn moves->mills [spaces player]
-  "a list of bools if the candidate moves + player are all the same"
-  (let [next-move (icollect [_ y (ipairs spaces)]
-                            (icollect [_ x (ipairs y)]
-                                      (if (= x :x) player x))) ]
-    (icollect [_ move (ipairs next-move)]
-      (accumulate [acc true
-                   idx m (ipairs move)]
-        (and acc (= player m))))))
-
 (fn any [t]
-	(accumulate [acc false
+  "take a list of booleans, returns true if any of them are true"
+  (accumulate [acc false
                i x (ipairs t)]
                (or acc x)))
 
+(fn move-mills [moves-list]
+  (icollect [_ moves (ipairs moves-list)]
+    (let [player (. moves 1)]
+      (accumulate [acc true
+                   _ m (ipairs moves)]
+                  (and acc (not= m 0) (= player m))))))
 
-(fn mill? [all-mills current-moves next-move player]
-  "Does the current move for the current player create a mill?"
-  (let [candidates (get-candidates all-mills next-move)
-        moves (candidates->moves candidates current-moves next-move player)
-        mills (moves->mills moves player)
-        result (any mills)]
-		result))
-
-{: mill?
+(fn candidate-moves [candidates moves]
+  "Just turning board spaces into player moves"
+  (icollect [_ spaces (ipairs candidates)]
+            (icollect [_ space (ipairs spaces)]
+                      (. moves space))))
+
+(fn mill-at? [all-mills current-moves move]
+  "Is there a mill at this move?"
+  (let [candidates (get-candidates all-mills move)
+        my-moves (candidate-moves candidates current-moves)
+        my-mills (move-mills my-moves)
+        result (any my-mills)
+        ]
+    result))
+
+{: mill-at?
  ;; not for consumption,
  ;; just for testing:
  : get-candidates
- : candidates->moves
- : moves->mills
+ : candidate-moves
+ : move-mills
  : any
  }
diff --git a/lib/mill.test.fnl b/lib/mill.test.fnl
index 8bd3522..04f7e97 100644
--- a/lib/mill.test.fnl
+++ b/lib/mill.test.fnl
@@ -1,89 +1,48 @@
 (let [{: describe
        :end test-end} (require :lib.test)
-      {: mill?
+      {: mill-at?
        : get-candidates
-       : candidates->moves
-       : moves->mills
+       : move-mills
+       : candidate-moves
        : any
        } (require :lib.mill)
       {: mills } (require :lib.constants)
-      with-mills (partial mill? mills)]
-
+      with-mills (partial mill-at? mills)]
 
   (describe "Mill" (fn []
     (describe "#get-candidates()" (fn [t]
         (t
-         (let [move 3
-							 expected [[1 2 3] [3 15 24]]
-               moves [ 1 1 0 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ]
-							]
-				 	{:given (string.format "a move of %d" move)
-					 :should "return [[1 2 3] [3 15 24]]" 
-           : expected 
-           :actual (get-candidates mills move)
-           }))
+          (let [move 3
+                expected [[1 2 3] [3 15 24]]
+                moves [ 1 1 0 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ]
+               ]
+            {:given (string.format "a move of %d" move)
+            :should "return [[1 2 3] [3 15 24]]" 
+            : expected 
+            :actual (get-candidates mills move)
+            }))
         (t
-         (let [move 1
-							 expected [[1 2 3] [1 10 22]]
-               moves [ 0 0 0 ]
-							]
-				 	{:given (string.format "a move of %d" move)
-					 :should "return [[1 2 3] [1 10 22]]" 
-           : expected 
-           :actual (get-candidates mills move)
-           }))))
-				
-
-    (describe "#candidates->moves()" (fn [t]
-          (t 
-						(let [candidates [[1 2 3] [1 10 22]] 
-								  moves [0 1 1 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 2]
-								  expected [[:x 1 1] [:x 2 2]]
-								  move 1
-								  player 2
-								  ]
-							 {:given "a list of spaces and of current moves"
-								:should "return a map of spaces to moves"
-								: expected
-								:actual (candidates->moves candidates moves move player)
-								}))
-          (t 
-						(let [candidates [[1 2 3] [3 15 24]]
-								  moves [ 1 1 0 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ]
-							 		expected [[1 1 :x] [:x 0 0]]
-									move 3
-									player 1
-									]
-							 {:given "a list of candidates and of current moves"
-								:should "return an x-map of spaces to moves"
-								: expected
-								:actual (candidates->moves candidates moves move player)
-								}))))
-
-
-    (describe "#moves->mills()" (fn [t]
-          (t 
-						(let [spaces [[:x 1 1] [:x 2 2]]
-									moves [0 1 1 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 2]
-									player 2
-									]
-							 {:given "a list of spaces and of current moves"
-								:should "return a map of spaces to moves"
-								:expected [false true]
-								:actual (moves->mills spaces player)
-								}))
-          (t 
-						(let [spaces [[1 1 :x] [:x 0 0]]
-								  moves [ 1 1 0 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ]
-									player 1
-									]
-							 {:given "a list of canditate-moves and of current moves"
-								:should "return a map of spaces to moves"
-								:expected [true false]
-								:actual (moves->mills spaces player)
-								}))))
-
-
+          (let [move 1
+                expected [[1 2 3] [1 10 22]]
+                moves [ 0 0 0 ]
+               ]
+            {:given (string.format "a move of %d" move)
+            :should "return [[1 2 3] [1 10 22]]" 
+            : expected 
+            :actual (get-candidates mills move)
+            }))
+        (t
+          (let [move 1
+                moves [2 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
+                expected [[1 2 3] [1 10 22]]
+               ]
+            {:given (string.format "a move of %d" move)
+            :should "still return [[1 2 3] [1 10 22]]" 
+            : expected 
+            :actual (get-candidates mills move)
+            }))
+        ))
+        
     (describe "#any()" (fn [t]
         (t {:given "a table of false false true"
             :should "return true"
@@ -106,36 +65,86 @@
             :actual (any [true])
            })))
 
+    (describe "#move-mills()" (fn [t]
+      (t
+        (let [moves [[1 1 1] [0 2 2]]
+              ]
+          {:given "a list of moves"
+           :should "turn them into true/false if they are mills"
+           :expected [true false]
+           :actual (move-mills moves)
+           }))
+      (t
+        (let [moves [[0 1 1] [0 2 2]]
+              ]
+          {:given "no mills"
+           :should "should return false"
+           :expected [false false]
+           :actual (move-mills moves)
+           }))
+      (t
+        (let [moves [[2 2 2] [2 0 0]]
+              ]
+          {:given "mill, no mill"
+           :should "should return true false"
+           :expected [true false]
+           :actual (move-mills moves)
+           }))
+      ))
+
+    (describe "#candidate-moves()" (fn [t]
+      (t (let [spaces [[1 2 3] [1 10 22]]
+               moves [2 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
+               ]
+         {:given "spaces [[1 2 3] [1 10 22]]"
+          :should "map to moves"
+          :expected [[2 2 2] [2 0 0]]
+          :actual (candidate-moves spaces moves) 
+          }
+         )
+       )  
+    ))
 
-    (describe "#mill?()" (fn [t]
+    (describe "#mill-at?()" (fn [t]
         (t 
           (let [move 1
-                player 1
-								moves [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
+                moves [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
+                ]
+            {:given "no mills"
+             :should "return false"
+             :expected false
+             :actual (mill-at? mills moves move)
+             }))
+        (t 
+          (let [move 4
+                moves [1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
+                with-mills (partial mill-at? mills) 
                 with-moves (partial with-mills moves)]
-            {:given (string.format "a move of P%d:%d with moves %s" player move (table.concat moves ","))
-             :should "not be a mill"
+            {:given "a mill but not at Move"
+             :should "return false"
              :expected false
-             :actual (with-moves move player)
+             :actual (with-moves move)
              }))
         (t 
-          (let [move 3
-                player 1
-                moves [1 1 0]
+          (let [move 1
+                moves [2 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
+                with-mills (partial mill-at? mills) 
                 with-moves (partial with-mills moves)]
-            {:given (string.format "a move of P%d:%d with moves %s" player move (table.concat moves ","))
-             :should "be a mill"
+            {:given "a mill"
+             :should "return true"
              :expected true
-             :actual (with-moves move player)
+             :actual (with-moves move)
              }))
         (t 
-          (let [move 3
-                player 1
-                moves [ 1 1 0 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ]
+          (let [move 1
+                moves [2 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
+                with-mills (partial mill-at? mills) 
                 with-moves (partial with-mills moves)]
-            {:given (string.format "a move of P%d:%d with moves %s" player move (table.concat moves ","))
-             :should "be a mill"
-             :expected true
-             :actual (with-moves move player)
-             }))))
+            {:given "a mill"
+             :should "return the opposite of false"
+             :expected false
+             :actual (not (with-moves move))
+             }))
+        ))
+
     (test-end))))