import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.util.Random; public class GomokuGame { 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_TOKENS_COUNT = 60; // nb de jetons private Player player1; private Player player2; private GomokuBoard board; private GomokuRenderer renderer; Color colorP1; int currP; int nbTokens1, nbTokens2; public static void main(String[] args) { // Test GomokuGame g = new GomokuGame(); System.out.println(g.load(Path.of(".cache/test.dat"))); g.renderer = new ConsoleRenderer(); g.renderer.init(g); g.renderer.update(); g.board.expandBoard(Cardinal.SE); g.renderer.update(); } 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; } public void startGame() { } /** * Place the token on the cell where the player play. * @param Player get player to play the cell. */ public GomokuCell play(Player player) { GomokuCell cellToPlay = player.chooseMove(board); cellToPlay.setState(player.color); return cellToPlay; } public boolean save(Path filename) { // save the game state to the file // 1. Open the file // 2. Write the first line with: // w h colorP1 currP nbTokens1 nbTokens2 // 3. Write the next h lines with the board // 4. Close the file // 5. Return true if successful, false otherwise // if filename is null, save to default file in ".cache/save.dat" if (filename == null) { filename = Path.of(".cache/save.dat"); } try (BufferedWriter writer = Files.newBufferedWriter(filename)) { // Write the first line writer.write(String.format("%d %d %s %d %d %d%n", this.getBoard().getWidth(), this.getBoard().getHeight(), colorP1, currP, nbTokens1, nbTokens2 )); // Write the board for (int i = 0; i < this.getBoard().getHeight(); ++i) { for (int j = 0; j < this.getBoard().getWidth(); ++j) { char c = ' '; switch (board.get(i, j).getState()) { case BLACK: c = 'X'; break; case WHITE: 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.newLine(); } } catch (IOException e) { System.err.println("Error writing file: " + e.getMessage()); return false; } catch (Exception e) { System.err.println("Unexpected error: " + e.getMessage()); return false; } return true; } public boolean load(Path filename) { // load the game state from the file // 1. Open the file // 2. Read the first line to get: // w h colorP1 currP nbTokens1 nbTokens2 // 3. Read the next h lines to get the board // 4. Close the file // 5. Initialize the board with the read values int w, h; Color[][] colors; try (BufferedReader reader = Files.newBufferedReader(filename)) { String line = reader.readLine(); if (line == null) { throw new IOException("Empty save file"); } String[] parts = line.split(" "); if (parts.length != 6) { throw new IOException("Invalid save file format"); } w = Integer.parseInt(parts[0]); h = Integer.parseInt(parts[1]); colorP1 = Color.valueOf(parts[2]); currP = Integer.parseInt(parts[3]); nbTokens1 = Integer.parseInt(parts[4]); nbTokens2 = Integer.parseInt(parts[5]); if (w <= 0 || h <= 0) { throw new IllegalArgumentException("Invalid board dimensions"); } colors = new Color[h][w]; for (int i = 0; i < h; ++i) { line = reader.readLine(); if (line == null) { throw new IOException("Unexpected end of file"); } if (line.length() != w) { throw new IOException("Invalid board line format"); } for (int j = 0; j < w; ++j) { switch (line.charAt(j)) { case 'X': colors[i][j] = Color.BLACK; break; case 'O': colors[i][j] = Color.WHITE; break; case '.': colors[i][j] = Color.NIL; break; default: throw new IllegalArgumentException("Invalid color: " + line.charAt(j)); } } } } catch (IOException e) { System.err.println("Error reading file: " + e.getMessage()); return false; } catch (NumberFormatException e) { System.err.println("Invalid number format: " + e.getMessage()); return false; } catch (IllegalArgumentException e) { System.err.println("Invalid color format: " + e.getMessage()); return false; } catch (Exception e) { System.err.println("Unexpected error: " + e.getMessage()); return false; } // Initialize the board with the read values this.board = new GomokuBoard(w, h, colors); return true; } public GomokuBoard getBoard() { return this.board; } }