FAQ Search Memberlist Usergroups
Jolt Country Forum Index
Register Profile Log in to check your private messages Log in
Log in Log in

Parsing dictionary words as objects

 
This forum is locked: you cannot post, reply to, or edit topics.   This topic is locked: you cannot edit posts or make replies.    Jolt Country Forum Index -> Hugo's House of Horrors
View previous topic :: View next topic  
Author Message
Bainespal



Joined: 09 Jul 2010
Posts: 151

PostPosted: Tue Mar 01, 2011 9:19 am    Post subject: Parsing dictionary words as objects Reply with quote

At a point in my game, the PC will be in a dark room. I want to respond to variations of the command "turn on the lights" without implementing a "lights" object. The problem is made more complicated by the fact that I already have an object in the game with the nouns "light" and "lights," but that object has nothing to do with the action I'm trying to intercept here.

After a lot of bumbling around, I took Roody's advice for his thread by putting my code in "actor PreParse" in the before rule of the "you" object. I'm trying to insert my own text with a CustomError message, by calling ParseError with the number corresponding to the one I used in my replacement of CustomError. (I learned that GetInput is designed for something totally different).

I think I'm starting to make a little bit of progress, but now I'm about out of ideas. I used the Debugger to follow the code, and I noticed that Parse gets called after my condition "if verbroutine = &DoSwitchOn" is evaluated. I think this may be part of the problem. I'm thinking the whole use of PreParse is to supplant Parse altogether for this command.

Sorry to bother you guys about this. I'll copy my code below. If anyone has any suggestions, they would be greatly appreciated.

Code:

before
  {
    actor PreParse
    {
      if self in upper_storey and upper_storey is not light
      {
        if verbroutine = &DoSwitchOn  ! "&" because I don't want to call the routine
        {
          if word[3] = "light" or "lightswitch" or "lights"
          {
            ParseError(103)
            return true
          }
          else
          {
            return false
          }
        }
      } ! end verbroutine
    } ! end actor
  } ! end before

Note that "upper_storey" is the room.
Back to top
View user's profile Send private message
Tdarcos



Joined: 16 May 2008
Posts: 4441
Location: University Park, Maryland

PostPosted: Tue Mar 01, 2011 11:24 am    Post subject: Re: Parsing dictionary words as objects Reply with quote

Bainespal wrote:
Code:
if verbroutine = &DoSwitchOn  ! "&" because I don't want to call the routine
        {
          if word[3] = "light" or "lightswitch" or "lights"

Two questions: what do "verbroutine" and "DoSwitchOn" represent in this context and why is it important not to call something?
_________________
The lessons of history teach us - if they teach us anything - that no one learns the lessons of history.
Back to top
View user's profile Send private message Send e-mail Visit poster's website
Roody_Yogurt



Joined: 29 Apr 2002
Posts: 1993
Location: Milwaukee

PostPosted: Tue Mar 01, 2011 11:26 am    Post subject: Reply with quote

The game doesn't know what the verbroutine is until Parse is done with the input line, so checking for any verbroutine in PreParse will only apply to the previous turn.

Try:
Code:

if (word[1] = "turn","switch") and word[2] = "on" and (word[3] = \
"light","lightswitch","lights")
Back to top
View user's profile Send private message AIM Address
Roody_Yogurt



Joined: 29 Apr 2002
Posts: 1993
Location: Milwaukee

PostPosted: Tue Mar 01, 2011 1:08 pm    Post subject: Reply with quote

Also, if your parsing routing doesn't work out for you, you could always make a "turn on the lights" verb grammar entry that points to a routine that does what you want if the conditions are right or otherwise tries to Perform(&DoSwitchOn, lightobject).
Back to top
View user's profile Send private message AIM Address
Bainespal



Joined: 09 Jul 2010
Posts: 151

PostPosted: Tue Mar 01, 2011 6:08 pm    Post subject: Reply with quote

Tdarcos wrote:
Two questions: what do "verbroutine" and "DoSwitchOn" represent in this context and why is it important not to call something?

DoSwitchOn is the library routine that controls the default action caused by the player trying to turn something on. I don't want this routine to actually try to run when I'm just trying to test whether the command that the player entered is covered by it. Without the "&" character, I discovered through the Debugger that the DoSwitchOn routine was being called and was trying to act on "nothing". It actually succeeded in turning "nothing" on, so that next time I tried it, part of the weird response was that Nothing was already on!

Roody_Yogurt wrote:
The game doesn't know what the verbroutine is until Parse is done with the input line, so checking for any verbroutine in PreParse will only apply to the previous turn.

Now that I think about, I suppose that makes sense. How can Hugo know what the current verbroutine is unless it's already done some parsing on the player's input? I was thinking that if I could only figure out a way to use the standard action routine and pass off a dictionary word to replace the nonexistant object, it would be a very elegant and economic solution. Oh, well.

Next, I'll try to intercept all three words in the command. I would have had to allow for synonymous commands like "FLIP SWITCH" anyways. I knew there must have been some way to make all this work using grammar definitions, but I haven't looked into that path at all yet.

As always, thank you. :)
Back to top
View user's profile Send private message
Bainespal



