Created
February 17, 2018 15:24
-
-
Save arthurmco/43a3020ca22d65d8e395dd143856fe7f to your computer and use it in GitHub Desktop.
simple pathfinder in clojure
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns tribalia-pathfinder.core-test | |
(:require [clojure.test :refer :all] | |
[tribalia-pathfinder.core :refer :all])) | |
(defn- squared | |
[x] | |
(* x x)) | |
(deftest test-path-euclidian | |
"Test the euclidian distance function" | |
(is (= (squared | |
(path-euclidian-distance {:xPos 1 :yPos 1} {:xPos 2 :yPos 2} ))) | |
2.0)) | |
(deftest test-path-taxicab | |
(is (= (path-taxicab-distance {:xPos 1 :yPos 1} {:xPos 2 :yPos 2} )) | |
2)) | |
(def test-path | |
"The path to what we test" | |
{:start {:xPos 10 :yPos 20} | |
:end {:xPos 20 :yPos 40}}) | |
(def test-start (test-path :start)) | |
(def test-end (test-path :end)) | |
(deftest test-calc-point | |
(is (= ((path-calc-point-score test-start test-start test-end) :f) | |
(float (path-taxicab-distance test-start test-end))) | |
"Test if :f is equal to the taxicab distance of starting-ending") | |
(is (= ((path-calc-point-score test-end test-start test-end) :f) | |
(path-euclidian-distance test-start test-end)) "Test if :f is equal to the euclidian distance of starting-ending")) | |
(deftest test-lower-score | |
(is (= (path-get-lower-score-point {:f 1.2} {:f 1.3} {:f 0.9} {:f 90} ) | |
{:f 0.9}) "First test") | |
(is (= (path-get-lower-score-point | |
{:f 0.9912} {:f 0.9913} {:f 0.9909} {:f 0.9990} ) | |
{:f 0.9909}) "Too next values test") | |
) | |
(def test-point {:xPos 2 :yPos 6}) | |
(deftest test-path-neighbors | |
(is (= (count (path-generate-neighbors test-point)) 8)) | |
(is (= (count (set (path-generate-neighbors test-point))) 8)) | |
(is | |
(= ( count (take-while | |
#(reduce (fn [oldr pos] | |
(or oldr (= pos test-point))) | |
false | |
(path-generate-neighbors %)) | |
(path-generate-neighbors test-point))) | |
8) "Check if all neighbors are neighbors of the original point too")) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns tribalia-pathfinder.core | |
(:gen-class)) | |
;;; Help to improve Tribalia pathfinder | |
(def core-path | |
"The path to what we test" | |
{:start {:xPos 10 :yPos 21} | |
:end {:xPos 20 :yPos 40}}) | |
(defn path-euclidian-distance | |
"Calculate the Euclidian distance between :pstart and :pend | |
Return the distance" | |
[pstart pend] | |
(Math/sqrt (+ (Math/pow (- (pend :xPos) (pstart :xPos)) 2) | |
(Math/pow (- (pend :yPos) (pstart :yPos)) 2)))) | |
(defn path-taxicab-distance | |
"Calculate the taxicab/Manhattan distance between two points | |
Return the distance" | |
[pstart pend] | |
(+ (- (pend :xPos) (pstart :xPos)) | |
(- (pend :yPos) (pstart :yPos)))) | |
(defn path-calc-point-score | |
"Calculate the point score of a path. Returns the path, with the point score | |
The g prop is the known movement cost, from the starting point to here | |
The h prop is the estimated movement cost, from here to end | |
The f prop is the actual score of the point. | |
The slot with the lowest 'g' score wins and will be chosen | |
" | |
[point pstart pend] | |
( -> point | |
(assoc :g (path-euclidian-distance pstart point) | |
:h (path-taxicab-distance point pend)) | |
(assoc :f (+ (path-euclidian-distance pstart point) | |
(path-taxicab-distance point pend))))) | |
(defn path-get-lower-score-point | |
"Get the point with the lower 'f' score" | |
[& args] | |
(reduce (fn [plow pact] | |
(if (< (plow :f) (pact :f)) | |
plow | |
pact)) | |
{:f 99999999} | |
(into () args))) | |
(defn path-generate-neighbors | |
"Generate neighbors for some point" | |
[point] | |
(let [px (point :xPos) py (point :yPos)] | |
[(assoc (dissoc point :xPos) :xPos (inc px)) | |
(assoc (dissoc point :xPos) :xPos (dec px)) | |
(assoc (dissoc point :xPos :yPos) :xPos (inc px) :yPos (inc py)) | |
(assoc (dissoc point :xPos :yPos) :xPos (dec px) :yPos (dec py)) | |
(assoc (dissoc point :xPos :yPos) :xPos (inc px) :yPos (dec py)) | |
(assoc (dissoc point :xPos :yPos) :xPos (dec px) :yPos py) | |
(assoc (dissoc point :yPos) :yPos (inc py)) | |
(assoc (dissoc point :yPos) :yPos (dec py))] | |
)) | |
(defn -main | |
"I don't do a whole lot ... yet." | |
[& args] | |
(println (path-euclidian-distance (core-path :start) (core-path :end))) | |
(println (path-taxicab-distance (core-path :start) (core-path :end))) | |
(println "Hello, World!")) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment