Refactor expandBoard() method
This commit is contained in:
@@ -1,12 +1,86 @@
|
||||
|
||||
|
||||
/**
|
||||
* Represents a cardinal direction.
|
||||
*
|
||||
* This enumeration represents a cardinal direction (N, S, E, W, ...) as well as
|
||||
* operations on cardinals, such as rotation and inverse cardinals.
|
||||
*/
|
||||
public enum Cardinal {
|
||||
N,
|
||||
NE,
|
||||
E,
|
||||
SE,
|
||||
S,
|
||||
SW,
|
||||
W,
|
||||
NW;
|
||||
N (0),
|
||||
NE (1),
|
||||
E (2),
|
||||
SE (3),
|
||||
S (4),
|
||||
SW (5),
|
||||
W (6),
|
||||
NW (7);
|
||||
|
||||
/** Integer representation of the cardinal (starting at 0 for North) */
|
||||
private final int value;
|
||||
|
||||
/** Private constructor for the enumeration */
|
||||
private Cardinal(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the integer representation of the cardinal direction.
|
||||
* @return the integer representing the cardinal direction
|
||||
* (starting at 0 for North)
|
||||
*/
|
||||
public int asInt() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the cardinal direction corresponding to the given integer.
|
||||
* @param value integer representing a cardinal direction
|
||||
* @return a cardinal corresponding to the integer parameter
|
||||
* @throws IllegalArgumentException when the integer value is not valid
|
||||
* (not in the range 0-7)
|
||||
*/
|
||||
public static Cardinal fromInt(int value) {
|
||||
for (Cardinal cardinal : Cardinal.values()) {
|
||||
if (cardinal.value == value) {
|
||||
return cardinal;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("Invalid value: " + value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the opposite cardinal direction.
|
||||
* @return the opposite cardinal direction of this cardinal
|
||||
*/
|
||||
public Cardinal inverse() {
|
||||
return fromInt((this.value + 4) % 8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Rotates the cardinal direction by a given number of steps.
|
||||
* @param steps the number of steps to rotate (positive for clockwise,
|
||||
* negative for counterclockwise)
|
||||
* @return the new cardinal direction after rotation
|
||||
* @throws IllegalArgumentException when the number of steps is not valid
|
||||
* (not in the range -7 to 7)
|
||||
*/
|
||||
public Cardinal rotate(int steps) {
|
||||
return fromInt((this.value + steps + 8) % 8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Rotates the cardinal direction 90 degrees clockwise.
|
||||
* @return the new cardinal direction after a 90-degree clockwise rotation
|
||||
*/
|
||||
public Cardinal rotate90CW() {
|
||||
return rotate(2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Rotates the cardinal direction 90 degrees counterclockwise.
|
||||
* @return the new cardinal direction after a 90-degree counterclockwise rotation
|
||||
*/
|
||||
public Cardinal rotate90CCW() {
|
||||
return rotate(-2);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,15 +24,22 @@ public class GomokuBoard{
|
||||
test.get(1,1).setState(Color.BLACK);
|
||||
System.out.println(test);
|
||||
System.out.println(test.getPlayableCells());
|
||||
test.expandBoard(Cardinal.SW);
|
||||
test.expandBoard(Cardinal.SW);
|
||||
test.expandBoard(Cardinal.SW);
|
||||
test.expandBoard(Cardinal.SW);
|
||||
test.expandBoard(Cardinal.SW);
|
||||
test.expandBoard(Cardinal.SW);
|
||||
test.expandBoard(Cardinal.SW);
|
||||
|
||||
System.out.println(Cardinal.NE.rotate90CW());
|
||||
System.out.println(Cardinal.NE.rotate90CCW());
|
||||
System.out.println(Cardinal.NE.rotate(1));
|
||||
System.out.println(Cardinal.NE.rotate(-1));
|
||||
System.out.println(Cardinal.NE.inverse());
|
||||
|
||||
System.out.println(test);
|
||||
test.expandBoardv2(Cardinal.N);
|
||||
System.out.println(test);
|
||||
test.expandBoardv2(Cardinal.S);
|
||||
System.out.println(test);
|
||||
test.expandBoardv2(Cardinal.W);
|
||||
System.out.println(test);
|
||||
test.expandBoardv2(Cardinal.SE);
|
||||
System.out.println(test);
|
||||
System.out.println(test.getPlayableCells());
|
||||
}
|
||||
|
||||
//------------------Constructors--------------------------
|
||||
@@ -56,17 +63,17 @@ public class GomokuBoard{
|
||||
this.firstCell = new GomokuCell(Color.NIL);
|
||||
this.boardWidth = width;
|
||||
this.boardHeight = height;
|
||||
this.genCells(width, height, colors);
|
||||
this.generateCells(width, height, colors);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method gen all cells in the board and link each other.
|
||||
* This method generate all cells in the board and link each other.
|
||||
* @param width Size of width.
|
||||
* @param height Size of height.
|
||||
* @param colors Array of Color.
|
||||
*/
|
||||
private void genCells(int width, int height, Color[][] colors){
|
||||
private void generateCells(int width, int height, Color[][] colors){
|
||||
this.firstCell = new GomokuCell(colors == null ? Color.NIL : colors[0][0]);
|
||||
GomokuCell act = this.firstCell;
|
||||
GomokuCell top = null;
|
||||
@@ -111,9 +118,9 @@ public class GomokuBoard{
|
||||
while (i != x || j != y){
|
||||
Cardinal c = Cardinal.SE;
|
||||
if (i < x) i++;
|
||||
else c = Cardinal.E;
|
||||
if (j < y) j++;
|
||||
else c = Cardinal.S;
|
||||
if (j < y) j++;
|
||||
else c = Cardinal.E;
|
||||
act = act.getNeighbour(c);
|
||||
}
|
||||
return act;
|
||||
@@ -124,7 +131,7 @@ public class GomokuBoard{
|
||||
* This method return all cells in the board in the order.
|
||||
* @return All cells with a array 2D.
|
||||
*/
|
||||
private GomokuCell[][] getAllsCells(){
|
||||
private GomokuCell[][] getAllCells(){
|
||||
GomokuCell[][] cells = new GomokuCell[this.boardHeight][this.boardWidth];
|
||||
GomokuCell act = this.firstCell;
|
||||
GomokuCell nextLine = this.firstCell.getNeighbour(Cardinal.S);
|
||||
@@ -148,7 +155,7 @@ public class GomokuBoard{
|
||||
|
||||
public List<GomokuCell> getPlayableCells(){
|
||||
List<GomokuCell> output = new ArrayList<>();
|
||||
for (GomokuCell[] line : this.getAllsCells()) {
|
||||
for (GomokuCell[] line : this.getAllCells()) {
|
||||
for (GomokuCell c : line) {
|
||||
if (c.isPlayable() && c.getState() == Color.NIL)
|
||||
output.add(c);
|
||||
@@ -300,6 +307,95 @@ public class GomokuBoard{
|
||||
this.firstCell = newOrigin;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Expands the board in the specified direction.
|
||||
* This method is used to add a new row, column, or both to the board.
|
||||
* It creates new cells in the specified direction and links them to the existing cells.
|
||||
* It also updates the board dimensions accordingly.
|
||||
* @param direction The cardinal direction in which to expand the board.
|
||||
* @see Cardinal
|
||||
* @version 2.0
|
||||
*/
|
||||
public void expandBoardv2(Cardinal direction) {
|
||||
// for composed directions, expand in both components
|
||||
// e.g. SE -> expand in S and E
|
||||
if ((direction.asInt() % 2) != 0) {
|
||||
// if the direction is not even, it is a composed direction
|
||||
// call the same function in both components
|
||||
this.expandBoardv2(direction.rotate(-1));
|
||||
this.expandBoardv2(direction.rotate(1));
|
||||
return;
|
||||
}
|
||||
|
||||
// find the suitable corner cell to expand from
|
||||
Cardinal cornerCellDirection = direction.rotate(-1);
|
||||
|
||||
// move to the corner cell
|
||||
// go to the center of the board
|
||||
GomokuCell cornerCell = this.get(this.boardWidth / 2, this.boardHeight / 2);
|
||||
GomokuCell nextCell;
|
||||
// move while possible to the desired corner of the board
|
||||
do {
|
||||
nextCell = cornerCell.getNeighbour(cornerCellDirection);
|
||||
// if the next cell is null, then attempt to move
|
||||
// in the original direction
|
||||
if (nextCell == null) {
|
||||
cornerCellDirection = direction;
|
||||
nextCell = cornerCell.getNeighbour(cornerCellDirection);
|
||||
// if we already reached the end of the board, try the
|
||||
// direction perpendicular to the original direction
|
||||
if (nextCell == null) {
|
||||
cornerCellDirection = direction.rotate90CCW();
|
||||
nextCell = cornerCell.getNeighbour(cornerCellDirection);
|
||||
}
|
||||
} else {
|
||||
cornerCell = nextCell;
|
||||
}
|
||||
} while (nextCell != null);
|
||||
|
||||
// then, add (n - 1) cells in the direction rotated by 90 degrees CW,
|
||||
// where n is either the board width or board height.
|
||||
// e.g. for an expansion to the North, add (n - 1) cells to the EAST
|
||||
// of the anchor cell
|
||||
GomokuCell anchor = new GomokuCell(Color.NIL);
|
||||
GomokuCell nextTo = cornerCell;
|
||||
GomokuCell before = cornerCell.getNeighbour(direction.rotate90CCW());
|
||||
GomokuCell after = cornerCell.getNeighbour(direction.rotate90CW());
|
||||
Cardinal forwardDirection = direction.rotate90CW();
|
||||
|
||||
while (nextTo != null) {
|
||||
// link the anchor cell with its neighbours
|
||||
GomokuCell.link(before, anchor, direction.rotate(1));
|
||||
GomokuCell.link(nextTo, anchor, direction);
|
||||
GomokuCell.link(after, anchor, direction.rotate(-1));
|
||||
// add a new cell next to the anchor and link it to the anchor,
|
||||
// if the end of the board is not reached (to avoid creating an
|
||||
// additional cell)
|
||||
nextCell = null;
|
||||
if (after != null) nextCell = new GomokuCell(Color.NIL);
|
||||
GomokuCell.link(anchor, nextCell, forwardDirection);
|
||||
// set the anchor to the next cell and update the neighbours
|
||||
anchor = nextCell;
|
||||
before = nextTo;
|
||||
nextTo = after;
|
||||
if (after != null) after = after.getNeighbour(forwardDirection);
|
||||
}
|
||||
|
||||
// update the board dimensions;
|
||||
if (direction == Cardinal.N || direction == Cardinal.S) {
|
||||
this.boardHeight++;
|
||||
} else {
|
||||
this.boardWidth++;
|
||||
}
|
||||
|
||||
// for the North and West expansions, update the first cell
|
||||
// (top-left cell reference) of the entire board
|
||||
if (direction == Cardinal.N || direction == Cardinal.W) {
|
||||
this.firstCell = this.firstCell.getNeighbour(direction);
|
||||
}
|
||||
}
|
||||
|
||||
//------------------Overides--------------------------
|
||||
|
||||
/**
|
||||
@@ -309,7 +405,7 @@ public class GomokuBoard{
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder out = new StringBuilder();
|
||||
GomokuCell[][] cells = this.getAllsCells();
|
||||
GomokuCell[][] cells = this.getAllCells();
|
||||
for (GomokuCell[] line : cells) {
|
||||
for (GomokuCell c : line) {
|
||||
out.append(c.toString());
|
||||
|
||||
Reference in New Issue
Block a user