From a256cbfdc9269f1bf1fa110b19375754c70e2dc5 Mon Sep 17 00:00:00 2001 From: Yash Shah Date: Wed, 21 May 2025 22:01:32 +0200 Subject: [PATCH] Save game --- src/backend/Board.java | 52 +++++++++++- src/backend/Game.java | 180 ++++++++++++++++++++--------------------- src/backend/Piece.java | 24 ++++++ 3 files changed, 162 insertions(+), 94 deletions(-) diff --git a/src/backend/Board.java b/src/backend/Board.java index bb2a29a..1a8fd1d 100644 --- a/src/backend/Board.java +++ b/src/backend/Board.java @@ -2,6 +2,7 @@ package backend; import java.util.ArrayList; +import java.util.List; public class Board { private int width; @@ -418,15 +419,60 @@ public class Board { /* saving-loading feature :*/ + // in Board.java + + /** + * @return each line representing one piece, plus a header: + * Line 0: width,height,turnNumber,turnWhite,enPassantX,enPassantY + * Lines 1–N: serialized Pieces + */ public String[] toFileRep() { - return null; + List lines = new ArrayList<>(); + + int epX = enPassantTarget == null ? -1 : enPassantTarget[0]; + int epY = enPassantTarget == null ? -1 : enPassantTarget[1]; + // header + lines.add(width + "," + + height + "," + + turnNumber + "," + + turnWhite + "," + + epX + "," + epY); + + // pieces + for (Piece p : pieces) { + lines.add(p.toFileRep()); + } + + return lines.toArray(new String[0]); } + + // in Board.java + public Board(String[] array) { - this.pieces = new ArrayList<>(); - //TODO + this.pieces = new ArrayList<>(); + // parse header + String[] hdr = array[0].split(","); + this.width = Integer.parseInt(hdr[0]); + this.height = Integer.parseInt(hdr[1]); + this.turnNumber = Integer.parseInt(hdr[2]); + this.turnWhite = Boolean.parseBoolean(hdr[3]); + int epX = Integer.parseInt(hdr[4]); + int epY = Integer.parseInt(hdr[5]); + this.enPassantTarget = (epX >= 0 && epY >= 0) ? new int[]{epX, epY} : null; + // parse pieces + for (int i = 1; i < array.length; i++) { + Piece p = Piece.fromFileRep(array[i]); + this.pieces.add(p); + } + + // clear other state + this.selected = null; + this.highlighted = new ArrayList<>(); + this.moveHistory = new ArrayList<>(); } + public Piece getPieceAt(int x, int y) { for (Piece piece : pieces) { diff --git a/src/backend/Game.java b/src/backend/Game.java index c6ae7ea..49ce7f5 100644 --- a/src/backend/Game.java +++ b/src/backend/Game.java @@ -1,115 +1,113 @@ package backend; import windowInterface.MyInterface; +import java.nio.file.Path; +import java.nio.file.Files; +import java.nio.charset.StandardCharsets; +import java.io.IOException; +import java.util.Arrays; +import java.util.List; public class Game extends Thread { + private AutoPlayer aiPlayer; + private Board board; + private MyInterface mjf; + private int COL_NUM = 8; + private int LINE_NUM = 8; + private int loopDelay = 250; + private boolean[] activationAIFlags; - private AutoPlayer aiPlayer; - private Board board; + public Game(MyInterface mjfParam) { + mjf = mjfParam; + board = new Board(COL_NUM, LINE_NUM); + activationAIFlags = new boolean[2]; + aiPlayer = new AutoPlayer(); + } - private MyInterface mjf; - private int COL_NUM = 8; - private int LINE_NUM = 8; - private int loopDelay = 250; - boolean[] activationAIFlags; + // ─── Save & load ─────────────────────────────────────────────────────── + public void saveToFile(Path path) throws IOException { + String[] lines = board.toFileRep(); + Files.write(path, Arrays.asList(lines), StandardCharsets.UTF_8); + } - public Game(MyInterface mjfParam) { - mjf = mjfParam; - board = new Board(COL_NUM, LINE_NUM); - loopDelay = 250; - LINE_NUM = 8; - COL_NUM = 8; - activationAIFlags = new boolean[2]; - aiPlayer = new AutoPlayer(); - } + public void loadFromFile(Path path) throws IOException { + List lines = Files.readAllLines(path, StandardCharsets.UTF_8); + board = new Board(lines.toArray(new String[0])); + // refresh UI for the new board state: + mjf.update(board.getTurnNumber(), board.isTurnWhite()); + } + // ─────────────────────────────────────────────────────────────────────── - public int getWidth() { - return board.getWidth(); - } + public int getWidth() { return board.getWidth(); } + public int getHeight() { return board.getHeight(); } - public int getHeight() { - return board.getHeight(); - } + @Override + public void run() { + while(true) { + aiPlayerTurn(); + mjf.update(board.getTurnNumber(), board.isTurnWhite()); + try { Thread.sleep(loopDelay); } + catch (InterruptedException e) { e.printStackTrace(); } + } + } - public void run() { - while(true) { - aiPlayerTurn(); - mjf.update(board.getTurnNumber(), board.isTurnWhite()); - try { - Thread.sleep(loopDelay); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - } - - private boolean isAITurn() { - return activationAIFlags[board.isTurnWhite()?1:0]; - } + private boolean isAITurn() { + return activationAIFlags[board.isTurnWhite() ? 1 : 0]; + } - private void aiPlayerTurn() { - if (isAITurn()) { - Move bestMove = aiPlayer.getBestMoveUsingNegamax(board, 2); // Change depth as needed - if (bestMove != null) { - board.playMove(bestMove); - } - } - } + private void aiPlayerTurn() { + if (isAITurn()) { + Move bestMove = aiPlayer.getBestMoveUsingNegamax(board, 2); + if (bestMove != null) board.playMove(bestMove); + } + } - public void clickCoords(int x, int y) { - int width = this.getWidth(); - int height = this.getHeight(); - if(0>x || 0>y || x>width || y>height) { - System.out.println("Click out of bounds"); - return; - } - if(!isAITurn()) { - board.userTouch(x, y); - } - - } + public void clickCoords(int x, int y) { + if (x < 0 || y < 0 || x >= getWidth() || y >= getHeight()) { + System.out.println("Click out of bounds"); + return; + } + if (!isAITurn()) board.userTouch(x, y); + } - public void setPiece(boolean isWhite, PieceType type, int x, int y) { - board.setPiece(isWhite, type, x, y); - } + public void setPiece(boolean isWhite, PieceType type, int x, int y) { + board.setPiece(isWhite, type, x, y); + } - public String[] getFileRepresentation() { - return board.toFileRep(); - } + public String[] getFileRepresentation() { + return board.toFileRep(); + } - public void setLoopDelay(int delay) { - this.loopDelay = delay; - } + public void setLoopDelay(int delay) { + this.loopDelay = delay; + } - public void setDefaultSetup() { - board.cleanBoard(); - board.populateBoard(); - } + public void setDefaultSetup() { + board.cleanBoard(); + board.populateBoard(); + } - public void setBoard(String[] array) { - board = new Board(array); - } + public void setBoard(String[] array) { + board = new Board(array); + } - public Iterable getPieces() { - return board.getPieces(); - } + public Iterable getPieces() { + return board.getPieces(); + } - public boolean isSelected(int x, int y) { - return board.isSelected(x, y); - } + public boolean isSelected(int x, int y) { + return board.isSelected(x, y); + } - public boolean isHighlighted(int x, int y) { - return board.isHighlighted(x, y); - } + public boolean isHighlighted(int x, int y) { + return board.isHighlighted(x, y); + } - public void undoLastMove() { - board.undoLastMove(); - } - - public void toggleAI(boolean isWhite) { - this.activationAIFlags[isWhite?1:0] = !this.activationAIFlags[isWhite?1:0]; - } - - + public void undoLastMove() { + board.undoLastMove(); + } + public void toggleAI(boolean isWhite) { + activationAIFlags[isWhite ? 1 : 0] = !activationAIFlags[isWhite ? 1 : 0]; + } } diff --git a/src/backend/Piece.java b/src/backend/Piece.java index 8090bc3..7aeb61f 100644 --- a/src/backend/Piece.java +++ b/src/backend/Piece.java @@ -59,5 +59,29 @@ public class Piece { this.hasMoved = moved; } + // in Piece.java + + /** e.g. "true,Pawn,4,1,false" */ + public String toFileRep() { + return isWhite() + "," + + getType().name() + "," + + getX() + "," + + getY() + "," + + hasMoved(); + } + + /** parse the same format */ + public static Piece fromFileRep(String line) { + String[] parts = line.split(","); + boolean white = Boolean.parseBoolean(parts[0]); + PieceType type = PieceType.valueOf(parts[1]); + int x = Integer.parseInt(parts[2]); + int y = Integer.parseInt(parts[3]); + boolean moved = Boolean.parseBoolean(parts[4]); + Piece p = new Piece(white, type, x, y); + p.setHasMoved(moved); + return p; + } + }