Wiz Programming Tutorials

Wyvern uses lots of Lists, Sets, Hashes, Arrays, and other data structures in its arguments. This tutorial will show you how to read and manipulate them.

As an example, the wyvern.lib.GameMap interface has a getMonsterList() function that returns a Set of the monsters in the map. (Sadly, it's a poorly-named function - should have been called getMonsters()).

Quickie Definitions

There are four main kinds of data structures used in Wyvern:
  • List - a sequential, ordered list of items. You can get the first item, the second item, and so on.

  • Set - an unordered "bag" of items. They're not numbered, and they can be returned in any order.

  • Map - a set of unordered key/value pairs. By far the most common example is every game object's property list. The keys are property names, like "level", and the values are miscellaneous objects like Integers, Strings, Booleans, and Beans. Sometimes a Map is also called a "Dictionary".

  • Array - a sequential, ordered list of items, just like a List. You don't see them as often as you see Lists. There are some performance differences between Arrays and Lists, but nothing that you really need to care about right now.

Sometimes you'll see specific subclasses in the API, such as LinkedList, ArrayList, HashSet, HashMap, and TreeMap. Don't worry too much about those for now. The nice thing is that they're all accessed the same way, which we'll explain below.

Python has its own set of data structures (arrays, lists, maps, and so on) with its own specific language constructs for creating and manipulating them. You are more than welcome to use them for your own purposes. However, you'll need to use this code in this tutorial when you're manipulating Wyvern built-in data structures (since they're written in Java).

Many of the Wyvern game classes return one of the four standard data structures, or take one as a parameter. For example, there's a method called

	wyvern.lib.GameMap.getObjectsAt(x, y)
That returns a List of the objects at location (x, y). The list is just like any other list, and you can do all the normal operations to it that we cover below.

Accessing Values

There are four fundamental operations for every data structure:
  • get() - retrieves an item from a data structure.

  • add() (or put() for Maps) - sticks an item (or key/value pair) into the data structure.

  • contains() - tells you if an object is contained in the data structure.

  • iteration - this is where you process every item in the data structure. It's got a special section below.

It's very convenient to have the List, Set and Map APIs bookmarked, so you should bookmark to this link:

Java 2 Platform API

It has the Javadoc API documentation for all the Java classes. The one you'll visit the most often is in the Java 2 Platform Packages (in the right frame), under the package java.util. It has the API definitions for all the data structures that Wyvern uses.

For example, you can click on the List interface, scroll down to the Method Summary, and see all the methods on List. You have all of these methods available to you in your Wyvern coding - in fact, you can call all of the thousands of methods in the entire Java API.

In fact, you actually have access to three complete API sets in Wyvern:

So your code in Wyvern is actually sitting on a truly gigantic bundle of code, all of which you can use freely for your coding. It helps to familiarize yourself with the tools you've got at your disposal!

Iterators

You access all the data structures above (except Arrays) using an Iterator. It goes through each item in the data structure and returns them to you one at a time. Here's the basic pattern:

<span class='keyword'></span>it<span class='keyword'></span> = <span class='keyword'></span>mylist<span class='keyword'></span>.<span class='keyword'></span>iterator<span class='keyword'></span>()<br><<span class='keyword'></span>font<span class='keyword'></span> <span class='keyword'></span>color<span class='keyword'></span>=<span class='string'>"<span class='keyword'></span>blue<span class='keyword'></span>"</span>><span class='keyword'></span>while<span class='keyword'></span></<span class='keyword'></span>font<span class='keyword'></span>> <span class='keyword'></span>it<span class='keyword'></span>.<span class='keyword'></span>hasNext<span class='keyword'></span>():<br>    <span class='keyword'></span>item<span class='keyword'></span> = <span class='keyword'></span>it<span class='keyword'></span>.<span class='keyword'></span>next<span class='keyword'></span>()<br><span class='comment'>    # ... do something with item ...</span>

This works identically for Lists and Sets, except that for Sets, the items could come in any order.

For Maps, you can iterate over the keys or the values. To iterate over the keys, do this:

<span class='keyword'></span>it<span class='keyword'></span> = <span class='keyword'></span>mylist<span class='keyword'></span>.<span class='keyword'></span>keySet<span class='keyword'></span>().<span class='keyword'></span>iterator<span class='keyword'></span>()<br><span class='keyword'></span>while<span class='keyword'></span> <span class='keyword'></span>it<span class='keyword'></span>.<span class='keyword'></span>hasNext<span class='keyword'></span>():<br>    <span class='keyword'></span>key<span class='keyword'></span> = <span class='keyword'></span>it<span class='keyword'></span>.<span class='keyword'></span>next<span class='keyword'></span>()<br><span class='comment'>    # ... do something with key ...</span>

The best way to iterate over the values of a Map is to iterate over the keys, and pull out the value for each key, like so:

<span class='keyword'></span>it<span class='keyword'></span> = <span class='keyword'></span>mylist<span class='keyword'></span>.<span class='keyword'></span>keySet<span class='keyword'></span>().<span class='keyword'></span>iterator<span class='keyword'></span>()<br><span class='keyword'></span>while<span class='keyword'></span> <span class='keyword'></span>it<span class='keyword'></span>.<span class='keyword'></span>hasNext<span class='keyword'></span>():<br>    <span class='keyword'></span>key<span class='keyword'></span> = <span class='keyword'></span>it<span class='keyword'></span>.<span class='keyword'></span>next<span class='keyword'></span>()<br>    <span class='keyword'></span>value<span class='keyword'></span> = <span class='keyword'></span>mylist<span class='keyword'></span>.<span class='keyword'></span>get<span class='keyword'></span>(<span class='keyword'></span>key<span class='keyword'></span>)<br><span class='comment'>    # ... do something with value ...</span>

Deleting Items During Iteration

Sometimes you want to delete items from a data structure as you're going through it. You can't just say list.remove(item), because you'll get something called a ConcurrentModificationException when you try to do the next call to it.next().

Instead, the Iterator provides a remove() method for you. To remove "rhialto" from a list of names, you'd do this:

<span class='keyword'></span>it<span class='keyword'></span> = <span class='keyword'></span>namelist<span class='keyword'></span>.<span class='keyword'></span>iterator<span class='keyword'></span>()<br><span class='keyword'></span>while<span class='keyword'></span> <span class='keyword'></span>it<span class='keyword'></span>.<span class='keyword'></span>hasNext<span class='keyword'></span>():<br>    <span class='keyword'></span>name<span class='keyword'></span> = <span class='keyword'></span>it<span class='keyword'></span>.<span class='keyword'></span>next<span class='keyword'></span>()<br>    <span class='keyword'></span>if<span class='keyword'></span> <span class='keyword'></span>name<span class='keyword'></span> == '<span class='keyword'></span>rhialto<span class='keyword'></span>':<br>        <span class='keyword'></span>it<span class='keyword'></span>.<span class='keyword'></span>remove<span class='keyword'></span>()

Arrays

Note: for experienced Python programmers: when we say "Array" here, we mean a Java array, such as

	String[ ] names = { "Joe", "Fred", "Bob" };

You don't use Iterators to go through a Java array. Here's the pattern:

<span class='keyword'></span>for<span class='keyword'></span> <span class='keyword'></span>i<span class='keyword'></span> <span class='keyword'></span>in<span class='keyword'></span> <span class='keyword'></span>range<span class='keyword'></span>(<span class='keyword'></span>len<span class='keyword'></span>(<span class='keyword'></span>myarray<span class='keyword'></span>)):<br>    <span class='keyword'></span>item<span class='keyword'></span> = <span class='keyword'></span>args<span class='keyword'></span>[<span class='keyword'></span>i<span class='keyword'></span>]<br>    ... <span class='keyword'></span>do<span class='keyword'></span> <span class='keyword'></span>something<span class='keyword'></span> <span class='keyword'></span>with<span class='keyword'></span> <span class='keyword'></span>item<span class='keyword'></span> ...

It's more or less like an Iterator. Here's a working example that shows you how to use it. In this case, we've written an object that provides a command called "argtest". When you type "argtest" followed by some arguments, it prints out the arguments you typed.

Note that we didn't actually parse the arguments - they come pre-parsed in the CommandEvent passed into Command.execute(). You can get them via event.getArgs(), which returns an Array of the arguments.

<span class='keyword'></span>from<span class='keyword'></span> <span class='keyword'></span>java<span class='keyword'></span>.<span class='keyword'></span>lang<span class='keyword'></span> <span class='keyword'></span>import<span class='keyword'></span> <span class='keyword'></span>String<span class='keyword'></span><br><span class='keyword'></span>from<span class='keyword'></span> <span class='keyword'></span>wyvern<span class='keyword'></span>.<span class='keyword'></span>lib<span class='keyword'></span> <span class='keyword'></span>import<span class='keyword'></span> <span class='keyword'></span>Command<span class='keyword'></span><br><span class='keyword'></span>from<span class='keyword'></span> <span class='keyword'></span>wyvern<span class='keyword'></span>.<span class='keyword'></span>kernel<span class='keyword'></span>.<span class='keyword'></span>maps<span class='keyword'></span> <span class='keyword'></span>import<span class='keyword'></span> <span class='keyword'></span>MapObject<span class='keyword'></span><br><br><span class='keyword'>class</span> <span class='function'>argtest</span>(MapObject, Command):<br><br>    <span class='keyword'>def</span> <span class='function'>initialize</span>(self):<br>        <span class='keyword'></span><span class='instance'>self</span><span class='keyword'></span>.<span class='keyword'></span>super__initialize<span class='keyword'></span>()<br><br><span class='comment'>        # give it any old appearance</span><br>        <span class='keyword'></span><span class='instance'>self</span><span class='keyword'></span>.<span class='keyword'></span>setDefaultCategory<span class='keyword'></span>(<span class='string'>"<span class='keyword'></span>objects<span class='keyword'></span>"</span>)<br>        <span class='keyword'></span><span class='instance'>self</span><span class='keyword'></span>.<span class='keyword'></span>setDefaultBitmap<span class='keyword'></span>(<span class='string'>"<span class='keyword'></span>jade_key<span class='keyword'></span>"</span>)<br>        <span class='keyword'></span><span class='instance'>self</span><span class='keyword'></span>.<span class='keyword'></span>setProperty<span class='keyword'></span>('<span class='keyword'></span>short<span class='keyword'></span>', '<span class='keyword'></span>arg<span class='keyword'></span> <span class='keyword'></span>tester<span class='keyword'></span>')<br>        <span class='keyword'></span><span class='instance'>self</span><span class='keyword'></span>.<span class='keyword'></span>setProperty<span class='keyword'></span>('<span class='keyword'></span>desc<span class='keyword'></span>', <span class='string'>"<span class='keyword'></span>type<span class='keyword'></span> <<span class='keyword'></span>font<span class='keyword'></span> <span class='keyword'></span>color<span class='keyword'></span>="</span><span class='keyword'></span>4169FF<span class='keyword'></span><span class='string'>">'<span class='keyword'></span>argtest<span class='keyword'></span> [<span class='keyword'></span>args<span class='keyword'></span>]' <span class='keyword'></span>to<span class='keyword'></span> <span class='keyword'></span>see<span class='keyword'></span> <span class='keyword'></span>your<span class='keyword'></span> <span class='keyword'></span>args<span class='keyword'></span>"</span></<span class='keyword'></span>font<span class='keyword'></span>>)<br><br>    <span class='keyword'>def</span> <span class='function'>knowsCommand</span>(self, cmd):<br>        <span class='keyword'></span>return<span class='keyword'></span> <span class='keyword'></span>String<span class='keyword'></span>.<span class='keyword'></span>startsWith<span class='keyword'></span>(<span class='keyword'></span>cmd<span class='keyword'></span>, <span class='string'>"<span class='keyword'></span>argtest<span class='keyword'></span> "</span>)<br><br>    <span class='keyword'>def</span> <span class='function'>createEvent</span>(self, event):<br>        <span class='keyword'></span>return<span class='keyword'></span> <span class='keyword'></span>event<span class='keyword'></span><br><br>    <span class='keyword'>def</span> <span class='function'>execute</span>(self, event):<br><br>        <span class='keyword'></span>agent<span class='keyword'></span> = <span class='keyword'></span>event<span class='keyword'></span>.<span class='keyword'></span>getAgent<span class='keyword'></span>()<br><br><span class='comment'>        # this returns a string array</span><br>        <span class='keyword'></span>args<span class='keyword'></span> = <span class='keyword'></span>event<span class='keyword'></span>.<span class='keyword'></span>getArgs<span class='keyword'></span>()<br><br>        <span class='keyword'></span>for<span class='keyword'></span> <span class='keyword'></span>i<span class='keyword'></span> <span class='keyword'></span>in<span class='keyword'></span> <span class='keyword'></span>range<span class='keyword'></span>(<span class='keyword'></span>len<span class='keyword'></span>(<span class='keyword'></span>args<span class='keyword'></span>)):<br>            <span class='keyword'></span>agent<span class='keyword'></span>.<span class='keyword'></span>message<span class='keyword'></span>(<span class='keyword'></span>args<span class='keyword'></span>[<span class='keyword'></span>i<span class='keyword'></span>])</<span class='keyword'></span>pre<span class='keyword'></span>>

<< Previous Chapter Next Chapter >>