Alon Emanuel
Alon Emanuel

Reputation: 184

Bidirectional dependency of two objects

BACKGROUND

I have the following:

class Fire extending Element,

class Wood extending Element,

class Tile which composites Element.

The Tile class represents a tile in a world/screen/canvas, and has some graphical and logical functionality in it. It composites an Element object, because every tile in the "world" is made out of some substance (=element).

I want to achieve the functionality of fire spreading - when a fire element "touches" a wood element, I want the wood element to become fire. Logically, this should be done within the fire element, but doing that, I'm unable to change the given Tile's element (e.g. from Wood to Fire).

The "world" is initialized as a grid of tiles that are composed of Wood elements, except for one tile that has a Fire element which is supposed to spread.

WHAT I'VE TRIED

I've tried Linking together elements, meaning each element has access to his four nearest neighbors. That way a fire can access a nearby piece of wood. This doesn't solve the problem of changing a Tile's element type when fire touches wood.

I've tried moving the entire functionality to the Tile class. Although it does solve the problem, I don't like it for two reasons:

  1. Logically, I want the fire to act autonomously, meaning the fire is what spreads, and not the tile.

  2. As a result, the Tile class has many methods that are only fire related (such as spread()), which requires me to check - "is this tile composed of a fire element?", which is bad practice.

CODE EXAMPLE

class Fire extends Element{
    public void spread(){
        // Move to all four neighbors and turn them into Fire elements
    }
}

class Wood extends Element{
}

class Tile{
    private Element _element;

}

IN DEPTH

  1. The 'grid' of tiles consists of a 2-dimensional array of Tiles (logic part), and a JavaFx Pane consisting of all tiles (visual part).

  2. A fire 'spreads' when it touches a neighbor tile and turns it from Wood to Fire. A fire ceases to spread when it consumed (=changed to fire) a given threshold of wood, e.g. after it consumed 30 pieces of wood. In a sense, the fire can keep track of the wood it consumed.

Thanks in advance!

Upvotes: 3

Views: 950

Answers (1)

Andrew
Andrew

Reputation: 49656

My instant thought was there should a class to manage fire spreading. Let's say, there's a World class, the one that is aware of the grid of tiles and their nature. Fire doesn't know anything about Wood, its location, its neighbours. The same goes for Wood. They are independent objects that live their lives. The World is up to decide where they reside and how they interact with each other.

Let's imagine Fire releases an event and tells

I wanna spread. Here are the locations I'd like to occupy. My height/my intensity/my frequency/my [any other characteristic of fire] is ..."

The World receives the message, takes into account the fire's characteristics, and modify the grid accordingly.

OK. With this intensity/height/[any other characteristic] of the fire, this and this Wood elements are going to be burnt. I will replace them with new Fire instances (or I will make a copy the existing Fire object and put a reference to it into the expected-to-be-burnt cells).

It would be interesting to have one instance of Fire and keep track of all the elements it burned. I can see a modified version of the copy constructor.

Fire(Fire current, Elements... newlyTakenElements)

Though, you're free to figure out your own way how to record it.

With this, you would be able to restore cells (fully or partially) when the fire comes to end. You could also analyse how the fire was developing. I am not sure if this may come in handy, but it's fascinating to design.


I am thinking of alternatives... I still believe giving too much information (the whole map of tiles) to Fire isn't a way to go and any interaction between Wood and Fire cells should go through the manager class.

Have a look at another scenario that suggests the World provides a partial view of itself as a list of contiguous to the fire elements.

-I wanna spread.

-OK. Here's a list of adjacent burnable elements. I am not aware of your characteristics. It's up to you to decide how many cells (and which ones) you are going to burn.

-I've burned them all. Give me more!

The world gives another list until the fire is sated.

Upvotes: 2

Related Questions