August 27, 2007
by Branden
First off if you want to follow along, it would be a good idea to download the current Abalone source code and read the first article in the series..
I ended the first entry of this series talking about nodes - how each space on the board of Abalone is a node. After deciding on the concept of nodes my next step was to think about what kind of data each node needed to contain. Each node need to know about it's immediate neighbors and what it's current state is (empty, has a black marble or has a white marble). By the looks of it both of these types of data were well suited for something known as an enumerated type. Unfortunately ActionScript 3 doesn't explicitly support enumerated types, but they can be sufficiently faked.
Thus, we have the AbaloneDirection class and the AbaloneState class. Both of these classes should never be instatiated - instead they just hold our special sets of data. So what's the benefit of storing our states in the special strings? Why not just use strings in the first place? Well, that comes down to working smarter and having your tools work for you. If you use this faked-up enumerated type and always refer to AbaloneState.EMPTY then you don't have to worry about funny misspellings and other nasty errors that the compiler won't catch for you. Sure, it's a little more work up front, but your code ends up being much more clean and easier to debug - which is a pretty fair trade off in my book.
The only funny thing in those two classes is that the AbaloneDirection class also has a static method named getInverse - this method helps in making connections between two nodes go both ways. That is NodeA connects to NodeB through it's AbaloneDirection.RIGHT edge. That means that NodeB needs to connect back to NodeA using it's AbaloneDirection.LEFT edge.
Now that our data is sorted out, let's get back to the nodes themselves. After thinking about it a bit I realized that there were in actuality two types of nodes - the regular nodes that we've already discussed and the gutter that surrounds the playing board. These two different types of nodes are similar in that marbles can be pushed into them, but what they actually do when marbles are pushed into them is different. It would be nice if they were essentially interchangable - something that can be pulled off through the use of an interface. I defined a simple interface called IAbaloneNode that enforces two methods, setNeighbor and push. Then I defined two classes, AbaloneNode and AbaloneGutter that implemented that interface.
AbaloneNode defines it's setNeighbor method so that it both makes references to the neighbor and makes sure the neighbor has a reference back to it. The push method of AbaloneNode "pushes" the state of the node onto the appropriate neighbor and handles the logic of dealing with empty nodes along the way. It turns out that AbaloneGutter can't push marbles back into the playing board, so it's setNeighbor method can be blank (it has to have a setNeighbor method though, to conform to the interface). The push method of AbaloneGutter accepts whatever state was pushed into it and then broadcasts out an event of the type AbaloneEvent.EJECT that contains the state (type of marble) that was ejected.
Notice that with all of this that there is no enforcement of the rules of Abalone - and for good reason. By keeping the classes as simple as possible and having them handle one concept (how nodes connect) we end up with more flexible and easier to understand code. In the next part of this series we'll be looking at the code that defines and enforces the rules of Abalone.
When I finally did figure out how to begin it was through what I call problem minimization. I simply kept breaking down the problem until it was as small as possible. What's the smallest part of Abolone? A single position the board - let's call it a node. Each node can contain either a black marble, a white marble, or no marbles. Each node also has 6 neighbors. This concept ends up being a variation of a data structure that every computer science student learns in the first or second class they every learn - a 




