Difference between revisions of "Said"

From AGI Wiki
Jump to navigationJump to search
 
(4 intermediate revisions by one other user not shown)
Line 1: Line 1:
 
The '''said''' command is used to evaluate the input entered by the player. It returns TRUE if the player entered text that matches the pattern specified by the argument values.
 
The '''said''' command is used to evaluate the input entered by the player. It returns TRUE if the player entered text that matches the pattern specified by the argument values.
  
 
+
== Syntax ==
  
== Syntax ==
+
said(WORDGRPNUM1, WORDGRPNUM2, ...)<br />
<div class="CodeBlockHeader" >Code:</div>
 
<div class="CodeBlockStyle">
 
<syntaxhighlight lang="agi">code goes here.
 
said(WORDGRPNUM1, WORDGRPNUM2, ...)
 
 
said("word1", "word2", ...)
 
said("word1", "word2", ...)
</syntaxhighlight></div>
 
&nbsp;
 
  
== Description ==
+
== Remarks ==
  
The said test command is different to all other commands in the language in that it accepts a special type of parameter and can have any number of parameters. It is used to test if the player has entered certain words.  
+
Test commands are only valid in an <code>if</code> statement.
  
First, the process of parsing player input needs to be explained. When the player enters a command, the interpreter does the following things with it:
+
The '''said''' command compares its arguments against the [[parsed input]].
  
* Removes certain punctuation characters
+
The '''said''' test command is unique from all other AGI commands in two respects. First the argument values are 16 bit numbers, not 8 bit. Second, the number of arguments is variable (but must be at least one).
* Assigns each word entered a number starting from 1. When doing this, it tries to find the longest sequence of characters that match a word in the [[WORDS.TOK|WORDS.TOK]] file (so for example if the words "door", "knob" and "door knob" were in the WORDS.TOK file and the player entered "turn door knob" then the words would be "turn" and "door knob" instead of "turn", "door" and "knob'). Words in group 0 (usually things like "a", "my", "the') are skipped (not assigned numbers).
 
* If one or more words that are not in the WORDS.TOK file are found, it will set v9 (unknown_word_no in the template game) to the first unknown word.  
 
  
'''Note:''' The above is based purely on observation. I am not sure if the interpreter does exactly this, or in this order.  
+
The actual arguments stored in compiled code include the number of arguments in the command as an 8 bit number, followed by the 16 bit word group numbers. Compilers do not require the programmer to enter the number of words; they automatically calculate the total number of words, and insert it into the compiled code during compilation.
  
Once the player input has been received, flag 2 (input_recieved in the template game) is set and flag 4 input_parsed in the template game) is reset.  
+
The argument values are 16 bit numbers because they are compared against the [[word group numbers]] that are stored in the [[WORDS.TOK]] file. Most compilers will accept numbers as the word group arguments, or literal text values that correspond to words in the WORDS.TOK file. The compiler will insert the corresponding word group number into the compiled code automatically.
  
