Newsgroup: it.comp.giochi.avventure.testuali
Titolo: [I6] prendere le creature

supponiamo di voler inserire un personaggio non giocatore che però possa 
essere preso e messo in  inventario (tipo un pappagallo, un grillo 
parlante, un folletto, etc...)
quale è la soluzione migliore?

 parlante, un folletto, etc...)
A 'naso' direi mantenerlo animato ma scrivere le before per il
prendi/lascia in modo da consentirne la manipolazione

 prendi/lascia in modo da consentirne la manipolazione
č quello che pensavo di fare, solo che mi crea alcuni inconvenienti:
quando ci sono piů personaggi nella medesima locazione ed il giocatore
digita "parla" (o qualsiasi altro verbo "life") senza indicare altro, 
normalmente compare un messaggio che chiede essere piů precisi...
ora sembra invece che il parser decida che il png trasportata sia "piů 
vicino" e quindi lo sceglie.
la cosa non mi piace molto (ok č una sottigliezza, ma che volete...)
e non riesco a capire dove intervenire per impedirlo.
suggerimenti sono apprezzati...
ciao

 
mmm, ho appena "scoperto" che se do l'attributo concealed nel momento in
cui il png è trasportato quest'ultimo passa in secondo piano per il parser.
chi sa dirmi dove e come viene gestita la scelta di un oggetto non 
specificato nel comando, ovvero come influiscono gli attributi e le 
posizioni dell'oggetto nella scelta dello stesso?
chooseobject sembra unicamente permettere di influenzare la scelta nel 
caso di ambiguità, ma se il parser decide che tale ambiguità non esiste 
perchè un oggetto è trasportato o nascosto o altro?

 perchè un oggetto è trasportato o nascosto o altro?
Secondo me ti devi tuffare in quell'incubo di codice che implementa le
regole di scoping... in fin dei conti e' cosi' che stabilisce la
"raggiungibilita'" e quindi probabilmente il "punteggio" di priorita'
(in TADS la questione e' MOOOOLTO piu' esplicita, come impostazione lo
preferisco ad inform sotto molti punti di vista)

 "raggiungibilita'" e quindi probabilmente il "punteggio" di priorita'
è proprio un incubo, la soluzione dovrebbe essere nella routine 
Adjudicate in parserm.h, ma nelson solo sa come viene costruito il 
meccanismo di punteggi e se è possibile modificarlo...
tra l'altro nel manuale parla sempre di come aggiungere allo scope mai 
di come togliere...

perchè un oggetto è trasportato o nascosto o altro?
nonzo. :)
max "torredifuoco" bianchi

 mhmhmhm. questo codice sembra funzionare:
effettivamento nell'esempio da te indicato il problema non si presenta,
anzi l'attributo concealed, messo o meno, non modifica il comportamento 
del gioco:
 >parla
a chi vuoi parlare? !il parser non sceglie
 >prendi pappagallo
ok
 >parla
(al bambino) !il parser scegli il bambino (perchè poi non lo so)
blabla
  ciò mi fa pensare che il diverso comportamento che ricevo io (dove 
invece al secondo "parla" sceglierebbe il pappagallo (a meno di dare a 
quest'ultimo l'attributo concealed), possa dipendere da modifiche ed 
estensioni inserite altrove (anche se non saprei dove andare a sbattere 
la testa)
ho trovato sul DM4 dove parla della meccanica dei punteggi assegnati 
nella ricerca del matching delle parole a pagina 240
1000xC punti con C tra 0 e 9 come assegnato nella routine chooseobject 
(0 di default)
500 punti se è nell'inventario o se è un personaggio ed il verbo è 
ask,tell,askfor
100 punti se non è concealed (e qui si spiega perche se do questo 
attributo il parser fa una scelta differente)
etc...
NOTA per vedere i punteggi durante il gioco nel matching degli oggetti 
bisogna impostare trace > 4
il tutto è parecchio complicato, e l'unico modo semplice di intervenire 
sul meccanismo sembra essere utilizzando la routine ChooseObject().
Che peraltro ha un peso notevole dando come minimo 1000 punti.
Inserendo infatti questa funzione nell'esempio:







[ChooseObjects obj code;
     if (code==2) {
                    if (action_to_be == ##ask or ##tell or ##askfor && 
parent(obj)==player) return 9; !punteggio massimo esageriamo :-)
     }
];
Include "ItalianG";
*********************************************************************
Il comportamento del parser cambia:
 >parla
