Untitled
unknown
java
3 years ago
5.1 kB
10
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...