[Home] [Downloads] [Search] [Help/forum]

Gammon Software Solutions forum

See www.mushclient.com/spam for dealing with forum spam. Please read the MUSHclient FAQ!

[Folder]  Entire forum
-> [Folder]  MUSHclient
. -> [Folder]  General
. . -> [Subject]  New feature - array handling for scripting
Home  |  Users  |  Search  |  FAQ
Username:
Register forum user name
Password:
Forgotten password?

New feature - array handling for scripting

[Reply to this subject]  Reply to this subject   [New subject]  Start a new subject   [Refresh] Refresh page


Pages: 1 2  

Posted by Nick Gammon   Australia  (19,338 posts)  [Biography] bio   Forum Administrator
Date Wed 17 Mar 2004 03:11 AM (UTC)  quote  ]

Amended on Wed 17 Mar 2004 05:19 AM (UTC) by Nick Gammon

Message
I would like to introduce a new feature that I have been working on for MUSHclient, in time for comment before it becomes official. :)

There have been some recent posts here about maintaining "lists of things", with the added problem of adding or deleting from the list.

You can do that to a certain extent in VBscript with arrays (dim blah (10)), and also by using Split and Join, however that gets fiddly if you want to just add something to the middle, or remove something from the middle.

I thought it would be nice to leverage off the container management functions provided in STL (Standard Template Library) and offer some similar things for MUSHclient scripts.

This is based around what I will call an "array", with the new script functions being Arrayxxxxxx where "xxxxxx" is some array-based function.

Arrays have the following properties:


  • You can have any number of arrays
  • They are stored in memory only, one set of arrays per world, and another set per plugin
  • By using ArrayImport and ArrayExport you can easily copy arrays into a single string, for loading/saving into variables (eg. MUSHclient variables)
  • Each array has a unique name (eg. spells, friends, foes)
  • Each array consists of any number of key/value pairs
  • You can randomly insert into, or delete from an array
  • You can list all available arrays (names of arrays)
  • You can list all the keys in a particular array
  • There is no restriction on array names, or key names, except that they cannot be empty
  • Array names, key names, and values have leading/trailing spaces stripped before they are stored
  • The array names, and key names, are automatically sorted into alphabetic order.


I'll work through an example here to show the idea. The examples show the script commands in VBscript, followed by the output from the output window in italics.

First, we'll create an array called "spells" and put some values (for mana) into it ...


ArrayCreate "spells"
ArraySet "spells", "dragonskin", "45"
ArraySet "spells", "dispel magic", "15"
ArraySet "spells", "farsight", "15"
ArraySet "spells", "galvanic whip", "30"


Now let's focus on a particular spell, "dispel magic". We'll see if we know about that one ...


s = "dispel magic"

Note "spell " & s & + " exists = " & ArrayKeyExists ("spells", s)

spell dispel magic exists = True


And what value is returned for it? ...


Note "mana required for " & s & " = " & ArrayGet ("spells", s)

mana required for dispel magic = 15


Let's export it into a comma-delimited list ...


Note ArrayExport ("spells", ",")

dispel magic,15,dragonskin,45,farsight,15,galvanic whip,30


And put the same thing into a variable for saving with the world file ...


SetVariable "spells", ArrayExport ("spells", ",")


What spells do we know (names only)? ...


Note ArrayExportKeys ("spells", ", ")

dispel magic, dragonskin, farsight, galvanic whip


Let's delete one (farsight) ...


ArrayDeleteKey "spells", "farsight"


How many spells do we now know? ...


Note ArraySize ("spells")

3


- Nick Gammon

www.gammon.com.au, www.mushclient.com
[Go to top] top

Posted by Nick Gammon   Australia  (19,338 posts)  [Biography] bio   Forum Administrator
Date Reply #1 on Wed 17 Mar 2004 03:30 AM (UTC)  quote  ]

Amended on Wed 17 Mar 2004 03:36 AM (UTC) by Nick Gammon

Message
You can even have "arrays in arrays" by doing something like the following. In this case I want to demonstrate how you might store multiple things for a particular spell, and then look one of them up.
First, create a couple of arrays, one for all spells, and one for the current one ...


