Register forum user name Search FAQ

Gammon Forum

Notice: Any messages purporting to come from this site telling you that your password has expired, or that you need to verify your details, confirm your email, resolve issues, making threats, or asking for money, are spam. We do not email users with any such messages. If you have lost your password you can obtain a new one by using the password reset link.

Due to spam on this forum, all posts now need moderator approval.

 Entire forum ➜ MUSHclient ➜ VBscript ➜ The Instr Function

The Instr Function

It is now over 60 days since the last post. This thread is closed.     Refresh page


Posted by Duma   USA  (9 posts)  Bio
Date Sun 15 Apr 2007 03:08 AM (UTC)
Message
I'm trying to make a compass for the game "Aetolia".

Everything is working except for one problem, when I use the instr function to find 'north', it finds the 'north' in 'northeast' or 'northwest' and returns north as > 0.

Is there a way to not catch the 'north' in 'northwest'?
Top

Posted by Nick Gammon   Australia  (23,173 posts)  Bio   Forum Administrator
Date Reply #1 on Sun 15 Apr 2007 04:39 AM (UTC)
Message
It would help to see more of your code, but I would personally check for northwest before north.

That is, if you look for "northwest" first, then you know you have northwest, and nor the first part of north.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Duma   USA  (9 posts)  Bio
Date Reply #2 on Sun 15 Apr 2007 04:47 AM (UTC)

Amended on Sun 15 Apr 2007 04:48 AM (UTC) by Duma

Message
Alright, it's pretty long though. It's probably longer than it needs to be even. Here it is -


Sub Compass(Name, Line, Wildcards)
	dim n, ne, e, se, s, sw, w, nw, u, d, i, o, exits
	exits = Wildcards(1)
	dim tExits(12)
	tExits(1) = "north"
	tExits(2) = "northeast"
	tExits(3) = "east"
	tExits(4) = "southeast"
	tExits(5) = "south"
	tExits(6) = "southwest"
	tExits(7) = "west"
	tExits(8) = "northwest"
	tExits(9) = "up"
	tExits(10) = "down"
	tExits(11) = "in"
	tExits(12) = "out"
	dim a
	for a = 1 to 12
		if instr(exits, tExits(a)) > 0 then
			select case a
				case 1
					n = 1
				case 2
					ne = 1
				case 3
					e = 1
				case 4
					se = 1
				case 5
					s = 1
				case 6
					sw = 1
				case 7
					w = 1
				case 8
					nw = 1
				case 9
					u = 1
				case 10
					d = 1
				case 11
					i = 1
				case 12
					o = 1
			end select
		else
			select case a
				case 1
					n = 0
				case 2
					ne = 0
				case 3
					e = 0
				case 4
					se = 0
				case 5
					s = 0
				case 6
					sw = 0
				case 7
					w = 0
				case 8
					nw = 0
				case 9
					u = 0
				case 10
					d = 0
				case 11
					i = 0
				case 12
					o = 0
			end select
		end if
	next
	world.replaceNotepad "Compass", ""
	if o = 1 and i = 1 then
		world.appendToNotepad "Compass", "Out In     " & vbcrlf
	elseif o = 1 and i = 0 then
		world.appendToNotepad "Compass", "Out        " & vbcrlf
	elseif o = 0 and i = 1 then
		world.appendToNotepad "Compass", "    In     " & vbcrlf
	else
		world.appendToNotepad "Compass", vbcrlf
	end if
	if n = 1 then
		world.appendToNotepad "Compass", "   N       " & vbcrlf
	end if
	if ne = 1 and nw = 1 then
		world.appendToNotepad "Compass", "NW | NE    " & vbcrlf
	elseif ne = 1 and nw = 0 then
		world.appendToNotepad "Compass", "   | NE    " & vbcrlf
	elseif ne = 0 and nw = 1 then
		world.appendToNotepad "Compass", "NW |       " & vbcrlf
	else  
		world.appendToNotepad "Compass", "   |       " & vbcrlf
	end if
	if u = 1 then
		world.appendToNotepad "Compass", "  \|/   up " & vbcrlf
	else
		world.appendToNotepad "Compass", "  \|/      " & vbcrlf
	end if
	if w = 1 and e = 1 then
		world.appendToNotepad "Compass", "W--X--E    " & vbcrlf
	elseif w = 1 and e = 0 then
		world.appendToNotepad "Compass", "W--X--     " & vbcrlf
	elseif w = 0 and e = 1 then
		world.appendToNotepad "Compass", " --X--E    " & vbcrlf
	else
		world.appendToNotepad "Compass", " --X--     " & vbcrlf
	end if
	if d = 1 then
		world.appendToNotepad "Compass", "  /|\  down" & vbcrlf
	else
		world.appendToNotepad "Compass", "  /|\      " & vbcrlf
	end if
	if sw = 1 and se = 1 then
		world.appendToNotepad "Compass", "SW | SE    " & vbcrlf
	elseif sw = 1 and se = 0 then
		world.appendToNotepad "Compass", "SW |       " & vbcrlf
	else
		world.appendToNotepad "Compass", "   |       " & vbcrlf
	end if
	if s = 1 then
		world.appendToNotepad "Compass", "   S       " & vbcrlf
	end if
	MoveNotepadWindow "Compass", 758,0,262,401
