CAAD

Comunidad de Aventuras Conversacionales y Relatos Interactivos
Fecha actual 08 Ago 2020 05:05

Todos los horarios son UTC + 1 hora




Nuevo tema Responder al tema  [ 16 mensajes ]  Ir a página 1, 2  Siguiente
Autor Mensaje
NotaPublicado: 15 Oct 2010 11:02 
Desconectado
xyzzy

Registrado: 09 Mar 2004 22:50
Mensajes: 9150
Tengo una condición por la cual el personaje tiene limitadas las acciones que puede realizar. Una de las que sí puede hacer es desplazarse de una localidad a otra, sin embargo cuando encadeno en el comando dos desplazamientos seguidos, en el segundo la excepción no se cumple y la condicion actua como si no fuera el verbo "ir".

Código:
   if(get(self,"con_granada")==true)
        { //para que salvo moverse (no arriba), o mirar se cumpla
         if(  (equals(verb,"ir") && (!args.contains("arriba"))) || equals(verb,"mirar"))   
         {return verb + " " + args;}
           
         if(equals(verb,"limpiar")&& args.contains("guerrero"))   
           {return verb + " " + args;}
         else {self.write("Lo que más te urge es deshacerte de esa granada.\n");
              end();}
        }


Citar:
>ve al corredor y luego al torreón.
Sales de la sala de armas.
Desde el salón te llegan los sonidos del banquete, el jolgorio te hace pensar en tu dama..
El corredor suele estar en penumbra, la luz de esta parte del castillo depende en gran parte del número de puertas que hay abiertas.

Lo que más te urge es deshacerte de esa granada.


Como ves no ha habido problema al acceder al corredor, pero sí al acceder a la Torre.
¿Alguna solución?

_________________
Si la mentira tuviera color, todos seríamos daltónicos...


Arriba
 Perfil  
 
NotaPublicado: 15 Oct 2010 11:14 
Desconectado
Samudio
Samudio
Avatar de Usuario

Registrado: 09 Mar 2004 16:16
Mensajes: 5312
Ubicación: Coruña
El problema es que la frase "ve al corredor y luego al torreón" se procesa así:

1. ve al corredor

2a. luego al torreón (first chance)

2b. ve luego al torreón (second chance)

Es decir, tú podrías tener algo definido para la palabra "luego" (que fuese un comando de tu aventura) y por lo tanto AGE te da la oportunidad de interceptarlo, y sólo si no lo interceptas, entonces actúa el modo "second chance" y se supone que hay un verbo elíptico ahí (ve luego al torreón).

Por lo tanto, para resolver este problema lo que tienes que hacer es poner el último write sólo si el verb es realmente un verbo:

if ( world.getLanguage().isVerb(verb) ) ...

Y si no se cumple esto, dejas pasar el parseCommand (no haciendo end()) para que así pueda entrar el modo "second chance", donde AGE te pondrá ahí el verbo elíptico.

_________________
Actúa siempre de tal modo que las decisiones de tu voluntad pudiesen servir como preceptos de una legislación universal (E. Kant)


Arriba
 Perfil  
 
NotaPublicado: 15 Oct 2010 11:22 
Desconectado
xyzzy

Registrado: 09 Mar 2004 22:50
Mensajes: 9150
Prefecto, repasaré otras situaciones similares para hacer los cambios oportunos.

Gracias
Jenesis

_________________
Si la mentira tuviera color, todos seríamos daltónicos...


Arriba
 Perfil  
 
NotaPublicado: 15 Oct 2010 17:20 
Desconectado
Semimomio
Semimomio
Avatar de Usuario

Registrado: 24 Ago 2007 00:41
Mensajes: 2023
Ubicación: Chile
Al, ¿podrías en algún momento escribir un documento formal en el que se explicara cómo funciona la filosofía y metodología del parsing de AGE? Me ha interesado y quisiera estudiarlo, para aprender sobre el parsing.

Sería un documento muy valioso. Gracias, antemano (aunque no puedas. :lol:)

Saludos. :mrgreen:

_________________
Eliuk Blau
eliukblau (AT) gmail.com
http://www.caad.es/eliukblau/


Arriba
 Perfil  
 
NotaPublicado: 15 Oct 2010 17:25 
Desconectado
Samudio
Samudio
Avatar de Usuario