ArrayCreate "spells"
ArrayClear "spells"
ArrayCreate "onespell"


We'll set up "onespell" as a separate array (mana, wearoff message, hitvict message) by using those as keys for this array ...


ArrayClear "onespell"
ArraySet "onespell", "mana",  "45"
ArraySet "onespell", "wearoff", _
    "Your flesh sheds its draconian aspects."
ArraySet "onespell", "hitvict", _
    "Your flesh changes to emulate the scaly skin of a dragon."


Now we'll export those values into the spells array, choosing a delimiter that won't be likely to occur in SMAUG messages ...


ArraySet "spells", "dragonskin", ArrayExport ("onespell", "~")


Now we'll clear that spell and start another one ...


ArrayClear "onespell"
ArraySet "onespell", "mana",  "75"
ArraySet "onespell", "wearoff", _
    "The ethereal funnel about you ceases to exist."
ArraySet "onespell", "hitvict", _
    "An aura surrounds you, channeling violent energies in your direction!"


Now also export that one into the spells array, using a different key ...


ArraySet "spells", "ethereal funnel", ArrayExport ("onespell", "~")


We can check everything looks OK by exporting the whole spells array - we must choose a different delimiter, so that we don't get confused about the data per spell, and the delimiter betweeen spells ...


Note ArrayExport ("spells", "=")

dragonskin=hitvict~Your flesh changes to emulate the scaly skin of a dragon.~mana~45~wearoff~Your flesh sheds its draconian aspects.=ethereal funnel=hitvict~An aura surrounds you, channeling violent energies in your direction!~mana~75~wearoff~The ethereal funnel about you ceases to exist.


I put the major keys in bold to distinguish them from the minor keys (the major keys are the spell names, the minor keys are the attributes per spell).

We can use the new "debug arrays" debug facility to check what we have done ...


world.debug "arrays"

onespell
hitvict = An aura surrounds you, channeling violent energies in your direction!
mana = 75
wearoff = The ethereal funnel about you ceases to exist.
spells
dragonskin = hitvict~Your flesh changes to emulate the scaly skin of a dragon.~mana~45~wearoff~Your flesh sheds its draconian aspects.
ethereal funnel = hitvict~An aura surrounds you, channeling violent energies in your direction!~mana~75~wearoff~The ethereal funnel about you ceases to exist.
2 arrays.



Finally let's get some data back. We'll import the data for "ethereal funnel" into "onespell" ...


ArrayClear "onespell"
ArrayImport "onespell", ArrayGet ("spells",  "ethereal funnel"), "~"


Now let's look up the hitvict message ...


Note "hitvict message for ethereal funnel is: " & _
ArrayGet ("onespell", "hitvict")

hitvict message for ethereal funnel is: An aura surrounds you, channeling violent energies in your direction!


- Nick Gammon

www.gammon.com.au, www.mushclient.com
[Go to top] top

Posted by Nick Gammon   Australia  (19,338 posts)  [Biography] bio   Forum Administrator
Date Reply #2 on Wed 17 Mar 2004 04:05 AM (UTC)  quote  ]

Amended on Wed 17 Mar 2004 05:23 AM (UTC) by Nick Gammon

Message
So, my questions for anyone who has got this far into the thread are:


  1. Do you think it is a good idea to insist that array names, and key names, are not empty? The intention was to save the confusion of having "un-named" items, however maybe that is unnecessarily restrictive.

  2. Do you think it is a good idea to trim leading/trailing spaces from array names, and key names? The intention was to save confusion over things like an array called "spells" and a (very similar looking one) called "spells " (with the trailing space).

  3. Do you think it is a good idea to trim leading/trailing spaces from key values (ie. the data stored in the array). The intention again is to save confusion, but it stops you storing things where you might actually want the leading/trailing spaces.



- Nick Gammon

www.gammon.com.au, www.mushclient.com
[Go to top] top

Posted by Nick Gammon   Australia  (19,338 posts)  [Biography] bio   Forum Administrator
Date Reply #3 on Wed 17 Mar 2004 05:16 AM (UTC)  quote  ]
Message
The online documentation for the new functions has now been updated, and can be viewed at Arrays Documentation.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
[Go to top] top