End Sub


This is the trigger that calls the script -


<triggers>
  <trigger
   enabled="y"
   match="^You see exits leading (.*?)$"
   regexp="y"
   script="Compass"
   sequence="100"
  >
  </trigger>
</triggers>


And here's what you see when you enter a room -

A quiet hallway near the Hall of Inner Peace.
A vigilant monk stands here, alert and watchful for enemies of the city.
You see exits leading north, east, south and west(closed).
H:2380 M:2848 E:99% W:93% B:100% [eb]
Top

Posted by Nick Gammon   Australia  (23,173 posts)  Bio   Forum Administrator
Date Reply #3 on Sun 15 Apr 2007 05:07 AM (UTC)

Amended on Sun 15 Apr 2007 05:09 AM (UTC) by Nick Gammon

Message
This is one of the reasons why I am recommending Lua scripting. This is much more easily solved with a simple regular expression. Take this test:


test = "You see exits leading north, northeast, east, south and west(closed)."

for exit in string.gmatch (test, "%w+") do
  print (exit)
end -- for


Running this prints:


You
see
exits
leading
north
northeast
east
south
and
west
closed


What it has done is broken the line into words, and you can see that there is no problem here with northeast and north being confused.

Obviously we have a few extraneous words (like "you" and "see") but we can ignore those.

Now to do something useful with those words, we can directly enter them into a table, for looking up later:


test = "You see exits leading north, northeast, east, in, south and west(closed)."

directions = {}  -- empty table

for exit in string.gmatch (test, "%w+") do
  directions [exit] = true
end -- for

if directions.out and directions ["in"] then
  AppendToNotepad ("Compass", "Out In     \r\n")
elseif directions.out then
  AppendToNotepad ("Compass", "Out        \r\n")
elseif directions ["in"] then
  AppendToNotepad ("Compass", "    In     \r\n")
else
  AppendToNotepad ("Compass", "\r\n")
end -- out


Each exit that was found will be in the table with a "true" value, so we can test for it, as I have shown.

I had to treat "in" a bit differently because "in" is a Lua keyword.

The other exits will be similar (eg. directions.north, directions.south and so on).

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Nick Gammon   Australia  (23,173 posts)  Bio   Forum Administrator
Date Reply #4 on Sun 15 Apr 2007 05:13 AM (UTC)

Amended on Sun 15 Apr 2007 05:14 AM (UTC) by Nick Gammon

Message
You can save a bit of typing too by making a helper function to do the appending, because there is a lot of repetition there with the notepad name:


function appendit (s)
  AppendToNotepad ("Compass", s .. "\r\n")
end -- appendit 

if directions.out and directions ["in"] then
  appendit ("Out In     ")
elseif directions.out then
  appendit ("Out        ")
elseif directions ["in"] then
  appendit ("    In     ")
else
  appendit ("")
end -- out


That makes the whole thing easier to read. You could do a similar thing in VBscript too. When you find yourself doing something lengthy over and over, it is probably time to make a small subroutine to do it for you.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Nick Gammon   Australia  (23,173 posts)  Bio   Forum Administrator
Date Reply #5 on Sun 15 Apr 2007 05:43 AM (UTC)

Amended on Sun 15 Apr 2007 09:16 PM (UTC) by Nick Gammon

Message
Here is a replacement for the whole script, done in Lua. I think this is much easier to read.

Instead of having heaps of "if" statements, I made a small "choose" function. You supply it a word and a condition (eg. "E"). If the condition is true, it returns the word, otherwise it returns the same number of spaces, as the word is long.

That way, if you can't go that way, it automatically space-fills your compass with the correct gap.


