286 lines
9.1 KiB
Java
286 lines
9.1 KiB
Java
import java.util.ArrayList;
|
|
import java.util.Arrays;
|
|
import java.util.HashMap;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
|
|
|
|
public class GomokuBoard{
|
|
/** The firstcell in the board, at the top left of the board. */
|
|
private GomokuCell firstCell;
|
|
/** The width of the GomokuBoard.*/
|
|
private int boardWidth;
|
|
/** The height of the GomokuBoard.*/
|
|
private int boardHeight;
|
|
|
|
public static void main(String[] args) {
|
|
Color[][] colors = {{Color.BLACK,Color.BLACK,Color.BLACK},
|
|
{Color.BLACK,Color.BLACK,Color.BLACK},
|
|
{Color.WHITE,Color.WHITE,Color.WHITE}};
|
|
GomokuBoard test = new GomokuBoard(3,3, colors);
|
|
test.get(1,1).setState(Color.BLACK);
|
|
System.out.println(test);
|
|
System.out.println(test.getPlayableCells());
|
|
}
|
|
|
|
//------------------Constructors--------------------------
|
|
|
|
/**
|
|
* This constructor take the width and the height to creat a board of gomoku.
|
|
* @param width Size of width.
|
|
* @param height Size of height.
|
|
*/
|
|
public GomokuBoard(int width, int height){
|
|
this(width, height, null);
|
|
}
|
|
|
|
/**
|
|
* This constructor take the width and the height to creat a board of gomoku.
|
|
* @param width Size of width.
|
|
* @param height Size of height.
|
|
* @param colors Is colors of cells after load a game.
|
|
*/
|
|
public GomokuBoard(int width, int height, Color[][] colors){
|
|
this.firstCell = new GomokuCell(Color.NIL);
|
|
this.boardWidth = width;
|
|
this.boardHeight = height;
|
|
this.genCells(width, height, colors);
|
|
}
|
|
|
|
|
|
/**
|
|
* This method gen 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){
|
|
this.firstCell = new GomokuCell(colors == null ? Color.NIL : colors[0][0]);
|
|
GomokuCell act = this.firstCell;
|
|
GomokuCell top = null;
|
|
|
|
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);
|
|
|
|
}
|
|
if (j != width -1 ){
|
|
GomokuCell right = new GomokuCell(colors == null ? Color.NIL : colors[i][j+1] );
|
|
GomokuCell.link(act, right, Cardinal.E);
|
|
act = right;
|
|
}
|
|
}
|
|
act = nextLine;
|
|
if (act == null) break;
|
|
top = act.getNeighbour(Cardinal.N);
|
|
}
|
|
}
|
|
|
|
//------------------Gets--------------------------
|
|
|
|
/**
|
|
* This method get a cell in specific position in the board.
|
|
* @param x The position x on the board.
|
|
* @param y The position y on the board.
|
|
* @return GomokuCell in the position.
|
|
*/
|
|
public GomokuCell get(int x, int y){
|
|
int i = 0, j = 0;
|
|
GomokuCell act = this.firstCell;
|
|
// System.out.println("x: "+x+" y: "+y);
|
|
while (i != x || j != y){
|
|
// System.out.println("i: "+i+" j: "+j);
|
|
Cardinal c = Cardinal.SE;
|
|
if (i < x) i++;
|
|
else c = Cardinal.E;
|
|
if (j < y) j++;
|
|
else c = Cardinal.S;
|
|
act = act.getNeighbour(c);
|
|
}
|
|
return act;
|
|
|
|
}
|
|
|
|
/**
|
|
* This method return all cells in the board in the order.
|
|
* @return All cells with a array 2D.
|
|
*/
|
|
private GomokuCell[][] getAllsCells(){
|
|
GomokuCell[][] cells = new GomokuCell[this.boardHeight][this.boardWidth];
|
|
GomokuCell act = this.firstCell;
|
|
GomokuCell nextLine = this.firstCell.getNeighbour(Cardinal.S);
|
|
for (int i = 0; i < this.boardHeight; i++) {
|
|
for (int j = 0; j < this.boardWidth; j++) {
|
|
cells[i][j] = act;
|
|
act = act.getNeighbour(Cardinal.E);
|
|
}
|
|
act = nextLine;
|
|
if (act != null){
|
|
nextLine = act.getNeighbour(Cardinal.S);
|
|
}
|
|
}
|
|
return cells;
|
|
}
|
|
|
|
/**
|
|
* This method return a list of playable cell.
|
|
* @return List of GomokuCell wich all is playable.
|
|
*/
|
|
|
|
public List<GomokuCell> getPlayableCells(){
|
|
List<GomokuCell> output = new ArrayList<>();
|
|
for (GomokuCell[] line : this.getAllsCells()) {
|
|
for (GomokuCell c : line) {
|
|
if (c.isPlayable())
|
|
output.add(c);
|
|
}
|
|
}
|
|
|
|
return output;
|
|
|
|
}
|
|
//------------------Methods--------------------------
|
|
|
|
/**
|
|
* This method return a Map of number aligned cells.
|
|
* @param cell A cell.
|
|
* @return Map of number aligned cells.
|
|
*/
|
|
public Map<Cardinal, Integer> countAlignedCells(GomokuCell cell){
|
|
|
|
Map<Cardinal, Integer> map = new HashMap<>();
|
|
Map<Cardinal, Integer> mapColor = cell.getSameColorNeighbour();
|
|
|
|
map.put(Cardinal.N, mapColor.get(Cardinal.N)+mapColor.get(Cardinal.S)+1);
|
|
map.put(Cardinal.W,mapColor.get(Cardinal.W)+mapColor.get(Cardinal.E)+1);
|
|
map.put(Cardinal.NW, mapColor.get(Cardinal.NW)+mapColor.get(Cardinal.SE)+1);
|
|
map.put(Cardinal.SW, mapColor.get(Cardinal.SW)+mapColor.get(Cardinal.NE)+1);
|
|
|
|
return map;
|
|
}
|
|
|
|
/**
|
|
* This method return the number max of the aligned Cells.
|
|
* @param mapColor A map of number aligned cells.
|
|
* @return int, the number max of the aligned Cells.
|
|
*/
|
|
public int countMax(Map<Cardinal, Integer> mapColor){
|
|
|
|
Map<Cardinal, Integer> map = new HashMap<>();
|
|
int max = 0;
|
|
for (Map.Entry<Cardinal, Integer> entry : map.entrySet()) {
|
|
if(entry.getValue() > max){
|
|
max = entry.getValue();
|
|
}
|
|
}
|
|
return max;
|
|
}
|
|
|
|
public void expandBoard(Cardinal direction){
|
|
switch (direction) {
|
|
case Cardinal.SE:
|
|
this.expandBoard(Cardinal.S);
|
|
this.expandBoard(Cardinal.E);
|
|
return;
|
|
|
|
case Cardinal.NE:
|
|
this.expandBoard(Cardinal.N);
|
|
this.expandBoard(Cardinal.E);
|
|
return;
|
|
|
|
case Cardinal.SW:
|
|
this.expandBoard(Cardinal.S);
|
|
this.expandBoard(Cardinal.W);
|
|
return;
|
|
|
|
case Cardinal.NW:
|
|
this.expandBoard(Cardinal.N);
|
|
this.expandBoard(Cardinal.W);
|
|
return;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
List<Cardinal> cardinals = Arrays.asList(Cardinal.values());
|
|
Cardinal topDirection = cardinals.get((cardinals.indexOf(direction) + 4)%8);
|
|
Cardinal topMinus = cardinals.get((cardinals.indexOf(topDirection) + 2)%8);
|
|
Cardinal topPlus = cardinals.get((cardinals.indexOf(topDirection) - 2)%8);
|
|
|
|
GomokuCell act = new GomokuCell(Color.NIL);
|
|
int maxLen = 0;
|
|
GomokuCell top = null;
|
|
GomokuCell newOrigin = null;
|
|
switch (direction) {
|
|
case Cardinal.N:
|
|
top = this.get(0, 0);
|
|
maxLen = this.boardWidth;
|
|
newOrigin = act;
|
|
break;
|
|
|
|
case Cardinal.W:
|
|
top = this.get(0,0);
|
|
maxLen = this.boardHeight;
|
|
newOrigin = act;
|
|
break;
|
|
|
|
case Cardinal.S:
|
|
top = this.get(this.boardHeight-1, 0);
|
|
maxLen = this.boardWidth;
|
|
newOrigin = this.get(0, 0);
|
|
break;
|
|
|
|
case Cardinal.E:
|
|
top = this.get(0, this.boardWidth-1);
|
|
maxLen = this.boardHeight;
|
|
newOrigin = this.get(0, 0);
|
|
break;
|
|
|
|
default:
|
|
throw new IllegalStateException("Why are you here ?");
|
|
}
|
|
|
|
|
|
for (int i = 0; i < maxLen; i++) {
|
|
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);
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
//------------------Overides--------------------------
|
|
|
|
/**
|
|
* This method print the board cell by cell with change line when
|
|
* the line is finished.
|
|
*/
|
|
@Override
|
|
public String toString() {
|
|
StringBuilder out = new StringBuilder();
|
|
GomokuCell[][] cells = this.getAllsCells();
|
|
for (GomokuCell[] line : cells) {
|
|
for (GomokuCell c : line) {
|
|
out.append(c.toString());
|
|
}
|
|
out.append("\n");
|
|
}
|
|
return out.toString();
|
|
}
|
|
}
|