Package freecell.model

Source Code of freecell.model.Game$MoveTracker

package freecell.model;

import freecell.model.action.MoveAction;
import freecell.model.pile.Cell;
import freecell.model.pile.Foundation;
import freecell.model.pile.Pile;
import freecell.model.pile.Tableau;

import java.util.ArrayList;
import java.util.Deque;
import java.util.LinkedList;
import java.util.List;

public class Game {
    private List<Cell> cells = new ArrayList<>(4);
    private List<Foundation> foundations = new ArrayList<>(4);
    private List<Tableau> tableaux = new ArrayList<>(8);
    private MoveTracker moveTracker = new MoveTracker();

    public Game() {
        for (int i = 0; i < 4; i++) {
            cells.add(new Cell());
            foundations.add(new Foundation());
        }
        for (int i = 0; i < 8; i++)
            tableaux.add(new Tableau());
        newGame();
    }

    public List<Cell> getCells() {
        return cells;
    }

    public List<Foundation> getFoundations() {
        return foundations;
    }

    public List<Tableau> getTableaux() {
        return tableaux;
    }

    /**
     * Moves cards from one pile to another, if the move is valid.
     */
    public boolean move(Pile fromPile, Pile toPile) {
        int cardsMoved = toPile.moveFrom(fromPile);
        if (cardsMoved > 0) {
            moveTracker.addMove(new MoveAction(fromPile, toPile, cardsMoved));
            return true;
        }
        return false;
    }

    /**
     * Redo a move that was previously undone.
     *
     * @return true if another redo can be performed
     */
    public boolean redo() {
        if (moveTracker.hasNextMove()) {
            moveTracker.getNextMove().redo();
        }
        return moveTracker.hasNextMove();
    }

    /**
     * Undo a previous move.
     *
     * @return true if another undo can be performed
     */
    public boolean undo() {
        if (moveTracker.hasLastMove()) {
            moveTracker.getLastMove().undo();
        }
        return moveTracker.hasLastMove();
    }

    /**
     * Returns true if the game cannot be lost.
     */
    public boolean isWon() {
        for (Pile pile : tableaux) {
            if (!pile.isInOrder()) {
                return false;
            }
        }
        return true;
    }

    /**
     * Returns true if the game cannot be won.
     */
    public boolean isLost() {
        // Are free cells full?
        for (Pile pile : cells) {
            if (pile.isEmpty()) {
                return false;
            }
        }
        // Can you not move to any tableau?
        for (Pile pile : tableaux) {
            for (Pile tableau : tableaux) {
                if (pile.canMoveFrom(tableau)) {
                    return false;
                }
            }
            for (Pile cell : cells) {
                if (pile.canMoveFrom(cell)) {
                    return false;
                }
            }
        }
        // Can you not move to any home cell?
        for (Pile pile : foundations) {
            for (Pile tableau : tableaux) {
                if (pile.canMoveFrom(tableau)) {
                    return false;
                }
            }
            for (Pile cell : cells) {
                if (pile.canMoveFrom(cell)) {
                    return false;
                }
            }
        }
        return true;
    }

    public void newGame() {
        Deck deck = Deck.newDeck();
        deck.shuffle();
        moveTracker.clearMoves();
        for (Pile pile : tableaux) {
            pile.clear();
        }
        for (Pile pile : cells) {
            pile.clear();
        }
        for (Pile pile : foundations) {
            pile.clear();
        }
        // Deal 6 cards to each tableau.
        for (int i = 0; i < 6; i++) {
            for (int j = 0; j < 8; j++) {
                Card card = deck.deal();
                card.turn();
                tableaux.get(j).addCard(card);
            }
        }
        // Deal an additional card to first 4.
        for (int i = 0; i < 4; i++) {
            Card card = deck.deal();
            card.turn();
            tableaux.get(i).addCard(card);
        }
    }

    private static class MoveTracker {
        private final Deque<MoveAction> nextMoves = new LinkedList<>();
        private final Deque<MoveAction> previousMoves = new LinkedList<>();

        public void clearMoves() {
            nextMoves.clear();
            previousMoves.clear();
        }

        public boolean hasLastMove() {
            return !previousMoves.isEmpty();
        }

        public MoveAction getLastMove() {
            MoveAction lastMove = previousMoves.pop();
            nextMoves.push(lastMove);
            return lastMove;
        }

        public boolean hasNextMove() {
            return !nextMoves.isEmpty();
        }

        public MoveAction getNextMove() {
            MoveAction nextMove = nextMoves.pop();
            previousMoves.push(nextMove);
            return nextMove;
        }

        public void addMove(MoveAction move) {
            MoveAction nextMove = nextMoves.peek();
            /*
             * if new move differs from saved next move,
             * clear the remaining next moves
             */
            if (move.equals(nextMove)) {
                nextMoves.pop();
            } else {
                nextMoves.clear();
            }
            previousMoves.push(move);
        }
    }
}
TOP

Related Classes of freecell.model.Game$MoveTracker

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.