Registrado: 09 Mar 2004 16:16
Mensajes: 5312
Ubicación: Coruña
Eliuk: mira en http://www.caad.es/aetheria/doc/doku.ph ... rsecommand al final, la sección que se llama "El proceso de análisis de AGE". Tiene más o menos lo que tú pides, tal vez no con un gran nivel de detalle pero sí suficiente para enterarse de cómo parse el AGE. Y si tienes dudas sobre algún paso, puedes preguntarme, claro.

_________________
Actúa siempre de tal modo que las decisiones de tu voluntad pudiesen servir como preceptos de una legislación universal (E. Kant)


Arriba
 Perfil  
 
NotaPublicado: 17 Oct 2010 22:09 
Desconectado
Semimomio
Semimomio
Avatar de Usuario

Registrado: 24 Ago 2007 00:41
Mensajes: 2023
Ubicación: Chile
Al-Khwarizmi escribió:
la sección que se llama "El proceso de análisis de AGE". Tiene más o menos lo que tú pides


FTW! :mrgreen:

_________________
Eliuk Blau
eliukblau (AT) gmail.com
http://www.caad.es/eliukblau/


Arriba
 Perfil  
 
NotaPublicado: 03 Nov 2010 08:44 
Desconectado
xyzzy

Registrado: 09 Mar 2004 22:50
Mensajes: 9150
Vuelvo a este hilo, porque el caso se ha repetido y esta vez me parece más complicado de resolver.
A lo largo de la aventura se suceden eventos que hacen que el protagonista cambie de localidad sin tener en cuenta la intención del jugador. Si uno de estos updates tiene lugar en el momento que el jugador ha escrito una orden compuesta que no puede ser llevada a cabo en la nueva localidad, el sistema imprime la frase típica de quien ha intentado hacer algo que no se puede hacer.
¿Se puede detener ese proceso de algún modo para evitar que se tengan en cuenta las ordenes emitidas por el jugador?

_________________
Si la mentira tuviera color, todos seríamos daltónicos...


Arriba
 Perfil  
 
NotaPublicado: 03 Nov 2010 10:31 
Desconectado
Samudio
Samudio
Avatar de Usuario

Registrado: 09 Mar 2004 16:16
Mensajes: 5312
Ubicación: Coruña
Pues no es muy fácil hacer eso porque los parseCommands están diseñados para que si el jugador pone "coger la manzana y comerla" todo se procese exactamente igual que si pone "coger la manzana" y luego "comerla", para facilitar las cosas al programador de aventuras en los casos "normales".

Pero poderse se puede, se puede hacer todo :D

Se me ocurre la solución siguiente:

- En el preprocessCommand (que, como sabes, sí que procesa directamente lo que ha puesto el jugador, o sea, le entra "coger la manzana y comerla"), pones una propiedad "numOrden" del jugador a 0.
- Al principio del parseCommand del jugador (que recibe las órdenes ya desmenuzadas) incrementas la propiedad "numOrden" en una unidad (y no haces end(), para que todo siga su curso normalmente, simplemente se actualiza esa propiedad para saber en qué número de orden estás dentro de la secuencia).
- Cuando cambias al jugador de habitación con esos eventos que mencionas, le pones una propiedad "desactivarOrdenesCompuestas" a true.
- Ahora al principio del parseCommand del jugador, justo después del incremento de la propiedad numOrden, haces:
Código:
   if ( get( self , "numOrden" ) > 2 && get( self , "desactivarOrdenesCompuestas" ) ) { self.writeDenial("No haces el resto de cosas que ibas a hacer.\n"); end(); }

- Y ya para rematar, en el preprocessCommand, justo antes de poner numOrden a 0, vuelves a poner desactivarOrdenesCompuestas a false para que esto no afecte a las siguientes órdenes.

Con esto te debería funcionar como tú quieres.

_________________
Actúa siempre de tal modo que las decisiones de tu voluntad pudiesen servir como preceptos de una legislación universal (E. Kant)


Arriba
 Perfil  
 
NotaPublicado: 07 Nov 2010 10:30 
Desconectado
xyzzy

Registrado: 09 Mar 2004 22:50
Mensajes: 9150
Aprovecho que tengo un rato para volver sobre este asunto.

Al-Khwarizmi escribió:
- En el preprocessCommand (que, como sabes, sí que procesa directamente lo que ha puesto el jugador, o sea, le entra "coger la manzana y comerla"), pones una propiedad "numOrden" del jugador a 0.


¿El objeto mundo puede tener propiedades?
Si es así ¿cómo accedo a ellas desde otro objeto?
¿O puedo poner un preprocessCommand en el propio objeto jugador?

