Skip to content

Instantly share code, notes, and snippets.

@arnar
Created January 19, 2009 12:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save arnar/48969 to your computer and use it in GitHub Desktop.
Save arnar/48969 to your computer and use it in GitHub Desktop.
;; agents.lisp
(defstruct env
(width 2)
(height 1)
(x-pos 0)
(y-pos 0)
(dirt-vector (make-array 2))
(moves-so-far 0))
(defstruct agent
(name "A")
(program nil) ;; a function of percept -> action
)
(defvar *env*)
(defun env-dirt (x y env)
(aref (env-dirt-vector env)
(+ x (* y (env-width env)))))
(defun set-env-dirt (x y env dirty)
(setf (aref (env-dirt-vector env)
(+ x (* y (env-width env))))
dirty))
;; Draws a picture of an environment
(defun print-env (env)
(let ((w (env-width env))
(h (env-height env))
(x (env-x-pos env))
(y (env-y-pos env)))
(format t " ")
(dotimes (j w) (format t "~a~0,4:@t" j))
(format t "~%")
(dotimes (i h)
(format t " ")
(dotimes (j w) (format t "+---"))
(format t "+~%")
(format t "~a~4t" i)
(dotimes (j w)
(format t "| ")
(if (and (= j x) (= i y))
(format t "A")
(format t " "))
(if (env-dirt j i env)
(format t ";")
(format t " ")))
(format t "|~%")
)
(format t " ")
(dotimes (j w) (format t "+---"))
(format t "+~%")
)
)
;; Constructs the perception for an environment
(defun get-percept (env)
(list :x (env-x-pos env)
:y (env-y-pos env)
:dirty (env-dirt (env-x-pos env)
(env-y-pos env)
env)))
;; Applies an action to an enviornment, updating all relevant fields
(defun update-env (action env)
(cond ((eq action 'suck) (set-env-dirt (env-x-pos env)
(env-y-pos env)
env
NIL
)
)
((eq action 'left) (setf (env-x-pos env)
(max (1- (env-x-pos env)) 0))
(setf (env-moves-so-far env) (1+ (env-moves-so-far env))))
((eq action 'right) (setf (env-x-pos env)
(min (1+ (env-x-pos env))
(1- (env-width env))))
(setf (env-moves-so-far env) (1+ (env-moves-so-far env))))
((eq action 'up) (setf (env-y-pos env)
(max (1- (env-y-pos env)) 0))
(setf (env-moves-so-far env) (1+ (env-moves-so-far env))))
((eq action 'down) (setf (env-y-pos env)
(min (1+ (env-y-pos env))
(1- (env-height env))))
(setf (env-moves-so-far env) (1+ (env-moves-so-far env))))
))
;; Initializes global environment
(defun init-env (width height dirt-probability)
(setf *env* (make-env :width width
:height height
:dirt-vector (make-array (* width height))))
(dotimes (i (* width height))
(setf (aref (env-dirt-vector *env*) i)
(< (random 1.0) dirt-probability))))
;; Simulates a step of an agent on the global environment
(defun simulate-step (agent performance-measure)
(let ((action (funcall (agent-program agent) (get-percept *env*))))
(update-env action *env*)
(format t "Agent ~a just performed action: ~a~%" (agent-name agent) action)
(print-env *env*)
(format t "Performance evaluation: ~a~%" (funcall performance-measure *env* agent))
))
;; Simulates while user asks to keep going, prints every step
(defun simulate (agent performance-measure)
(loop (simulate-step agent performance-measure)
(if (not (y-or-n-p "Perform another step? [y/n]: ")) (return))))
;; Simulates a given number of steps and prints the resulting performance value
(defun simulate-quiet (agent performance-measure steps)
(dotimes (i steps)
(update-env (funcall (agent-program agent) (get-percept *env*)) *env*))
(format t "Performed ~a steps of simulation, performance value: ~a~%"
stfeps (funcall performance-measure *env* agent)))
;; Simply count the number of clean squares
(defun example-measure (env agent)
(count-if #'not (env-dirt-vector env)))
;; This agent assumes a 2x1 environment
(defun example-agent-program (percept)
(if (getf percept :dirty)
'suck
(if (= 0 (getf percept :x))
'right
'left
)
)
)
;; To initialize the vacuum-cleaner environment, call
;; (init-env 10 20 .5)
;; where 10 and 20 are the width and height, respectively, and .5 is the probability
;; of a square containing dirt
;; To test an agent interactively, call
;; (simulate (make-agent :name "Simple" :program #'example-agent-program) #'example-measure)
;; To test an agent for a number of steps, call
;; (simulate-quiet (make-agent :name "Simple" :program #'example-agent-program) #'example-measure 100)
;; where 100 is the number of steps to perform
;;; Local Variables: ***
;;; indent-tabs-mode: NIL ***
;;; End: ***
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment