0

I'm currently building a simple simulation software that emulates animals in an environment and how they would generally interact with each other.

The "animals are created as objects. So I have a main Animal class, and many other classes that extend this class ( i.e. Wolf, Lion, Deer, etc).

I need to build a class that creates an environment for them to roam about on. I was thinking whether a 2 dimensional array might work for the same?

Animal object would be able to "roam" about on this matrix, scanning the surrounding cells for other Animals to interact with.

Would this be the best way to go about building a particular environment for the objects to "move" about on? Just looking for opinions.

Umang Mehta
  • 1,467
  • 11
  • 16
Martin
  • 166
  • 1
  • 15
  • Need more input on your needs.. This is how tile based games work so it might work for you – Karthik T Sep 09 '13 at 07:17
  • 4
    "Just looking for opinions". Thats not really a good fit for SO. – diestl Sep 09 '13 at 07:17
  • Title should not contain tags. Also this question is very broad and covers quite large topic. – Leri Sep 09 '13 at 07:18
  • if your objective is AI(artificial intelligence) , go matlab , not sure but some java-matlab exists – Srinath Ganesh Sep 09 '13 at 07:20
  • Why bother with an array, which will restrict your model's resolution to an arbitrarily discretized level of precision? Why not just tag each critter with a location attribute? This approach would also be easy to generalize to 3-d in case you want to add birds, bats, fish, etc. – pjs Sep 09 '13 at 13:55

5 Answers5

0

A 2-dimensional Array would be nice. It´s very good when creating a kind of playing field.

When you also want a 3rd-Dimension, e.g. for birds which are flying, or a worm in the ground you will need a 3-dimensional Array

Regards

Holger
  • 496
  • 3
  • 8
  • 1
    A third dimension can be simulated with a 2D array quite easily. There is no need to create a 3D array. It's a waste of memory. You can either treat birds and subterranean animals differently, or use a bitmask as mentioned in another answer. – RaptorDotCpp Sep 09 '13 at 07:26
0

Yep that's a very good way to start. Go for it!

One hint as you go... you can use a bitmask for what is actually on the square (rather than a third dimension). So, something that was on the ground, could take up the 0x1 bit, and something in the air could take 0x2 (= 10 in binary).

So you have:

int[][] tiles = ...;
// something in the air moved to 0, 1..
tiles[0][1] ||= 0x2;
pfrank
  • 2,090
  • 1
  • 19
  • 26
0

Think of a chess board. It is made up of squares. Each square can have a piece on it.

For your idea the board is like the world. The square is an area on the world. A piece is an animal.

The world could have a 2d array of squares and each square could either have one animal or a List<Animal> on it.

TofuBeer
  • 60,850
  • 18
  • 118
  • 163
0

There are probably many ways that you could go about this. Most of which are not known to me. However I have recently solved a similar problem in two different ways:

Two Dimensional Array

Implementing the "Map" as a two Dimensional Array is the obvious solution. Most likely for this scenario you will want an List implementation so that you can resize easily. It will however require nested loops and such to search for a particular location, and the indexes might become somewhat confusing.

Map

A (in my opinion) better way to solve this problem would be to use a Map. You should create a Position class that has two variables (or three for a three-dimensional map) that record the X and Y position (Make sure you also implement the equals() and hashCode() methods). You can then use a Position object as the key in a Map implementation, stored against instances of Animal. This will allow for faster searching of a particular location (see HashMap vs ArrayList performance am I correct), and tidier code, ie no nested loops when iterating over the whole map. You can loop over the whole map like this:

for(Map.Entry<Position, Animal> entry : animalMap.getEntries()){
    //Do stuff
}

A couple of years ago I saw a tutorial project that implemented a Fox/Rabbit simulation. You may want to have a look at that for some ideas: http://www.bluej.org/objects-first/

You need to download the "Book Projects" .zip file. The relevant project is in Chapter 10.

Community
  • 1
  • 1
diestl
  • 2,020
  • 4
  • 23
  • 37
  • Not sure where you get that a Map would be faster than an array, or how you would remove nested loops. With an array it is [x][y] - no searching at all, direct access. If you want to go through app Positions in the Map you are still going to have nested loops to build all the Positions. – TofuBeer Sep 09 '13 at 07:30
  • @TofuBeer I am assuming that the OP would require a re-sizable array (ArrayList for instance). In this case access performance would be better with a Map implementation. No nested loops are required to go through the entire map. – diestl Sep 09 '13 at 07:39
  • I wouldn't assume an ArrayList, the poster said 2d array. An ArrayList of ArrayLists would still be faster than a Map. Either way I don't think speed should be a factor, none of them are going to be especially slow. If you want to go through the Map, Position by Position for a range (say 1,2 to 5,7) you are going to need a nested loop. If you have another way to do it I'd love to hear it. – TofuBeer Sep 09 '13 at 07:46
  • @TofuBeer Yes, when looping over part of the map, nested loops will be required. It would be easier to extend the Map idea to three dimension (if required). – diestl Sep 09 '13 at 07:54
  • This answer was especially helpful. I know this question may have been broad and not exactly the type to put on here, but after searching for over a day i still wasn't sure of the best solution. I eventually plan to move up to a 3 dimensional model to include flight, but that is later on. For now, I think I will try the ArrayList method. And yes, @tofubeer, speed is not a priority for me right now. – Martin Sep 09 '13 at 13:35
0

For a completely different approach, check out this paper which describes how to do movement and sensing in a discrete-event framework rather than a time-stepped/gridded framework. Advantages include that it easily generalizes to 3-d, and that things happen in your model when and where they actually happen rather than rounded to the nearest delta-t and spatial grid location. It's also more computationally efficient in most cases. If you have n critters there are O(n**2) potential interactions to be evaluated every delta-t. By contrast, when an event occurs it changes the status of a single critter, so you only have to do O(n) work to see how the change might affect interactions with all the other critters. Since events are generally rarer than time steps, this translates into a huge win computationally.

To see an example of this, check out this Java applet. The blue dots are patrol boats, the yellow and green dots are boats of various types that are supposed to stay north of the purple line. If they cross the line they get intercepted and boarded for inspection. The animation has to be done in a time-stepped fashion, but the underlying model is discrete-event. If you click the pause button and then the play button, you'll see that the model runs like a bat out of hades when not tied to the time-stepping of the animation. Substitute critters for boats and change the specific behaviors, and it's a reasonable start on your animal simulation.

pjs
  • 18,696
  • 4
  • 27
  • 56