When the said test command is used, it goes through each word given as a parameter and compares it with the corresponding word entered by the player. If they are the same (or are in the same word group), then it continues onto the next word. The comparison is not case sensitive. If all the words are the same, and there are no entered words left over, then the said command returns true and sets flag 4.  
+
When the '''said''' command executes, AGI first checks [[reserved flag]] [[f2 (input received)]] to determine if the player has entered any input. If not, the '''said''' command returns FALSE. It then checks reserved flag [[f4 (said found match)]] to determine if a previous '''said''' test has already accepted the player's input. If so, the '''said''' command returns FALSE.
  
There are a couple of special word groups:
+
After verifying that the player has entered input and that the input has not yet been accepted, AGI enters a loop to check the words in the '''said''' command against the words entered by the player (and stored in the player-entered word data arrays).
  
Word group 1: "anyword" - if this word is given as a parameter, then any word will do. So if you test for said ("eat", "anyword" ) then the result will be true if the player enters "eat cake", "eat chocolate", "eat worm", eat sword", etc.  
+
If the word in the '''said''' command matches the corresponding player-entered word, AGI moves to the next word. If all words match, and the number of words entered by the player match the number of words match the number of words being tested in the '''said''' command, then [[reserved flag]] [[f4 (said found match)]] is set to TRUE and the command returns a value of TRUE. Otherwise, the command returns a value of FALSE as soon as it finds a word that doesn't match.
  
Word group 9999: "rol" (rest of line) - this means the rest of the line. If you test for said rk ill", "roi") then he result will be true if the player enters "kill lion", "kill lion with sword", etc.
+
There are two special word values that can be used in the said command. If the test word value in the '''said''' command equals 1 ("anyword"), then it automatically matches the next word in the [[ player-entered word data array]] regardless of its actual value. If the test word value in the '''said''' command equals 9999 ("rol") then it matches the next word and the rest of the line is ignored.
 +
Some examples illustrate how the '''said''' command works:<br />
  
&nbsp;
+
<pre> Player types "look at the brick wall"
 +
After parsing, the player-entered words are "look", "brick", "wall"
  
== Remarks ==
+
said("look") returns FALSE (number of words are different)
 +
said("look", "down", "floor") returns FALSE(second word doesn't match)
 +
said("look", "brick", "wall") returns TRUE (all words match)
 +
said("look", "anyword", "wall") returns TRUE (second word matches regardless of what player entered)
 +
said("look", "rol") returns TRUE (rest of line matches regardless of what player entered)
 +
</pre>
  
* Test commands are only valid in an if statement.
+
As mentioned above, words from [[wordgroup]] 0 are ignored by AGI, and normally don't return TRUE in a '''said''' command. However, there is a bug in AGI which will cause <code>said(0)</code> to return TRUE when an unknown word is detected. When the unknown word is detected, a zero is stored in the [[ player-entered word data array]] at the location of the unknown word; the '''said''' command will consider this a match for wordgroup 0, and return TRUE.
  
* This statement can be combined with the Not operator to create a 'did not say' test.
+
The '''said''' test command can be combined with the <code>NOT</code> operator to test if the player did not type a specific phrase.
  
* The '''said''' command is unique from all other AGI commands in two respects. First the argument values are 16 bit numbers, not 8 bit. Second, the number of arguments is variable (but must be at least one).
+
== Possible Errors ==
  
* The argument values are 16 bit numbers because they are compared against the word group numbers that are stored in the WORDS.TOK file.
+
None.
  
* The compiler will accept numbers as the word group arguments, or literal text values that correspond to words in the WORDS.TOK file. The compiler will insert the corresponding word group number into the compiled code automatically.
+
== Example ==
 
 
* The interpreter parses any text that the player enters as input. The said command compares its arguments against the parsed input.
 
 
 
* A detailed explanation of how the comparison is carried out by the interpreter can be found in the said command section of the Player Input topic.
 
  
* The actual arguments stored in compiled code include the number of arguments in the command as an 8 bit number, followed by the 16 bit word group numbers. The compiler does not require the programmer to enter the number of words; it automatically calculates the total number of words, and inserts it into the compiled code during compilation.
 
&nbsp;
 
 
== Example ==
 
 
<div class="CodeBlockHeader">Code:</div>
 
<div class="CodeBlockHeader">Code:</div>
<div class="CodeBlockStyle">
 
 
<syntaxhighlight lang="agi">
 
<syntaxhighlight lang="agi">
if (said(2124)) {  //assume word number 2124 = "look")
+
if(said(2124))
   print("You look around.");
+
  [ assume word number 2124 = "look")
}
+
   print("You look around and see nothing of interest.");
 
+
  }
if (said("look")) {  //same as above, but using literal text instead of number
 
  print("you look around");
 
}
 
  
//use "rol" (9999) and "anyword" (1) for special cases
+
if(said("look"))
if (said(2124, 1)) {  //same as: said("look", "anyword")
+
  [ same as above, but using literal text instead of number
   print("It looks ok.");
+
   print("You look around and see nothing of interest.");
}
+
  }
  
if (said(2124, 9999)) { //same as: said("look", "rol")
+
[ use "rol" (9999) and "anyword" (1) for special cases
 +
if(said("look", "anyword"))
 +
  { [ doesn't matter what word comes after "look"
 +
  print("It looks ok.");
 +
  }
 +
if(said("look", "rol"))
 +
  { [ any number of words after "look" is OK
 
   print("Ignore that.");
 
   print("Ignore that.");
}
+
  }
</syntaxhighlight></div>
+
</syntaxhighlight>
&nbsp;
 
  
 
== Technical Information ==
 
== Technical Information ==
  
<blockquote>
 
 
{| border="1" cellpadding="2"
 
{| border="1" cellpadding="2"
| style="background-color: #efefef" | '''Required interpreter version'''
+
| style="background-color: #efefef" width="200" | '''Required Interpreter Version:'''
| Available in all AGI versions
+
| width="175" | Available in all AGI versions.
 
|-
 
|-
| style="background-color: #efefef" | '''Bytecode value'''
+
| style="background-color: #efefef" | '''Byte-Code Value:'''
 
| 14 (0x0E hex)
 
| 14 (0x0E hex)
 
|}
 
|}
</blockquote>
 
&nbsp;
 
 
== Sources ==
 
 
* [[AGI Studio|AGI Studio]] help file
 
* [[WinAGI|WinAGI]] help file
 
  
&nbsp;
+
== See Also ==
  
[[Category:Logic Commands]]
+
[[Test Commands]]<br />
[[Category:Test Commands]]
+
[[Player Input Commands]]<br />
 +
[[Category:Commands]]<br />

Latest revision as of 12:32, 20 April 2019

The said command is used to evaluate the input entered by the player. It returns TRUE if the player entered text that matches the pattern specified by the argument values.

Syntax

said(WORDGRPNUM1, WORDGRPNUM2, ...)
said("word1", "word2", ...)

Remarks

Test commands are only valid in an if statement.

The said command compares its arguments against the parsed input.

The said test command is unique from all other AGI commands in two respects. First the argument values are 16 bit numbers, not 8 bit. Second, the number of arguments is variable (but must be at least one).

The actual arguments stored in compiled code include the number of arguments in the command as an 8 bit number, followed by the 16 bit word group numbers. Compilers do not require the programmer to enter the number of words; they automatically calculate the total number of words, and insert it into the compiled code during compilation.

The argument values are 16 bit numbers because they are compared against the word group numbers that are stored in the WORDS.TOK file. Most compilers will accept numbers as the word group arguments, or literal text values that correspond to words in the WORDS.TOK file. The compiler will insert the corresponding word group number into the compiled code automatically.

When the said command executes, AGI first checks reserved flag f2 (input received) to determine if the player has entered any input. If not, the said command returns FALSE. It then checks reserved flag f4 (said found match) to determine if a previous said test has already accepted the player's input. If so, the said command returns FALSE.

After verifying that the player has entered input and that the input has not yet been accepted, AGI enters a loop to check the words in the said command against the words entered by the player (and stored in the player-entered word data arrays).

If the word in the said command matches the corresponding player-entered word, AGI moves to the next word. If all words match, and the number of words entered by the player match the number of words match the number of words being tested in the said command, then reserved flag f4 (said found match) is set to TRUE and the command returns a value of TRUE. Otherwise, the command returns a value of FALSE as soon as it finds a word that doesn't match.

There are two special word values that can be used in the said command. If the test word value in the said command equals 1 ("anyword"), then it automatically matches the next word in the player-entered word data array regardless of its actual value. If the test word value in the said command equals 9999 ("rol") then it matches the next word and the rest of the line is ignored. Some examples illustrate how the said command works:

 Player types "look at the brick wall" 
 After parsing, the player-entered words are "look", "brick", "wall"

 said("look") returns FALSE (number of words are different)
 said("look", "down", "floor") returns FALSE(second word doesn't match)
 said("look", "brick", "wall") returns TRUE (all words match)
 said("look", "anyword", "wall") returns TRUE (second word matches regardless of what player entered)
 said("look", "rol") returns TRUE (rest of line matches regardless of what player entered)

As mentioned above, words from wordgroup 0 are ignored by AGI, and normally don't return TRUE in a said command. However, there is a bug in AGI which will cause said(0) to return TRUE when an unknown word is detected. When the unknown word is detected, a zero is stored in the player-entered word data array at the location of the unknown word; the said command will consider this a match for wordgroup 0, and return TRUE.

The said test command can be combined with the NOT operator to test if the player did not type a specific phrase.

Possible Errors

None.

Example

Code:

<syntaxhighlight lang="agi"> if(said(2124))

 {  [ assume word number 2124 = "look")
  print("You look around and see nothing of interest.");
 }

if(said("look"))

 {  [ same as above, but using literal text instead of number
  print("You look around and see nothing of interest.");
 }

[ use "rol" (9999) and "anyword" (1) for special cases if(said("look", "anyword"))

 { [ doesn't matter what word comes after "look"
  print("It looks ok."); 
 }

if(said("look", "rol"))

 { [ any number of words after "look" is OK
  print("Ignore that.");
 }

</syntaxhighlight>

Technical Information

Required Interpreter Version: Available in all AGI versions.
Byte-Code Value: 14 (0x0E hex)

See Also

Test Commands
Player Input Commands