Document GomokuBoard class file
This commit is contained in:
@@ -71,6 +71,8 @@ public class GomokuBoard {
|
||||
this(width, height, null);
|
||||
}
|
||||
|
||||
// - Private methods ----------------------------------
|
||||
|
||||
/**
|
||||
* Generate the cells of the board.
|
||||
*
|
||||
@@ -83,41 +85,52 @@ public class GomokuBoard {
|
||||
* @param colors Array of Color to fill the board.
|
||||
*/
|
||||
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]);
|
||||
GomokuCell act = this.topLeftCell;
|
||||
GomokuCell top = null;
|
||||
GomokuCell currentCell = this.topLeftCell;
|
||||
GomokuCell previousLineCell = null;
|
||||
|
||||
// Run through the height of the board
|
||||
for (int i = 0; i < height; i++) {
|
||||
GomokuCell nextLine = 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);
|
||||
GomokuCell nextLineCell = null;
|
||||
|
||||
// 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) {
|
||||
GomokuCell right = new GomokuCell(colors == null ? Color.NIL : colors[i][j + 1]);
|
||||
GomokuCell.link(act, right, Cardinal.E);
|
||||
act = right;
|
||||
GomokuCell.link(currentCell, right, Cardinal.E);
|
||||
currentCell = right;
|
||||
}
|
||||
}
|
||||
act = nextLine;
|
||||
if (act == null)
|
||||
break;
|
||||
top = act.getNeighbour(Cardinal.N);
|
||||
// Move to the next line, and update the previous line cell
|
||||
currentCell = nextLineCell;
|
||||
if (currentCell != null) {
|
||||
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.
|
||||
*/
|
||||
@@ -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.
|
||||
*/
|
||||
@@ -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 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) {
|
||||
if (x < 0 || x >= this.width)
|
||||
return null;
|
||||
if (y < 0 || y >= this.height)
|
||||
return null;
|
||||
if (x < 0 || x >= this.width) return null;
|
||||
if (y < 0 || y >= this.height) return null;
|
||||
int i = 0, j = 0;
|
||||
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) {
|
||||
Cardinal c = Cardinal.SE;
|
||||
if (i < x)
|
||||
i++;
|
||||
else
|
||||
c = Cardinal.S;
|
||||
if (j < y)
|
||||
j++;
|
||||
else
|
||||
c = Cardinal.E;
|
||||
if (i < x) i++; // if not in the desired column, move to the right
|
||||
else c = Cardinal.S; // otherwise, move down
|
||||
if (j < y) j++; // if not in the desired row, move down
|
||||
else c = Cardinal.E; // otherwise, move to the right
|
||||
// get the next cell in that direction
|
||||
act = act.getNeighbour(c);
|
||||
}
|
||||
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.
|
||||
* @return GomokuCell in the position.
|
||||
* 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 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) {
|
||||
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() {
|
||||
// Create a 2D array to hold all cells
|
||||
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 nextLine = this.topLeftCell.getNeighbour(Cardinal.S);
|
||||
// Iterate through the height and width of the board
|
||||
for (int i = 0; i < this.height; i++) {
|
||||
// Fill the current row with cells
|
||||
for (int j = 0; j < this.width; j++) {
|
||||
cells[i][j] = act;
|
||||
act = act.getNeighbour(Cardinal.E);
|
||||
}
|
||||
// Move to the next line (if it exists)
|
||||
if (nextLine != null) {
|
||||
act = nextLine;
|
||||
if (act != null) {
|
||||
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() {
|
||||
List<GomokuCell> output = new ArrayList<>();
|
||||
for (GomokuCell[] line : this.getAllCells()) {
|
||||
for (GomokuCell c : line) {
|
||||
if (c.isPlayable() && c.getState() == Color.NIL)
|
||||
output.add(c);
|
||||
List<GomokuCell> playableCells = new ArrayList<>();
|
||||
GomokuCell[][] cells = this.getAllCells();
|
||||
// Iterate through all cells on the board
|
||||
for (GomokuCell[] line : cells) {
|
||||
for (GomokuCell cell : line) {
|
||||
// Check if the cell is playable
|
||||
if (cell.isPlayable()) {
|
||||
playableCells.add(cell);
|
||||
}
|
||||
}
|
||||
|
||||
return output;
|
||||
|
||||
}
|
||||
return playableCells;
|
||||
}
|
||||
|
||||
// ------------------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.
|
||||
*/
|
||||
public void setWidth(int width) {
|
||||
this.width = width;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the height of the board.
|
||||
* This method takes a cell as input and returns a map of the number of
|
||||
* aligned cells in each cardinal direction.
|
||||
* The method checks the state of the cell and its neighbours in each
|
||||
* direction and counts the number of aligned cells.
|
||||
* The current cell is included in the count, thus the count starts at 1.
|
||||
*
|
||||
* @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) {
|
||||
this.height = height;
|
||||
}
|
||||
public Map<Cardinal, Integer> countAlignedCells(GomokuCell cell) {
|
||||
|
||||
// ------------------Methods--------------------------
|
||||
Map<Cardinal, Integer> map = new EnumMap<>(Cardinal.class);
|
||||
|
||||
/**
|
||||
* This method return a Map of number aligned cells.
|
||||
*
|
||||
* @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)
|
||||
// Iterate over 4 non-opposite directions
|
||||
// (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)
|
||||
for (int i = 0; i < 4; i++) {
|
||||
// Get the direction
|
||||
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
|
||||
GomokuCell nextCell = cell.getNeighbour(direction);
|
||||
@@ -265,23 +291,24 @@ public class GomokuBoard {
|
||||
count++;
|
||||
nextCell = nextCell.getNeighbour(direction.inverse());
|
||||
}
|
||||
|
||||
// Store the count in the map
|
||||
map.put(direction, count);
|
||||
}
|
||||
|
||||
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.
|
||||
* @return int, the number max of the aligned Cells.
|
||||
* This method takes a map of aligned cells in each direction
|
||||
* 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;
|
||||
for (Map.Entry<Cardinal, Integer> entry : mapColor.entrySet()) {
|
||||
for (Map.Entry<Cardinal, Integer> entry : cellCountMap.entrySet()) {
|
||||
if (entry.getValue() > max) {
|
||||
max = entry.getValue();
|
||||
}
|
||||
@@ -290,8 +317,8 @@ public class GomokuBoard {
|
||||
}
|
||||
|
||||
/**
|
||||
* Expands the board in the specified direction.
|
||||
* This method is used to add a new row, column, or both to the board.
|
||||
* Expand 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.
|
||||
@@ -306,11 +333,16 @@ public class GomokuBoard {
|
||||
// if the direction is not even, it is a composed direction
|
||||
// call the same function in both components
|
||||
this.expandBoard(direction.rotate(-1));
|
||||
this.expandBoard(direction.rotate(1));
|
||||
this.expandBoard(direction.rotate( 1));
|
||||
return;
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
// move to the corner cell
|
||||
@@ -326,7 +358,8 @@ public class GomokuBoard {
|
||||
cornerCellDirection = direction;
|
||||
nextCell = cornerCell.getNeighbour(cornerCellDirection);
|
||||
// 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) {
|
||||
cornerCellDirection = direction.rotate90CCW();
|
||||
nextCell = cornerCell.getNeighbour(cornerCellDirection);
|
||||
@@ -339,10 +372,10 @@ public class GomokuBoard {
|
||||
// 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
|
||||
// of the anchor cell, which will be the nth cell in the row
|
||||
GomokuCell anchor = new GomokuCell(Color.NIL);
|
||||
GomokuCell nextTo = cornerCell;
|
||||
GomokuCell before = cornerCell.getNeighbour(direction.rotate90CCW());
|
||||
GomokuCell nextTo = cornerCell;
|
||||
GomokuCell after = cornerCell.getNeighbour(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
|
||||
// additional cell)
|
||||
nextCell = null;
|
||||
if (after != 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;
|
||||
@@ -380,20 +414,27 @@ public class GomokuBoard {
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------Overides--------------------------
|
||||
// - Override Methods ---------------------------------
|
||||
|
||||
/**
|
||||
* This method print the board cell by cell with change line when
|
||||
* the line is finished.
|
||||
* Return a string representation of the board.
|
||||
*
|
||||
* 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
|
||||
public String toString() {
|
||||
StringBuilder out = new StringBuilder();
|
||||
GomokuCell[][] cells = this.getAllCells();
|
||||
// Iterate through all cells on the board
|
||||
for (GomokuCell[] line : cells) {
|
||||
// Append the string representation of each cell to the output
|
||||
for (GomokuCell c : line) {
|
||||
out.append(c.toString());
|
||||
}
|
||||
// Add a new line after each row
|
||||
out.append("\n");
|
||||
}
|
||||
return out.toString();
|
||||
|
||||
Reference in New Issue
Block a user