Seraphim
Seraphim

Reputation: 181

Using an uninitialised variable in a constructor

So I have a rather simple piece of code:

    Soldier Horseman = new Soldier("Horseman",Archer, 20);
    Soldier Spearman = new Soldier("Spearman",Horseman, 10);
    Soldier Archer = new Soldier("Archer",Spearman, 10);

Where the constructor for soldier takes the arguments

    Soldier(String name, Soldier target, double range)

The target is then used to calculate distance between the two in a method.

public double DistanceCalculation() {
    distanceToTarget = ((Math.pow((soldierPosition[0] - soldierTarget.soldierPosition[0]), 2)) + Math.pow((soldierPosition[1] - soldierTarget.soldierPosition[1]), 2));
    return distanceToTarget;

However, when I try to create this code, the top most soldier cannot be created because its target doesnt exist yet. I tried using String instead of Soldier in the constructor, but then I cannot figure out how to convert string into Soldier so that the SoldierTarget.soldierPosition works. Any ideas?

Upvotes: 1

Views: 89

Answers (4)

FredK
FredK

Reputation: 4084

Don't set the target in the constructor. Set it in another method:

Soldier target;
Soldier(String name,double range) {
  // etc
}
public void setTarget( Soldier s ) {
   target = s;
}

Then you can do this:

Soldier horseman = new Soldier("Horseman", 20);
Soldier spearman = new Soldier("Spearman", 10);
Soldier archer = new Soldier("Archer", 10);

horseman.setTarget(archer);
spearman.setTarget( horseman );
archer.setTarget(spearman);

This way each soldier knows about his current target. Then if (for example) horseman vanquishes the archer, you can just call horseman.setTarget(spearman) to set a new target. I was assuming range was the soldier's maximum attack range, but if it is the distance to the target it should not be set in the constructor either.

Upvotes: 3

SiKing
SiKing

Reputation: 10329

How about something like:

Soldier Horseman = null;
Soldier Spearman = null;
Soldier Archer = null;
Horseman = new Soldier("Horseman",Archer, 20);
Spearman = new Soldier("Spearman",Horseman, 10);
Archer = new Soldier("Archer",Spearman, 10);

Upvotes: 0

Paul Boddington
Paul Boddington

Reputation: 37645

It may be a better idea to store the information about targets in a separate data structure, e.g. a HashMap<Soldier, Soldier>. Then you can make Soldier immutable, and all the circularity problems disappear.

Soldier horseman = new Soldier("Horseman", 20);
Soldier spearman = new Soldier("Spearman", 10);
Soldier archer = new Soldier("Archer", 10);
Map<Soldier, Soldier> targets = new HashMap<>();
targets.put(horseman, archer);
targets.put(archer, spearman);
targets.put(spearman, horseman);

Upvotes: 4

dmux
dmux

Reputation: 442

You could create another constructor (in addition to your already existing one):

Soldier(String name, double range)

and then in your DistanceCalculation method, perform a hasTarget() check.

Upvotes: 2

Related Questions