I am working on a project for my Object Orientated Java II course, and I am having trouble with starting it, as I can't seem to follow the logic of how the abstract classes I have to override with my own concrete classes are constructed (without running into a StackOverflowError). I am not allowed to declare any new state information in my concrete classes or modify the given abstract classes.
Here is the code for the abstract "Game" class:
public abstract class Game
{
protected Board board; // the board for this game
protected Player p1; // the game's first player
protected Player p2; // the game's other player
protected Player winner; // the game's winner
protected int score1; // p1's score
protected int score2; // p2's score
protected Player currentPlayer; // the player whose turn it is to play
/**
* Constructor for objects of class Game
*
* @param board an empty, game-specific board to play the
* game on
*/
public Game(Board board)
{
this.board = board;
board.setGame( this );
score1 = score2 = 0;
}// constructor
/**
* Plays an entire game
*/
public void play()
{
setUp();
board.display();
while (! gameOver() )
{
p1.playAMove();
board.display();
if (gameOver())
break;
p2.playAMove();
board.display();
}// main game loop
wrapUp();
}// play method
/**
* Sets up the board in its initial configuration as well as
* the two players of this game
*/
public abstract void setUp();
/**
* Determines whether or not the game has ended
*/
public abstract boolean gameOver();
/**
* Finishes the game after a tie or a win
*/
public abstract void wrapUp();
}
Here is the code for the abstract "Board" class:
public abstract class Board
{
protected Game game; // the game using this board
protected Piece[][] board; // the state of the board
protected int rows; // the vertical size of the board
protected int cols; // the horizontal size of the board
/**
* Constructor for objects of class Board
*
* @param game game the board is used for
* @param numRows number of rows of the board
* @param numColumns number of columns of the board
*/
public Board(Game game, int numRows, int numColumns)
{
this.game = game;
rows = numRows;
cols = numColumns;
board = new Piece[rows][cols];
}// constructor
/**
* Associates to this board the game that uses it
*
* @param game the game that uses this board
*/
public void setGame(Game game)
{
this.game = game;
}// setGame method
/**
* Returns the piece located at the given position or null
* if no piece is at that location; throws an exception if
* the location is off the board
*
* @param row the row index of the location
* @param column the column index of the location
* @return the piece at the given location or null
* if the location is empty
*/
protected Piece getPiece(int row, int column)
throws InvalidBoardPositionException
{
if (row < 0 || row >= rows || column < 0 || column >= cols)
throw new InvalidBoardPositionException(row,column);
return board[row][column];
}// getPiece method
/**
* Puts down the given piece at the given location; throws an
* exception if the location is off the board or already
* occupied
*
* @param piece the piece to place on the board
* @param row the row index of the target location
* @param column the column index of the target location
*/
protected void putPiece(Piece piece, int row, int column)
throws InvalidBoardPositionException
{
if ( row < 0 || row >= rows ||
column < 0 || column >= cols ||
! isEmpty(row,column) )
throw new InvalidBoardPositionException(row,column);
board[row][column] = piece;
}// putPiece method
/**
* Removes from the board the piece at the given location;
* throws an exception if the location is off the board or empty
*
* @param row the row index of the target location
* @param column the column index of the target location
*/
protected void removePiece(int row, int column)
throws InvalidBoardPositionException
{
if ( row < 0 || row >= rows ||
column < 0 || column >= cols ||
isEmpty(row,column) )
throw new InvalidBoardPositionException(row,column);
board[row][column] = null;
}// removePiece method
/**
* Returns true if and only if the specified location is
* empty
*
* @param row row index of the location being checked
* @param col column index of the location being checked
* @return true if and only if there is no piece at
* the location being checked
*/
protected boolean isEmpty(int row, int col)
{
return board[row][col] == null;
}// isEmpty method
/**
* Displays the board on the terminal window
*/
protected abstract void display();
}
I have to extend both classes (GGame extends Game, GBoard extends Board), and use this code in GGame to start the program:
public static void newGame()
{
new GGame().play();
}
There are other classes, but all I care about for now is actually getting the program to create an instance of "GGame" so I can move forward. I've tried doing this:
/**
* Constructor
*/
public GGame() //needs to have no parameters
{
super(new GBoard());
}
However, the constructor of the abstract "Board" class (which "GBoard" has to extend) requires an instance of "Game" to be passed to it. But if I pass an instance of "GGame" into the "GBoard" constructor it loops infinitely as new GGame()
and new GBoard()
call each other.
I'll take any ideas about what I can do, and will provide more info if necessary. I don't want someone to do the project for me, I'm just legitimately stuck and don't know how to proceed. I'm sure I'm missing something.
If you don't want to modify the implementation of abstract classes, you must pass null
to the constructor of the superclass as follows:
class BoardImpl extends Board {
BoardImpl() {
super(null, a, b);
}
}
class GameImpl extends Game {
GameImpl(Board board) {
super(board);
}
}
and then pass the Board instance to the Game constructor:
Board board = new BoardImpl();
Game game = new GameImpl(board);
also note that passing this
in the class constructor like this:
public Game(Board board)
{
this.board = board;
board.setGame( this );
score1 = score2 = 0;
}
is a very bad practice because at the time of passing this
instance is not yet fully constructed.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.