Document GomokuBoard class file
This commit is contained in:
@@ -71,6 +71,8 @@ public class GomokuBoard {
|
|||||||
this(width, height, null);
|
this(width, height, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// - Private methods ----------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate the cells of the board.
|
* Generate the cells of the board.
|
||||||
*
|
*
|
||||||
@@ -83,41 +85,52 @@ public class GomokuBoard {
|
|||||||
* @param colors Array of Color to fill the board.
|
* @param colors Array of Color to fill the board.
|
||||||
*/
|
*/
|
||||||
private void generateCells(int width, int height, Color[][] colors) {
|
private void generateCells(int width, int height, Color[][] colors) {
|
||||||
|
// Initialize the top-left cell of the board
|
||||||
|
// If colors is null, set the cell to empty (NIL)
|
||||||
this.topLeftCell = new GomokuCell(colors == null ? Color.NIL : colors[0][0]);
|
this.topLeftCell = new GomokuCell(colors == null ? Color.NIL : colors[0][0]);
|
||||||
GomokuCell act = this.topLeftCell;
|
GomokuCell currentCell = this.topLeftCell;
|
||||||
GomokuCell top = null;
|
GomokuCell previousLineCell = null;
|
||||||
|
|
||||||
|
// Run through the height of the board
|
||||||
for (int i = 0; i < height; i++) {
|
for (int i = 0; i < height; i++) {
|
||||||
GomokuCell nextLine = null;
|
GomokuCell nextLineCell = null;
|
||||||
if (i != height - 1) {
|
|
||||||
nextLine = new GomokuCell(colors == null ? Color.NIL : colors[i + 1][0]);
|
|
||||||
GomokuCell.link(act, nextLine, Cardinal.S);
|
|
||||||
}
|
|
||||||
for (int j = 0; j < width; j++) {
|
|
||||||
if (top != null) {
|
|
||||||
GomokuCell.link(act, top.getNeighbour(Cardinal.W), Cardinal.NW);
|
|
||||||
GomokuCell.link(act, top, Cardinal.N);
|
|
||||||
top = top.getNeighbour(Cardinal.E);
|
|
||||||
GomokuCell.link(act, top, Cardinal.NE);
|
|
||||||
|
|
||||||
|
// Create the first cell of the next line, except for the last line
|
||||||
|
if (i != height - 1) {
|
||||||
|
nextLineCell = new GomokuCell(colors == null ? Color.NIL : colors[i + 1][0]);
|
||||||
|
GomokuCell.link(currentCell, nextLineCell, Cardinal.S);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run through the width of the board
|
||||||
|
for (int j = 0; j < width; j++) {
|
||||||
|
// Link the current cell with the 3 cells above it
|
||||||
|
// (if they exist) to create the diagonal and up links
|
||||||
|
if (previousLineCell != null) {
|
||||||
|
GomokuCell.link(currentCell, previousLineCell.getNeighbour(Cardinal.W), Cardinal.NW);
|
||||||
|
GomokuCell.link(currentCell, previousLineCell, Cardinal.N);
|
||||||
|
previousLineCell = previousLineCell.getNeighbour(Cardinal.E);
|
||||||
|
GomokuCell.link(currentCell, previousLineCell, Cardinal.NE);
|
||||||
}
|
}
|
||||||
|
// Create the cell to the right of the current cell
|
||||||
|
// and link it to the current cell, then set it as the current cell
|
||||||
if (j != width - 1) {
|
if (j != width - 1) {
|
||||||
GomokuCell right = new GomokuCell(colors == null ? Color.NIL : colors[i][j + 1]);
|
GomokuCell right = new GomokuCell(colors == null ? Color.NIL : colors[i][j + 1]);
|
||||||
GomokuCell.link(act, right, Cardinal.E);
|
GomokuCell.link(currentCell, right, Cardinal.E);
|
||||||
act = right;
|
currentCell = right;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
act = nextLine;
|
// Move to the next line, and update the previous line cell
|
||||||
if (act == null)
|
currentCell = nextLineCell;
|
||||||
break;
|
if (currentCell != null) {
|
||||||
top = act.getNeighbour(Cardinal.N);
|
previousLineCell = currentCell.getNeighbour(Cardinal.N);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------Gets--------------------------
|
// - Getters ------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the width of the board.
|
* Return the width of the board.
|
||||||
*
|
*
|
||||||
* @return The width of the board.
|
* @return The width of the board.
|
||||||
*/
|
*/
|
||||||
@@ -126,7 +139,7 @@ public class GomokuBoard {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the height of the board.
|
* Return the height of the board.
|
||||||
*
|
*
|
||||||
* @return The height of the board.
|
* @return The height of the board.
|
||||||
*/
|
*/
|
||||||
@@ -135,61 +148,78 @@ public class GomokuBoard {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method get a cell in specific position in the board.
|
* Return the cell at the specified coordinates.
|
||||||
|
*
|
||||||
|
* This method returns the cell at the specified coordinates (x, y) on the
|
||||||
|
* board. If the coordinates are out of bounds of the board size,
|
||||||
|
* it returns null.
|
||||||
*
|
*
|
||||||
* @param x The position x on the board.
|
* @param x The position x on the board.
|
||||||
* @param y The position y on the board.
|
* @param y The position y on the board.
|
||||||
* @return GomokuCell in the position.
|
* @return The cell at the specified coordinates, or null if out of bounds.
|
||||||
*/
|
*/
|
||||||
public GomokuCell get(int x, int y) {
|
public GomokuCell get(int x, int y) {
|
||||||
if (x < 0 || x >= this.width)
|
if (x < 0 || x >= this.width) return null;
|
||||||
return null;
|
if (y < 0 || y >= this.height) return null;
|
||||||
if (y < 0 || y >= this.height)
|
|
||||||
return null;
|
|
||||||
int i = 0, j = 0;
|
int i = 0, j = 0;
|
||||||
GomokuCell act = this.topLeftCell;
|
GomokuCell act = this.topLeftCell;
|
||||||
|
// Move to the desired cell
|
||||||
|
// by following the neighbours in the SE direction
|
||||||
|
// until the desired coordinates are reached
|
||||||
while (i != x || j != y) {
|
while (i != x || j != y) {
|
||||||
Cardinal c = Cardinal.SE;
|
Cardinal c = Cardinal.SE;
|
||||||
if (i < x)
|
if (i < x) i++; // if not in the desired column, move to the right
|
||||||
i++;
|
else c = Cardinal.S; // otherwise, move down
|
||||||
else
|
if (j < y) j++; // if not in the desired row, move down
|
||||||
c = Cardinal.S;
|
else c = Cardinal.E; // otherwise, move to the right
|
||||||
if (j < y)
|
// get the next cell in that direction
|
||||||
j++;
|
|
||||||
else
|
|
||||||
c = Cardinal.E;
|
|
||||||
act = act.getNeighbour(c);
|
act = act.getNeighbour(c);
|
||||||
}
|
}
|
||||||
return act;
|
return act;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method get a cell in specific position in the board.
|
* Return the cell at the specified coordinates.
|
||||||
*
|
*
|
||||||
* @param xy The position on the board.
|
* This method returns the cell at the specified coordinates (x, y) on the
|
||||||
* @return GomokuCell in the position.
|
* board. If the coordinates are out of bounds of the board size,
|
||||||
|
* it returns null.
|
||||||
|
*
|
||||||
|
* @param xy The coordinates of the cell to get.
|
||||||
|
* @return The cell at the specified coordinates, or null if out of bounds.
|
||||||
*/
|
*/
|
||||||
public GomokuCell get(Coordinate xy) {
|
public GomokuCell get(Coordinate xy) {
|
||||||
return this.get(xy.x, xy.y);
|
return this.get(xy.x, xy.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method return all cells in the board in the order.
|
* Return all cells of the board.
|
||||||
*
|
*
|
||||||
* @return All cells with a array 2D.
|
* This method returns all cells of the board in a 2D array. Each cell is
|
||||||
|
* represented by its coordinates (x, y) in the array, and the array is
|
||||||
|
* organized in rows and columns the same way as the board.
|
||||||
|
*
|
||||||
|
* @return A 2D array of all cells on the board.
|
||||||
|
* @see GomokuCell
|
||||||
|
* @see GomokuBoard#get(int, int)
|
||||||
*/
|
*/
|
||||||
private GomokuCell[][] getAllCells() {
|
private GomokuCell[][] getAllCells() {
|
||||||
|
// Create a 2D array to hold all cells
|
||||||
GomokuCell[][] cells = new GomokuCell[this.height][this.width];
|
GomokuCell[][] cells = new GomokuCell[this.height][this.width];
|
||||||
|
// Start from the top-left cell and fill the array from left to right
|
||||||
|
// and top to bottom
|
||||||
GomokuCell act = this.topLeftCell;
|
GomokuCell act = this.topLeftCell;
|
||||||
GomokuCell nextLine = this.topLeftCell.getNeighbour(Cardinal.S);
|
GomokuCell nextLine = this.topLeftCell.getNeighbour(Cardinal.S);
|
||||||
|
// Iterate through the height and width of the board
|
||||||
for (int i = 0; i < this.height; i++) {
|
for (int i = 0; i < this.height; i++) {
|
||||||
|
// Fill the current row with cells
|
||||||
for (int j = 0; j < this.width; j++) {
|
for (int j = 0; j < this.width; j++) {
|
||||||
cells[i][j] = act;
|
cells[i][j] = act;
|
||||||
act = act.getNeighbour(Cardinal.E);
|
act = act.getNeighbour(Cardinal.E);
|
||||||
}
|
}
|
||||||
act = nextLine;
|
// Move to the next line (if it exists)
|
||||||
if (act != null) {
|
if (nextLine != null) {
|
||||||
|
act = nextLine;
|
||||||
nextLine = act.getNeighbour(Cardinal.S);
|
nextLine = act.getNeighbour(Cardinal.S);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -197,60 +227,56 @@ public class GomokuBoard {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method return a list of playable cell.
|
* Return all playable cells of the board.
|
||||||
*
|
*
|
||||||
* @return List of GomokuCell wich all is playable.
|
* This method returns a list of all playable cells on the board.
|
||||||
|
* A cell is considered playable if it has not been played on yet
|
||||||
|
* (i.e., it is empty) and is next to at least one occupied cell.
|
||||||
|
* The method iterates through all cells on the board and checks their
|
||||||
|
* playability status. It returns a list of cells that are playable.
|
||||||
|
*
|
||||||
|
* @return A list of all playable cells on the board.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public List<GomokuCell> getPlayableCells() {
|
public List<GomokuCell> getPlayableCells() {
|
||||||
List<GomokuCell> output = new ArrayList<>();
|
List<GomokuCell> playableCells = new ArrayList<>();
|
||||||
for (GomokuCell[] line : this.getAllCells()) {
|
GomokuCell[][] cells = this.getAllCells();
|
||||||
for (GomokuCell c : line) {
|
// Iterate through all cells on the board
|
||||||
if (c.isPlayable() && c.getState() == Color.NIL)
|
for (GomokuCell[] line : cells) {
|
||||||
output.add(c);
|
for (GomokuCell cell : line) {
|
||||||
|
// Check if the cell is playable
|
||||||
|
if (cell.isPlayable()) {
|
||||||
|
playableCells.add(cell);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return playableCells;
|
||||||
return output;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------Gets--------------------------
|
// - Methods ------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the width of the board.
|
* Return the number of aligned cells in each direction.
|
||||||
*
|
*
|
||||||
* @param width The new width of the board.
|
* This method takes a cell as input and returns a map of the number of
|
||||||
*/
|
* aligned cells in each cardinal direction.
|
||||||
public void setWidth(int width) {
|
* The method checks the state of the cell and its neighbours in each
|
||||||
this.width = width;
|
* direction and counts the number of aligned cells.
|
||||||
}
|
* The current cell is included in the count, thus the count starts at 1.
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the height of the board.
|
|
||||||
*
|
*
|
||||||
* @param height The new height of the board.
|
* @param cell The cell to check for aligned cells.
|
||||||
|
* @return A map of the number of aligned cells in each direction.
|
||||||
*/
|
*/
|
||||||
public void setHeight(int height) {
|
public Map<Cardinal, Integer> countAlignedCells(GomokuCell cell) {
|
||||||
this.height = height;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------Methods--------------------------
|
Map<Cardinal, Integer> map = new EnumMap<>(Cardinal.class);
|
||||||
|
|
||||||
/**
|
// Iterate over 4 non-opposite directions
|
||||||
* This method return a Map of number aligned cells.
|
// (N, NE, E, SE) and count the number of aligned cells in that direction
|
||||||
*
|
// as well as in the opposite direction (S, SW, W, NW)
|
||||||
* @param cell A cell.
|
|
||||||
* @return Map of number aligned cells.
|
|
||||||
*/
|
|
||||||
public EnumMap<Cardinal, Integer> countAlignedCells(GomokuCell cell) {
|
|
||||||
|
|
||||||
EnumMap<Cardinal, Integer> map = new EnumMap<>(Cardinal.class);
|
|
||||||
|
|
||||||
// Iterate over all different axes (4 directions)
|
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
|
// Get the direction
|
||||||
Cardinal direction = Cardinal.fromInt(i);
|
Cardinal direction = Cardinal.fromInt(i);
|
||||||
int count = 1; // Start with the current cell
|
int count = 1; // Include the current cell in the count
|
||||||
|
|
||||||
// Check in the positive direction
|
// Check in the positive direction
|
||||||
GomokuCell nextCell = cell.getNeighbour(direction);
|
GomokuCell nextCell = cell.getNeighbour(direction);
|
||||||
@@ -265,23 +291,24 @@ public class GomokuBoard {
|
|||||||
count++;
|
count++;
|
||||||
nextCell = nextCell.getNeighbour(direction.inverse());
|
nextCell = nextCell.getNeighbour(direction.inverse());
|
||||||
}
|
}
|
||||||
|
// Store the count in the map
|
||||||
map.put(direction, count);
|
map.put(direction, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method return the number max of the aligned Cells.
|
* Count the maximum number of aligned cells.
|
||||||
*
|
*
|
||||||
* @param mapColor A map of number aligned cells.
|
* This method takes a map of aligned cells in each direction
|
||||||
* @return int, the number max of the aligned Cells.
|
* and returns the maximum number of aligned cells.
|
||||||
|
*
|
||||||
|
* @param cellCountMap The map of aligned cells in each direction.
|
||||||
|
* @return The maximum number of aligned cells.
|
||||||
*/
|
*/
|
||||||
public int countMax(Map<Cardinal, Integer> mapColor) {
|
public int countMax(Map<Cardinal, Integer> cellCountMap) {
|
||||||
|
|
||||||
int max = 0;
|
int max = 0;
|
||||||
for (Map.Entry<Cardinal, Integer> entry : mapColor.entrySet()) {
|
for (Map.Entry<Cardinal, Integer> entry : cellCountMap.entrySet()) {
|
||||||
if (entry.getValue() > max) {
|
if (entry.getValue() > max) {
|
||||||
max = entry.getValue();
|
max = entry.getValue();
|
||||||
}
|
}
|
||||||
@@ -290,8 +317,8 @@ public class GomokuBoard {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Expands the board in the specified direction.
|
* Expand the board in the specified direction.
|
||||||
* This method is used to add a new row, column, or both to the board.
|
* 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
|
* It creates new cells in the specified direction and links them to the
|
||||||
* existing cells.
|
* existing cells.
|
||||||
* It also updates the board dimensions accordingly.
|
* It also updates the board dimensions accordingly.
|
||||||
@@ -306,11 +333,16 @@ public class GomokuBoard {
|
|||||||
// if the direction is not even, it is a composed direction
|
// if the direction is not even, it is a composed direction
|
||||||
// call the same function in both components
|
// call the same function in both components
|
||||||
this.expandBoard(direction.rotate(-1));
|
this.expandBoard(direction.rotate(-1));
|
||||||
this.expandBoard(direction.rotate(1));
|
this.expandBoard(direction.rotate( 1));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// find the suitable corner cell to expand from
|
// find the suitable corner cell to expand from
|
||||||
|
// e.g. for an expansion to the North, the corner cell is the
|
||||||
|
// top-left cell of the board
|
||||||
|
// the corner cell is defined as, when looking from the center of the
|
||||||
|
// board in the direction of the expansion, the leftmost cell at the
|
||||||
|
// edge of the board.
|
||||||
Cardinal cornerCellDirection = direction.rotate(-1);
|
Cardinal cornerCellDirection = direction.rotate(-1);
|
||||||
|
|
||||||
// move to the corner cell
|
// move to the corner cell
|
||||||
@@ -326,7 +358,8 @@ public class GomokuBoard {
|
|||||||
cornerCellDirection = direction;
|
cornerCellDirection = direction;
|
||||||
nextCell = cornerCell.getNeighbour(cornerCellDirection);
|
nextCell = cornerCell.getNeighbour(cornerCellDirection);
|
||||||
// if we already reached the end of the board, try the
|
// if we already reached the end of the board, try the
|
||||||
// direction perpendicular to the original direction
|
// direction perpendicular to the original direction, but
|
||||||
|
// to the left (to get to the leftmost cell)
|
||||||
if (nextCell == null) {
|
if (nextCell == null) {
|
||||||
cornerCellDirection = direction.rotate90CCW();
|
cornerCellDirection = direction.rotate90CCW();
|
||||||
nextCell = cornerCell.getNeighbour(cornerCellDirection);
|
nextCell = cornerCell.getNeighbour(cornerCellDirection);
|
||||||
@@ -339,10 +372,10 @@ public class GomokuBoard {
|
|||||||
// then, add (n - 1) cells in the direction rotated by 90 degrees CW,
|
// then, add (n - 1) cells in the direction rotated by 90 degrees CW,
|
||||||
// where n is either the board width or board height.
|
// 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
|
// e.g. for an expansion to the North, add (n - 1) cells to the EAST
|
||||||
// of the anchor cell
|
// of the anchor cell, which will be the nth cell in the row
|
||||||
GomokuCell anchor = new GomokuCell(Color.NIL);
|
GomokuCell anchor = new GomokuCell(Color.NIL);
|
||||||
GomokuCell nextTo = cornerCell;
|
|
||||||
GomokuCell before = cornerCell.getNeighbour(direction.rotate90CCW());
|
GomokuCell before = cornerCell.getNeighbour(direction.rotate90CCW());
|
||||||
|
GomokuCell nextTo = cornerCell;
|
||||||
GomokuCell after = cornerCell.getNeighbour(direction.rotate90CW());
|
GomokuCell after = cornerCell.getNeighbour(direction.rotate90CW());
|
||||||
Cardinal forwardDirection = direction.rotate90CW();
|
Cardinal forwardDirection = direction.rotate90CW();
|
||||||
|
|
||||||
@@ -355,8 +388,9 @@ public class GomokuBoard {
|
|||||||
// if the end of the board is not reached (to avoid creating an
|
// if the end of the board is not reached (to avoid creating an
|
||||||
// additional cell)
|
// additional cell)
|
||||||
nextCell = null;
|
nextCell = null;
|
||||||
if (after != null)
|
if (after != null) {
|
||||||
nextCell = new GomokuCell(Color.NIL);
|
nextCell = new GomokuCell(Color.NIL);
|
||||||
|
}
|
||||||
GomokuCell.link(anchor, nextCell, forwardDirection);
|
GomokuCell.link(anchor, nextCell, forwardDirection);
|
||||||
// set the anchor to the next cell and update the neighbours
|
// set the anchor to the next cell and update the neighbours
|
||||||
anchor = nextCell;
|
anchor = nextCell;
|
||||||
@@ -380,20 +414,27 @@ public class GomokuBoard {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------Overides--------------------------
|
// - Override Methods ---------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method print the board cell by cell with change line when
|
* Return a string representation of the board.
|
||||||
* the line is finished.
|
*
|
||||||
|
* This method returns a string representation of the board. The string
|
||||||
|
* representation is based on the state of each cell on the board.
|
||||||
|
*
|
||||||
|
* @return The string representation of the board.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
StringBuilder out = new StringBuilder();
|
StringBuilder out = new StringBuilder();
|
||||||
GomokuCell[][] cells = this.getAllCells();
|
GomokuCell[][] cells = this.getAllCells();
|
||||||
|
// Iterate through all cells on the board
|
||||||
for (GomokuCell[] line : cells) {
|
for (GomokuCell[] line : cells) {
|
||||||
|
// Append the string representation of each cell to the output
|
||||||
for (GomokuCell c : line) {
|
for (GomokuCell c : line) {
|
||||||
out.append(c.toString());
|
out.append(c.toString());
|
||||||
}
|
}
|
||||||
|
// Add a new line after each row
|
||||||
out.append("\n");
|
out.append("\n");
|
||||||
}
|
}
|
||||||
return out.toString();
|
return out.toString();
|
||||||
|
|||||||
Reference in New Issue
Block a user