jueves, 30 de octubre de 2008

Un sistema de conversación decente

De rebote, gracias al código de Ad Verbum, al fín he encontrado -casi, pero me vale- lo que estaba buscando de una forma más sencilla a como lo tenía planteado meses atrás: una forma de leer muchos trocitos dentro de una cadena de texto, y con todos los "objetos-texto reconocido" que quiera. Y lo mejor de todo es que esos trocitos ni siquiera son objetos, luego no interfieren con nada, sólo pueden interferir entre ellos, y aquí entra la buena estrategia para diseñar las raíces de vocabulario de conversación.

Para empezar unifico todos los dispares y poco útiles -a mi juicio- modos de comunicarse que hay en inform:

Extend only 'grita' replace
* -> chillar
* noun -> chillar
* 'a//' creature -> chillar
* 'a//' creature topic -> hablar
* topic -> chillar;
verb 'chilla' = 'grita';

extend 'habla' replace
* ->hablar
* noun->hablar
* topic ->hablar;

extend 'pregunta' replace
* ->hablar
* noun->hablar
* topic ->hablar;

extend 'dile' replace
* ->hablar
* noun->hablar
* topic ->hablar;

extend 'pide' replace
* ->hablar
* noun->hablar
* topic ->hablar;

[hablarSub;
"Hablas, pero nadie te responde.";
];

[comohablarsub;
"Para hablar utiliza la fórmula: DECIR TAL";
];


A continuación viene el detector de cadenas, con la pequeña pega de que hay que escribir los caracteres uno a uno, y que no puedes detectar concatenación con espacios... salvo enrevesando la fórmula con más loops.

[BeforeParsing i j thisword thislength x;
bla1=0; !marca de texto detectado
bla2=0; !marca de texto detectado
bla3=0; !marca de texto detectado
bla4=0; !marca de texto detectado
for (i=parse-->0,j=1:j<=i:j++)
{
thisword = WordAddress(j);
thislength = WordLength(j);
if ( thisword -> 0 >= 'a' && thisword -> 0 <= 'z' ){ if(hablador in location){ if(thisword->0=='v' && thisword->1=='e'
&& thisword->2=='t' && thisword->3=='e') bla1=10;

if(thisword->0=='r' && thisword->1=='i'
&& thisword->1=='o') bla2=1;

if(thisword->0=='t' && thisword->1=='o' && thisword->2=='r'
&& thisword->3=='r' && thisword->4=='e') bla2=2;

!...etc


Y por fín, el personaje hablador. El nuevo sistema de hablar se detectará en el reaccionar_antes (react_before) del personaje, ya que de momento no necesito múltiples interlocutores, y todo lo que hables te lo replicará el único PSI presente, que traga con todo, hasta con su propio nombre si lo pones. Y de paso, me fusilo el Order y el Answer, que también forman parte del club de los modos de hablar múltiples:

object hablador "PSI hablador"
with name 'psi',
react_before[;

answer, order: <
ComoHablar>;rtrue;

hablar:
if (bla1==10)print "Has dicho vete";
if(bla2==1)print "Has dicho río";
if(bla2==2)print "Has dicho torre, torreón, o torrecita";
],
!...etc



Por ahora, mucho mejor que lo que tenía, y... hecho y funcional.
(El código es para compilar en Glulx, para Z-code cambian ciertas cosas)

5 comentarios:

Mel Hython dijo...

Herel, con todos esos 'if' esto que has construido es completamente adhoc. Y no hay forma de transformarlo en una librería... pero... habría una forma.

Defines una tabla que va a ser tu 'vocabulario a la PAWS', en donde tiene que estar el número a traducir y la cadena de caracteres a interpretar. El programador crearía su propia versión del vocabulario.

Al iniciar la aventura tienes que coger esta tabla y ordenarla alfabéticamente, y en el BeforeParsing en lugar de hacerlo con ifs adhoc lo que haces es recorrer con bucles la tabla anterior hasta encontrar la coincidencia y entonces devolver el código asociado.

En el fondo estás recreando el parseado de PAWS.

Al-Khwarizmi dijo...

Dios mío, pero eso de mirar letra por letra es un horror. Se convierte en un infierno para cualquier uso no trivial que quieras hacer de ello. Mira que, que Inform no permita hacer una sencilla comparación de strings...

¡Y luego aún saldrán los que dicen que se puede hacer de todo con las herramientas que existen! Tal vez se puedan hacer muchas cosas, pero si no es práctico hacerlas, la posibilidad teórica no basta.

Herel dijo...

Bueno, es copypaste copypaste, y cambiar las letritas. Algo es algo... O:)

Mel, ahora mismo no sé cómo hacer eso de leer de una tabla.
Y por supuesto, me encantaría tener un modo PAWSlike dentro de inform.

El Clérigo Urbatain dijo...

Eso es lo más injugable que he visto en mi vida. Te vuelvo a recordar el artículo de Zak sobre el tema de cadenas de texto en inform:

http://www.caad.es/informate/docs/tablas.zip

Léetelo, quizás te sea de ayuda y puedas evitar esa mazmorrosidad.

:P

Herel dijo...

¿Injugable? Quizá laborioso de programar, pero te aseguro que en jugabilidad obtienes más flexibilidad que con Etemas.

Echemos un vistazo a lo de las tablas...