IF ITALIA - Il sito Italiano sull'Interactive Fiction
VIII. ROUTINE DI CONGIUNZIONE
Visto che, per dirla semplice, l'interprete non conosce cose tipo attributi, proprietà ed oggetti se non nel senso tecnico, sono state fornite una serie di routine che servono a facilitare la comunicazione tra l'interprete ed il programma.Insieme a queste routine di congiunzione ci sono una serie di variabili globali e proprietà che sono predefinite dal compilatore ed a cui accede l'interprete. Queste sono:
GLOBALI:
object l'oggetto diretto di un verbo xobject l'oggetto indiretto self l'oggetto che si riferisce a se stesso words numero totale di parole player l'oggetto giocatore location la posizione del giocatore verbroutine l'indirizzo della routine verbo endflag se non è false (0) chiama EndGame prompt per la riga di input objects numero totale di oggetti system_status dopo determinate operazioni PROPRIETÀ:
name nome dell'oggetto before routine pre verbo after routine post verbo noun nome(i) con cui riferirsi all'oggetto adjective aggettivo(i) con cui riferirsi all'oggetto article "a", "an", "the", "some", ecc. (Insieme agli alias nouns e adjectives per noun e adjective definiti dalla libreria).
Le routine di congiunzione non sono necessarie. L'interprete possiede delle routine di default già pronte, sebbene queste potrebbero essere non molto utili per la maggior parte dei programmatori. Per questo HUGOLIB.H contiene le routine seguenti che implementano tutte le funzionalità della libreria. Se si vuole usare una routine differente al posto di quella fornita, la routine deve essere sostituita usando 'replace'.
VIII.a. Parse
La routine Parse, se esiste, viene chiamata dal parser dell'interprete. Qui il programma può modificare la riga di input prima che venga controllata la grammatica. Quello che accade è:1. La riga di input è suddivisa in parole (dall'interprete).
2. La routine Parse, se esiste, viene chiamata.
3. Il controllo ritorna all'interprete per l'esame della grammatica.Ad esempio, la routine Parse in HUGOLIB.H si occupa di cose come i pronomi ("he", "she", "it", "them") e la ripetizione dell'ultimo comando valido (con "again" o "g").
La restituzione di true da parte della routine Parse comporta una nuova chiamata al parser dell'interprete; se si restituisce false l'elaborazione prosegue normalmente. Questa cosa è utile nel caso la routine Parse abbia cambiato la riga di input in maniera sostanziale, richiedendo una riconfigurazione delle parole già suddivise.
NOTA: Visto che la routine Parse della libreria è piuttosto grande, è stata fornita una routine PreParse -- che nella libreria è stata definita vuota -- che può essere sostituita più facilmente per un parsing addizionale.
VIII.b. ParseError
La routine ParseError viene chiamata tutte le volte che un comando non è valido. ParseError viene chiamata nella formaParseError(<numeroerrore>, <oggetto>)dove <oggetto> è il numero dell'oggetto (se presente) dell'oggetto coinvolto nell'errore.NOTA: L'interprete imposta anche una variabile speciale chiamata 'parse$', usabile solo in un'istruzione print (o insieme a 'string'), che rappresenta il componente illegale di una riga di input, che sia il verbo, un nome di oggetto, un nome parziale di oggetto, od ogni altra combinazione di parole. Ad esempio:
print "La parola illegale era: "; parse$; "."Le risposte di default fornite dalla routine di errore del parser dell'interprete sono:
NUMERO
ERRORERISPOSTA 0 "What?" 1 "You can't use the word <parse$>." 2 "Better start with a verb." 3 "You can't <parse$> multiple objects." 4 "Can't do that." 5 "You haven't seen any <parse$>, nor are you likely to in the near future even if such a thing exists." 6 "That doesn't make any sense." 7 "You can't use multiple objects like that." 8 "Which <parse$> do you mean,...?" 9 "Nothing to <parse$>." 10 "You haven't seen anything like that." 11 "You don't see that." 12 "You can't do that with the <parse$>." 13 "You'll have to be a little more specific." 14 "You don't see that there." 15 "You don't have that." 16 "You'll have to make a mistake first." 17 "You can only correct one word at a time." La routine ParseError in HUGOLIB.H fornisce risposte su misura che tengono conto di cose come, ad esempio, il giocatore è in prima o seconda persona, un oggetto è un personaggio o meno, e se è maschio o femmina.
Se la routine ParseError non fornisce una risposta per un particolare <numeroerrore> deve restituire false. La restituzione di false è un segnale che indica all'interprete di continuare con il messaggio predefinito. La restituizione di 2 indica che bisogna reinterpretare l'intera riga (utile nel caso in cui una particolare sintassi sia stata intercettata come un errore, cambiata, e debba essere reinterpretata).
NOTA: Se si vogliono usare dei messaggi di errore personalizzati per le routine di parsing dell'utente, bisogna sostiture (replace) la routine CustomError con una nuova routine (chiamata con gli stessi parametri di ParseError), assicurandosi che <numeroerrore> sia maggiore od uguale a 100.
VIII.c. EndGame
La routine EndGame viene chiamata immediatamente tutte le volte che la variabile globale EndFlag è diversa da 0, senza curarsi del fatto che la funzione corrente sia o meno terminata.La routine EndGame di HUGOLIB.H reagisce in maniera differente a seconda di come sia stata impostata endflag:
endflag RISULTATO 1 Il giocatore vince 2 Il giocatore muore (3 Altra fine non fornita di default dalla routine PrintEndGame) Restituire false da EndGame comporta il termine del gioco; un valore non falso ricomincia da capo.
NOTA: Per modificare solo il messaggio visualizzato alla fine del gioco (default: "*** YOU'VE WON THE GAME! ***" e "*** YOU ARE DEAD ***") bisogna sostituire la routine PrintEndGame. Oltre che ad essere non falsi i vari valori di endflag non hanno significato, tranne per PrintEndGame.
VIII.d. FindObject
La routine si occupa di controllare tutte le proprietà necessarie, gli attributi e la gerarchia degli oggetti per determinare se un particolare oggetto è disponibile o meno. Ad esempio il child [figlio] di un oggetto parent [padre] potrebbe essere disponibile se il padre è un platform [piattaforma], ma non disponibile se il parent è un container [contenitore] (e chiuso) -- sebbene internamente la gerarchia degli oggetti sia la stessa.FindObject viene chiamata con:
FindObject(<oggetto>, <locazione>)dove <oggetto> è l'oggetto in questione e <locazione> è l'oggetto dove la disponibilità deve essere controllata. (Di solito <locazione> è una stanza, a meno che un parent differente sia stato specificato nella riga di input).FindObject restituisce true (1) se l'oggetto è disponibile, false (0) altrimenti. Restituisce 2 se l'oggetto è visibile, ma non raggiungibile fisicamente.
La routine FindObject in HUGOLIB.H considera non solo la posizione di <oggetto> nell'albero degli oggetti, ma controlla anche gli attributi del parent per vedere se è aperto o chiuso. Inoltre controlla la proprietà found_in [trovato_in], nel caso in cui <oggetto> sia assegnato a locazioni multiple invece di un determinato parent, e poi controlla la proprietà in_scope [a_portata] dell'oggetto (se esiste).
Infine il comportamento predefinito di FindObject richiede che il giocatore abbia incontrato l'oggetto per renderlo valido in un'azione, deve avere l'attributo known [conosciuto] impostato. Per evitarlo bisogna sostituire la routine ObjectIsKnown con una routine che restituisce un valore true incondizionatamente.
Esiste un caso speciale in cui l'interprete si aspetta che la routine FindObject sia utile: ed è quando la routine viene chiamata con <locazione> uguale a 0. Questo avviene tutte le volte che l'interprete ha bisogno di sapere se un oggetto è disponibile -- ignorando le regole che normalemente governano la disponibilità degli oggetti -- come quando un'istruzione grammaticale 'anything' [qualunque cosa] viene incontrata, o quando l'interprete ha bisogno di distinguere tra due o più oggetti apparentemente identici.
(Inoltre FindObject può essere chiamata dall'interprete con <oggetto> e <locazione> entrambi a 0 per ripristinare una distinzione di oggetti operata dalla libreria).
VIII.e. SpeakTo
La routine SpeakTo viene chiamata tutte le volte che una riga di input comincia con un nome di un oggetto valido invece di un verbo. In questo modo il giocatore può indirizzare i comandi ai personaggi (di solito) nel gioco. Ad esempio:Professor Plum, drop the lead pipeÈ compito della routine SpeakTo interpretare correttamente l'istruzione.SpeakTo viene chiamata con:
SpeakTo(<personaggio>)dove <personaggio> nell'esempio precedente dovrebbe essere l'oggetto Professor Plum.Le variabili globali object, xobject e verbroutine vengono impostate normalmente. Nell'esempio precedente i valori sarebbero
object leadpipequando SpeakTo viene chiamata.
xobject nothing
verbroutine &DoDropLa routine SpeakTo di HUGOLIB.H fornisce un'interpretazione base delle domande, così che
Professor Plum, what about the lead pipe?viene indirizzata alla routine verbo appropriata, come se il giocatore avesse scritto:ask Professor Plum about the lead pipeI comandi imperativi, comeColonel Mustard, stand upvengono prima indirizzati alla proprietà order_response dell'oggetto personaggio in questione. A questo punto è compito di <personaggio>.order_response analizzare verbroutine (così come object e xobject se necessario) per vedere se la richiesta è valida. Se non è prevista nessuna risposta, order_response deve restituire false.order_response
{
if verbroutine = &DoGet
"Vorrei, ma la mia schiena mi fa troppo male."
else
return false
}VIII.f. Perform
La routine Perform è quella che viene chiamata dall'interprete per eseguire la verbroutine appropriata, con gli oggetti diretti e indiritti forniti. È compito di Perform eseguire i controlli alle routine before per determinare se l'esecuzione corrisponde a verbroutine.Perform viene chiamata con:
Perform(<verbroutine>, <object>, <xobject>, <accoda>)I primi tre argomenti sono il verbo (sempre), l'oggetto (se fornito) e l'oggetto indiretto, cioè l'xobject (se fornito). Il parametro <accoda> è 0 a meno che la routine verbo debba essere chiamata più di una volta per oggetti multipli. (Come caso speciale <accoda> è -1 se object o xobject sono un numero fornito in input come una o più cifre, in modo da indicare a Perform di non effettuare le normali chiamate alle routine before/after).Ad esempio i vari comandi del giocatore potrebbero (approssimativamente, a seconda delle routine verbo e degli oggetti) generare le chiamate:
>i(Se non esiste una routine Perform, l'interprete esegue la chiamata di default a player.before, location.before, xobject.before e object.before, infine verbroutine se nessuno di questi restituisce true).
Perform(&doInventory, 0, 0, 0)>get key
Perform(&DoGet, key_object, 0, 0)>put the key on the table
Perform(&DoPutIn, key_object, table_object, 0)>turn the dial to 127
Perform(&DoTurn, dial, 127, -1)>get key and banana
Perform(&DoGet, key_object, 0, 1)
Perform(&DoGet, banana, 0, 2)
©2000 Simone Zanella e ©2000 IF Italia. E' vietata la riproduzione.