function Compass(Name, Line, Wildcards)

  local dir = {}  -- no directions yet
  
  for exit in string.gmatch (Wildcards [1], "%w+") do
    dir [exit] = true
  end -- for
  
  -- append to the notepad for us
  local function appendit (s)
    AppendToNotepad ("Compass", s .. "\r\n")
  end -- appendit 
  
  -- return the word, or equivalent spaces
  local function choose (what, condition)
    if condition then
      return what
    end -- if
  
   return string.rep (" ", #what)
  end -- choose
  
  -- clear the notepad
  ReplaceNotepad ("Compass", "")
  
  -- draw the compass
  appendit (choose ("Out", dir.out) .. " " .. choose ("In", dir ["in"]))
  appendit ("   " .. choose ("N", dir.north))
  appendit (choose ("NW", dir.northwest) .. " | " .. choose ("NE", dir.northeast))
  appendit ("  \\|/   " .. choose ("up", dir.up))
  appendit (choose ("W", dir.west) .. "--|--" .. choose ("E", dir.east))
  appendit ("  /|\\   " .. choose ("down", dir.down))
  appendit (choose ("SW", dir.southwest) .. " | " .. choose ("SE", dir.southeast))
  appendit ("   " .. choose ("S", dir.south))
  MoveNotepadWindow ("Compass", 758, 0, 262, 401)
end -- function



With a test of:

"You see exits leading north, northeast, southwest, southeast, east, up, down, in, south and west(closed)."

My compass looked like this:


    In
   N
   | NE
  \|/   up
W--|--E
  /|\   down
SW | SE
   S


With a test of:

"You see exits leading southeast, east, up, out, in, south and west(closed)."

My compass looked like this:


Out In
    
   |   
  \|/   up
W--|--E
  /|\       
   | SE
   S

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Duma   USA  (9 posts)  Bio
Date Reply #6 on Sun 15 Apr 2007 05:55 AM (UTC)
Message
I don't think I'm quite ready to switch to Lua yet. Do you need to rewrite all of your old scripts to change your programming language?

But anyways I found a way to get it to work, like you said I should've I checked for 'northeast' before 'north' but now I delete the 'northeast' from the string. So far it is working out alright.

Thanks for all the help recently.
Top

Posted by Nick Gammon   Australia  (23,173 posts)  Bio   Forum Administrator
Date Reply #7 on Sun 15 Apr 2007 06:33 AM (UTC)
Message
Glad you got it to work. :)

Quote:

Do you need to rewrite all of your old scripts to change your programming language?


With something simple like that, which is really one trigger, you could turn it into a plugin. The plugin can be in Lua, even if your other scripts are in VBscript. Here is how I did that:


<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE muclient>
<!-- Saved on Sunday, April 15, 2007, 4:31 PM -->
<!-- MuClient version 3.85 -->

<!-- Plugin "Compass" generated by Plugin Wizard -->

<muclient>
<plugin
   name="Compass"
   author="Nick Gammon"
   id="c176d579effc57ef104fc407"
   language="Lua"
   purpose="Shows the exits in a compass-style notepad window"
   date_written="2007-04-15 16:31:08"
   requires="3.85"
   version="1.0"
   >

</plugin>


<!--  Triggers  -->