Joined: 09 Jul 2010
Posts: 151

PostPosted: Mon Mar 14, 2011 6:39 am    Post subject: Reply with quote

Specifying each word that I want to intercept does indeed work, but I discovered the correct place for this code is in a replacement of the PreParse routine and not in an "actor" rule in the player object's before routine.

When I had the PreParse code in the player object, once the condition for displaying the CustomError message was initially met, all subsequent commands in the game produced the CustomError message, including meta-commands like "QUIT" and "RESTORE." I tried returning in various places, but nothing seemed to make any difference.

Looking through the Hugo by Example wiki, I read the article about the PreParse routine. I noticed the use of replacing PreParse in the code snippet from Down that was posted, which is more complicated than what I want to do but about the same idea. So, now I'm good. :-)

I appreciate all the work that's gone into that wiki. It pretty much saved my project here.
Back to top
View user's profile Send private message
Roody_Yogurt



Joined: 29 Apr 2002
Posts: 1993
Location: Milwaukee

PostPosted: Mon Mar 14, 2011 6:59 am    Post subject: Reply with quote

Hmm, you should still be able to trap the words in the actor before stuff, but I'd have to see the code to troubleshoot it. Anyhow, you got it working which is all that matters.

As far as the wiki goes, I've written the majority of the code examples on there, yet even I go to the wiki all of the time to remind myself how to do things. Coding without internet access these days is a little like coding in the dark because of how much I use it, so it has very much been matching my original vision for it (which Royce Odle made a reality). I'm glad to hear that it is as useful to others as it has been for me!
Back to top
View user's profile Send private message AIM Address
Bainespal



Joined: 09 Jul 2010
Posts: 151

PostPosted: Mon Mar 14, 2011 3:53 pm    Post subject: Reply with quote

It turns out I was mistaken. The problem probably had nothing to do with the code being in the player object's before property. I tried replacing PreParse early one morning before I had to run off to class, and I'd thought that it had worked, but it really hadn't.

However, now I really have found the solution! I noticed how Kent Tessman is always using local variables in his routines, including those that use the word[] array, such as the very code from Down that I had been looking at. I was suspecting that Hugo was setting the word[] entries to the words I was trying to test for when it read the line:
Code:
if word[1] = "turn" and word[2] = "on" and word[3] = "lights"
Examining the executed code in the Debugger, I noticed that the CustomError message was always displayed whenever PreParse made it to that condition, even if the condition was not true.

I added local variables in my replaced PreParse routine and set them to the specific dictionary words from the player's command:
Code:
local 1st, 2nd, 3rd
1st = word[1]
2nd = word[2]
3rd = word[3]


And now the condition that was giving me so much trouble looks like this:

Code:
if 1st = "turn" or "switch" and 2nd = "on" and 3rd = "light" or "lights" or "lightswitch" or "lamp"


I'm pretty sure that the Hugo Book has some examples of testing for a specific array entry (but probably not the word[] array), so I don't understand why I had to do this, but it works, so I'm done questioning.
Back to top
View user's profile Send private message
Roody_Yogurt



Joined: 29 Apr 2002
Posts: 1993
Location: Milwaukee

PostPosted: Mon Mar 14, 2011 7:40 pm    Post subject: Reply with quote

Yeah, I don't think that conditional statement is your problem, either. If you want to post you code here or PM me with it, I'd be happy to troubleshoot it for you. Otherwise, good luck!
Back to top
View user's profile Send private message AIM Address
Bainespal