a chi vuoi parlare? !il parser non sceglie
 >prendi pappagallo
ok
 >parla
(al pappagallo) !la routine interviene e cambia la scelta
Squawk!
A questo proposito devo dire che il manuale non è proprio chiarissimo, 
io avevo inteso che la routine poteva essere usata solo in caso di 
ambiguità ovvero quando il parser risponde che "a chi vuoi parlare?" o 
"cosa vuoi prendere?" ed avevo ignorato come invece potessere essere 
utilizzata per far cambiare scelta al parser stesso.
Rimane comunque il problema, a questo punto, che se è facile dare la 
precedenza ad un oggetto lo è molto meno togliergli "visibilità" dal 
momento che le possibilità rimangono solamente dargli l'attributo 
concealed (-100punti) o scenery (-10punti)
Se qualcuno sa se esistono altri modi per abbassare il punteggio di 
matching del parser batti un colpo...
ciao
marco
post scriptum:
ecco i punti nell'esempio originale per il secondo comando parla:
      Tu (20) in l'Il tuo studio : 571 points
      Il bambino (28) in l'Il tuo studio : 676 points
      Il piccolo pappagallo (27) in te stesso : 556 points
nell'esempio con l'intervento chooseobject:
      Tu (20) in l'Il tuo studio : 1571 points
      Il bambino (28) in l'Il tuo studio : 1676 points
      Il piccolo pappagallo (27) in te stesso : 9556 points
ed infatti ha aggiunto 9000 punti al pappagallo, ma perche' i 1000 agli 
altri due oggetti? boh

 altri due oggetti? boh
La return implicita di una funzione property e' false ovvero 0
La return implicita di una funzione standalone e' true, ovvero 1 :P
In caso di dubbio meglio specificare il valore desiderato... i default
sono comodi, ma in questo caso... brrrrr

When performing a LoopOverScope. 
max "torredifuoco" bianchi
p.s. mi sa che l'entry point routine chooseobject non influisce piu'
di tanto.
p.p.s. gli esercizi!! 8)

matching del parser batta un colpo...
anch'io aborro i punteggi di matching... ;) ho provato a implementare
delle nuove regole di scope, dicevo, e ce l'ho quasi fatta. visto che
il comportamento di default del parser dell'esempio e' di scegliere il
bambino o rispondere "a chi vuoi parlare?", ho provato a fargli
scegliere in ogni caso il pappagallo se si trova nello stesso parent
del bambino. il codice e' bacato, ad esempio su sequenze come "prendi
tutto", "prendi pappagallo", "parla", "parla" mi risponde con un "a
chi vuoi parlare?" e se continuo con "i" o "l" e "parla" torna a miti
consigli e sceglie il pappagallo!
poi ho provato del codice equivalente (quasi identico) al tuo
utilizzando la simpatica chooseobject. sempre puntando in direzione
pappagallo - che inizialmente e' sulla scrivania. sul primo "parla"
sceglie pappagallo, ma gia' dal secondo risponde "hey! puoi farlo solo
con esseri viventi." bloccandosi e salutando per sempre il pennuto.
altro baco.
infine mi sono fatto ispirare dal §33 del dm4, esercizio 105, e ho
esteso la grammatica di 'parla', scrivendo *a manina* una piccola
routine di disambiguazione. questa funziona ma e' primitiva... in
pratica sceglie sempre la creatura che ha la priorita' piu' alta - ho
definito la classe talkingcreature e la proprieta' priority, che si
puo' cambiare a seconda della situazione da codice. su "parla" la
routine d'azione fa un confronto tra le priority degli oggetti della
classe talkingcreature in scope.
sarebbe bello ottenere qualcosa del genere: "a chi vuoi parlare, al
bambino o al pappagallo?" "pappagallo" "squawk"...
comunque ecco il codice: ho commentato via quello relativo ai due
tentativi falliti. puoi provare a modificarlo, se vuoi.
*****************************************************************************
Constant Story "GALLO2";
Constant Headline "^Una piccola IF con Inform che prova
  a prendere un bambino e a parlare con un pappagallo.^";
Constant MANUAL_PRONOUNS;
Include "Parser";
Include "VerbLib";
Include "Replace";
[ Initialise; location = study; "^Ciao!^"; ];
Class TalkingCreature;
Class Room
  with description "Una stanza vuota.",
  has light;
 
Class Furniture
  with before [; Take, Pull, Push, PushDir:
  			print_ret (The) self, " @`e troppo pesante.";
],
  has static supporter;
