Skip to content

Instantly share code, notes, and snippets.

@Xion Xion/Cell.java
Created Dec 28, 2014

Embed
What would you like to do?
Cell enum from Taphoo
package pl.org.xion.taphoo.logic;
/**
* An utility class to hold ranges of cells' values.
* @author Xion
*/
final class CellRanges {
/**
* Private constructor to prevent instantiation.
*/
private CellRanges() {
}
// constants for value ranges
public static final int FIRST = 0;
public static final int NUMBER_FIRST = 1;
public static final int NUMBER_LAST = 31;
public static final int ARROW_CLASSIC_FIRST = 37;
public static final int ARROW_CLASSIC_LAST = 40;
public static final int ARROW_TURN_FIRST = 48;
public static final int ARROW_TURN_LAST = 59;
public static final int ARROW_DOUBLE1_FIRST = 64;
public static final int ARROW_DOUBLE1_LAST = 75;
public static final int ARROW_DOUBLE2_FIRST = 80;
public static final int ARROW_DOUBLE2_LAST = 87;
public static final int ARROW_DOUBLE3_FIRST = 92;
public static final int ARROW_DOUBLE3_LAST = 95;
public static final int TELEPORT_FIRST = 112;
public static final int TELEPORT_LAST = 127;
public static final int SWITCH_FIRST = 160;
public static final int SWITCH_OFF_FIRST = 160;
public static final int SWITCH_OFF_LAST = 175;
public static final int SWITCH_ON_FIRST = 176;
public static final int SWITCH_ON_LAST = 191;
public static final int SWITCH_LAST = 191;
public static final int DOOR_FIRST = 208;
public static final int DOOR_CLOSED_FIRST = 208;
public static final int DOOR_CLOSED_LAST = 223;
public static final int DOOR_OPEN_FIRST = 224;
public static final int DOOR_OPEN_LAST = 239;
public static final int DOOR_LAST = 239;
public static final int LAST = 255;
}
/**
* Enumeration with possible cells and various utility functions to operate on them.
* @author Xion
*/
public enum Cell {
// WARNING: Do *not* change the order of the constants!
Empty(0, new Direction[0]),
// numbers
One(1, Empty), Two(2, One), Three(3, Two), Four(4, Three), Five(5, Four), Six(6, Five), Seven(7, Six), Eight(8, Seven), Nine(9, Eight), Ten(
10, Nine), Eleven(11, Ten), Twelve(12, Eleven), Thirteen(13, Twelve), Fourteen(14, Thirteen), Fifteen(15, Fourteen), Sixteen(
16, Fifteen), Seventeen(17, Sixteen), Eighteen(18, Seventeen), Nineteen(19, Eighteen), Twenty(20, Nineteen), TwentyOne(21,
Twenty), TwentyTwo(22, TwentyOne), TwentyThree(23, TwentyTwo), TwentyFour(24, TwentyThree), TwentyFive(25, TwentyFour), TwentySix(
26, TwentyFive), TwentySeven(27, TwentySix), TwentyEight(28, TwentySeven), TwentyNine(29, TwentyEight), Thirty(30, TwentyNine), ThirtyOne(
31, Thirty),
// classic arrows
// TODO: consider whether exitDirs should not be Direction.values() as in Ultimate Stuntman puzzles
// (probably not)
ArrowLeft(37, Direction.LEFT, Empty), ArrowUp(38, Direction.UP, Empty), ArrowRight(39, Direction.RIGHT, Empty), ArrowDown(40,
Direction.DOWN, Empty),
// single arrows with turns
ArrowLeftToRight(48, Direction.LEFT, Direction.RIGHT, Empty), ArrowUpToDown(49, Direction.UP, Direction.DOWN, Empty), ArrowRightToLeft(
50, Direction.RIGHT, Direction.LEFT, Empty), ArrowDownToUp(51, Direction.DOWN, Direction.UP, Empty), ArrowUpToLeft(52,
Direction.UP, Direction.LEFT, Empty), ArrowDownToLeft(53, Direction.DOWN, Direction.LEFT, Empty), ArrowLeftToUp(54,
Direction.LEFT, Direction.UP, Empty), ArrowRightToUp(55, Direction.RIGHT, Direction.UP, Empty), ArrowUpToRight(56,
Direction.UP, Direction.RIGHT, Empty), ArrowDownToRight(57, Direction.DOWN, Direction.RIGHT, Empty), ArrowLeftToDown(58,
Direction.LEFT, Direction.DOWN, Empty), ArrowRightToDown(59, Direction.RIGHT, Direction.DOWN, Empty),
// double arrows
ArrowLeftToLeftUp(64, Direction.LEFT, Direction.LEFT_UP, Empty), ArrowUpToLeftUp(65, Direction.UP, Direction.LEFT_UP, Empty), ArrowRightToLeftUp(
66, Direction.RIGHT, Direction.LEFT_UP, Empty), ArrowDownToLeftUp(67, Direction.DOWN, Direction.LEFT_UP, Empty), ArrowLeftToLeftRight(
68, Direction.LEFT, Direction.LEFT_RIGHT, Empty), ArrowUpToLeftRight(69, Direction.UP, Direction.LEFT_RIGHT, Empty), ArrowRightToLeftRight(
70, Direction.RIGHT, Direction.LEFT_RIGHT, Empty), ArrowDownToLeftRight(71, Direction.DOWN, Direction.LEFT_RIGHT, Empty), ArrowLeftToLeftDown(
72, Direction.LEFT, Direction.LEFT_DOWN, Empty), ArrowUpToLeftDown(73, Direction.UP, Direction.LEFT_DOWN, Empty), ArrowRightToLeftDown(
74, Direction.RIGHT, Direction.LEFT_DOWN, Empty), ArrowDownToLeftDown(75, Direction.DOWN, Direction.LEFT_DOWN, Empty), ArrowLeftToUpRight(
80, Direction.LEFT, Direction.UP_RIGHT, Empty), ArrowUpToUpRight(81, Direction.UP, Direction.UP_RIGHT, Empty), ArrowRightToUpRight(
82, Direction.RIGHT, Direction.UP_RIGHT, Empty), ArrowDownToUpRight(83, Direction.DOWN, Direction.UP_RIGHT, Empty), ArrowLeftToUpDown(
84, Direction.LEFT, Direction.UP_DOWN, Empty), ArrowUpToUpDown(85, Direction.UP, Direction.UP_DOWN, Empty), ArrowRightToUpDown(
86, Direction.RIGHT, Direction.UP_DOWN, Empty), ArrowDownToUpDown(87, Direction.DOWN, Direction.UP_DOWN, Empty), ArrowLeftToRightDown(
92, Direction.LEFT, Direction.RIGHT_DOWN, Empty), ArrowUpToRightDown(93, Direction.UP, Direction.RIGHT_DOWN, Empty), ArrowRightToRightDown(
94, Direction.RIGHT, Direction.RIGHT_DOWN, Empty), ArrowDownToRightDown(95, Direction.DOWN, Direction.RIGHT_DOWN, Empty),
// teleports
TeleportAlpha(112), TeleportBeta(113), TeleportGamma(114), TeleportDelta(115), TeleportEpsilon(116), TeleportZeta(117), TeleportEta(118), TeleportTheta(
119), TeleportIota(120), TeleportKappa(121), TeleportLambda(122), TeleportMu(123), TeleportNu(124), TeleportXi(125), TeleportOmicron(
126), TeleportPi(127),
// switches (off)
// (their post-enter cells are defined strangely since there is a circular dependency
// in switches that has to be resolved somehow)
SwitchOffA(160, Direction.values(), CellRanges.SWITCH_ON_FIRST + 0, Direction.values()), SwitchOffB(161, Direction.values(),
CellRanges.SWITCH_ON_FIRST + 1, Direction.values()), SwitchOffC(162, Direction.values(), CellRanges.SWITCH_ON_FIRST + 2,
Direction.values()), SwitchOffD(163, Direction.values(), CellRanges.SWITCH_ON_FIRST + 3, Direction.values()), SwitchOffE(164,
Direction.values(), CellRanges.SWITCH_ON_FIRST + 4, Direction.values()), SwitchOffF(165, Direction.values(),
CellRanges.SWITCH_ON_FIRST + 5, Direction.values()), SwitchOffG(166, Direction.values(), CellRanges.SWITCH_ON_FIRST + 6,
Direction.values()), SwitchOffH(167, Direction.values(), CellRanges.SWITCH_ON_FIRST + 7, Direction.values()), SwitchOffI(168,
Direction.values(), CellRanges.SWITCH_ON_FIRST + 8, Direction.values()), SwitchOffJ(169, Direction.values(),
CellRanges.SWITCH_ON_FIRST + 9, Direction.values()), SwitchOffK(170, Direction.values(), CellRanges.SWITCH_ON_FIRST + 10,
Direction.values()), SwitchOffL(171, Direction.values(), CellRanges.SWITCH_ON_FIRST + 11, Direction.values()), SwitchOffM(172,
Direction.values(), CellRanges.SWITCH_ON_FIRST + 12, Direction.values()), SwitchOffN(173, Direction.values(),
CellRanges.SWITCH_ON_FIRST + 13, Direction.values()), SwitchOffO(174, Direction.values(), CellRanges.SWITCH_ON_FIRST + 14,
Direction.values()), SwitchOffP(175, Direction.values(), CellRanges.SWITCH_ON_FIRST + 15, Direction.values()),
// switches (on)
SwitchOnA(176, Direction.values(), SwitchOffA, Direction.values()), SwitchOnB(177, Direction.values(), SwitchOffB, Direction.values()), SwitchOnC(
178, Direction.values(), SwitchOffC, Direction.values()), SwitchOnD(179, Direction.values(), SwitchOffD, Direction.values()), SwitchOnE(
180, Direction.values(), SwitchOffE, Direction.values()), SwitchOnF(181, Direction.values(), SwitchOffF, Direction.values()), SwitchOnG(
182, Direction.values(), SwitchOffG, Direction.values()), SwitchOnH(183, Direction.values(), SwitchOffH, Direction.values()), SwitchOnI(
184, Direction.values(), SwitchOffI, Direction.values()), SwitchOnJ(185, Direction.values(), SwitchOffJ, Direction.values()), SwitchOnK(
186, Direction.values(), SwitchOffK, Direction.values()), SwitchOnL(187, Direction.values(), SwitchOffL, Direction.values()), SwitchOnM(
188, Direction.values(), SwitchOffM, Direction.values()), SwitchOnN(189, Direction.values(), SwitchOffN, Direction.values()), SwitchOnO(
190, Direction.values(), SwitchOffO, Direction.values()), SwitchOnP(191, Direction.values(), SwitchOffP, Direction.values()),
// door (closed)
DoorClosedA(208, new Direction[0]), DoorClosedB(209, new Direction[0]), DoorClosedC(210, new Direction[0]), DoorClosedD(211,
new Direction[0]), DoorClosedE(212, new Direction[0]), DoorClosedF(213, new Direction[0]), DoorClosedG(214, new Direction[0]), DoorClosedH(
215, new Direction[0]), DoorClosedI(216, new Direction[0]), DoorClosedJ(217, new Direction[0]), DoorClosedK(218,
new Direction[0]), DoorClosedL(219, new Direction[0]), DoorClosedM(220, new Direction[0]), DoorClosedN(221, new Direction[0]), DoorClosedO(
222, new Direction[0]), DoorClosedP(223, new Direction[0]),
// door (open)
DoorOpenA(224), DoorOpenB(225), DoorOpenC(226), DoorOpenD(227), DoorOpenE(228), DoorOpenF(229), DoorOpenG(230), DoorOpenH(231), DoorOpenI(
232), DoorOpenJ(233), DoorOpenK(234), DoorOpenL(235), DoorOpenM(236), DoorOpenN(237), DoorOpenO(238), DoorOpenP(239),
// general
Solid(248), Start(254, new Direction[0], Direction.values()), Goal(255, Direction.values(), new Direction[0])
;
// fields
private final int value;
private Direction[] enterDirs, exitDirs;
private Object postEnter, postExit; // either Cell or Integer
// Constructors
/**
* Constructor. Simplest variant which allows passing via either direction and does not change the cell when doing
* so.
* @param value Numerical value of the cell
*/
Cell(int value) {
this(value, (Cell) null);
}
/**
* Constructor. A variant which allows passing via either direction and changes the cell after doing so.
* @param value Numerical value of the cell
* @param postExit Cell which this one transforms to after player leaves it
*/
Cell(int value, Cell postExit) {
this(value, Direction.values(), postExit);
}
/**
* Constructor. A variant which allows passing via specified direction and does not change the cell after doing so.
* @param value Numerical value of the cell
* @param transitDirs Directions the player can transit this cell via
*/
Cell(int value, Direction[] transitDirs) {
this(value, transitDirs, transitDirs);
}
/**
* Constructor. A variant which allows passing via specified direction and changes the cell after doing so.
* @param value Numerical value of the cell
* @param transitDirs Directions the player can transit this cell via
* @param postExit Cell which this one transfroms to after player leaves it
*/
Cell(int value, Direction[] transitDirs, Cell postExit) {
this(value, transitDirs, transitDirs, postExit);
}
/**
* Constructor. A variant which allows entering from specified directions, exiting to specified directions but does
* not change the cell after doing so.
* @param value Numerical value of the cell
* @param enterDirs Directions the player can enter this cell from
* @param exitDirs Directions the player can exit this cell to
*/
Cell(int value, Direction[] enterDirs, Direction[] exitDirs) {
this(value, enterDirs, exitDirs, null);
}
/**
* Constructor. A variant which allows entering from specified directions, exiting to specified directions and
* changes the cell after doing so.
* @param value Numerical value of the cell
* @param enterDirs Directions the player can enter this cell from
* @param exitDirs Directions the player can exit this cell to
* @param postExit Cell which this one transforms to after player leaves it
*/
Cell(int value, Direction[] enterDirs, Direction[] exitDirs, Cell postExit) {
this(value, enterDirs, null, exitDirs, postExit);
}
/**
* Constructor. A variant which allows entering from specified directions, exiting to specified directions and
* changes the cell when player enters it.
* @param value Numerical value of the cell
* @param enterDirs Directions the player can enter this cell from
* @param postEnter Cell which this one transforms to when player enters it
* @param exitDirs Directions the player can exit this cell to
*/
Cell(int value, Direction[] enterDirs, Cell postEnter, Direction[] exitDirs) {
this(value, enterDirs, postEnter, exitDirs, null);
}
/**
* Constructor. A variant which allows entering from specified directions, exiting to specified directions and
* changes the cell when player enters it. The post-enter cell is specified as numerical value; this is a special
* case, required to resolve circular dependency in definition of switches.
* @param value Numerical value of the cell
* @param enterDirs Directions the player can enter this cell from
* @param postEnter Value of cell which this one transforms to when player enters it
* @param exitDirs Directions the player can exit this cell to
*/
Cell(int value, Direction[] enterDirs, int postEnter, Direction[] exitDirs) {
this(value, enterDirs, postEnter, exitDirs, value);
}
/**
* Constructor. Most complicated and powerful variant. Allows specifying directions of entering, exiting and cell
* transformation on both events.
* @param value Numerical value of the cell
* @param enterDirs Directions the player can enter this cell from
* @param postEnter Cell which this one transforms to when player enters it
* @param exitDirs Directions the player can exit this cell to
* @param postExit Cell which this one transforms to after player leaves it
*/
Cell(int value, Direction[] enterDirs, Cell postEnter, Direction[] exitDirs, Cell postExit) {
this.value = value;
this.enterDirs = enterDirs != null ? enterDirs : new Direction[0];
this.postEnter = postEnter != null ? postEnter : this;
this.exitDirs = exitDirs != null ? exitDirs : new Direction[0];
this.postExit = postExit != null ? postExit : this;
}
/**
* Constructor. Most complicated and powerful variant. Allows specifying directions of entering, exiting and cell
* transformation on both events.
* @param value Numerical value of the cell
* @param enterDirs Directions the player can enter this cell from
* @param postEnter Value of cell which this one transforms to when player enters it
* @param exitDirs Directions the player can exit this cell to
* @param postExit Value of cell which this one transforms to after player leaves it
*/
Cell(int value, Direction[] enterDirs, int postEnter, Direction[] exitDirs, int postExit) {
this.value = value;
this.enterDirs = enterDirs != null ? enterDirs : new Direction[0];
this.postEnter = Integer.valueOf(postEnter);
this.exitDirs = exitDirs != null ? exitDirs : new Direction[0];
this.postExit = Integer.valueOf(postExit);
}
// Other creation methods
/**
* Retrieves the cell corresponding to given value.
* @param value Value of cell
* @return Cell corresponding to this value
* @throws IllegalArgumentException If value is outside of allowed range
*/
public static Cell fromValue(int value) {
if (!(value >= CellRanges.FIRST && value <= CellRanges.LAST))
throw new IllegalArgumentException("Cell value outside of allowed range");
// find the cell corresponding to given value
// (using bisection!!one!!eleven)
Cell[] vals = values();
int left = 0, right = vals.length - 1, mid, midVal;
// special case for ends of search interval
if (vals[left].getValue() == value)
return vals[left];
if (vals[right].getValue() == value)
return vals[right];
while (left < right) {
mid = left + (right - left) / 2;
midVal = vals[mid].getValue();
if (value < midVal) {
right = mid; // choose left interval
continue;
}
if (value > midVal) {
left = mid; // choose right interval
continue;
}
return vals[mid];
}
return null;
}
/**
* Retrieves number cell.
* @param i Cell's number, starting from one
* @return Cell of given number
* @throws IndexOutOfBoundsException If number is outside of given range
*/
public static Cell number(int i) {
if (!(i >= CellRanges.NUMBER_FIRST && i <= CellRanges.NUMBER_LAST))
throw new IndexOutOfBoundsException("Number outside of vaild range.");
return fromValue(CellRanges.NUMBER_FIRST - 1 + i);
}
/**
* Retrieves teleport cell.
* @param i Teleport's index, starting from zero
* @return Teleport cell of given index
* @throws IndexOutOfBoundsException If index is outside of valid range
*/
public static Cell teleport(int i) {
i += CellRanges.TELEPORT_FIRST;
if (!(i >= CellRanges.TELEPORT_FIRST && i <= CellRanges.TELEPORT_LAST))
throw new IndexOutOfBoundsException("Teleport index outside of valid range");
return fromValue(i);
}
/**
* Retrieves turned off switch cell.
* @param i Switch's index, starting from zero
* @return Switch-off cell of given index
* @throws IndexOutOfBoundsException If index is outside of valid range
*/
public static Cell switchOff(int i) {
i += CellRanges.SWITCH_OFF_FIRST;
if (!(i >= CellRanges.SWITCH_OFF_FIRST && i <= CellRanges.SWITCH_OFF_LAST))
throw new IndexOutOfBoundsException("Switch index outside of valid range");
return fromValue(i);
}
/**
* Retrieves turned on switch cell.
* @param i Switch's index, starting from zero
* @return Switch-on cell of given index
* @throws IndexOutOfBoundsException If index is outside of valid ranges
*/
public static Cell switchOn(int i) {
i += CellRanges.SWITCH_ON_FIRST;
if (!(i >= CellRanges.SWITCH_ON_FIRST && i <= CellRanges.SWITCH_ON_LAST))
throw new IndexOutOfBoundsException("Switch index outside of valid range");
return fromValue(i);
}
/**
* Retrieves closed door cell.
* @param i Door's index, starting from zero
* @return Closed door cell of given index
* @throws IndexOutOfBoundsException If index is outside of valid range
*/
public static Cell doorClosed(int i) {
i += CellRanges.DOOR_CLOSED_FIRST;
if (!(i >= CellRanges.DOOR_CLOSED_FIRST && i <= CellRanges.DOOR_CLOSED_LAST))
throw new IndexOutOfBoundsException("Door index outside of valid range");
return fromValue(i);
}
/**
* Retrieves open door cell.
* @param i Door's index, starting from zero
* @return Open door cell of given index
* @throws IndexOutOfBoundsException If index is outside of valid range
*/
public static Cell doorOpen(int i) {
i += CellRanges.DOOR_OPEN_FIRST;
if (!(i >= CellRanges.DOOR_OPEN_FIRST && i <= CellRanges.DOOR_OPEN_LAST))
throw new IndexOutOfBoundsException("Door index outside of valid range");
return fromValue(i);
}
// Access methods
/**
* Retrieves the numerical value associated with this cell.
* @return Numerical value of the cell
*/
public int getValue() {
return value;
}
/**
* Retrieves the directions which player can enter this cell from.
* @return Cell's enter directions
*/
public Direction[] getEnterDirections() {
return enterDirs;
}
/**
* Retrieves the cell this one transforms to upon player entering it
* @return Post-enter cell
*/
public Cell getPostEnterCell() {
if (postEnter instanceof Integer)
postEnter = Cell.fromValue(((Integer) postEnter).intValue());
return (Cell) postEnter;
}
/**
* Retrieves the directions which player can exit this cell to
* @return Cell's exit directions
*/
public Direction[] getExitDirections() {
return exitDirs;
}
/**
* Retrieves the cell this one transforms to upon player exiting it
* @return Post-exit cell
*/
public Cell getPostExitCell() {
if (postExit instanceof Integer)
postExit = Cell.fromValue(((Integer) postExit).intValue());
return (Cell) postExit;
}
// Methods for checking cell type
/**
* Checks whether this cell is a number value.
* @return Whether this is a number value
*/
public boolean isNumber() {
return value >= CellRanges.NUMBER_FIRST && value <= CellRanges.NUMBER_LAST;
}
/**
* Checks whether this cell is a classic arrow (up, down, left or right).
* @return Whether this is a classic arrow
*/
public boolean isClassicArrow() {
return value >= CellRanges.ARROW_CLASSIC_FIRST && value <= CellRanges.ARROW_CLASSIC_LAST;
}
/**
* Checks whether this cell is a turn arrow (single arrow that forces direction change).
* @return Whether this is a turn arrow
*/
public boolean isTurnArrow() {
return value >= CellRanges.ARROW_TURN_FIRST && value <= CellRanges.ARROW_TURN_LAST;
}
/**
* Check whether this cell is a single arrow, i.e. with one possible direction of entering and one possible
* direction for leaving (but not necessarily the same one).
* @return Whether this is a single arrow
*/
public boolean isSingleArrow() {
return isClassicArrow() || isTurnArrow();
}
/**
* Checks whether this cell is a double (fork) arrow.
* @return Whether this is a double arrow
*/
public boolean isDoubleArrow() {
return (value >= CellRanges.ARROW_DOUBLE1_FIRST && value <= CellRanges.ARROW_DOUBLE1_LAST)
|| (value >= CellRanges.ARROW_DOUBLE2_FIRST && value <= CellRanges.ARROW_DOUBLE2_LAST)
|| (value >= CellRanges.ARROW_DOUBLE3_FIRST && value <= CellRanges.ARROW_DOUBLE3_LAST);
}
/**
* Checks whether this cell is an arrow.
* @return Whether this is an arrow
*/
public boolean isArrow() {
return isSingleArrow() || isDoubleArrow();
}
/**
* Checks whether this cell is a teleport.
* @return Whether this is a teleport
*/
public boolean isTeleport() {
return value >= CellRanges.TELEPORT_FIRST && value <= CellRanges.TELEPORT_LAST;
}
/**
* Checks whether this cell is a switch turned off.
* @return Whether this is a switch turned off
*/
public boolean isSwitchOff() {
return value >= CellRanges.SWITCH_OFF_FIRST && value <= CellRanges.SWITCH_OFF_LAST;
}
/**
* Checks whether this cell is a switch turned on.
* @return Whether this is a switch turned on
*/
public boolean isSwitchOn() {
return value >= CellRanges.SWITCH_ON_FIRST && value <= CellRanges.SWITCH_ON_LAST;
}
/**
* Checks whether this cell is a switch (regardless of its state).
* @return Whether this is a switch
*/
public boolean isSwitch() {
return value >= CellRanges.SWITCH_FIRST && value <= CellRanges.SWITCH_LAST;
}
/**
* Checks whether this cell is a closed door.
* @return Whether this is a closed door
*/
public boolean isDoorClosed() {
return value >= CellRanges.DOOR_CLOSED_FIRST && value <= CellRanges.DOOR_CLOSED_LAST;
}
/**
* Checks whether this cell is an open door.
* @return Whether this is is an open door
*/
public boolean isDoorOpen() {
return value >= CellRanges.DOOR_OPEN_FIRST && value <= CellRanges.DOOR_OPEN_LAST;
}
/**
* Checks whether this cell is a door (open or closed).
* @return Whether this is a door
*/
public boolean isDoor() {
return value >= CellRanges.DOOR_FIRST && value <= CellRanges.DOOR_LAST;
}
/**
* Checks whether this cell is a destroyable one and must be got rid of in order for player to beat the level.
* @return Whether this cell is destroyable
*/
public boolean isDestroyable() {
return isNumber() || isArrow();
}
// Extracting indices
/**
* Extracts index of teleport from the cell.
* @return Teleport index, zero-based
* @throws IllegalStateException If the cell is not a teleport
*/
public int getTeleportIndex() {
if (!isTeleport())
throw new IllegalStateException("Cell is not a teleport");
return value - CellRanges.TELEPORT_FIRST;
}
/**
* Extracts index of switch from the cell.
* @return Switch index, zero-based
* @throws IllegalStateException If the cell is not a switch
*/
public int getSwitchIndex() {
if (isSwitchOn())
return value - CellRanges.SWITCH_ON_FIRST;
if (isSwitchOff())
return value - CellRanges.SWITCH_OFF_FIRST;
throw new IllegalArgumentException("Cell is not a switch");
}
/**
* Extracts index of door from the cell.
* @return Door index, zero-based
* @throws IllegalStateException If the cell is not a door
*/
public int getDoorIndex() {
if (isDoorOpen())
return value - CellRanges.DOOR_OPEN_FIRST;
if (isDoorClosed())
return value - CellRanges.DOOR_CLOSED_FIRST;
throw new IllegalStateException("Cell is not a door");
}
// Checking accessibility
/**
* Checks whether player is allowed to enter the cell when coming from given direction.
* @param dir Direction where the player is coming from
* @return Whether player can enter the cell
*/
public boolean canEnter(Direction dir) {
Direction[] dirs = getEnterDirections();
if (dirs == null)
return false;
for (Direction d : dirs)
if (d.equals(dir))
return true;
return false;
}
/**
* Checks whether player is allowed to exit the cell when going to given direction.
* @param dir Direction where the player is going to
* @return Whether player can exit the cell
*/
public boolean canExit(Direction dir) {
Direction[] dirs = getExitDirections();
if (dirs == null)
return false;
for (Direction d : dirs)
if (d.equals(dir))
return true;
return false;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.