Merge branch 'master' of gitlab.isima.fr:audorival/gomoku

This commit is contained in:
Dorian HAMDANI
2025-04-07 08:58:32 +02:00
5 changed files with 159 additions and 84 deletions

View File

@@ -1,7 +1,28 @@
public enum Color { public enum Color {
NIL, NIL(-1),
WHITE, WHITE(0),
BLACK; BLACK(1);
private final int val;
Color(int i) {
this.val = i;
}
public Color fromInt(int i) {
for (Color c : Color.values()) {
if (c.val == val) {
return c;
}
}
throw new IllegalArgumentException("Invalid value: " + this);
}
public Color inverse() {
if (this.val == -1)
throw new IllegalArgumentException("No inverse of NIL");
return fromInt((this.val + 1) % 2);
}
} }

View File

@@ -1,40 +1,55 @@
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Random; import java.util.Random;
import java.util.HashMap;
public class GomokuAI extends Player {
// ------------------Constructors--------------------------
public class GomokuAI extends Player{
/** /**
* This class is an extends of the class Player, this allows the GomokuAI to choose his move. * The constructor of the Human.
*/ *
* @param name The name of the player.
* @param color The color of the player.
*/
public GomokuAI(String name, Color color) {
super(name, color);
}
/**
* This class is an extends of the class Player, this allows the GomokuAI to
* choose his move.
*/
/** The random initialization */ /** The random initialization */
Random random = new Random(); Random random = new Random();
/** The difficulty of the GomokuAI */ /** The difficulty of the GomokuAI */
int difficulty = 0; int difficulty = 0;
//------------------Methods-------------------------- // ------------------Methods--------------------------
/** /**
* Return the coordinate of the move played by the Gomoku AI. * Return the coordinate of the move played by the Gomoku AI.
* @param board The actual Gomoku board. *
* @return The Cell of the move played. * @param board The actual Gomoku board.
*/ * @return The Cell of the move played.
public GomokuCell chooseMove(GomokuBoard board){ */
@Override
public GomokuCell chooseMove(GomokuBoard board) {
List<GomokuCell> playableCell = board.getPlayableCells(); List<GomokuCell> playableCell = board.getPlayableCells();
GomokuCell playCell; GomokuCell playCell;
int x=0,y=0; int x = 0, y = 0;
switch (difficulty) { switch (difficulty) {
case 0: case 0:
playCell = playableCell.get(random.nextInt(playableCell.size())); playCell = playableCell.get(random.nextInt(playableCell.size()));
break; break;
case 1: case 1:
Map<GomokuCell, Integer> map = GetCellPoint(board); Map<GomokuCell, Integer> map = GetCellPoint(board);
int max=0; int max = 0;
for (Map.Entry<GomokuCell, Integer> entry : map.entrySet()) { for (Map.Entry<GomokuCell, Integer> entry : map.entrySet()) {
if(entry.getValue() > max){ if (entry.getValue() > max) {
max = entry.getValue(); max = entry.getValue();
playCell = entry.getKey(); playCell = entry.getKey();
} }
@@ -43,25 +58,25 @@ public class GomokuAI extends Player{
throw new AssertionError(); throw new AssertionError();
} }
System.out.println("L'IA à choisi : "+ x+", "+ y); System.out.println("L'IA à choisi : " + x + ", " + y);
return playCell; return playCell;
} }
/** /**
* Return a Map of all Cell playable, and their point. * Return a Map of all Cell playable, and their point.
* @param board The actual Gomoku board. *
* @return the Map of all Cell playable, and their point. * @param board The actual Gomoku board.
*/ * @return the Map of all Cell playable, and their point.
public Map<GomokuCell, Integer> GetCellPoint(GomokuBoard board){ */
public Map<GomokuCell, Integer> GetCellPoint(GomokuBoard board) {
List<GomokuCell> playableCell = board.getPlayableCells(); List<GomokuCell> playableCell = board.getPlayableCells();
Map<GomokuCell, Integer> map = new HashMap<>(); Map<GomokuCell, Integer> map = new HashMap<>();
for (GomokuCell gomokuCell : playableCell) { for (GomokuCell gomokuCell : playableCell) {
switch(this.color){ switch (this.color) {
case Color.WHITE: case Color.WHITE:
gomokuCell.setState(Color.BLACK); gomokuCell.setState(Color.BLACK);
@@ -81,6 +96,4 @@ public class GomokuAI extends Player{
return map; return map;
} }
} }

View File

@@ -1,12 +1,12 @@
import java.nio.file.Path;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Random;
import java.io.BufferedWriter;
public class GomokuGame { public class GomokuGame {
public static final int DEFAULT_BOARD_WIDTH = 15; // largeur du plateau public static final int DEFAULT_BOARD_WIDTH = 15; // largeur du plateau
public static final int DEFAULT_BOARD_HEIGHT = 15; // hauteur du plateau public static final int DEFAULT_BOARD_HEIGHT = 15; // hauteur du plateau
public static final int DEFAULT_TOKENS_COUNT = 60; // nb de jetons public static final int DEFAULT_TOKENS_COUNT = 60; // nb de jetons
@@ -32,7 +32,26 @@ public class GomokuGame {
g.renderer.update(); g.renderer.update();
} }
public void newGame() { public void newGame(boolean bot, String name1, String name2) {
Color[] possible = { Color.WHITE, Color.BLACK };
int rnd = new Random().nextInt(possible.length);
Color colorPlayer1 = possible[rnd];
Color colorPlayer2 = colorPlayer1.inverse();
this.player1 = new Human(name1, colorPlayer1);
if (bot) {
this.player2 = new GomokuAI(name2, colorPlayer2);
} else {
this.player2 = new Human(name2, colorPlayer2);
}
this.board = new GomokuBoard(15, 15);
this.colorP1 = colorPlayer1;
this.currP = this.player1.color == Color.WHITE ? 1: 2;
this.nbTokens1 = 60;
this.nbTokens2 = 60;
} }
@@ -44,7 +63,7 @@ public class GomokuGame {
// save the game state to the file // save the game state to the file
// 1. Open the file // 1. Open the file
// 2. Write the first line with: // 2. Write the first line with:
// w h colorP1 currP nbTokens1 nbTokens2 // w h colorP1 currP nbTokens1 nbTokens2
// 3. Write the next h lines with the board // 3. Write the next h lines with the board
// 4. Close the file // 4. Close the file
// 5. Return true if successful, false otherwise // 5. Return true if successful, false otherwise
@@ -70,12 +89,19 @@ public class GomokuGame {
for (int j = 0; j < this.getBoard().getWidth(); ++j) { for (int j = 0; j < this.getBoard().getWidth(); ++j) {
char c; char c;
switch (board.get(i, j).getState()) { switch (board.get(i, j).getState()) {
case BLACK: c = 'X'; break; case BLACK:
case WHITE: c = 'O'; break; c = 'X';
case NIL: c = '.'; break; break;
default: throw new IllegalStateException( case WHITE:
String.format("Unexpected value at cell (%d, %d): %s", i, j, board.get(i, j).getState())
); break;
case NIL:
c = '.';
break;
default:
throw new IllegalStateException(
String.format("Unexpected value at cell (%d, %d): %s", i, j,
board.get(i, j).getState()));
} }
writer.write(c); writer.write(c);
} }
@@ -95,7 +121,7 @@ public class GomokuGame {
// load the game state from the file // load the game state from the file
// 1. Open the file // 1. Open the file
// 2. Read the first line to get: // 2. Read the first line to get:
// w h colorP1 currP nbTokens1 nbTokens2 // w h colorP1 currP nbTokens1 nbTokens2
// 3. Read the next h lines to get the board // 3. Read the next h lines to get the board
// 4. Close the file // 4. Close the file
// 5. Initialize the board with the read values // 5. Initialize the board with the read values
@@ -138,9 +164,15 @@ public class GomokuGame {
for (int j = 0; j < w; ++j) { for (int j = 0; j < w; ++j) {
switch (line.charAt(j)) { switch (line.charAt(j)) {
case 'X': colors[i][j] = Color.BLACK; break; case 'X':
case 'O': colors[i][j] = Color.WHITE; break; colors[i][j] = Color.BLACK;
case '.': colors[i][j] = Color.NIL; break; break;
case 'O':
colors[i][j] = Color.WHITE;
break;
case '.':
colors[i][j] = Color.NIL;
break;
default: default:
throw new IllegalArgumentException("Invalid color: " + line.charAt(j)); throw new IllegalArgumentException("Invalid color: " + line.charAt(j));
} }

View File

@@ -1,65 +1,74 @@
import java.io.Console; import java.io.Console;
public class Human extends Player{ public class Human extends Player {
// ------------------Constructors--------------------------
/** /**
* This class is an extends of the class Player, this allows the player to choose his move. * The constructor of the Human.
*
* @param name The name of the player.
* @param color The color of the player.
*/
public Human(String name, Color color) {
super(name, color);
}
/**
* This class is an extends of the class Player, this allows the player to
* choose his move.
*/ */
//------------------Methods-------------------------- // ------------------Methods--------------------------
/** /**
* Return the coordinate of the move played by the player. * Return the coordinate of the move played by the player.
* @param board The actual Gomoku board. *
* @return The cell of the move played. * @param board The actual Gomoku board.
*/ * @return The cell of the move played.
public GomokuCell chooseMove(GomokuBoard board){ */
@Override
public GomokuCell chooseMove(GomokuBoard board) {
Console cons = System.console(); Console cons = System.console();
int x=0,y=0; int x = 0, y = 0;
boolean pass = false; boolean pass = false;
do{ do {
do{ do {
try { try {
System.out.println("Veuillez saisir le X"); System.out.println("Veuillez saisir le X");
x = Integer.parseInt( cons.readLine()); x = Integer.parseInt(cons.readLine());
pass=true; pass = true;
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
System.out.println("Ce n'est pas un nombre !"); System.out.println("Ce n'est pas un nombre !");
pass=false; pass = false;
} }
} } while (!pass);
while(!pass);
do {
do{
try { try {
System.out.println("Veuillez saisir le Y"); System.out.println("Veuillez saisir le Y");
y = Integer.parseInt( cons.readLine()); y = Integer.parseInt(cons.readLine());
pass=true; pass = true;
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
System.out.println("Ce n'est pas un nombre !"); System.out.println("Ce n'est pas un nombre !");
pass=false; pass = false;
} }
} } while (!pass);
while(!pass);
pass = board.get(x, y).isPlayable();
pass =board.get(x,y).isPlayable(); if (!pass) {
if(!pass)
{
System.out.println("Cette case n'est pas jouable !"); System.out.println("Cette case n'est pas jouable !");
} }
} } while (!pass);
while(!pass);
System.out.println("Vous avez saisi : "+ x+", "+ y);
System.out.println("Vous avez saisi : " + x + ", " + y);
return board.get(x,y);
return board.get(x, y);
} }
} }

View File

@@ -21,7 +21,7 @@ abstract class Player{
* @param name The name of the player. * @param name The name of the player.
* @param color The color of the player. * @param color The color of the player.
*/ */
public void Player(String name,Color color){ public Player(String name,Color color){
this.name = name; this.name = name;
this.color = color; this.color = color;
} }