سؤال

The program I am trying to create is a basic game where the user inputs a grid size the selects blocks receiving either a prize which adds to the score, a bandit which takes points away from the score or a bomb to end the game. I am getting a stack flow error and i can not figure out why?

Sorry for the large amounts of code I am just unable to find the problem!

This is the stack overflow error I'm receiving. It happens after you enter the grid size(It is much longer then this as you can see gameItems, blockHop, and prize keep repeating continuously :

java.lang.StackOverflowError
at java.lang.System.nanoTime(Native Method)
at java.util.Random.<init>(Random.java:62)
at BlockHop.<init>(BlockHop.java:12)
at GameItems.<init>(GameItems.java:20)
at Prize.<init>(Prize.java:9)
at BlockHop.<init>(BlockHop.java:27)
at GameItems.<init>(GameItems.java:20)
at Prize.<init>(Prize.java:9)
at BlockHop.<init>(BlockHop.java:27)
at GameItems.<init>(GameItems.java:20)
at Prize.<init>(Prize.java:9)
at BlockHop.<init>(BlockHop.java:27)
at GameItems.<init>(GameItems.java:20)

Block Hop GUI:

import java.util.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class BlockHopGUI extends JFrame{

  private BlockHop bh;
  private JButton [][] board;
  private JLabel scorePoints;
  private PlayHandler ph;  // listener for buttons

  public BlockHopGUI( int gridSize ) {
    super( "Click to uncover prizes" );
    bh = new BlockHop( gridSize );
    System.out.println( "gridsize: " + gridSize );
    Container c = getContentPane( );
    JPanel p = new JPanel( );
    board = new JButton[gridSize][gridSize];
    p.setLayout( new GridLayout( gridSize, gridSize ) );

    ph = new PlayHandler( );
    for ( int row = 0; row < board.length; row++ )
      for ( int col = 0; col < board.length; col++ ) {
      board[row][col] = new JButton( "" );
      board[row][col].addActionListener(ph);
      p.add( board[row][col] );
    }
    c.add( p, BorderLayout.CENTER );

    JPanel scorePanel = new JPanel( );
    JLabel scoreLabel = new JLabel( "Score: " );
    scorePoints = new JLabel( Integer.toString( bh.getScore( ) ) );
    scorePanel.add( scoreLabel );
    scorePanel.add( scorePoints );

    c.add( scorePanel, BorderLayout.SOUTH );

    setSize( 500, 500 );
    setVisible( true );  
  }

  private class PlayHandler implements ActionListener {
    public void actionPerformed( ActionEvent ae ) {
      for ( int row = 0; row < board.length; row++ ) 
        for ( int col = 0; col < board[0].length; col++ ) {
        if ( ae.getSource( ) == board[row][col] ) {
         bh.play( row, col );
         board[row][col].setText( bh.getLabel( row, col ) );
         board[row][col].removeActionListener( ph );
         break;
        }
      }
      scorePoints.setText(  Integer.toString( bh.getScore( ) ) );
      if ( bh.isGameOver( ) ) {
        JOptionPane.showMessageDialog( null, "Game over! Final points: " 
                                    + bh.getScore( ) );
        System.exit( 1 );   
      }

Block Hop Class:

import java.util.*;
import java.awt.*;
import javax.swing.*;

public class BlockHop {

  Random rand = new Random();
  private GameItems [] [] board;
  int score = 100;
  int row;
  int col;

  public BlockHop () {
    board = new GameItems [1][1];
    board[0][0] =  new Prize( 0, 0, 'P') ;
  }

  public BlockHop( int gridSize )  {
    board = new GameItems [gridSize][gridSize];
    int end = 10;
    int start = 1;
       for ( int row = 0; row < board.length; row++ )
        for ( int col = 0; col < board[row].length; col++ ) {

    int numAssign = rand.nextInt( end - start + 1 ) + start;
       // System.out.print("test");
       switch (numAssign) {
      case 1: case 2 : case 3 : case 4 : case 5 : case 6 :
        board[row][col] =  new Prize( row, col, 'P') ;
        System.out.print("test");
        break;
      case 7:
        board[row][col] = ( new Bomb( row, col, 'B') );
        System.out.print("test");
        break;
    case 8: case 9 : case 10 :
        board[row][col] = ( new Bandit( row, col, 'X') );
        System.out.print("test");
        break;
    }
   }

  }

  public void  play( int row, int col )  {
  String newID = getLabel(row, col);
   //newID.adjustScore()

  }


   public int getScore( ) {

    return score;
  }



  public String getLabel(int row, int col) {
   if ((board[row][col]).equals('P'))
     return "p";
   else if ((board[row][col]).equals('X'))
     return "x";
   else
     return "b";

  }

  public boolean isGameOver( ) {
    if ( getScore() < 0)
      return true;
    else
   return false; 
  }



}

Game Item Class:

import java.awt.*;
import javax.swing.*;
import java.io.*;

public abstract class GameItems extends BlockHop {

  private char ID;  // block type
  private int row;      // row 
  private int col;      // column


  public GameItems (){
    ID = ' ';
    row = 0;
    col = 0;
  }

  public GameItems (int newRow, int newCol, char newId) {
    row = newRow;
    col = newCol;
    ID = newId;


  }

  public int adjustScore(char input) {
    switch (input) {
      case 'P' :
     score += 10;
     break;
      case 'X':
     score -= 5;
     break;
      case 'B' :
     score -= 2000;
     break;

  }
    return score;

    }
    }

Prize Class:

public class Prize extends GameItems{
  public Prize () {
    super();
  }

  public Prize (int row, int col, char id) {
    super (row, col, id);
  }
}

Bomb Class:

public class Bomb extends GameItems {
  public Bomb () {
    super();
  }

  public Bomb (int row, int col, char id) {
    super (row, col, id);
  }
}

Bandit class:

public class Bandit extends GameItems {
  public Bandit () {
    super();
  }

  public Bandit (int row, int col, char id) {
    super (row, col, id);
  }
}
هل كانت مفيدة؟

المحلول

It is indeed a stack overflow in the constructor..

In BlockHop you have:

  public BlockHop () {

    board = new GameItems [1][1]; 
    prize = new Prize(...);
  }

However you have GameItems defined as:

public abstract class GameItems extends BlockHop {
//...
}

Every time you construct an instance of a class that inherits from GameItems, it constructs a BlockHop which constructs a Prize which inherits GameItems.. Why? because:

public class Prize extends GameItems {
//...
}

So now every time you construct a Prize, it constructs a block hop and vice versa.

نصائح أخرى

StackOverflowError itself telling you what is wrong with the program, If you see these lines which are making a pattern

at Prize.<init>(Prize.java:9)
at BlockHop.<init>(BlockHop.java:27)
at GameItems.<init>(GameItems.java:20)

If you check these lines. all these are happening at time of object creation of these classes which clearly says that for creation of GameItems you need BlackHop creation and for BlackHop you need Prize Creation and for Prize you need GameItems creation. And this is due to your inheritance hierarchy. Hence the Stack Overflow Error happening.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top