Help!!!

Hi guys, i am making a game in which I need a different keyboardprimitive () job.
Usually it reads the input until you press ENTER, and then it goes on a newline.
I need instead that it reads the input until you press SPACE BAR, and it doesn’t goes on a newline.

I tried to look up at the parserm.h library renaming in in .txt but couldn’t find a solution, any ideas?

Z-machine or Glulx?

I am not very proficient in the Z-machine, but on Glulx with Glk you would have to do this with character input instead of line input. (glk_set_terminators_line_event almost does what you want, except that it’s restricted to special keycodes.) Jon Ingold has been working on an extension that simulates line input with character input; it might be a good starting point.

Ok, maybe I can just call a Redarray (); and then split the big array into single array for every word?
I need to record an array for each word in the sentence.
Is there a function to split up vectors in single words (words are separated by spacebar)? Any ideas? :slight_smile:

Two preliminary questions occur to me: (1) Are you using Inform 6 or Inform 7? (2) What exactly is your goal, in terms of what you want the game to do?

The first reason I ask that second question is because it appears you may be trying to recreate the parser from scratch. That’s not likely to be necessary – and just separating out the words is only the beginning of the process. The second reason is because the game is probably going to need to put its output on a line below the prompt, so I’m not sure what you gain by not waiting for a carriage return.

The specifics of how you would do what you’re trying to do would differ, depending on whether you’re using I6 or I7.

Well, you’re right.

  1. Ok, so I’m using inform 6
  2. My goal is to ask the player some open questions, and evaluate his answer in terms of score, let’s do an example:

My name is Nicola, I live in Rome
so i’m gonna ask the player:

Open question: What’s my name and where I live?
Player answer: your name is nicola, you live in rome.

Now the program is gonna record this answer as an array.
Then I know that to evaluate this open question, i’m gonna check if it contains the right keywords: in this case the keywords are “nicola” “rome”.

So I need to say to the program: “scan if the array contains the keywords, and add +1 score for each keyword that the array contains”

This case the player answer contains two keywords, so the score is gonna raise +2.

How i’m gonna do this?
I want inform to split the player answer array into multiple arrays (one for each word), then i’m gonna use the function:

if ((CmpStr(word1, keyword1))==1)
{
score++;
};

I’m gonna write one of this for each word of the player answer, so there will be many CmpStr function that will check if any word contained in the player answer corresponds to the keywords.
This way I can evaluate the player response to an open question.
I’m ovviously previously defining what the keywords are with the PrintToBuffer function, and I’m reading the array with the ReadArray function.

Then I miss the splitting function, actually readarray just reads a big array (that contains the whole answer), still I need small arrays, that contains the single words of the answer.

Hope I explained that clearly, ask me for further explications, hope you can solve this problem :wink:

You may be able to do most or all of what you want to do using the parse_name function. This is what I was wondering about.

If you look it up in the DM4, you’ll see that parse_name lets you count up the number of matching words and return the result. You would need to create a fake object of some sort, and put it in scope, in order to use its parse_name.

One limitation that you’ll have to think about is that the parser will expect to see a verb of some kind before the string of words that may or may not be the name of this fake object. To do that, you might want to insert a fake verb word (such as “try”) before the command is considered by parse_name.

Look up the BeforeParsing entry point. I’m not sure this will work for you, as I don’t know if it lets you add a new word as word 1. Chapter 31 of the DM4 talks about the business of parse tokens – you may find something useful there.

In a nutshell, what I’m suggesting is this:

(1) Using BeforeParsing, convert “your name is nicola, you live in rome” to “try your name is nicola you live in rome” (note that I got rid of the comma).

(2) Create a fake object with a parse_name that checks for “nicola” and “rome”.

(3) When the game asks that question, move this object into the room with the player. (You have to have at least one room, even if it’s invisible.)

(4) Have parse_name save the number of matching words, using a property of the object.

(5) Create a verb for “try”.

(6) Write a before response for the Try action that checks the number of matching words and prints out a suitable response.