Room study "Il tuo studio";
Furniture -> desk "scrittoio"
  with name 'scrittoio' 'scrivania' 'tavolo';
 
Object -> -> phone "vecchio telefono"
  with name 'vecchio' 'telefono',
       description "Sembra vecchio ma funzionante.";
TalkingCreature -> -> parrot "piccolo pappagallo"
  with name 'piccolo' 'pappagallo' 'pappa' 'gallo' 'pap',
       description "@`E colorato come un arcobaleno.",
       before [;
		Take:
			move self to player;
			"Lentamente e con la massima delicatezza
			raccogli il pappagallino.";
		Drop:
			move self to location;
			"Appoggi a terra il pappagallino.";
       ],
       life "Squawk!!",
       priority 100,
  has animate;
TalkingCreature -> baby "bambino"
  with name 'bambino' 'bambi' 'bam',
       description "Ha circa due anni.",
       before [;
		Take:
			move self to player;
			"Prendi in braccio il bambino.";
		Drop:
			move self to location;
			"Appoggi a terra il bambino.";
		Examine:
			self.priority = 150;
			rfalse;
       ],
       life "Mama!",
       priority 50,
  has animate;
![ InScope;
!	if (scope_reason == TALKING_REASON && parrot in location &&
baby in location && noun == nothing) {
!		PlaceInScope(parrot);
!		rtrue;
!	}
!	if (scope_reason == TALKING_REASON && parrot in player && baby
in player && noun == nothing) {
!		PlaceInScope(parrot);
!		rtrue;
!	}
!	if (scope_reason == TALKING_REASON && parrot in desk && baby
in desk && noun == nothing) {
!		PlaceInScope(parrot);
!		rtrue;
!	}
!	rfalse;
!];
![ ChooseObjects obj code;
!	if (code == 2) {
!		if ((action_to_be == ##Tell || action_to_be == ##Ask
|| action_to_be == ##Askfor) && parent(obj) has supporter) return 5;
!		if ((action_to_be == ##Tell || action_to_be == ##Ask
|| action_to_be == ##Askfor) && parent(obj) == location) return 4;
!		if ((action_to_be == ##Tell || action_to_be == ##Ask
|| action_to_be == ##Askfor) && parent(obj) == player) return 3;
!	}
!];
Include "ItalianG";
[ DefaultTellSub x o p;
	objectloop (x ofclass TalkingCreature) { ! non has animate
perche' anche il selfobj has animate ma non ha priority... sarebbe da
aggiustare
		if (TestScope(x)) {
			if (o == nothing && p == 0) {
				o = x;
				p = x.priority;
			}
			if (x.priority > p) {
				o = x;
				p = x.priority;
			}
		}
	}
	print "(con ", (the) o, ")^";
	<<tell o>>;
];
Extend 'parla' first * 			-> DefaultTell;
*****************************************************************************
max "torredifuoco" bianchi
p.s. prima o poi faccio partire un bel treddino su raif, se gia' non
ci hai pensato tu (non lo sto seguendo in questi giorni).

];
max "torredifuoco" bianchi

bambino o al pappagallo?" "pappagallo" "squawk"...
ok, fatto. c'e' del codice - verso la fine del § 30 del dm4 - che
mostra come implementare una feature di "adventure" (1975): scrivendo
il nome di una locazione gia' visitata e adiacente ci si muove nella
sua direzione. l'approccio e' utile anche nel caso "inferire l'oggetto
e fare disambiguation".
si tratta di...
1) estendere opportunamente la grammatica di 'parla', in modo da
distinguere i casi in cui siano presenti nessuna creatura parlante,
una o piu' d'una. nell'ultimo caso stampa la fatidica domanda "a chi
vuoi parlare...".
2) usare l'entry point unknownverb per la risposta, che puo' giungere
solo al turno successivo alla domanda (non usate timer o daemon per
carita'). la routine si occupa di distinguere le risposte valide da
quelle non valide e dice al parser di trattarle come se fossero parte
delle grammatica di un verbo "non riconoscibile" definito all'uopo.
3) scrivere l'entry point printverb per gestire i messaggi d'errore.
4) fare attenzione alle variabili globali e agli array, una bella
routine "spazzina" e' indispensabile (io ne ho usati 1 e 1
rispettivamente).
forse si puo' fare meglio, ma per adesso mi accontento: funziona. non
posto il codice a causa della sua sconveniente lunghezza (oltre 200
linee). se siete curiosi, mandatemi una email.
max "torredifuoco" bianchi