3

so for the game I'm creating I have a few classes that extend GameDriver.

Up until this point, on all the other classes I've been able to extend GameDriver and then In GameDriver I can do:

ArrayList<Card>  library = new ArrayList<Card>();

Today I started on the GameAI class and I extended GameDriver, and when I put:

GameAI Enemy = new GameAI();

In the same spot I put the other line of code (Right below public class GameDriver)

I get:

java.lang.StackOverflowError
at java.util.WeakHashMap.expungeStaleEntries(Unknown Source)
at java.util.WeakHashMap.getTable(Unknown Source)
at java.util.WeakHashMap.get(Unknown Source)
at java.awt.Component.checkCoalescing(Unknown Source)
at java.awt.Component.<init>(Unknown Source)
at java.awt.Container.<init>(Unknown Source)
at java.awt.Panel.<init>(Unknown Source)
at java.awt.Panel.<init>(Unknown Source)
at java.applet.Applet.<init>(Unknown Source)
at GameDriver.<init>(GameDriver.java:14)
at GameAI.<init>(GameAI.java:8)
at GameDriver.<init>(GameDriver.java:40)
at GameAI.<init>(GameAI.java:8)

If I put it in the public void init() of my applet, then it doesn't give an error on run, but then I wouldn't be able to access it from my other methods, am I over looking something? All nighters normally don't help my brain...

This is what the GameAI looks like as of right now:

public class GameAI extends GameDriver {

    public int life;
    public int energy;

    public void drawPhase(){

    }

    public GameAI(){
        life = 20;
        energy = 2;
    }
}

And then some bits of the GameDriver:

public class GameDriver extends Applet implements MouseMotionListener,MouseListener {

Graphics g; 
Image offscreen;
Dimension dim; 

int playerLife = 20;
int playerEnergy = 8;

int xMouse; 
int yMouse;
int lineThickness = 4;
int handSize = 6;
int currentHover;
boolean slotHover;
int currentSelected;
boolean slotClicked;
int currentHoverBoard;
boolean slotHoverBoard;
boolean slotClickedBoard;
int currentSelectedBoard;

boolean canPlace;
ArrayList<Card>  library = new ArrayList<Card>();
ArrayList<Card>  hand = new ArrayList<Card>();
ArrayList<Card>  playerBoard = new ArrayList<Card>();
GameAI Enemy;
int[] handBoxX = new int[handSize];
int[] handBoxY = new int[handSize];
int[] handBoxW = new int[handSize];
int[] handBoxH = new int[handSize];

int[] playerBoardX = new int[8];
int[] playerBoardY = new int[8];
int[] playerBoardW = new int[8];
int[] playerBoardH = new int[8];



public void init(){
    this.setSize(640, 480);
    dim = this.getSize();
    addMouseMotionListener(this);
    addMouseListener(this);
    createLibrary();
    drawFirstHand();
    printHand();


    GameAI Enemy = new GameAI();
    checkEnemy();



    offscreen = createImage(this.getSize().width,this.getSize().height);
    g = offscreen.getGraphics(); 
}

public void checkEnemy(){
    System.out.println(Enemy.energy);
}

... Alot more methods and stuff below, but nothing to do with the GameAI enemy
Jeremy Sayers
  • 637
  • 4
  • 10
  • 23
  • 1
    Can you post the code of your constructors? In particular `GameAI` and `GameDriver` – Lukas Eder Aug 19 '12 at 14:54
  • As of right now, GameAI is 100% blank, just a blank constructer, and then a blank method called drawPhase just to test out, as for GameDriver I'm not using the constructor – Jeremy Sayers Aug 19 '12 at 14:56
  • "StackOverflow" isn't just a cute name of a web site - it indicates a condition where you have overflowed the stack, and one of the most common ways to overflow the stack is to have an infinite loop of contructors, where the constructor of your object is causing another object to be created, and that's causing another object to be created, ad infinitum. – Paul Tomblin Aug 19 '12 at 14:56
  • @JeremySayers: Your stack trace indicates something else. The two constructors seem to be direclty inter-dependent. You can even see the line numbers where one calls the other. Note that if `A` extends `B`, then `A` will always call a super-constructor, even if you don't explicitly write that code. Please post their code – Lukas Eder Aug 19 '12 at 14:58
  • Do you have a constructor for GameDriver? Or any member initialization calling GameAI, or init()? – onon15 Aug 19 '12 at 15:12
  • @JeremySayers you have a circular dependency. – obataku Aug 19 '12 at 15:12
  • You're instantiating a GameAI in GameDriver.init. If init is called during its ctor process, you have a circular dependency. – Dave Newton Aug 19 '12 at 15:15
  • Then would this be better? I have this in below the GameDriver class ArrayList Enemy = new ArrayList(); and then in the init I can do Enemy.add(new GameAI()); and then I can just do Enemy.get(0).doSomthing(); is that an ok way? – Jeremy Sayers Aug 19 '12 at 15:17

1 Answers1

3

You're creating a GameAI object inside of GameDriver, the class it extends. This will cause recursion to continue until you run out of memory.

Solution: don't do this. Your GameAI class should not extend GameDriver as that's the wrong way to share information and it simply won't work even if you didn't have this recursion nightmare. Instead give GameAI a GameDriver field and pass the GameDriver instance into GameAI through its constructor.

i.e.,

class GameAI {
   private GameDriver gameDriver;

   public GameAI(GameDriver gameDriver) {
      this.gameDriver = gameDriver;
   }

   //.... more code
}  

Edit 2
If you want one GameAI object, you'd do

GameAI gameAi = new GameAI(this);

If you want an array or List of them, you'd do this in a loop.

Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
  • Ok so I get that part, but then in the GameDriver how do I create a GameAI object? Same way as usual? – Jeremy Sayers Aug 19 '12 at 15:23
  • Thank you so much, I'm guessing I should do the same thing with my cards class? Haha – Jeremy Sayers Aug 19 '12 at 15:26
  • @Jeremy: be very selective about using inheritance. You should only have one class extend another if it is truly a subtype of the parent. Don't use it to try to share variables as you're doing above. GameAI is not in its essence truly a child of GameDriver, not in any universe. – Hovercraft Full Of Eels Aug 19 '12 at 15:35