Posted by Shadowfyr   USA  (1,775 posts)  [Biography] bio
Date Reply #4 on Wed 17 Mar 2004 05:39 AM (UTC)  quote  ]
Message
Umm.. Split and Join are not really major issues. The only *real* problem with arrays as they exist are glitched in some language implimentations and stupid things that they left out.

Example:

*Things I would like to see arrays do*>
split - That can split to a dynamic array.
join - Most have this.
sort - Optional.
Add - Inserting an item, either at position X or just adding to a sorted list.
Delete - Same as Add but in reverse.

*VBScript*>
split - creates a static array. This is practically useless for some things. This is the one that annoys me a lot and makes coding a version of the last three below more complicated.
join - works fine.
sort - not available.
add - not available.
delete - not available.
Pop - (Theoretically) simple to emulate with Redim.
Push - Also (theoretically) simple to do Redim.

I say theoretically because the effects of redim seemed to have been a bit unpredictable for some people.

*JavaScript*>
Concat - Joins two arrays of the same type.
Pop - Treats array as a stack and returns then deletes the last item.
Push - Treats array as a stack and pushes a new value into the last place.
Reverse - Reverses the current order of the array.
Shift - Like Pop, but first item.
Slice - Returns a section of an array in a new array.
Sort - Sorts the contents.
Splice - Cuts out a section of the array, but can insert a replacement.
toLocalString - Converts date info to a string.
toString - Basically 'join'.
Unshift - Like Push, but inserts at the start of the array.
Length - Number of elements.

*PerlScript*>
Sort - Same as JScript.
Reverse - Same as JScript.
Pop - Same as JScript.
Push - Same as JScript.
Hashes - Key indexed array type. Like a mini database.
Count - number of elements.
Keys - Returns a new array containing keys from a Hash.
Values - Returns a new array containing values from a Hash.
Shift - Same as JScript.
Unshift - Same as JScript.
Delete - Remove something by key.
Exists - True is the key for this item exists.

*Python*>
This is a bit obscure, but since it is based off of containers or something of the sort, then it must support Delitem, Len, Iter, GetItem, SetItem. There is also an array.py module that probably impliments the rest of the stuff.

So, your idea duplicates what already exists in Perl's hash tables and Python's lists, including the use of keys almost exactly. However it can't create simple non-keyed arrays from what I can see, which is imho not useful. It also duplicates most stuff already in JScript, but it doesn't actually go far enough to replace most of them. It would really only be useful for us VBScript people, because while the language is imho probably the easiest to learn, the array implimentation it uses completely sucks.

That said:

1. Good idea for a hash table, bad idea for an array, which shouldn't have keys anyway.

2. Yes. If the user wants to intentionally duplucate a name they can do "Somename1" or even "Somename_".

3. No. The value may have been intentionally added with those spaces, data should come out the same as it goes in.

Whether it is really useful or an improvement over anything other that what VBScript does is more of an issue. Especially since your method to use more than one dimension is probably slower than using the script languages version. A simple library of functions that give VB the same Add, Delete, Push, Pop, Shift, Unshift, etc. features and you could simply 'include' within a plugin would make a lot more sense than duplicating something that already exists in every other script language.

main {
__if (Schrodinger_Cat is Alive or version >= "XP"){
____if version = "Vista" then Performance /= Number_of_Cores;
____call Functional_Code();}
__else
____call Crash_Windows();}
[Go to top] top

Posted by Nick Gammon   Australia  (19,338 posts)  [Biography] bio   Forum Administrator
Date Reply #5 on Wed 17 Mar 2004 06:37 AM (UTC)  quote  ]
Message
Shadowfyr, congratulations! That post brought your number of posts on this forum up to the 1,000 mark. :)

- Nick Gammon

www.gammon.com.au, www.mushclient.com
[Go to top] top

Posted by Meerclar   USA  (569 posts)  [Biography] bio
Date Reply #6 on Wed 17 Mar 2004 10:53 AM (UTC)  quote  ]
Message
Looks more like a watered down database than an array but the idea works :) The export functions actually almost identically mimic database exports too now that I've taken a 2nd look at em.

