Casting SPELs
Capítulo 5:
Paseando por nuestro mundo.
Pasearnos por nuestro mundo significa acceder a otros lugares. La función w_a_l_k__direction , que toma una dirección como argumento, cambia el lugar en el cual nos encontramos, esto es, la variable global location . Tampoco aquí seguimos al pie de la letra el estilo de programación funcional.
w_a_l_k__direction(direction):= block(
[ next_: assoc_( direction,rest( assoc_(location,map), 2 ) ) ],
if listp(next_) then (
location: third (next_),
l_o_o_k() )
else "you cant go that way. ")$
Nos vuelve a ayudar aquí la función assoc_ para dar con la descripción del camino a seguir. Si existe una descripción para la dirección seleccionada, encontramos nuestra nueva posición como tercer elemento de la lista next_ , en caso contrario recibimos un aviso. El símbolo next está reservado en Maxima, razón por la cual hemos utilizado el guión bajo para evitar conflictos. Se utiliza next para describir en una sentencia for cómo debe cambiar la variable de control tras cada iteración.
Una vez hemos llegado con éxito a un nuevo lugar, echamos un vistazo alrededor con l_o_o_k() . Con w_a_l_k__direction(direction)
podemos continuar nuestro camino. Para hacer las cosas más fáciles definimos
en esta ocasión un operador-prefijo.
prefix("walk")$
"walk"(direction):= w_a_l_k__direction(direction)$
Debemos aportar una dirección a seguir como argumento. La cosa pinta de la siguiente manera:
walk west;
==> you are in a beautiful garden. there is a well in front of you.
there is a door going east from here. you see a chain on the floor.
you see a frog on the floor.
En realidad deberíamos haber utilizado 'west , pero como en nuestro juego no se le va a dar ningún valor al símbolo west , podemos obviar el uso del apóstrofo con toda tranquilidad.
Ahora vamos a construir una función que nos va a permitir tomar objetos del suelo.
prefix("pickup")$
"pickup"(object):=
if is_at( object,location,object_locations ) then (
object_locations: cons([object,'body],object_locations),
sconcat("you are now carrying the ",object,".") )
else "you cannot get that. "$
No aprendemos nada nuevo con esto. Al contrario que en walk aquí hemos definido la función dentro de la definición del operador. Con 'body se introduce en object_locations un cuarto lugar.
Cojamos la cadena:
pickup chain;
==> you are now carrying the chain.
A fin de que no tengamos que estar pendientes de las cosas que llevamos encima, necesitamos una instrucción que nos informe de ello en cualquier momento, dándonos una lista de tales objetos.
at_body():=
sublist( objects,lambda([x],is_at(x,'body,object_locations)) )$
La instrucción inventory; escribe esta lista en formato de cadena sin las comas de separación.
nofix("inventory")$
"inventory"():=
apply( sconcat,
map( lambda([x],sconcat(x," ")),
at_body() ))$
inventory;
==> chain
Para el siguiente capítulo vamos a preparar una función que nos diga si portamos un objeto determinado. Hacemos uso de la función member , que nos indica si una lista contine cierto elemento.
have(object):=
member( object,at_body() )$
Introducción |
Capítulo 1 |
Capítulo 2 |
Capítulo 3 |
Capítulo 4 |
Capítulo 5 |
Capítulo 6 |
Capítulo 7 |
Agradecimientos |
Licencia
© Mario Rodríguez Riotorto, 2006
|