Untitled

 avatar
unknown
java
2 years ago
5.1 kB
5
Indexable
import java.util.Arrays;

/**
 * The state and logic for the Pyramid Puzzle game.
 */
public class PyramidPuzzle {

    private final int [][] state;
    private final int numOfDisks;
    private int numOfMoves;

    /**
     * Create a new PyramidPuzzle object with the indicated number of disks.
     *
     * @param numDisks the number of disks
     */

    public PyramidPuzzle(int numDisks) {
        this.state = new int[Peg.values().length][numDisks]; // zeroes
        this.numOfDisks = numDisks;
        initNewRound();
    }

    /**
     * Create a new PyramidPuzzle object with four disks.
     */

    public PyramidPuzzle() {
        this(4);
    }

    /**
     * Initialize a new round, i.e. reset numMoves and the values in the state matrix.
     */

    public void initNewRound() {
        // set zeroes for all positions in state
        for( int peg = Peg.LEFT.getIndex(); peg < Peg.RIGHT.getIndex(); peg++) {
            for( int pos = 0; pos < numOfDisks; pos++){
            state[peg][pos] = 0;
            }
        }
        for(int pos = 0; pos < numOfDisks; pos++){
            state[Peg.LEFT.getIndex()][pos] = numOfDisks - pos;
        }
        this.numOfMoves = 0;
    }

        /**
         * @return the number of disks
         */

    public int getNumDisks() {
        return numOfDisks;
    }

    /**
     * @return the current number of moves
     */

    public int getNumMoves() {
        return numOfMoves;
    }

    /**
     * Return whether the suggested move is allowed or not.
     * NB! This method does not move the disk.
     *
     * @param src  the peg to move a disk from
     * @param dest the disc to move the disk to
     * @return true if the move is allowed, false otherwise
     */

    public boolean isAllowedMove(Peg src, Peg dest) {
        if(getTopSize(src) == 0){
            System.out.println("\nThis peg is empty!");
            return false;
        } else if((getTopSize(src) < getTopSize(dest)) || (getTopSize(dest) == 0 && getTopSize(src) > 0)){
            return true;
        } else
            System.out.println("\nThis move is not allowed!");
        return false;
    }

    /**
     * Move a disk and update the number of moves.
     *
     * @param src  the peg to move a disk from
     * @param dest the disc to move the disk to
     * @return true if the move is alloed and performed
     */

    public boolean makeMove(Peg src, Peg dest) {
        //checks if move is allowed
        if(isAllowedMove(src, dest) == false){
            return false;
        }
        //if allowed
        int srcTopPos = getTopIndex(src);
        int destTopPos = getTopIndex(dest);
        int discSize = getTopSize(src);

        //move
        state[dest.getIndex()][destTopPos + 1] = discSize;
        state[src.getIndex()][srcTopPos] = 0;
        numOfMoves++;
        return true;
    }

    /**
     * Return true if all disks are at the right peg in ascending order, i.e. the puzzle
     * is solved, otherwise return false.
     *
     * @return true if the puzzle is solved
     */

    public boolean isSolved() {
        if(state[Peg.values().length - 1][numOfDisks - 1] == 1) {
            return true;
        }
        else {
            return false;
        }
    }

    /**
     * Return a <em>copy</em> of the internal state, a two-dimensional int
     * array, dimensions [num of pegs][num of disks]. The value of a single
     * field represents the size of the disk; zero represents an empty position.
     *
     * @return a copy of the internal state
     */

    public int[][] getCopyOfState() {
        int[][] copy = new int[Peg.values().length][];
        for(int i = 0; i < Peg.values().length; i++)
        {
            copy[i] = new int[state[i].length];
            for (int j = 0; j < state[i].length; j++)
            {
                copy[i][j] = state[i][j];
            }
        }
        return copy;
    }

    /**
     * Return a string with format [values at left peg], [values at middle peg], [values at right peg].
     * Example: [4,3,2,0], [0,0,0,0], [1,0,0,0], 1
     *
     * @return a string representation of the object
     */

    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        for (Peg peg : Peg.values()) {
            builder.append(Arrays.toString(state[peg.getIndex()]));
            builder.append(", ");
        }
        builder.append(numOfMoves);
        return builder.toString();
    }

    // private helper methods
    // 0 represents empty pin
    private int getTopSize(Peg peg) {
        int pegInd = peg.getIndex();
        //from top
        for(int i = numOfDisks-1; i >= 0; i--){
            if(state[pegInd][i] != 0){
                return state[pegInd][i];
            }
        }
        return 0;
    }

    // -1 represents empty rod
    private int getTopIndex(Peg peg) {
        int pegInd = peg.getIndex();
        //from top
        for(int i = numOfDisks-1; i >= 0; i--){
            if(state[pegInd][i] != 0){
                return i;
            }
        }
        return -1;
    }
}
Editor is loading...