To answer the questions you posed however:
Yes, yes and yes.

Granted, I'm looking at it as a coder (and dba) at this point so I consider all of those features a good thing in designing anything that even loosely mimics a database structure and could very easily be extended to become a database structure.

Meerclar - Lord of Cats
Coder, Builder, and Tormenter of Mortals
Stormbringer: Rebirth
storm-bringer.org:4500
www.storm-bringer.org
[Go to top] top

Posted by David Haley   USA  (3,881 posts)  [Biography] bio   Moderator
Date Reply #7 on Wed 17 Mar 2004 11:29 AM (UTC)  quote  ]

Amended on Wed 17 Mar 2004 11:34 AM (UTC) by David Haley

Message
Having an associative array seems perfect. To solve Shadowfyr's concern about arrays not having keys, there should be a mechanism to "fake" keys, e.g. just use the "next available index" as a key, where next available index is size (or size+1, depending on whether your indices start from 0 or from 1.)

So, it'll be a associate array, but instead of mapping string key to value, it maps "integer index" key to value.

Great stuff, Nick. :)


(Edit:)
Oh, and to answer your questions, yes, yes, yes - or, for the third option, could this be made a flag that is on by default? If the user wants to *not* trim spaces - which should be a fairly rare thing - they can just turn the flag off.
E.g.
ArrayCreate "spells"
ArrayOption "spells", "trimkeys", "off"


I suppose you could have other array options (maybe for the questions 1-2 you asked), but can't think of any more off the top of my head in my tired state.

David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone

http://david.the-haleys.org
[Go to top] top

Posted by Poromenos   Greece  (1,037 posts)  [Biography] bio
Date Reply #8 on Wed 17 Mar 2004 05:00 PM (UTC)  quote  ]
Message
NONONO please don't mess with the data... What if you want to store formatted output? You can't delete leading or trailing spaces, however I agree with the other two proposals. I think that the programmer is responsible enough to see if he has spaces in his data, so I think it's an unnecessary restriction even in the names, but it will cause problems if you "trim" the data...

Vidi, Vici, Veni.
http://porocrom.poromenos.org/ Read it!
[Go to top] top

Posted by Meerclar   USA  (569 posts)  [Biography] bio
Date Reply #9 on Wed 17 Mar 2004 07:12 PM (UTC)  quote  ]
Message
An array would not be the best way to capture formatted output in the first place. Capture it to a text file using a fixed width font and read the file if you need the info ingame. Or better yet, setup either a spreadsheet or full database depending on how much formatted data needs to be captured and stored.

Meerclar - Lord of Cats
Coder, Builder, and Tormenter of Mortals
Stormbringer: Rebirth
storm-bringer.org:4500
www.storm-bringer.org
[Go to top] top

Posted by Poromenos   Greece  (1,037 posts)  [Biography] bio
Date Reply #10 on Wed 17 Mar 2004 07:49 PM (UTC)  quote  ]
Message
It was just an example, what i'm trying to say is that you don't need to trim variables since the programmer should know what he is doing.

Vidi, Vici, Veni.
http://porocrom.poromenos.org/ Read it!
[Go to top] top

Posted by Nick Gammon   Australia  (19,338 posts)  [Biography] bio   Forum Administrator
Date Reply #11 on Wed 17 Mar 2004 08:48 PM (UTC)  quote  ]
Message
OK, thanks everyone. Starting from the top, and after a good night's sleep, I can think a bit more clearly ...

Quote:

Shadowfyr
*VBScript*>
sort - not available.
add - not available.
delete - not available.
...
Whether it is really useful or an improvement over anything other that what VBScript does is more of an issue.


I think this is the nub of it. Let's assume if you are writing a plugin that you want it to be useable on most people's PCs, that means basically VBscript or Jscript, because the other languages are an optional download.

I'm not sure whether Jscript supports keyed arrays, VB certainly doesn't (seem to).

I am using the word "array" loosely here. It is really a variant of a "map" in STL terminology, however I thought that using the word "map" would be confusing in a MUD client, as people associate maps with automappers and such.

