Vacuum agent problem

Discussion of Common Lisp
Post Reply
davidlever
Posts: 3
Joined: Fri Mar 11, 2016 8:30 am

Vacuum agent problem

Post by davidlever » Sun Mar 13, 2016 1:16 am

I have this problem that require me to win this agent.

Code: Select all

(defmethod get-percept ((env vacuum-world-radar) agent)
  (let ((grid (copy-array (vacuum-world-grid env)))
        (home (grid-environment-start env)))
    (append (call-next-method) (list grid (grid-environment-start env)))))

(defstructure (dumb-traversal-vacuum-agent-with-radar
  (:include agent
    (program #'dumb-traversal-vacuum-agent-with-radar-program))))

(defun dumb-traversal-vacuum-agent-with-radar-program (percept)
    (destructuring-bind (bump dirt home loc heading radar home-loc) percept
        (let ((go-to-dirt (find-some-in-grid radar 'DIRT))
              (go-to-home home-loc))
            (let ((turn (turn-towards-dirt loc heading
                    (if go-to-dirt go-to-dirt go-to-home))))
                (cond
                    (turn turn)
                    (dirt 'suck)
                    ((and (not go-to-dirt) home) 'shut-off)
                    (t 'forward)
                    )))))

(defun find-some-in-grid (radar type)
    (dotimes (x (car (array-dimensions radar)))
        (dotimes (y (cadr (array-dimensions radar)))
            (let ((elems (aref radar x y)))
                (dolist (e elems)
                    (when (eq (type-of e) type)
                        (return-from find-some-in-grid (list x y)))) nil))))

(defun turn-towards-dirt (loc heading go-to-dirt)
    (let ((vdiff (- (first go-to-dirt) (first loc)))
          (hdiff (if (= (- (first go-to-dirt) (first loc)) 0)
                     (- (second go-to-dirt) (second loc))
                     0))
          (vheading (first heading))
          (hheading (second heading)))
        (let ((vdiffn (if (= vdiff 0) 0 (/ vdiff (abs vdiff))))
              (hdiffn (if (= hdiff 0) 0 (/ hdiff (abs hdiff)))))
            (let ((cprodz
                (-  (* vdiffn hheading)
                    (* hdiffn vheading))))
                ; (format t "~%loc: ~A, heading: ~A, go-to-dirt: ~A, cprodz: ~A, diffn: ~A ~A ~%" loc heading go-to-dirt cprodz vdiffn hdiffn)
                (cond
                    ((or (= (abs (- vdiffn vheading)) 2)
                        (= (abs (- hdiffn hheading)) 2)) '(turn right))
                    ((> cprodz 0) '(turn right))
                    ((< cprodz 0) '(turn left))
                    (t nil))))))

So i wrote an agent like the one below but i am stuck. Could anyone help me.

Code: Select all

(defun smart-traversal-vacuum-agent-with-radar-program (percept)
    (destructuring-bind (bump dirt home loc heading radar home-loc) percept
        (let ((go-to-dirt (find-some-in-grid radar 'DIRT))
              (go-to-home home-loc))
            (let ((turn (turn-towards-dirt loc heading
                    (if go-to-dirt go-to-dirt go-to-home))))
                (cond
                    (turn turn)
                    (dirt 'suck)
                    ((and (not go-to-dirt) home) 'shut-off)
                    (t 'forward)
                    )))))

;;; Changes in code here (Best -first search heuristic)
(defun find-some-in-grid (radar type)
	(dotimes (pos-x (car (array-dimensions radar)))
        (dotimes (pos-y (cadr (array-dimensions radar)))
 ;; Create a label called distance for local function binding to find the euclidean distance
  (labels ((distance (x y) 
              (+ (abs (- x pos-x)) 
                 (abs (- y pos-y)))))
     (destructuring-bind (width height) 
         (array-dimensions radar)
       ;; Function to find the best distance. So first declare two functions called best-distance and best
       ;; best take in the coordinate or point 
       ;; best-distance take in the distance of the calculated distance of the point
       ;; Then the algorithm will simply loop through the array dimension (width * height) and compare the distance.
       ;; The if the new x and y coordinate distance is smaller than the previous found best-distance, best-distance will store the new found distance while 
       ;; best function will store the new cooridnate .
       ;; the algorithm will then return the best coordinates
       (let ((best nil)
            (best-distance (+ width height)))
         (loop for x from 0 below width
           do (loop for y from 0 below height
                 do (loop for element in (aref radar x y)
                       do (when (eql (type-of element) type)
                             (when (<= (distance x y) best-distance)
                                (setf best (list x y))
                                (setf best-distance (distance x y))))))))
         best)))))

;;; No change to original code
(defun turn-towards-dirt (loc heading go-to-dirt)
    (let ((vdiff (- (first go-to-dirt) (first loc)))
          (hdiff (if (= (- (first go-to-dirt) (first loc)) 0)
                     (- (second go-to-dirt) (second loc))
                     0))
          (vheading (first heading))
          (hheading (second heading)))
        (let ((vdiffn (if (= vdiff 0) 0 (/ vdiff (abs vdiff))))
              (hdiffn (if (= hdiff 0) 0 (/ hdiff (abs hdiff)))))
            (let ((cprodz
                (-  (* vdiffn hheading)
                    (* hdiffn vheading))))
                ; (format t "~%loc: ~A, heading: ~A, go-to-dirt: ~A, cprodz: ~A, diffn: ~A ~A ~%" loc heading go-to-dirt cprodz vdiffn hdiffn)
                (cond
                    ((or (= (abs (- vdiffn vheading)) 2)
                        (= (abs (- hdiffn hheading)) 2)) '(turn right))
                    ((> cprodz 0) '(turn right))
                    ((< cprodz 0) '(turn left))
                    (t nil))))))

David Mullen
Posts: 78
Joined: Mon Dec 01, 2014 12:29 pm
Contact:

Re: Vacuum agent problem

Post by David Mullen » Sun Mar 13, 2016 3:38 pm

In find-some-in-grid, that last reference to BEST is outside of the let form that binds it.

Post Reply