## redUniverse: Support for Discrete Worlds

2010-12-15 06:22

clean-up #30:

As the last thing for this month-of-cleaning-up-old-code-and-taking-care-of-forgotten-projects, I finally wrote some methods that I had been planning for a long time. They add support for discrete worlds to my redUniverse quark.

It's all fairly simple.

In a 2 dimensional world there are 8 neighbouring cells/locations. The surroundings method returns them.

``````a= RedWorld(RedVector[100, 200])  //a 2D world
a.surroundings
[ [ -1, -1 ], [ -1, 0 ], [ -1, 1 ], [ 0, -1 ], [ 0, 1 ], [ 1, -1 ], [ 1, 0 ], [ 1, 1 ] ]
``````

And in a 3 dimensional world, the number of surrounding cells grows to 26. That is 3 * 3 * 3 - 1 where the minus one is the [0, 0] location.

``````a= RedWorld(RedVector[100, 200, 300])  //a 3D world
a.surroundings
[ [ -1, -1, -1 ], [ -1, -1, 0 ], [ -1, -1, 1 ], [ -1, 0, -1 ], [ -1, 0, 0 ], [ -1, 0, 1 ], [ -1, 1, -1 ], [ -1, 1, 0 ], [ -1, 1, 1 ], [ 0, -1, -1 ], [ 0, -1, 0 ], [ 0, -1, 1 ], [ 0, 0, -1 ], [ 0, 0, 1 ], [ 0, 1, -1 ], [ 0, 1, 0 ], [ 0, 1, 1 ], [ 1, -1, -1 ], [ 1, -1, 0 ], [ 1, -1, 1 ], [ 1, 0, -1 ], [ 1, 0, 0 ], [ 1, 0, 1 ], [ 1, 1, -1 ], [ 1, 1, 0 ], [ 1, 1, 1 ] ]
``````

And the numbers for 4, 5 and 6 dimensional worlds (not that I ever used >3) are 80, 242, 728 respectively. (A `RedWorld` can have any number of dimensions.)

Also it is possible to not only get the directly adjacent cell, but neighbours further away. This example bumps up the `surroundingArea` variable from the default 1 to 2. Now the surroundings are all the cells next to and two steps away from [0, 0].

``````a= RedWorld(RedVector[100, 200])  //a 2F world
a.surroundingArea= 2
a.surroundings
[ [ -2, -2 ], [ -2, -1 ], [ -2, 0 ], [ -2, 1 ], [ -2, 2 ], [ -1, -2 ], [ -1, -1 ], [ -1, 0 ], [ -1, 1 ], [ -1, 2 ], [ 0, -2 ], [ 0, -1 ], [ 0, 1 ], [ 0, 2 ], [ 1, -2 ], [ 1, -1 ], [ 1, 0 ], [ 1, 1 ], [ 1, 2 ], [ 2, -2 ], [ 2, -1 ], [ 2, 0 ], [ 2, 1 ], [ 2, 2 ] ]
``````

That is 24 neighbour locations per single cell in a 2D world.

So the `surroundings` method only give relative positions and the size of the neighbourhood. Not so useful. But there are the two other methods called `surroundingLocations` and `neighbours` that is what one should use. `surroundingLocations` takes an object and returns a list of locations depending on the current surroundings.

``````a= RedWorld(RedVector[100, 200])  //a 2D world
b= RedObject(a, RedVector[10, 20])  //an object at location [10, 20]
a.surroundingLocations(b)  //get the surrounding locations of object b
[ RedVector[ 9, 19 ], RedVector[ 9, 20 ], RedVector[ 9, 21 ], RedVector[ 10, 19 ], RedVector[ 10, 21 ], RedVector[ 11, 19 ], RedVector[ 11, 20 ], RedVector[ 11, 21 ] ]
``````

Last the `neighbours` method that returns an array of any nearby objects.

``````a= RedWorld(RedVector[100, 200])  //a 2D world
b= RedObject(a, RedVector[10, 20])  //an object at location [10, 20]
c= RedObject(a, RedVector[11, 21])  //an object at location [11, 21]
a.neighbours(b)  //get the neighbouring objects of object b
[ a RedObject ]
``````

The different worlds deals with border conditions differently. `RedWorld` wraps all the locations around and `RedWorld3` filters out locations. Compare...

``````a= RedWorld(RedVector[100, 200])  //a 2D world without borders
b= RedObject(a, RedVector[0, 0])  //an object at upper left corner location [0, 0]
a.surroundingLocations(b)  //get the surrounding locations of object b
[ RedVector[ 99, 199 ], RedVector[ 99, 0 ], RedVector[ 99, 1 ], RedVector[ 0, 199 ], RedVector[ 0, 1 ], RedVector[ 1, 199 ], RedVector[ 1, 0 ], RedVector[ 1, 1 ] ]
``````
``````a= RedWorld3(RedVector[100, 200])  //a 2D world with borders
b= RedObject(a, RedVector[0, 0])  //an object at upper left corner location [0, 0]
a.surroundingLocations(b)  //get the surrounding locations of object b
[ RedVector[ 0, 1 ], RedVector[ 1, 0 ], RedVector[ 1, 1 ] ]
``````

The `neighbours` method is quite slow at the moment, but I hope to be able to speed it up considerably later on.

Anyway, here is the complete SVN diff: sourceforge.net/p/quarks/code/1765/