Merge branch 'master' of https://gitlab.isima.fr/audorival/gomoku
This commit is contained in:
@@ -1,8 +1,7 @@
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import java.util.EnumMap;
|
||||
|
||||
/**
|
||||
* The board of the game Gomoku.
|
||||
@@ -45,6 +44,7 @@ public class GomokuBoard{
|
||||
|
||||
/**
|
||||
* This constructor take the width and the height to creat a board of gomoku.
|
||||
*
|
||||
* @param width Size of width.
|
||||
* @param height Size of height.
|
||||
*/
|
||||
@@ -54,6 +54,7 @@ public class GomokuBoard{
|
||||
|
||||
/**
|
||||
* 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.
|
||||
@@ -65,9 +66,9 @@ public class GomokuBoard{
|
||||
this.generateCells(width, height, colors);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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.
|
||||
@@ -98,7 +99,8 @@ public class GomokuBoard{
|
||||
}
|
||||
}
|
||||
act = nextLine;
|
||||
if (act == null) break;
|
||||
if (act == null)
|
||||
break;
|
||||
top = act.getNeighbour(Cardinal.N);
|
||||
}
|
||||
}
|
||||
@@ -107,6 +109,7 @@ public class GomokuBoard{
|
||||
|
||||
/**
|
||||
* Returns the width of the board.
|
||||
*
|
||||
* @return The width of the board.
|
||||
*/
|
||||
public int getWidth() {
|
||||
@@ -115,6 +118,7 @@ public class GomokuBoard{
|
||||
|
||||
/**
|
||||
* Returns the height of the board.
|
||||
*
|
||||
* @return The height of the board.
|
||||
*/
|
||||
public int getHeight() {
|
||||
@@ -123,29 +127,47 @@ public class GomokuBoard{
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
if (x < 0 || x >= this.boardWidth) return null;
|
||||
if (y < 0 || y >= this.boardHeight) return null;
|
||||
if (x < 0 || x >= this.boardWidth)
|
||||
return null;
|
||||
if (y < 0 || y >= this.boardHeight)
|
||||
return null;
|
||||
int i = 0, j = 0;
|
||||
GomokuCell act = this.firstCell;
|
||||
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++;
|
||||
else
|
||||
c = Cardinal.S;
|
||||
if (j < y)
|
||||
j++;
|
||||
else
|
||||
c = Cardinal.E;
|
||||
act = act.getNeighbour(c);
|
||||
}
|
||||
return act;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This method get a cell in specific position in the board.
|
||||
*
|
||||
* @param xy The position on the board.
|
||||
* @return GomokuCell in the position.
|
||||
*/
|
||||
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 with a array 2D.
|
||||
*/
|
||||
private GomokuCell[][] getAllCells() {
|
||||
@@ -167,6 +189,7 @@ public class GomokuBoard{
|
||||
|
||||
/**
|
||||
* This method return a list of playable cell.
|
||||
*
|
||||
* @return List of GomokuCell wich all is playable.
|
||||
*/
|
||||
|
||||
@@ -187,6 +210,7 @@ public class GomokuBoard{
|
||||
|
||||
/**
|
||||
* Set the width of the board.
|
||||
*
|
||||
* @param width The new width of the board.
|
||||
*/
|
||||
public void setWidth(int width) {
|
||||
@@ -195,6 +219,7 @@ public class GomokuBoard{
|
||||
|
||||
/**
|
||||
* Set the height of the board.
|
||||
*
|
||||
* @param height The new height of the board.
|
||||
*/
|
||||
public void setHeight(int height) {
|
||||
@@ -205,32 +230,49 @@ public class GomokuBoard{
|
||||
|
||||
/**
|
||||
* 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){
|
||||
public EnumMap<Cardinal, Integer> countAlignedCells(GomokuCell cell) {
|
||||
|
||||
Map<Cardinal, Integer> map = new HashMap<>();
|
||||
Map<Cardinal, Integer> mapColor = cell.getSameColorNeighbour();
|
||||
EnumMap<Cardinal, Integer> map = new EnumMap<>(Cardinal.class);
|
||||
|
||||
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);
|
||||
// Iterate over all different axes (4 directions)
|
||||
for (int i = 0; i < 4; i++) {
|
||||
Cardinal direction = Cardinal.fromInt(i);
|
||||
int count = 1; // Start with the current cell
|
||||
|
||||
// Check in the positive direction
|
||||
GomokuCell nextCell = cell.getNeighbour(direction);
|
||||
while (nextCell != null && nextCell.getState() == cell.getState()) {
|
||||
count++;
|
||||
nextCell = nextCell.getNeighbour(direction);
|
||||
}
|
||||
|
||||
// Check in the negative direction
|
||||
nextCell = cell.getNeighbour(direction.inverse());
|
||||
while (nextCell != null && nextCell.getState() == cell.getState()) {
|
||||
count++;
|
||||
nextCell = nextCell.getNeighbour(direction.inverse());
|
||||
}
|
||||
|
||||
map.put(direction, count);
|
||||
}
|
||||
|
||||
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()) {
|
||||
for (Map.Entry<Cardinal, Integer> entry : mapColor.entrySet()) {
|
||||
if(entry.getValue() > max){
|
||||
max = entry.getValue();
|
||||
}
|
||||
@@ -241,8 +283,10 @@ 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.
|
||||
* It creates new cells in the specified direction and links them to the existing cells.
|
||||
* 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
|
||||
*/
|
||||
@@ -302,13 +346,15 @@ public class GomokuBoard{
|
||||
// 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);
|
||||
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);
|
||||
if (after != null)
|
||||
after = after.getNeighbour(forwardDirection);
|
||||
}
|
||||
|
||||
// update the board dimensions;
|
||||
|
||||
@@ -6,15 +6,22 @@ import java.util.Map;
|
||||
* This class is cell of the board of the Gomoku game.
|
||||
*/
|
||||
public class GomokuCell {
|
||||
/** Enumerate neighbor with key in Cardinal direction and key representing the cell in that direction. */
|
||||
/**
|
||||
* Enumerate neighbor with key in Cardinal direction and key representing the
|
||||
* cell in that direction.
|
||||
*/
|
||||
private EnumMap<Cardinal, GomokuCell> neighbour;
|
||||
/** The state of the cell represented by the enumerate Color, Nil is empty, white and black for the color of a token */
|
||||
/**
|
||||
* The state of the cell represented by the enumerate Color, Nil is empty, white
|
||||
* and black for the color of a token
|
||||
*/
|
||||
private Color state;
|
||||
|
||||
// ------------------Constructors--------------------------
|
||||
|
||||
/**
|
||||
* The constructor of the cell.
|
||||
*
|
||||
* @param state The state by default of the cell.
|
||||
*/
|
||||
public GomokuCell(Color state) {
|
||||
@@ -26,6 +33,7 @@ public class GomokuCell{
|
||||
|
||||
/**
|
||||
* Return one neighbour.
|
||||
*
|
||||
* @param car The Cardinal direction.
|
||||
* @return The GomokuCell at the direction.
|
||||
*/
|
||||
@@ -35,6 +43,7 @@ public class GomokuCell{
|
||||
|
||||
/**
|
||||
* Return neighbours.
|
||||
*
|
||||
* @return The EnumMap of neighbours.
|
||||
*/
|
||||
public EnumMap<Cardinal, GomokuCell> getAllNeighbour() {
|
||||
@@ -43,6 +52,7 @@ public class GomokuCell{
|
||||
|
||||
/**
|
||||
* Return the number of same colored neighbours in all direction.
|
||||
*
|
||||
* @return The Map of neighbours.
|
||||
*/
|
||||
public Map<Cardinal, Integer> getSameColorNeighbour() {
|
||||
@@ -60,8 +70,7 @@ public class GomokuCell{
|
||||
for (Map.Entry<Cardinal, Integer> entry : map.entrySet()) {
|
||||
|
||||
GomokuCell actualcell = this;
|
||||
while(this.getState() == actualcell.getNeighbour(entry.getKey()).getState())
|
||||
{
|
||||
while (this.getState() == actualcell.getNeighbour(entry.getKey()).getState()) {
|
||||
entry.setValue(entry.getValue() + 1);
|
||||
actualcell = actualcell.getNeighbour(entry.getKey());
|
||||
}
|
||||
@@ -71,6 +80,7 @@ public class GomokuCell{
|
||||
|
||||
/**
|
||||
* Return the state.
|
||||
*
|
||||
* @return The state of the current cell with one Color.
|
||||
*/
|
||||
public Color getState() {
|
||||
@@ -81,6 +91,7 @@ public class GomokuCell{
|
||||
|
||||
/**
|
||||
* Change state of the current cell.
|
||||
*
|
||||
* @param c The color of the token played.
|
||||
* @throws IllegalStateException If the cell is not playable.
|
||||
*/
|
||||
@@ -88,11 +99,11 @@ public class GomokuCell{
|
||||
this.state = c;
|
||||
}
|
||||
|
||||
|
||||
// ------------------Booleans--------------------------
|
||||
|
||||
/**
|
||||
* This method returns if the current cell is empty
|
||||
*
|
||||
* @return True if is empty, False if is not.
|
||||
*/
|
||||
public boolean isEmpty() {
|
||||
@@ -101,6 +112,7 @@ public class GomokuCell{
|
||||
|
||||
/**
|
||||
* This method returns if the cell has already played.
|
||||
*
|
||||
* @return True if the cell is already played, False if is not.
|
||||
*/
|
||||
public boolean isPlayed() {
|
||||
@@ -109,21 +121,26 @@ public class GomokuCell{
|
||||
|
||||
/**
|
||||
* Return if the cell is playable.
|
||||
* @return True if the current cell can be played with the condition of the gomoku.
|
||||
*
|
||||
* @return True if the current cell can be played with the condition of the
|
||||
* gomoku.
|
||||
*/
|
||||
public boolean isPlayable() {
|
||||
if (this.state != Color.NIL)
|
||||
return false;
|
||||
for (Cardinal c : Cardinal.values()) {
|
||||
GomokuCell current = this.getNeighbour(c);
|
||||
if (current != null && current.isPlayed()) return true;
|
||||
if (current != null && current.isPlayed())
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// ------------------Methods--------------------------
|
||||
|
||||
/**
|
||||
* This method link the cell at the Cardinal position on the current cell.
|
||||
*
|
||||
* @param car The Cardinal direction of the cell to link.
|
||||
* @param cell The GomokuCell to link.
|
||||
*/
|
||||
@@ -131,11 +148,11 @@ public class GomokuCell{
|
||||
this.neighbour.put(car, cell);
|
||||
}
|
||||
|
||||
|
||||
// ------------------Statics--------------------------
|
||||
|
||||
public static void link(GomokuCell c1, GomokuCell c2, Cardinal c1Toc2) {
|
||||
if (c1 == null || c2 == null) return ;
|
||||
if (c1 == null || c2 == null)
|
||||
return;
|
||||
c1.linkCell(c1Toc2, c2);
|
||||
c2.linkCell(c1Toc2.inverse(), c1);
|
||||
}
|
||||
|
||||
@@ -26,16 +26,17 @@ public class GomokuGame {
|
||||
int currentPlayerInt;
|
||||
|
||||
Coordinate cellCoor = null;
|
||||
|
||||
GomokuGame(boolean renderer) {
|
||||
this.playRenderer = renderer;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
int sizeX = 0;
|
||||
int sizeY = 0;
|
||||
int nbToken = 0;
|
||||
int nbJetonsAligne = 0;
|
||||
int sizeX = 15;
|
||||
int sizeY = 15;
|
||||
int nbToken = 50;
|
||||
int nbJetonsAligne = 5;
|
||||
boolean renderer = false;
|
||||
String path_a_load = "";
|
||||
|
||||
@@ -71,8 +72,7 @@ public class GomokuGame {
|
||||
String bool = args[++i];
|
||||
if (bool == "true") {
|
||||
renderer = true;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
renderer = false;
|
||||
}
|
||||
}
|
||||
@@ -83,23 +83,20 @@ public class GomokuGame {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Test
|
||||
GomokuGame g = new GomokuGame(renderer);//metre true ou false si in veut l'affichage ou non
|
||||
if(path_a_load!="")
|
||||
{
|
||||
g.load(Path.of(path_a_load));
|
||||
}
|
||||
g.newGame(false, "Player 1", "Player 2", DEFAULT_TOKENS_COUNT);
|
||||
g.renderer = new ConsoleRenderer();
|
||||
g.renderer.init(g);
|
||||
g.board.expandBoard(Cardinal.SE);
|
||||
g.renderer.update();
|
||||
GomokuGame g = new GomokuGame(false);// metre true ou fals si in veut l'affichage ou non
|
||||
g.board = new GomokuBoard(sizeX, sizeY);
|
||||
g.board.get(sizeX / 2, sizeY / 2).setState(Color.BLACK);
|
||||
g.player1 = new Human("un", Color.WHITE, nbToken);
|
||||
g.player2 = new GomokuAI("deux", Color.BLACK, nbToken - 1);
|
||||
System.out.println(g.board);
|
||||
// g.renderer.update();
|
||||
g.startGame();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This method init the game with these parameters.
|
||||
*
|
||||
* @param bot If the player want to play with a bot it's true.
|
||||
* @param name1 Name of player one.
|
||||
* @param name2 Name of player two.
|
||||
@@ -134,32 +131,37 @@ public class GomokuGame {
|
||||
*/
|
||||
public void startGame() {
|
||||
/*
|
||||
GomokuCell actualPlayedCell = play(player1);
|
||||
if( NB_CELL_PLAY <= board.countMax(board.countAlignedCells(actualPlayedCell)))
|
||||
{
|
||||
System.out.println("c'est gangée !");
|
||||
}
|
||||
* GomokuCell actualPlayedCell = play(player1);
|
||||
* if( NB_CELL_PLAY <=
|
||||
* board.countMax(board.countAlignedCells(actualPlayedCell)))
|
||||
* {
|
||||
* System.out.println("c'est gangée !");
|
||||
* }
|
||||
*/
|
||||
this.currentPlayer = player1;
|
||||
while (this.player1.tokens > 0 || this.player2.tokens > 0) {
|
||||
GomokuCell currentPlay = null;
|
||||
while (currentPlay == null) {
|
||||
currentPlay = this.play(this.currentPlayer);
|
||||
}
|
||||
|
||||
if( NB_CELL_PLAY <= board.countMax(board.countAlignedCells(currentPlay)))
|
||||
{
|
||||
this.renderer.updateStatus("Le joueur " + this.currentPlayer + "a gagné !");
|
||||
System.out.println(board.countMax(board.countAlignedCells(currentPlay)));
|
||||
if (NB_CELL_PLAY <= board.countMax(board.countAlignedCells(currentPlay))) {
|
||||
// this.renderer.updateStatus("Le joueur " + this.currentPlayer + "a gagné !");
|
||||
return;
|
||||
}
|
||||
this.currentPlayer.tokens -= 1;
|
||||
this.currentPlayer = this.nextPlayer();
|
||||
System.out.println(this.board);
|
||||
}
|
||||
this.renderer.updateStatus("Match nul, il ne reste plus de jeton.");
|
||||
|
||||
// this.renderer.updateStatus("Match nul, il ne reste plus de jeton.");
|
||||
System.out.println("Match nul, il ne reste plus de jeton");
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Place the token on the cell where the player play.
|
||||
*
|
||||
* @param Player get player to play the cell.
|
||||
*/
|
||||
public GomokuCell play(Player player) {
|
||||
@@ -168,30 +170,29 @@ public class GomokuGame {
|
||||
while (this.cellCoor == null) {
|
||||
try {
|
||||
wait(16);
|
||||
}
|
||||
catch(InterruptedException e){
|
||||
} catch (InterruptedException e) {
|
||||
this.save(null);
|
||||
System.out.println(e);
|
||||
}
|
||||
}
|
||||
cellToPlay= this.board.get(this.cellCoor.x, this.cellCoor.y);
|
||||
if (cellToPlay == null || !cellToPlay.isPlayable()) { // If the cell is not playable we return null to not play.
|
||||
cellToPlay = this.board.get(this.cellCoor);
|
||||
if (cellToPlay == null || !cellToPlay.isPlayable()) { // If the cell is not playable we return null to not
|
||||
// play.
|
||||
return null;
|
||||
}
|
||||
cellToPlay.setState(player.color);
|
||||
this.cellCoor = null;
|
||||
}
|
||||
else{
|
||||
cellToPlay = player.chooseMove(board);
|
||||
} else {
|
||||
cellToPlay = player.chooseMove(this.board);
|
||||
cellToPlay.setState(player.color);
|
||||
}
|
||||
return cellToPlay;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method save the game on a file.
|
||||
*
|
||||
* @param filename The file to save.
|
||||
* @return True if successful and false if not.
|
||||
*/
|
||||
@@ -217,8 +218,7 @@ public class GomokuGame {
|
||||
colorP1,
|
||||
currentPlayerInt,
|
||||
this.player1.tokens,
|
||||
this.player2.tokens
|
||||
));
|
||||
this.player2.tokens));
|
||||
|
||||
// Write the board
|
||||
for (int i = 0; i < this.getBoard().getHeight(); ++i) {
|
||||
@@ -255,6 +255,7 @@ public class GomokuGame {
|
||||
|
||||
/**
|
||||
* This method load a game on the file.
|
||||
*
|
||||
* @param filename The file to load.
|
||||
* @return True if successful and False if not.
|
||||
*/
|
||||
@@ -342,6 +343,7 @@ public class GomokuGame {
|
||||
|
||||
/**
|
||||
* This method return the next player to play.
|
||||
*
|
||||
* @return The next player.
|
||||
*/
|
||||
private Player nextPlayer() {
|
||||
|
||||
@@ -34,6 +34,7 @@ public class Human extends Player {
|
||||
|
||||
int x = 0, y = 0;
|
||||
boolean pass = false;
|
||||
GomokuCell cell = null;
|
||||
|
||||
do {
|
||||
|
||||
@@ -61,7 +62,8 @@ public class Human extends Player {
|
||||
}
|
||||
} while (!pass);
|
||||
|
||||
pass = board.get(x, y).isPlayable();
|
||||
cell = board.get(y, x);
|
||||
pass = cell == null ? false : cell.isPlayable();
|
||||
if (!pass) {
|
||||
System.out.println("Cette case n'est pas jouable !");
|
||||
}
|
||||
@@ -69,6 +71,6 @@ public class Human extends Player {
|
||||
|
||||
System.out.println("Vous avez saisi : " + x + ", " + y);
|
||||
|
||||
return board.get(x, y);
|
||||
return cell;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user