_________________
Si la mentira tuviera color, todos seríamos daltónicos...


Arriba
 Perfil  
 
NotaPublicado: 07 Nov 2010 11:00 
Desconectado
Samudio
Samudio
Avatar de Usuario

Registrado: 09 Mar 2004 16:16
Mensajes: 5312
Ubicación: Coruña
El objeto mundo en sí no puede tener propiedades, porque no es una entidad. Pero desde un método (preprocessCommand o el que sea) puedes acceder a propiedades de cualquier entidad, así que no debería haber necesidad de poner ninguna en el mundo en sí. Todo lo que querrías poner en el mundo lo puedes simplemente poner en una entidad abstracta a la que accedas desde cualquier objeto: abstractEntity("misPropiedades"), por ejemplo. De esa forma puedes tener un almacén general de propiedades para el mundo, aunque el almacén no sea el propio mundo.

De todos modos, en la solución que te he puesto creor que lo más lógico sería que las propiedades numOrden y desactivarOrdenesCompuestas fuesen en el jugador, ya que son cosas asociadas a lo que está haciendo el jugador.

Sobre el método preprocessCommand, es un método que siempre se pone en el mundo pero AGE te pasa como parámetro el objeto correspondiente al jugador que ha puesto el comando (la declaración es String preprocessCommand ( Player jugador , String cadenaCompleta )). Por lo tanto, aunque no lo definas en el objeto jugador, puedes acceder a él y a sus propiedades.

_________________
Actúa siempre de tal modo que las decisiones de tu voluntad pudiesen servir como preceptos de una legislación universal (E. Kant)


Arriba
 Perfil  
 
NotaPublicado: 07 Nov 2010 11:05 
Desconectado
xyzzy

Registrado: 09 Mar 2004 22:50
Mensajes: 9150
Al-Khwarizmi escribió:
El objeto mundo en sí no puede tener propiedades, porque no es una entidad. Pero desde un método (preprocessCommand o el que sea) puedes acceder a propiedades de cualquier entidad, así que no debería haber necesidad de poner ninguna en el mundo en sí. Todo lo que querrías poner en el mundo lo puedes simplemente poner en una entidad abstracta a la que accedas desde cualquier objeto: abstractEntity("misPropiedades"), por ejemplo. De esa forma puedes tener un almacén general de propiedades para el mundo, aunque el almacén no sea el propio mundo.


Sí, eso es lo que estaba intentando hacer desde el propio jugador, pero al parecer me he oxidado en estos días de inactividad. xD
Voy a seguir intentándolo y si no lo consigo te volveré a consultar. :)

_________________
Si la mentira tuviera color, todos seríamos daltónicos...


Arriba
 Perfil  
 
NotaPublicado: 07 Nov 2010 11:57 
Desconectado
xyzzy

Registrado: 09 Mar 2004 22:50
Mensajes: 9150
Vale, parece que ya funciona.
Gracias :)

_________________
Si la mentira tuviera color, todos seríamos daltónicos...


Arriba
 Perfil  
 
NotaPublicado: 09 Nov 2010 12:49 
Desconectado
xyzzy