I got the idea from PHP (which this web site's dynamic content is written in), where you can have arrays with alpha indexes, like this:

person ['nick'] = 42;

or

person [2] = 55;

As Ksilyan says, it is really an associative array.

This is much more powerful than simple VB arrays, which are really "vectors" in the STL sense.

However based on the comments "it can't create simple non-keyed arrays from what I can see" I will make a change I was thinking of anyway, and that is to modify the sorting/matching behaviour.

What I have in mind is this:


  • Entries are keyed by an alpha key
  • The key can be a number (eg. "100")
  • If the key is a simple number, with or without sign, they will be sorted into numeric sequence


What this means is that you can easily treat the arrays as simple numeric arrays, without worrying about whether a sequence like 1, 11, 2 sorts as 1, 2, 11, or 1, 11, 2.

Straight "alpha" keys *would* sort as 1, 11, 2 as "11" is lower in the sort sequence than "2". This would make numeric keys fiddly to use, as you would have to put in leading zeroes.

That way, if you want a simple sequence of things, you just supply numeric keys (effectively creating a sparse vector), like this:


ArraySet "v", "1", "first entry"
ArraySet "v", "2", "second entry"
ArraySet "v", "40", "fortieth entry"
ArraySet "v", "100", "100th entry"
ArraySet "v", "-1", "this will now be first"


By "sparse" I mean you can index in with numbers, but not every position will necessarily be taken.

By choosing suitable key numbers you could implement a stack or a queue as well.

Quote:

Especially since your method to use more than one dimension is probably slower than using the script languages version.


I don't think speed is the major issue. I am thinking of things like an alias that might get information about a spell. Doing a keyed lookup is probably faster anyway than a linear search through variables or a language-dependent array anyway.

Having said that, the keyed lookup *would* be faster if you had a lot of them, because you could find (say) a spell out of a thousand by a simple lookup, whereas if you maintain a list, you may have to search through 999 of them to find it.

Quote:

Poromenos
NONONO please don't mess with the data... What if you want to store formatted output?


Yes I think you are right. If you want to get rid of the spaces you always can, but you can't put them back if they are gone.

I think I will also change it so it doesn't matter if the delimiter is in the data, I can see that as trouble waiting to happen.

I think something like the way mySQL exports its database as text files...

Say the delimiter is a comma, and you have data "fish,chips", it could be exported as:

food,fish\,chips

Then, of course, the \ symbol has to be exported as \\.






- Nick Gammon

www.gammon.com.au, www.mushclient.com
[Go to top] top

Posted by Poromenos   Greece  (1,037 posts)  [Biography] bio
Date Reply #12 on Wed 17 Mar 2004 09:41 PM (UTC)  quote  ]
Message
VB DOES support keyed arrays (well, at least i think so). They're called dictionaries, I haven't messed around with them, but look up the Dictionary object and you'll see what it's about.

Vidi, Vici, Veni.
http://porocrom.poromenos.org/ Read it!
[Go to top] top

Posted by Nick Gammon   Australia  (19,338 posts)  [Biography] bio   Forum Administrator
Date Reply #13 on Wed 17 Mar 2004 10:04 PM (UTC)  quote  ]
Message
Ah, OK - it is an ActiveX object.

Still, my proposed array handling is specifically designed for importing/exporting to standard variables, so that it can be readily used in plugins.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
[Go to top] top

Posted by Poromenos   Greece  (1,037 posts)  [Biography] bio
Date Reply #14 on Wed 17 Mar 2004 10:09 PM (UTC)  quote  ]
Message
True, I like it, (although i don't completely understand it:P)

Vidi, Vici, Veni.
http://porocrom.poromenos.org/ Read it!
[Go to top] 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.


8,168 views.

This is page 1, subject is 2 pages long: 1 2  [Next page]

[Reply to this subject]  Reply to this subject   [New subject]  Start a new subject   [Refresh] Refresh page

Go to topic:           Search the forum


[Go to top] top

[Home]

Written by Nick Gammon - 5K

Comments to: Gammon Software support
[RH click to get RSS URL] Forum RSS feed ( http://www.gammon.com.au/rss/forum.xml )

[Best viewed with any browser - 2K]    [Internet Contents Rating Association (ICRA) - 2K]    [Web site powered by FutureQuest.Net]