Joined: 09 Jul 2010
Posts: 151

PostPosted: Tue Mar 15, 2011 8:36 am    Post subject: Reply with quote

Well, okay. Here's the complete routine as it is now:

Code:
replace PreParse
{
  local 1st, 2nd, 3rd
  ! Let's see what happens if I try to store the player's command in local variables!
  1st = word[1]
  2nd = word[2]
  3rd = word[3]
  ! CustomError(100) holds the text for the PC trying to turn on his lights
  if player in upper_storey and upper_storey is not light
  {
    if 1st = "turn" or "switch" and 2nd = "on" and 3rd = "light" or "lights" or "lightswitch" or "lamp"
    {
      ParseError(100)
    }
    elseif 1st = "flip" and 2nd = "switch" or "lightswitch"
    {
      ParseError(100)
    }
    if tried_the_lights = false
    {
      tried_the_lights = true ! Needs to be set to determine when both necessary actions have been taken
    }
  }
}

It seems to be doing what I want it to, although I haven't fully implemented my plan for the global variable "tried_the_lights" yet. That's controlled by other code, and there are still a couple of things I think I can try before I ask for help.
Back to top
View user's profile Send private message
Roody_Yogurt



Joined: 29 Apr 2002
Posts: 1993
Location: Milwaukee

PostPosted: Tue Mar 15, 2011 9:43 am    Post subject: Reply with quote

I'll try to throw some working code together later, but in the meantime, according to that code, tried_the_lights is set to true no matter what the player types in (as long as he is in upper_storey in the dark), which is probably not exactly what you want.
Back to top
View user's profile Send private message AIM Address
Bainespal



Joined: 09 Jul 2010
Posts: 151

PostPosted: Tue Mar 15, 2011 1:37 pm    Post subject: Reply with quote

Roody_Yogurt wrote:
I'll try to throw some working code together later, but in the meantime, according to that code, tried_the_lights is set to true no matter what the player types in (as long as he is in upper_storey in the dark), which is probably not exactly what you want.

Very true. Thank you!

I suppose most of my problems with Hugo are due to my poor understanding of conditions. Frequently, I end up setting a condition to be true when I mean to test for it.
Back to top
View user's profile Send private message
Roody_Yogurt



Joined: 29 Apr 2002
Posts: 1993
Location: Milwaukee

PostPosted: Tue Mar 15, 2011 4:14 pm    Post subject: Reply with quote

Here should be some workable code for you:
Code:

replace PreParse
{
   if Contains(upper_storey,player) and upper_storey is not light
      {
      if (word[1] = "turn","switch") and (word[2] = "on") and (word[3] = "light","lights","lightswitch","lamp")
         {
         ParseError(100)
         tried_the_lights = true
         }
      elseif (word[1] = "flip") and (word[2] = "switch","lightswitch")
         {
         ParseError(100)
         tried_the_lights = true
         }
      }   
}


I mean to eventually do a shortcuts page on Hugo by Example, but yeah, 'if word[1] = "flip" or word[1] = "switch"' can be shortened to 'if word[1] = "flip","switch"'. Very helpful for parsing conditionals.

Also, it probably wouldn't apply to your game, but I used Contains instead of "if player in room_name" since Contains is a bit more robust. "if player in room_name" doesn't work if the player is in a vehicle or a platform (like a chair) since that makes the player a grandchild of the room, not a child. Contains will return true still in that case.
Back to top
View user's profile Send private message AIM Address
Bainespal



Joined: 09 Jul 2010
Posts: 151

PostPosted: Tue Mar 15, 2011 7:58 pm    Post subject: Reply with quote

Awesome! :-)

My previous code had stopped working after I changed something that I thought was unrelated. I'm grateful for this.
Back to top
View user's profile Send private message
Display posts from previous:   
This forum is locked: you cannot post, reply to, or edit topics.   This topic is locked: you cannot edit posts or make replies.    Jolt Country Forum Index -> Hugo's House of Horrors All times are GMT - 7 Hours
Page 1 of 1

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001 phpBB Group

Theme by Kage Musha - RPG Garden

Copyrights and trademarks are all of the belonging company. No copyright Infringement intended