;; liSP PROGRAM FOR THE LABRYNTH PROBLEM ;; THERE ARE TWO DOORS IN THE LABRYNHT MARKED WITH 'D' LETTER ;; THE BLOCKS WERE MARKED WITH THE 'B' LETTER ;; THE WALLS WERE MARKED WITH THE 'W LETTER ;; THE ROBOT WAS MARKED WITH THE 'R' LETTER ;; THE ROBOT FIND HIS WAY OUT OF THE LYBRANTH THROUGH THE CLOSEST DOOR TO HIS POSITION. ;; THE ROBOT APPLY THE BFS TECHNIQUE TO FIND HIS WAY OUT OF THE LABRHYNTH ;; HE ALSO APPLYS THE SHORTEST PASS TO FIND HIS WAY OUT OF THE LYBRANTH ;; THE RESULTS WITH DIFFERENT ROBOT STARTING POSITIONS AND A SNAP SHOT OF HIS STEPS TAKEN UNITL HE FOUND HIS WAY OUT OF THE LYBRANTH WERE RECORDED (progn (DEFPARAMETER *DOOR1* '(A B)) ;;DEFINE THE DOORS AND THE ROBOT VARIABLES (DEFPARAMETER *DOOR2* '(A B)) (DEFPARAMETER *ROBOT1* '(A B)) (DEFVAR *PREVIOUSDISTANCE*) (DEFVAR *TARGETDISTANCE*) ;; DEFINE THE TWO VARIBLES WHICH REPRESENTS THE ROBOT RELATIVE DISTANCE FROM THE CLOSEST DOOR (defvar *searchpoint*) ;; DEFINE THE VAR WHICH REPRESENTS THE SCANNING POINT FOR THE POSSIBLE ROBOT LOCATION (defvar *distance1* ) ;; DEFINE THE ROBOT RELATIVE DISTANCE TO THE DOOR1 (defvar *distance2*) ;; DEFINE THE ROBOT RELATIVE DISTANCE TO THE DOOR 2 (defvar *target-door*) ;; DEFINE THE CLOSEST DOOR TO THE ROBOT LOCATION (DEFVAR *DOORWASFOUND*) ;; DEFINE THE TERMINATING VARIABLE WHEN THE ROBOT PASS THROUGH THE DOOR (defvar *firstpoint*) ;; DEFINE VARIBLES WHICH ARE USED IN THE BFS TECHNIQUE (defvar *lastpoint*) (defvar level) ;; DEFINE THE LIST OF THE 3 CONSEQUTIVE LEVELS FROM THE LYBRANTH ACCORDING TO THE ROBOT LOCATION (defun x-component (a) ;; DEFINE THE X-COMPONENT OF THE OBJECT A (CAR a)) (defun y-component (a) ;; DEFINE THE Y-COMPONENT OF THE OBJECT A (cadr a)) (defun Z-component (a) ;; DEFINE THE DESCRIPTION OF THE OBJRCT, D, w, B, OR R. (cddr a)) (defun distance (D S) ;; DEFIN THE FUNCTION WHICH COMPUTES THE DISTANCE BETWEEN TWO OBJECTS IN THE LYBRANTH (setf w (sqrt (+(* (- (x-component D ) (x-component s)) (- (x-component D ) (x-component s))) (* (- (y-component D ) (y-component s)) (- (y-component D ) (y-component s))) )))) (setq blocks (make-hash-table :size 20)) ;; DEFINE A HASH TABLE IN WHICH THE BLOCKS LOCATION WILL BE STORED(BLOCKS DATA BASE) (setq maze (make-hash-table :size 150)) ;; DEFINE A HASH TABLE IN WHICH THE LYBRANTH DESCRIPTION WILL BE STORED. (defun doors-location () ;; DEFINE THE FUNCTON WHICH INTIALIZE THE DOORS LOCATIONS (setf *door1* (list 3 9)) (setf *door2* (list 9 3))) (defun blocks-initialization () ;; DEFINE THE FUNCTION WHICH WILL BUILD BLOCKS IN THE LYBRANTH (INTIALIZE THE BLOCKS DATA BASE) (setf c 0) (setf y 0) (setf x 3) (loop (when (= y 3) (return)) (setf c (incf c)) (setf y (incf y)) (setf (gethash c blocks) (list x y))) (loop (when (= x 6) (return)) (setf x (incf x)) (setf c (incf c)) (COND ((NOT (and (= X 5) (= Y 3)))(setf (gethash c blocks) (list x y))))) (loop (when (= y 6) (return)) (setf c (incf c)) (setf y (incf y)) (setf (gethash c blocks) (list x y))) (loop (when (= x 3) (return)) (setf c (incf c)) (setf x (decf x)) (COND ((NOT (and (= X 5) (= Y 6 )))(setf (gethash c blocks) (list x y))))) (loop (when (= y 8) (return)) (setf c (incf c)) (setf y (incf y)) (setf (gethash c blocks) (list x y))) ) (defun blocks-test ( x y c) ;;DEFINE THE FUNCTION WHICH CAN ACCESS THE BLOCKS DATA BASE (setf k 1) (setf w (list x y)) (loop (setf z (gethash k blocks)) (when (equal w Z) (return t)) (when (= k c) (return nil)) (setf k (incf k)) )) (defun mazeplane () ;;DEFINE THE FUNCTION WHICH BUILDS THE LYBRANTH AND REPRESENT IT AZ WILL AS THE ROBOT POSITION GRAPHICALLY (setf a (x-component *robot1*)) (setf b (y-component *robot1*)) (setf y 1) (setf j 0) (DOTIMES (y 10) (setf x 1) (format t " ~& " ) (terpri) (Dotimes ( x 10) (cond ((AND (= x (x-component *door1*)) (= y (y-component *door1* ))) (progn (format t " ~A " "D") (setf (gethash j maze) (list X Y 'door)))) ((AND (= x (x-component *door2*)) (= y (y-component *door2* ))) (progn (format t " ~A " "D") (setf (gethash j maze) (list X Y 'door)))) ((AND (= A x) (= B y)) (progn (format t " ~A " "R") (setf (gethash j maze) (list x y 'robot) ))) ((blocks-test x y 13) (progn (format t " ~A " "B") (setf (gethash j maze) (list x y 'Block)))) (t (cond ((OR (= y 0 ) (= y 9) (= x 0) (= x 9 )) (progn (format t " ~A " "w") (setf (gethash j maze) (list x Y 'wall) ) )) (t (progn (format t " ~A " "-") (setf (gethash j maze) (list x y 'pas) )))))) (setf j (incf j)) ))) (defun search-closest-door () ;;DEFINE THE FUNCTION WHICH FIND THE CLOSEST DOORS TO THE ROBOT LOCATION (setf *distance1* (distance *door1* *robot1*)) (setf *distance2* (distance *door2* *robot1*)) (cond ((< *distance1* *distance2*) (setf *target-door* *door1*) ) ((> *distance1* *distance2*) (setf *target-door* *door2*)) (t (setf *target-door* *door1*))) (print *target-door*) (print *robot1*) (print *distance1*) (print *distance2*) (print *door1*) ) (defun building-tree-levels (D) ;; DEFINE THE FUNCTION WHICH BUILD THE DYNAMIC 3 LEVEL TREE USED FOR THE BFS TECHNIQUE (setq i 0) (setq level(list i)) (setf h (- (X-COMPONENT D) 1)) (setf *firstpoint* h) (setf *lastpoint* (+ *firstpoint* 100)) (loop (when (= i 3) (return)) (loop (when (= *firstpoint* *lastpoint*) (return)) (setf z (gethash *firstpoint* maze)) (setq level (append level (list z))) (setf *firstpoint* (+ *firstpoint* 10)) ) (setq i (+ i 1)) (setf *firstpoint* (+ h i)) (setf *lastpoint* (+ *firstpoint* 100)) (setf level (cdr level)) ) (print level) ) (defun search-closest-step () ;;DEFINE FUNCTION WHICH FINDS THE NEW POSITION TO WHICH THE ROBOT CAN (PRINT "I AM NOW ON THE SEARCH-CLOSEST-STEP PROCESS") ;;MOVE ACCORDING TO THE BFS TECHNIQUE AND THE CLOSEST DOOR (search-closest-door) (setf *PREVIOUSDISTANCE* (distance *target-door* *robot1*)) (setf i 0) (loop (progn (SETF I(INCF i)) (setf *searchpoint* (CAR level)) ) (when (OR (eq *searChpoint* nil) (EQ *DOORWASFOUND* T)) (progn (mazeplane) (print "end of the job") (return))) (progn (setf *TARGETDISTANCE* (distance *target-door* *SEARCHPOINT*)) (cond ((and(< *TARGETDISTANCE* *PREVIOUSDISTANCE*) (OR (EQUAL (Z-COMPONENT *SEARCHPOINT*) '(PAS)) (EQUAL (Z-COMPONENT *SEARCHPOINT*) '(DOOR)))) (progn (setf *PREVIOUSDISTANCE* *TARGETDISTANCE*) (setf *robot1* (list (car *SEARCHPOINT* ) (cadr *SEARCHPOINT*))) ;;(PRINT "NEW ROBOTPOSITION") ;;(PRINT *ROBOT1*) (mazeplane) )) ((= *TARGETDISTANCE* 0) (SETQ *DOORWASFOUND* T))) (setf level (cdr level)) ))) (DEFUN ROBOT-ESCAPE () ;;THE MAIN FUNCTION THROUGH WHICH THE USER RUNS THE PROGRAM AND DEFINE THE ROBOT STARTING POSITION (SETF H (READ)) (SETF D (READ)) (SETF *ROBOT1* (LIST H D)) ;; THIS FUNCTION CALLS THE MOVE FUNCTION WHICH GUIDES THE ROBOT TO HIS WAY OUT OF THE LYBRANTH (PRINT *ROBOT1*) (SETQ *DOORWASFOUND* NIL) (mazeplane) (LOOP (WHEN (EQUAL *DOORWASFOUND* T) (PROGN (PRINT " haaaaaaaaaaaaaaaahhh I AM OUT OF THE MAZE ") (RETURN))) (MOVE) ) ) (DEFUN MOVE( ) ;; DEFINE THE FUNCTION WHICH GUID THE ROBOT TO HIS WAY OUT OF THE LYBRANTH (BUILDING-TREE-LEVELS *ROBOT1*) (SEARCH-CLOSEST-STEP) ) (doors-location) (blocks-initialization) )