Basic game design question

Hi all,

I’m currently designing the core for a personal game project of mine and seem to have got stuck with the simplist of problems.

The background

I have three classes

  • Mouse
  • Cat
  • Dog

all of which extend the Animal class.

There are only two other classes to consider: House which extends Building.

Class structures

Animal


public abstract class Animal {

  public int x,y,qty;

  public Animal(int x, int y, int qty) {
    this.x = x;
    this.y = y;
    this.qty = qty;
  }

}

Mouse


public class Mouse extends Animal {

  public static final int ID = 1;

  public Mouse(int x, int y, int qty) {
    super(x,y,qty);
  }

}

Building


public abstract class Building {

  // Option 1
  Animal[] pets;
  // Option 2
  ArrayList pets;
  // Option 3
  HashMap pets;

  public Building() {
    // Option 1
    pets = new Animal[2];
    // Option 2
    pets = new ArrayList();
    // Option 3
    pets = new HashMap();
  }

}

House


public class House extends Building {

  public static final int ID = 1;

  public House() {
    super();
    // Option 1 (Array)
    pets = new Animal[]{new Mouse(getX(), getY(), 1)};
    // Option 2 (ArrayList)
    pets.add(new Mouse(getX(), getY(), 1));
    // Option 3 (HashMap)
    pets.put(new Integer(Mouse.ID), new Integer(1));
  }

}

The problem

Seen in the Building and House classes are three options for ways to save your pet objects into the house. At any point though, another mouse could come into the house, bumping up the qty variable value by one of the mouse object. My question is how do I do this efficiently and what is the best method to use?

i.e. Using arrays - If a mouse enters the house, I first need to run through the pets array attempting to cast each element to a Mouse, upon success, the qty value is incremented, but using the instanceof or casting seems very inefficient.

Using ArrayLists - nice to use, but I can’t seem to find a nice way to pull individual animals out of the list when “building.getPet(id animalID)” is called.

Using HashMap - Each animal type has it’s own unique ID - this ID is fed into the key of the hashMap and the value associated with this is the qty variable. My problem with this is that I would no longer have access to any of the animal’s other variables, methods… If I were to use pets.put(new Mouse(x,y,z,1), new Integer(1)) this would duplicate the qty variable. :confused:

Ideally i’d like to use the unique static IDs as a lookup table to the actual class. So I think I’d use

 
pets.put(new Integer(Mouse.ID), new Mouse(x,y,z,1));

Generally, there won’t be more than 20 different type of animal in a building (the norm will be around 3). What would be the most efficient method to use?

Many thanks. Any advice would be much appreciated!

ribot

What in the name of heck does the quantity variable do? If it’s a total count of all animals of that type, you might be better making it a static member of Mouse, Cat and Dog, with an abstract getQuantity in the Animal class. However I think you’re looking at this from the wrong angle - either you want to treat all animals the same (in which case have one collection for all Animal-derived classes) and stop trying to get specific Mouse / etc, types only. Or you specifically hold different animals in seperate containers for each type.

Edit: And if you’re only expecting about 20ish animals total, stop worrying about efficiency and get a nice clean design. You could do a bogo sort on a 20 animal collection and your computer wouldn’t even blink.

hehe, thanks for the reply OT!

Well, what I meant is that there will be at most 20 different types of animals, but the quantities (number of each type) could easily be 30,000 or so. I do want to treat all the animals the same - it’s just that I need a nice efficient method to bump the number of a specific type’s quantity up or down by x.

I’m currently tending towards the HashMap:

where the House uses


pets.put(new Integer(Mouse.ID), new Mouse(x,y,z,1));

, which allows a fast lookup on the unique animal ID (Unless I’m wrong?).

:wink:

I then use a snippet of code (contained in Building) to update the number of a type of animal in a House:


public void setAnimalQty(int animalID, int qty) {
  if(stock.containsKey(new Integer(animalID))) {
    ((Animal)stock.get(new Integer(animalID))).setQty(qty);
  }
}

Aha, you’re not creating a Mouse object for each mouse then, it’s more like a MousePopulation, which represents a whole group of animals? In that case ignore what I said about static quantities. In that case a Map of some variety would be what you’re after.

If you want to do it the old-school way, and your ids will always be ints then you can just use an array as a look up table (where the id indexes into the correct object). But that tends to be more fragile and only really gains you a small amount of speed.

Excellent! Thanks for the confirmation OT.

Had thought about going the old skool route, but thought that it would probably be best that I went for something a little less fragile for part of the core of my engine.

Any idea as to the actual speed boost gained by using array lookup tables in relation to maps? (1 - 3%?)

Cheers,

ribot

Or to extend OT’s method (in Java 1.5), use an enum (e.g. AnimalType) for your object type, and an EnumMap<AnimalType,Animal> to map your object type to the object itself (which IIRC stores the values as an array so is nice and fast).