private Move solveMove(Move move) throws NoFreeCellException, AgainstTheRulesException { MoveMacro newMove = new MoveMacro(); Iterator stackIterator = stacks[move.getFrom()].createIterator(); FreeCellAllocator allocator = new FreeCellAllocator(); { // Find out if any move would be possible before we go to the trouble of creating a movemacro. boolean found = false; while (stackIterator.hasNext()) { Card theCard = (Card) stackIterator.next(); if (stacks[move.getTo()].canPush(theCard)) { found = true; break; } /* * TODO: A side effect of this is if the fromstack includes any * card that could be moved, the move will allocate free cells * until it runs out, even if the card is buried deep? * //int freeCells = allocator.getNumFreeCells(); * //for (int i=0; i < freeCells; i++) { */ } if (!found) { throw new AgainstTheRulesException("There are no valid moves possible."); } } // Go back to the beginning. stackIterator.reset(); while (stackIterator.hasNext()) { Card theCard = (Card) stackIterator.next(); // if this card can be moved, then create the move and end if (stacks[move.getTo()].canPush(theCard)) { newMove.addMove(move); break; } else { // if it can't be moved directly, then get a free cell and create a move to the free cell. int cell = allocator.getFreeCell(); newMove.addMove(new Move(move.getFrom(), cell, this)); } // If we get a NoFreeCellException here, it's passed back and newMove gets gc'ed. } // Now, go back through the moves and move everything to the destination stack in reverse order. Iterator moveIterator = newMove.createIterator(); moveIterator.previous(); // Skip the very last move, we don't need to repeat that. while (moveIterator.hasPrevious()) { Move theMove = (Move) moveIterator.previous(); newMove.addMove(new Move(theMove.getTo(), move.getTo(), this)); } return newMove; }
public void unmove(Move move) { try { Card theCard = stacks[move.getTo()].getTopCard(); stacks[move.getFrom()].deal(theCard); stacks[move.getTo()].pop(); } catch (Exception e) { controller.alert("Sorry, I guess you're outta luck."); } this.repaint(); }
public void doMove(Move move) throws AgainstTheRulesException, NoFreeCellException, InvalidCardException { Card theCard = null; try { theCard = stacks[move.getFrom()].pop(); stacks[move.getTo()].push(theCard); } catch (AgainstTheRulesException e1) { if (!theCard.equals(null)) { // If we managed to pop the card, deal it back. stacks[move.getFrom()].deal(theCard); } // TODO: If this move is already part of a movemacro, then we don't want to keep trying to // solve it. Move newMove = solveMove(move); newMove.execute(); addToHistory(move); } this.repaint(); }