/*
 * ej2.pl
 * parcial logica -- primer cuatrimestre 2004
 *
 * Debe escribir el programa Prolog que simule los movimientos
 * de una tortuga en un tablero cuyas dimensiones vienen dadas
 * por el hecho:
 *               dimension(N,M).
 *
 * El estado de la tortuga se representa madiante un termino
 * de la forma:
 *               tortuga(X, Y, D)
 * donde X e Y son enteros positivos que representan las
 * coordenadas horizontal y vertical de la posición del plano
 * ocupada por la tortuga, y D la orientacion de la tortuga,
 * representada por las constantes: este, oeste, norte y sur.
 * La tortuga puede moverse avanzando una posición en la dirección 
 * actual (siempre que no se salga del plano), o bien puede variar 
 * su dirección, girando 90 grados a la derecha (sin desplazarse
 * de su posición original), para representar estos movimientos
 * utilizaremos las constantes avanza y gira, respectivamente.
 *
 * a) Defina el predicado:
 *                mover(Eini, Movs, Efin).
 * que dados el estado inicial Eini de la tortuga y una lista de 
 * movimientos Movs, determine el estado final Efin, tras efectuar
 * los movimientos Movs.  Por ejemplo, suponiendo un plano de 
 * dimensiones lo suficientemente grandes:
 *   ?- mover(tortuga(2,3,este),
 *            [avanza, gira, gira, gira, avanza, avanza, gira, gira],
 *            Efin).
 * Efin = tortuga(3,5,sur)
 * 
 *
 * b) Defina el predicado:
 *             camino(Eini, Movs, Recorrido)
 * que dados el estado inicial Eini, y una lista de movimientos Movs
 * determine el camino recorrido por la tortuga tras efectuar los
 * movimientos Movs.  El camino sólo debe almacenar las posiciones
 * visitadas por la tortuga, independientemente del sentido de la 
 * orientación.  Por ejemplo, suponiendo un plano lo suficientemente
 * grande, tendremos:
 *
 * ?- camino(tortuga(2,3,este),
 *           [avanza, avanza, gira, avanza, avanza, avanza], Rec).
 * Rec = [ [2,3], [3,3], [4,3], [4,2], [4,1] ]a
 *
 * Tablero:
 *                         norte
 *          +-----------------------------------+
 *        8 | 1,8 |     |     |     |     | 6,8 |
 *          |-----+-----+-----+-----+-----+-----|
 *        7 |     |     |     |     |     |     |
 *          |-----+-----+-----+-----+-----+-----|
 *        6 |     | 2,6 |     |     |     |     |
 *          |-----+-----+-----+-----+-----+-----|
 *        5 |     |     |     |     |     |     |
 * oeste    |-----+-----+-----+-----+-----+-----| este
 *        4 |     |     |     |     |     |     |
 *          |-----+-----+-----+-----+-----+-----|
 *        3 |     |     |     |     |     |     |
 *          |-----+-----+-----+-----+-----+-----|
 *        2 |     |     |     |     |     |     |
 *          |-----+-----+-----+-----+-----+-----|
 *        1 | 1,1 |     |     |     |     | 6,1 |
 *          +-----------------------------------+
 *             1     2     3     4     5     6
 *                         sur
 */

inicial :-
	ejemplo_mover.

inicial :-
	ejemplo_camino.


ejemplo_mover :-
	mover(tortuga(2,3,este),
          [avanza, gira, gira, gira, avanza, avanza, gira, gira],
          Efin),
	write(Efin), nl.

ejemplo_mover :-
	write('fallo'), nl.



ejemplo_camino :-
	camino(tortuga(2,3,este),
	       [avanza, avanza, gira, avanza, avanza, avanza],
		   Rec),
	write(Rec).

ejemplo_camino :-
	write('fallo'), nl.




dimension(40,80).

/*
 * un_avance(Tortuga1, Tortuga2).
 * desde la posicion Tortuga1 se hace avanzar la
 * tortuga un casillero si es posible porque hay
 * espacio.  Si  no hay espacio la nueva posicion
 * Tortuga2 coincide con Tortuga1.
 */

un_avance( tortuga(X,Y1,norte), tortuga(X,Y2,norte) ):-
	dimension(_N,M),
	(
		Y1 < M, Y2 is Y1 + 1, !
		;
		Y2 is Y1
	).

un_avance( tortuga(X,Y1,sur), tortuga(X,Y2,sur) ):-
	(
		Y1 > 0, Y2 is Y1 - 1, !
		;
		Y2 = Y1
	).

un_avance( tortuga(X1,Y,este), tortuga(X2,Y,este) ):-
	dimension(N,_M),
	(
		X1 < N, X2 is X1 + 1, !
		;
		X2 = X1
	).

un_avance( tortuga(X1,Y,oeste), tortuga(X2,Y,oeste) ):-
	(
		X1 > 0, X2 is X1 - 1, !
		;
		X2 = X1
	).

/*
 * un_giro(Tortuga1, Tortuga2).
 * en la posicion actual, se mueve 90 grados a la derecha
 * la orientacion de la tortuga.  El resultado es Tortuga2.
 */

un_giro( tortuga(X,Y,norte), tortuga(X,Y,este)  ).
un_giro( tortuga(X,Y,este),  tortuga(X,Y,sur)   ).
un_giro( tortuga(X,Y,sur),   tortuga(X,Y,oeste) ).
un_giro( tortuga(X,Y,oeste), tortuga(X,Y,norte) ).


/* un_movimiento( Tortuga1, Movimiento, Tortuga2 ).
 * Se inicia la tortuga en Tortuga1, se aplica el 
 * movimiento Movimiento, lo cual pone a la tortuga
 * en el estado Tortuga2
 */

un_movimiento(T1, avanza, T2 ) :- un_avance(T1, T2).
un_movimiento(T1, gira,   T2 ) :- un_giro(T1, T2).




mover(E, [], E).

mover(E1, [Mov|RestoMovs], E2) :-
	un_movimiento(E1, Mov, E3),
	mover(E3, RestoMovs, E2).




camino(_T, [], []).

camino(tortuga(X1,Y1,Orientacion), [avanza|Movs], [[X1,Y1]|Rs]) :-
	un_avance(tortuga(X1,Y1,Orientacion), T2),
	camino(T2, Movs, Rs).

camino(T1, [gira|Movs], Rs) :-
	un_giro(T1, T2),
	camino(T2, Movs, Rs).


/* ej2.pl */