<triggers>
  <trigger
   enabled="y"
   match="^You see exits leading (.*?)$"
   regexp="y"
   send_to="12"
   sequence="100"
  >
  <send>  local dir = {}  -- no directions yet
  
  for exit in string.gmatch ("%1", "%%w+") do
    dir [exit] = true
  end -- for
  
  -- append to the notepad for us
  local function appendit (s)
    AppendToNotepad ("Compass", s .. "\\r\\n")
  end -- appendit 
  
  -- return the word, or equivalent spaces
  local function choose (what, condition)
    if condition then
      return what
    end -- if
  
   return string.rep (" ", #what)
  end -- choose
  
  -- clear the notepad
  ReplaceNotepad ("Compass", "")
  
  -- draw the compass
  appendit (choose ("Out", dir.out) .. " " .. choose ("In", dir ["in"]))
  appendit ("   " .. choose ("N", dir.north))
  appendit (choose ("NW", dir.northwest) .. " | " .. choose ("NE", dir.northeast))
  appendit ("  \\\\|/   " .. choose ("up", dir.up))
  appendit (choose ("W", dir.west) .. "--|--" .. choose ("E", dir.east))
  appendit ("  /|\\\\   " .. choose ("down", dir.down))
  appendit (choose ("SW", dir.southwest) .. " | " .. choose ("SE", dir.southeast))
  appendit ("   " .. choose ("S", dir.south))

  MoveNotepadWindow ("Compass", 758, 0, 262, 401)</send>
  </trigger>
</triggers>

</muclient>



I changed from using a script file function to "send to script" which required some minor changes to the way the code looks.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Duma   USA  (9 posts)  Bio
Date Reply #8 on Sun 15 Apr 2007 03:49 PM (UTC)
Message
Ok, my compass was working for a while, but now I'm confused on using multi-line triggers.

Most rooms look like this -

Valley road before city. (road).
The bright sun shines down, blanketing you with its life-giving warmth. A large
block of stone is standing here, waiting to be carried out of the quarry. A
bright-eyed missionary serenely patrols the streets of Enorian.
You see exits leading southeast and northwest.

And my trigger worked fine, but now I've run into some problems with rooms like this -

Bend in the highway. (road).
Small flakes of white float through your field of vision here and there. You see
exits leading northeast and west

And some are like this -

Highway surrounded by lush plains. (road).
Snowflakes float down around you, colouring the world white. You see exits
leading northeast, southeast and southwest

I've tried making a multi-line trigger -


<triggers>
  <trigger
   enabled="y"
   group="Compass"
   lines_to_match="2"
   match="^You see exits leading\n(.*)"
   multi_line="y"
   regexp="y"
   script="Compass"
   sequence="100"
  >
  </trigger>
</triggers>

and..

<triggers>
  <trigger
   enabled="y"
   group="Compass"
   lines_to_match="2"
   match="^You see\nexits leading (.*)"
   multi_line="y"
   regexp="y"
   script="Compass"
   sequence="100"
  >
  </trigger>
</triggers>


But they don't seem to work, any suggestions?
Top

Posted by Nick Gammon   Australia  (23,173 posts)  Bio   Forum Administrator
Date Reply #9 on Sun 15 Apr 2007 09:11 PM (UTC)
Message
You have a few problems with the regular expression. For a start you had "^You", the "^" symbol says to anchor to the start of the line, which it won't be in many cases.

Secondly, you have got "You see" which is specifying literally a space between "You" and "see" whereas you might get a newline.

Third, you need the (?s) option which is "dot matches all". That allows for a newline in the middle of the directions list. Otherwise a newline (eg. between "north" and "south") will fail to match.

This worked for me:


match="(?s)You[\s]see[\s]exits[\s]leading[\s](.*)"



- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Nick Gammon   Australia  (23,173 posts)  Bio   Forum Administrator
Date Reply #10 on Sun 15 Apr 2007 09:18 PM (UTC)
Message
Here is an adapted version of the plugin I made. I moved the script from "send to script" to a separate <script> part of the plugin - I think that is less confusing with the % and \ symbols in it. Also, it has the multi-line stuff in it:


<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE muclient>
<!-- Saved on Sunday, April 15, 2007, 4:31 PM -->
<!-- MuClient version 3.85 -->

<!-- Plugin "Compass" generated by Plugin Wizard -->

<muclient>
<plugin
   name="Compass"
   author="Nick Gammon"
   id="f806d9a43613c1983f95e697"
   language="Lua"
   purpose="Shows the exits in a compass-style notepad window"
   date_written="2007-04-16 07:30"
   requires="3.85"
   version="1.1"
   >

</plugin>


<!--  Triggers  -->

<triggers>
  <trigger
   enabled="y"
   lines_to_match="2"
   match="(?s)You[\s]see[\s]exits[\s]leading[\s](.*)"
   multi_line="y"
   regexp="y"
   script="Compass"
   sequence="100"
  >
  </trigger>
</triggers>

<script>
<![CDATA[

function Compass (Name, Line, Wildcards)

  local dir = {}  -- no directions yet
  
  for exit in string.gmatch (Wildcards [1], "%w+") do
    dir [exit] = true
  end -- for
  
  -- append to the notepad for us
  local function appendit (s)
    AppendToNotepad ("Compass", s .. "\r\n")
  end -- appendit 
  
  -- return the word, or equivalent spaces
  local function choose (what, condition)
    if condition then
      return what
    end -- if
  
   return string.rep (" ", #what)
  end -- choose
  
  -- clear the notepad
  ReplaceNotepad ("Compass", "")
  
  -- draw the compass
  appendit (choose ("Out", dir.out) .. " " .. choose ("In", dir ["in"]))
  appendit ("   " .. choose ("N", dir.north))
  appendit (choose ("NW", dir.northwest) .. " | " .. choose ("NE", dir.northeast))
  appendit ("  \\|/   " .. choose ("up", dir.up))
  appendit (choose ("W", dir.west) .. "--|--" .. choose ("E", dir.east))
  appendit ("  /|\\   " .. choose ("down", dir.down))
  appendit (choose ("SW", dir.southwest) .. " | " .. choose ("SE", dir.southeast))
  appendit ("   " .. choose ("S", dir.south))
  MoveNotepadWindow ("Compass", 758, 0, 262, 401)
end -- function

]]>
</script> 

</muclient>

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

The dates and times for posts above are shown in Universal Co-ordinated Time (UTC).

To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time.


33,545 views.

It is now over 60 days since the last post. This thread is closed.     Refresh page

Go to topic:           Search the forum


[Go to top] top

Information and images on this site are licensed under the Creative Commons Attribution 3.0 Australia License unless stated otherwise.