Registrado: 09 Mar 2004 22:50
Mensajes: 9150
Me estoy dando cuenta de que en el caso de que la primera de las acciones no sea posible vamos a tener el mismo problema una y otra vez. :(
Debería diseñarse un modo de evitar esto a nivel general, porque si no la labor del programador es interminable.
¿Alguna idea?

_________________
Si la mentira tuviera color, todos seríamos daltónicos...


Arriba
 Perfil  
 
NotaPublicado: 09 Nov 2010 13:26 
Desconectado
Samudio
Samudio
Avatar de Usuario

Registrado: 09 Mar 2004 16:16
Mensajes: 5312
Ubicación: Coruña
Hmm. Una forma totalmente automática de evitar eso, no la veo, porque yo creo que es algo que depende mucho de la semántica de las acciones, semántica que sólo conoce el que las programa.

Totalmente automático lo veo imposible porque por ejemplo, en el caso que planteabas antes, hay ciertas acciones que "teletransportan" al jugador a otra localidad y tú quieres que esas acciones interrumpan la cadena. Por otra parte, otras acciones hacen otras cosas diferentes y no la interrumpen. Tú distingues que las primeras deben interrumpirla y las segundas no porque sabes que lo que hacen implica que las siguientes acciones pierde el sentido en unas y en otras no; pero no hay forma automática de saber eso.

En el caso que mencionas ahora de las acciones fallidas... bueno, para acciones por defecto del AGE se podría hacer que al ejecutar una acción fallida se interrumpiera la cadena. Así, por ejemplo, en "coge la piedra y lánzala" si no hay piedra ya no intentarías lanzarla. Pero ¿seguro que eso es lo deseable siempre? Si el jugador pone "coge la espada y el escudo" y no puede coger la espada porque se lo impide un campo de fuerza o está fija al suelo o lo que sea, tal vez lo lógico sería coger el escudo igual, si se puede.

Aun suponiendo que uno interrumpa la cadena para las acciones fallidas (siempre se podría poner como opción, de forma que el programador pueda elegir si se cogería el escudo o no); queda el problema de las acciones personalizadas, ¿cuándo se considera que son fallidas y cuándo no? Tú puedes poner un end() tras dar un mensaje que semánticamente sea de éxito o de fracaso, no se distingue. Incluso hay casos donde semánticamente no está claro: si tú llamas a la puerta y nadie responde, o si coges un erizo y lo sueltas porque te has pinchado, o si blandes una espada y notas que está maldita y que ralentiza tus movimientos como si pesara treinta kilos, ¿eso son acciones fallidas que deberían detener la cadena de acciones, o no? Parece que, de nuevo, el programador debería ser el que decidiese, porque depende mucho del contexto.

Por eso digo que una solución totalmente general y automática no creo que se pueda dar. Ahora bien, lo que se me ocurre es dar una forma fácil de que:

- El programador pueda escoger si las acciones por defecto del AGE que sean claramente fallidas (como coger un escudo que no existe) interrumpen la cadena o no,
- Para las acciones personalizadas, el programador tenga una forma más o menos sencilla de especificar si interrumpen la cadena o no. Por ejemplo, que aparte del end() (finaliza esta acción) haya también un, digamos, endAll() (finaliza no sólo esta acción, sino toda la cadena de acciones de la que forme parte). El programador sería el que decidiría cuándo usa un end() y cuándo usa un endAll().

No sé si ves esto bien o tienes alguna idea mejor. ¿Algún otro sistema ha dado una solución mejor a esto?

En todo caso, si implemento esto llevará un tiempo programarlo, ya que implicará hacer bastantes cambios en las clases nucleares del AGE, no es un cambio superficial sino un añadido al algoritmo central del diseño del módulo de parsing (y que también incluye revisar todas las acciones por defecto fallidas).

_________________
Actúa siempre de tal modo que las decisiones de tu voluntad pudiesen servir como preceptos de una legislación universal (E. Kant)


Arriba
 Perfil  
 
NotaPublicado: 09 Nov 2010 14:19 
Desconectado
xyzzy

Registrado: 09 Mar 2004 22:50
Mensajes: 9150
Al-Khwarizmi escribió:
Ahora bien, lo que se me ocurre es dar una forma fácil de que:

- El programador pueda escoger si las acciones por defecto del AGE que sean claramente fallidas (como coger un escudo que no existe) interrumpen la cadena o no,
- Para las acciones personalizadas, el programador tenga una forma más o menos sencilla de especificar si interrumpen la cadena o no. Por ejemplo, que aparte del end() (finaliza esta acción) haya también un, digamos, endAll() (finaliza no sólo esta acción, sino toda la cadena de acciones de la que forme parte). El programador sería el que decidiría cuándo usa un end() y cuándo usa un endAll().

No sé si ves esto bien o tienes alguna idea mejor. ¿Algún otro sistema ha dado una solución mejor a esto?


Yo creo que con esto sería más que suficiente para la mayoría de los casos, que es de lo que se trata, después los casos puntuales ya son cosa del programador.
Es que el caso general no es tan raro, puede suceder en cualquier momento, incluso si el jugador muere podría intentar seguir con su objetivo desde el más allá. :lol:

Saludos
Jenesis

_________________
Si la mentira tuviera color, todos seríamos daltónicos...


Arriba
 Perfil  
 
Mostrar mensajes previos:  Ordenar por  
Nuevo tema Responder al tema  [ 16 mensajes ]  Ir a página 1, 2  Siguiente

Todos los horarios son UTC + 1 hora


¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 3 invitados


No puede abrir nuevos temas en este Foro
No puede responder a temas en este Foro
No puede editar sus mensajes en este Foro
No puede borrar sus mensajes en este Foro

Buscar:
Saltar a:  
Desarrollado por phpBB® Forum Software © phpBB Group
Traducción al español por Huan Manwë para phpBB-Es.COM