I am having a terrible time with using an ArrayList in a superclass. The ArrayList is used to hold objects of three different types of subclasses of superclass Enemy. Depending on how I reference an object in the ArrayList in the driver file dictates different results.
Enemy is a child of a superclass called fighter. Fighter holds the private data for all of the objects.
Here is the superclass Enemy.
import java.util.*;
public class Enemy extends Fighter {
public void getRandomEnemy(){};
public ArrayList<Enemy> enemy = new ArrayList<Enemy>();
Enemy(String wep, String arm, String nam, int health, int magResis, int physResis, int rangResis)
{
super(wep,arm,nam,health,magResis, physResis,rangResis);
}
}
For Example:
Two of Enemy's subclasses Troll and Sorcerer have objects of their respective types added to the ArrayList found in the parent class Enemy.
Troll and Sorcerer Constructors:
Sorcerer(String wep, String arm, String nam, int health, int magResis, int physResis, int rangResis)
{
super(wep,arm,nam,health,magResis, physResis,rangResis);
}
Troll(String wep, String arm, String nam, int health, int magResis, int physResis, int rangResis)
{
super(wep,arm,nam,health,magResis, physResis,rangResis);
}
I am adding objects to the ArrayList in superclass enemy through these methods. Each method is found in its respective class.
public void getRandomEnemy()
{
enemy.add(new Troll("Bow", "Leather", "Troll",350, 30, 15,30));
}
public void getRandomEnemy()
{
enemy.add(new Sorcerer("Staff", "Cloth", "Sorcerer",300, 70, 5,5));
}
Now in my driver file if I add objects of types troll and sorcerer to the ArrayList in enemy as such.
Driver file:
int p = 5; // adds 5 enemies to the ArrayList enemy
int randEnemy = 0;
for(int i =0; i < p; ++i)
{
randEnemy = (int) (Math.random() * (3));
if(randEnemy == 0)
{
sorc.getRandomEnemy();
}
else if(randEnemy == 1)
{
trol.getRandomEnemy();
}
else
{
og.getRandomEnemy();
}
}
This is where I begin to run into issues. For example, if I want to return the size of ArrayList enemy. The total size I have to do this in my driver file.
int size = sorc.enemy.size() + trol.enemy.size() + og.enemy.size();
I have to call each specific object type and add them together.
If I do Enemy.enemy.size(); It will return 0.
Again, things get fishy with the ArrayList when I want to attack an enemy.I have to specifically look for each Sorc object or Troll object in the ArrayList.
for(Enemy j : sorc.enemy)
{
System.out.println("Sorc's Health: " + j.getHealth());
System.out.println("Sorc's Armor: "+ j.getArmor());
sorc.takeDamage(attack, "Cloth", weapon);
}
If I do the code above I will get the correct health for the Sorcerer which is 300 and I will get the correct armor. But, the Sorcerer will not take any damage.
If I do this:
for(Enemy j : sorc.enemy)
{
System.out.println("Sorc's Health: " + j.getHealth());
System.out.println("Sorc's Armor: "+ j.getArmor());
j.takeDamage(attack, "Cloth", weapon);
}
The health will return -1999234 or some random negative value,but the takeDamage() method will work perfectly.
My question is why when I reference the object differently, I get different results? How do I properly reference the objects in the ArrayList to ensure the proper values are getting set? I am sure it isn't a logic error because I am setting the values in the constructors and calling the constructors in the getRandomEnemy() method to add objects to the ArrayList.
EDIT: Issue Fixed
In the superclass Fighter the constructor is defined as such.
public Fighter(String wep, String arm, String nam, int health, int magResis, int physResis, int rangResis)
{
this.name = nam;
this.weapon = wep;
this.armor = arm;
this.health = health;
this.magicResistance = magResis;
this.physicalResistance = physResis;
this.rangedResistance = rangResis;
}
Health was giving me the issue. It was the only variable turning out wonky data. As you see, the parameter has int health, and I am setting that argument that is passed through to this.health = health;
Even though I am using this. to distinguish between the the parameter and the instance variable, the value was coming out negative.
I simply changed the constructor to this:
public Fighter(String wep, String arm, String nam, int hea, int magResis, int physResis, int rangResis)
{
this.name = nam;
this.weapon = wep;
this.armor = arm;
this.health = hea;
this.magicResistance = magResis;
this.physicalResistance = physResis;
this.rangedResistance = rangResis;
}
and now everything works.