BUSQUEDA.LSP



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 	PROGRAMA QUE IMPLEMENTA UNA BUSQUEDA GENERAL
;;
;;	Autor: Ing. J. Rafael R. Ochoa
;;
;;	Materia: SISTEMAS EXPERTOS
;;
;;	MAESTRIA EN SISTEMAS COMPUTACIONALES
;;
;;
;;	Noviembre 1997
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun carga ()
	(load "c:\\rafa\\busqueda.lsp"))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;  		   el comienzo del juego de los
;;   		   8 cuadritos.
;;     	Regresa: Las fichas que se encuentran 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun juego ()
  	(print "Ingrese los elementos que componen el tablero")
	(print "Se trata de 8 fichas (1 - 8) y un espacio en")
	(print "blanco (B) Cada uno de los tres renglones consta")
	(print "de tres elementos separados por un ENTER")
	(setq inicio (forma_arreglo))
	(print "Ahora dame las posiciones finales de las fichas")
	(setq final (forma_arreglo))
	(print "Las fichas que se encuentran en posicion equivocada son: ")
	(checa_posicion inicio final)
)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;	Funciones: FORMA_ARREGLO y PREGUNTA
;;   	           ya sea el arreglo inicial
;;    		   como el final
;;     	Regresa: Un nuevo ARREGLO DE 3x3
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun forma_arreglo ()
	(setq x 0)
	(setq arreglo (make-array '(3 3)))
  	(loop
		(if (eq x 3) (return arreglo))
		(format t "~%Renglon ~a: " (+ x 1))
	 	(setq y 0)
			(loop
				(if (eq y 3) (return))
				(setf (aref arreglo x y) (pregunta))
				(setq y (1+ y))) 
		(setq x (1+ x))))

(defun pregunta ()
	(read))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;	Recibe: Un ARREGLO inicial => "a_i" y un
;;		ARREGLO final (goal) => "a_f"
;; 	Proposito: Determinar la cantidad de 
;;     	Regresa: Un NUMERO
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun checa_posicion (a_i a_f)
	(setq x 0)
	(setq mal 0)
	(loop
		(if (eq x 3) (return mal))
		(setq y 0)
		(loop
			(if (eq y 3) (return))
			(if (not (equal (aref a_i x y) (aref a_f x y))) 
			    (setq mal (1+ mal)))
			(setq y (1+ y)))
		(setq x (1+ x))))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;	Recibe: Un arreglo => "arreglo"
;;    		   del "blanco"
;;     	Regresa: Una LISTA DE DOS ELEMENTOS
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun busca-blanco (arreglo)
  (dolist (i '(0 1 2))
    (dolist (j '(0 1 2))
      (if (eq (aref arreglo i j) 'b)
	  (return-from busca-blanco (list i j))))))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;	Recibe: Un arreglo => "arreglo"
;; 	Proposito: Determinar los movimientos 
;;   	           disponibles de acuerdo a la
;;  	Regresa: Una LISTA con los movimientos 
;;    		 permitidos
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun genera-mvtos (arreglo)
  (let ((loc (busca-blanco arreglo)))
    (cond
     ((equal loc '(0 0)) '(l u))
     ((equal loc '(0 1)) '(r l u))
     ((equal loc '(0 2)) '(r u))
     ((equal loc '(1 0)) '(d l u))
     ((equal loc '(1 1)) '(l r u d))
     ((equal loc '(1 2)) '(d r u))
     ((equal loc '(2 0)) '(d l))
     ((equal loc '(2 1)) '(l d r))
     ((equal loc '(2 2)) '(d r)))))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;		=> "loc-b" y el sentido del 
;; 		movimiento (una LETRA) => "dir"
;;   	Regresa: Una LISTA con la ficha a mover
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun quien-mueve? (loc-b dir)
  (cond
    ((equal dir 'r) (list (first loc-b) (1- (second loc-b))))
    ((equal dir 'l)  (list (first loc-b) (1+ (second loc-b))))
    ((equal dir 'u)  (list (1- (first loc-b)) (second loc-b)))
    ((equal dir 'd)  (list (1+ (first loc-b)) (second loc-b)))))
    
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;	Recibe: Un arreglo => "arreglo" y la 
;; 	Proposito: Ejecuta el swap
;;   	Regresa: Un nuevo ARREGLO con una nueva
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun mueve (arreglo dir)
  (let* ((loc-b (busca-blanco arreglo))
	 (quien (quien-mueve? loc-b dir))
    	(nvo-arreglo (make-array '(3 3)))
	 (renglon 0)
	(columna 0))
	(loop
		(setq columna 0)
	 	(loop
	 		(setf (aref nvo-arreglo renglon columna) 
		       		(aref arreglo renglon columna))
		 	(incf columna)
		 	(when (eq columna 3) (return)))
		 (incf renglon)
		 (when (eq renglon 3) (return)))
	(rotatef (aref nvo-arreglo (first loc-b) (second loc-b))
		 (aref nvo-arreglo (first quien) (second quien)))
	nvo-arreglo))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;	Recibe: Un arreglo => "arreglo"
;;   	Regresa: Una LISTA DE ARREGLOS con todos
;;		 las posibilidades de movimientos
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun expand (arreglo)
  (let* ((movimientos (genera-mvtos arreglo)))
    (mapcar #'(lambda (dir)
		(mueve arreglo dir))
		movimientos)))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;;busqueda_general (problema estrategia fn)
;;	nodos=estado_inicial(problema)
;;	loop
;; 		if empty(nodos) return fail
;; 		nodo=estrategia(nodos)
;;		if goal(nodo) return nodo
;; 		else nodos=fn(nodos,expand(nodo))
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;;BFS (problema)
;; 	return busqueda_general(problema,primero,append)
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;