![]() | ![]() | ![]() | Rompecabezas un poco más complicados |
Vamos a programar el rompecabezas de la funda. Se trata de que la orden COGE FUNDA fracase, a menos que el jugador antes haya cortado las correas con el cuchillo. ¿Cómo lograr esto?
Para empezar habrá que añadir un nuevo objeto: las correas. Lo primero
es plantearse si estas correas son un objeto separado de todos los
demás, que el jugador pueda coger y llevarse, o si forman parte de la
propia funda, o si forman parte de la cama. Si forman parte de la
cama, habrá que evitar que el jugador pueda cogerlas. Esto es fácil
sin más que poner una respuesta apropiada ante la acción Take (Coger)
, como
por ejemplo: "Forman parte de la cama y no puedes llevártelas."
En cambio, si forman parte de la funda la cosa es un poco más compleja, ya que en principio el jugador no puede cogerlas, pero sin embargo si coge la funda, automáticamente debe coger también las correas. Inform está preparado para este tipo de situaciones. Es posible indicar que un objeto tiene "componentes" inseparables de él. Así, la funda tendría como un componente las correas. La librería maneja automáticamente esta situación de modo que si el jugador intenta COGER CORREAS, le dirá "Eso forma parte de la funda." Y no le dejará. En cambio, si consigue coger la funda de alguna forma, las correas también irán con él. Y si deja la funda en otra localidad, las correas también serán dejadas.
Para no complicar más la situación, haremos que las correas formen parte de la cama y por tanto no se puedan coger.
Una vez hayamos escrito el objeto correas
, hay que programar el
puzzle. Si el jugador pone CORTAR CORREAS CON CUCHILLO, marcaremos que
las correas están cortadas (activando su atributo general
). Esto lo
haremos capturando la acción Cut (Cortar)
en el objeto correas
. Por otra
parte, el objeto funda
debe capturar la acción Take
y permitir
que tenga éxito sólo si las correas
tienen activado general
(esto
es, han sido cortadas).
Ante la orden CORTAR CORREAS CON CUCHILLO, el parser generará la
acción Cut
, con noun=correas
y second=cuchillo
. Si el jugador
pone CORTAR CORREAS, a secas, entonces second
tomará el valor cero. Y
si pone CORTAR CORREAS CON CARBON, por ejemplo, entonces second
tomará
el valor carbon
. En nuestro código debemos comprobar que realmente
second
es el cuchillo, o bien cero (no se ha especificado con qué
cortar), y si no es ninguno de ellos imprimir un mensaje como "Eso no
vale para cortar."
Si el jugador pone CORTAR CORREAS sin especificar con qué, podemos hacer que el juego responda "Tienes que especificar con qué cortarlas.", pero personalmente creo que la jugabilidad mejoraría mucho si dotamos al juego de cierta "inteligencia", de modo que él mismo asuma que quiere cortarlas con el cuchillo, si el jugador lleva el cuchillo consigo.
Así pues, las diferentes situaciones a manejar son:
SI ya estaban cortadas "Ya están cortadas." y terminar SI especifica con qué cortar, y no es el cuchillo "Eso no corta" y terminar SI no espeficica con qué cortar, y no tiene el cuchillo "Necesitas tener algo que corte" y terminar EN OTRO CASO cortamos las correas
Lo que se traduce en el siguiente código Inform (fíjate en la descripción, es una rutina que cambia ligeramente según las correas estén ya cortadas o no):
Object correas "correas" Limbo with name 'correas' 'correa' 'cuero', description [; print "Son unas correas de cuero que "; if (correas has general) "cuelgan de la cama."; "sujetan la funda a la cama."; ], before [; Take: "Las correas forman parte de la cama. No puedes llevártelas."; Cut: if (correas has general) "Ya las has cortado."; if (second~=0 or cuchillo) "Eso no corta."; if ((second==0) && (cuchillo notin player)) "Necesitas tener algo cortante."; give correas general; "Cortas las correas con el cuchillo."; ], has female pluralname scenery; |
Observa que las correas comienzan en el limbo. Deben moverse al
dormitorio a la vez que la funda, es decir, al examinar el catre. De
paso aprovechamos para corregir un pequeño bug que había en el catre
de la versión anterior. Si te fijaste, al poner EXAMINA CATRE por
primera vez, el juego dice "El catre está cubierto por una funda", y
hace aparecer la funda. Al examinarlo la segunda vez dice "Sólo
restos de paja cubren el catre", asumiendo que el jugador ya ha
cogido la funda. Pero la descripción no es correcta si el jugador no
la ha cogido. La paja debe mencionarse sólo después de que el jugador
haya cogido la funda. Esto es fácil de corregir gracias a que Inform
tiene un atributo llamado moved
que se activa tan pronto como el
jugador coge el objeto (en realidad este atributo podría haberse
llamado taken (cogido)
y su función sería aún más clara).
Asi que ahora el catre debe contener el siguiente código:
description [; if (catre hasnt general) { ! Hacemos aparecer la funda y la correa move funda to Dormitorio; move correas to Dormitorio; give catre general; } if (funda has moved) "Sólo restos de paja cubren la cama."; "Una funda de tela cubre la cama."; ], |
Y la funda debe ser modificada para que impida la acción Take
a
menos que las correas hayan sido cortadas. Basta añadirle esto:
before [; Take: if (correas hasnt general) "La funda está sujeta a la cama por unas correas."; ], |
Por otro lado, si el jugador consigue coger la funda, al examinar la cama una segunda vez se le dirá que está cubierta de paja. Resulta natural que el jugador intente ahora COGER PAJA, pero ¡la paja está todavía en el Limbo! Debemos traer la paja al dormitorio en el instante en que el jugador consiga coger la funda.
Para lograrlo haremos uso de otra rutina que tienen todos los objetos
y que no habíamos necesitado hasta ahora. Se trata de la rutina after
, que es llamada por
Inform cuando la acción ha finalizado
con éxito. La rutina puede realizar las acciones que sean
convenientes, imprimir un mensaje si así lo desea, y retornar TRUE o
FALSE. Si retorna TRUE, la librería Inform no generará ningún mensaje extra
en pantalla. Si retorna FALSE, Inform generará el mensaje de éxito
habitual, por ejemplo, ante la acción Take
dirá "Cogido".
Así pues, podemos añadirle al objeto funda
el siguiente código:
after [; Take: if (paja in Limbo) { move paja to Dormitorio; "Con las correas cortadas logras coger la funda."; } ], |
![]() |
Debes recordar algo muy importante: La rutina after solo es
ejecutada para este objeto si la acción que intentó el jugador tuvo
éxito. De hecho, cuando after sea ejecutada, la acción ya habrá
terminado, y la funda ya estará en poder del jugador. Si intentó
COGER FUNDA, pero la acción fracasó, el código anterior no será
ejecutado.
|
Fíjate que, en caso de éxito, hacemos aparecer la paja, y mostramos un
mensaje. Ya que se trata de un print implícito, tras mostrar el
texto la rutina retornará TRUE, e Inform no añadirá nada más.
Fíjate también que antes de hacer aparecer la paja y emitir el mensaje
de éxito, comprobamos que la paja
esté en el limbo. Si no lo está,
no hacemos nada especial, por lo que Inform dirá su habitual
"Cogida." Este detalle es para tener en cuenta el caso de que el
jugador deje la funda en otro lugar y vuelva a cogerla más tarde. En
ese caso el mensaje "Con las correas cortadas logras coger la
funda." ya no tendría sentido, y de hecho no aparecerá, porque en ese
caso la paja estaría en el Dormitorio
y no en el Limbo
.
Como de costumbre, aquí tienes la versión completa del juego para que lo estudies, lo modifiques a tu antojo y lo pruebes.
![]() | ![]() | ![]() | Rompecabezas un poco más complicados |