(1) Using BeforeParsing, convert “your name is nicola, you live in rome” to “try your name is nicola you live in rome” (note that I got rid of the comma).
(2) Create a fake object with a parse_name that checks for “nicola” and “rome”.
(3) When the game asks that question, move this object into the room with the player. (You have to have at least one room, even if it’s invisible.)
(4) Have parse_name save the number of matching words, using a property of the object.
(5) Create a verb for “try”.
(6) Write a before response for the Try action that checks the number of matching words and prints out a suitable response.

Your indications soundend pretty cool, so I decided to stand on at night to try them.
You said you was wondering if that was actually possible (open question aren’t something pretty concerning inform), but I found those hints useful, except that I had to learn everything about parse_name.

That’s what I approximately made:

The mocking object:

Object book_mineral “libro sui minerali” ,
with parse_name [;
if (NextWord() == ‘tomato’ or ‘fried’) opscore++;
if (NextWord() == ‘fried’ or ‘tomato’) opscore++;
if (NextWord() == ‘tomato’ or ‘fried’) opscore++;
if (NextWord() == ‘fried’ or ‘tomato’) opscore++;
if (NextWord() == ‘tomato’ or ‘fried’) opscore++;
if (NextWord() == ‘fried’ or ‘tomato’) opscore++;
if (NextWord() == ‘tomato’ or ‘fried’) opscore++;
if (NextWord() == ‘fried’ or ‘tomato’) opscore++;
if (NextWord() == ‘tomato’ or ‘fried’) opscore++;
if (NextWord() == ‘fried’ or ‘tomato’) opscore++;
],
has ;

That’s able to catch 10 words, and if 1 of these are “tomato” or “fried” then opscore++ (Global constant).
Then as you said in point 4, the mocking object is able to record num of matching words, Cool :sunglasses:

Object is in the same room, ok, but about the “try” was impossible to make waht you said, actually if you player, declare “try your name is nicola you live in rome”, inform doesn’t recognised the subject of try and replicates “You can’t see any such thing.”
I think it’s due to the parse_name, anyway I solved easily on this (went over English.h, erased “You can’t see any such thing.”, and then print myself the suitable response.

Coming to the end, when the object recorded the constant “opscore” I realised it wasn’t just anymore an idea.
At last I didn’t succeed in the big deal, as you can observe, I didn’t mentioned the point 1 of your project.

I actually couldn’t find the way to make BeforeParsing adding the verb at the beginning of the input, that’s really the ending point, i look up at DM4, but I couldn’t do nothing about it, so I need the BeforeParsing Code that tranforms the user inputs adding the word
( an answer like maybe “your name is nicola, you live in rome” ->should end as something like-> “Climb your name is nicola you live in rome”)
So well:

  1. Adding the word 0
  2. Deleting commas

For anybody who can help I give you some cool stuff and idea about BeforeParsing code (to correct incorrect inputs ) I found around tryng to learn how it works, anybody who mastered BeforeParsing and can helps me would have all my gratefullness :nerd:

Extra stuff I found about same topic:

BeforeParsing code (to correct incorrect inputs ):
!----------------------------------------------------------------------
Constant MAX_WORDLENGTH = 10;

[BeforeParsing word num_word;
for (num_word=1 : num_word<=num_words : num_word++) {
word = tokenDict(num_word);
switch(word) {
‘cerbiato’, ‘crebiato’, ‘crebiatto’:
num_word = ReplaceWord(num_word,‘cerbiatto’);
‘prendi’:
num_word = ReplaceWord(num_word,‘lascia’);
}
}

];

[ReplaceWord num_word word new_word pos_word num_letter;
pos_word = tokenPos(num_word);
for (num_letter=0 : num_letter<=MAX_WORDLENGTH : num_letter++)
LTI_Insert(pos_word+num_letter, word->(num_letter+1));
#ifdef TARGET_GLULX;
Tokenise__(buffer,parse);
#ifnot;
@tokenise buffer parse;
#endif;
return 0;
];

And a quote about this library " LanguageToInformese(). ", according to the author Francesco Sircana, he used a lot BeforeParsing in it. Good job guys, if you find it, post the beforeparsing code, I’ll post my final job in exchange, thanks everybody !