I am working on a homework project in which we need to generate a state tree for the game of Golf Solitaire. To do this I decided to create a Move class which represents a move from one stack of cards to another – simply put, it holds a reference to the two stacks involved in a single move. Each node in my tree knows what it’s move is.
The problem I am currently having is that my trees are much too large – like OutOfMemoryError too large. Edit – I should note that when I make a tree for a very small game I do not get an error, but my tree is still much larger than it should be!
For those unfamiliar with the game: Golf Solitaire Rules. Note – We did not need to implement the restriction on playing a Queen after a King.
public void makeTree()
{
_root = makeNode( null, null, 0 );
}
private Node makeNode( Node parent, Move m, int depth )
{
Node node = new Node( parent, m, depth );
ArrayList<Move> moves = findAllMoves();
if( moves.size() == 0 )
node.setScore( getScore() );
else {
for( Move mv : moves ) {
mv.makeMove();
Node child = makeNode( node, mv, depth++ );
node.addChild( child );
mv.undoMove();
}
}
return node;
}
private ArrayList<Move> findAllMoves()
{
ArrayList<Move> moves = new ArrayList<Move>();
for( int i = 0; i < numPlayPiles; i++ ) {
if( _play[i].size() != 0 ) {
if( Math.abs( _play[i].top().getRank().ordinal() -
discard.getRank().ordinal() ) == 1 ) {
moves.add( new Move( _play[i], _discard ) );
}
}
}
if( _draw.size() != 0 )
moves.add( new Move( _draw, _discard ) );
return moves;
}
_play[i] is simply referencing a pile of cards in the game.
I realize this is a bit much of code to be posting in a question, but my question is simply about my logic. I have a suspicion that my error is in how I am returning makeNode yet I am totally stuck here. Could anybody confirm my suspicion and/or possibly give me some guidance?
For anybody who is curious, my issue was one of not reading the assignment properly. Specifically, my
findAllMovesmethod was the issue. A node should have either a move from the draw pile or all possible moves from play piles, but not both. My code above allows each child, even at the same depth, to each create aMovefrom the draw pile to discard pile – resulting in a huge amount of duplicate nodes.It also never checks the end-game conditions. As a result, each leaf node was either a losing score, or 0 (the method would recurse until the draw pile was empty even if the player already won).