diff --git a/schach/src/main/java/de/hs_mannheim/informatik/chess/controller/Controller.java b/schach/src/main/java/de/hs_mannheim/informatik/chess/controller/Controller.java index b4287bc..87e3886 100644 --- a/schach/src/main/java/de/hs_mannheim/informatik/chess/controller/Controller.java +++ b/schach/src/main/java/de/hs_mannheim/informatik/chess/controller/Controller.java @@ -46,6 +46,30 @@ public class Controller { } } + // Erster Zug + gui.getBtnFirst().addActionListener(e -> { + engine.setPositionToMoveIndex(0); + updateGuiBoard(); + }); + // Ein Zug zurück + gui.getBtnPrev().addActionListener(e -> { + int idx = Math.max(0, engine.getCurrentMoveIndex() - 1); + engine.setPositionToMoveIndex(idx); + updateGuiBoard(); + }); + // Ein Zug vor + gui.getBtnNext().addActionListener(e -> { + int idx = Math.min(engine.getMoveListSize(), engine.getCurrentMoveIndex() + 1); + engine.setPositionToMoveIndex(idx); + updateGuiBoard(); + }); + // Letzter Zug + gui.getBtnLast().addActionListener(e -> { + engine.setPositionToMoveIndex(engine.getMoveListSize()); + updateGuiBoard(); + }); + + gui.getFlipBoardButton().addActionListener(e -> { //ALLE Highlights und Borders zurücksetzen for (int row = 0; row < 8; row++) { @@ -134,7 +158,7 @@ public class Controller { public void updateGuiBoard() { BoardDTO board = engine.getBoardAsDTO(); - gui.updateBoard(board); // Passe die GUI an + gui.updateBoard(board); } // Hilfsmethode, um von Koordinaten (row/col) auf z.B. "E2" zu kommen @@ -145,7 +169,6 @@ public class Controller { } - // ... resetFieldBackground wie gehabt ... private void resetFieldBackground(int row, int col) { if ((row + col) % 2 == 0) { gui.getField(row, col).setBackground(new Color(0x778da9)); diff --git a/schach/src/main/java/de/hs_mannheim/informatik/chess/model/ChessEngine.java b/schach/src/main/java/de/hs_mannheim/informatik/chess/model/ChessEngine.java index 574f85d..8f0141c 100644 --- a/schach/src/main/java/de/hs_mannheim/informatik/chess/model/ChessEngine.java +++ b/schach/src/main/java/de/hs_mannheim/informatik/chess/model/ChessEngine.java @@ -1,6 +1,11 @@ package de.hs_mannheim.informatik.chess.model; import java.util.ArrayList; import java.util.List; +import java.util.logging.ConsoleHandler; +import java.util.logging.Level; +import java.util.logging.LogRecord; +import java.util.logging.Logger; +import java.util.logging.SimpleFormatter; import com.github.bhlangonijr.chesslib.Board; import com.github.bhlangonijr.chesslib.Piece; @@ -10,8 +15,12 @@ import com.github.bhlangonijr.chesslib.move.Move; public class ChessEngine { private Board board; private List moves = new ArrayList<>(); + private static final Logger logger = Logger.getLogger(ChessEngine.class.getName()); + + private int currentMoveIndex = 0; public ChessEngine() { + logging(); board = new Board(); } @@ -21,28 +30,44 @@ public class ChessEngine { Move libMove = new Move(Square.valueOf(from), Square.valueOf(to)); if (board.legalMoves().contains(libMove)) { board.doMove(libMove); - moves.add(libMove); // <-- hier merken! + + //Replay? Dann abschneiden + if (currentMoveIndex < moves.size()) { + logger.info("Replay-Modus: Züge nach " + currentMoveIndex + " werden entfernt."); + moves = new ArrayList<>(moves.subList(0, currentMoveIndex)); + } + moves.add(libMove); + currentMoveIndex++; + logger.info("Zug erfolgreich durchgeführt: " + libMove); return true; } + logger.warning("Ungültiger Zug: " + libMove); return false; } public List getLegalDestinations(String from) { + logger.info("Hole legale Züge von: " + from); List destinations = new ArrayList<>(); - Square fromSq = Square.valueOf(from.toUpperCase()); - for (Move move : board.legalMoves()) { - if (move.getFrom().equals(fromSq)) { - int fromRow = 8 - fromSq.getRank().ordinal() - 1; - int fromCol = fromSq.getFile().ordinal(); - int toRow = 8 - move.getTo().getRank().ordinal() - 1; - int toCol = move.getTo().getFile().ordinal();; - destinations.add(new MoveDTO(fromRow, fromCol, toRow, toCol)); + try { + Square fromSq = Square.valueOf(from.toUpperCase()); + for (Move move : board.legalMoves()) { + if (move.getFrom().equals(fromSq)) { + int fromRow = 8 - fromSq.getRank().ordinal() - 1; + int fromCol = fromSq.getFile().ordinal(); + int toRow = 8 - move.getTo().getRank().ordinal() - 1; + int toCol = move.getTo().getFile().ordinal(); + destinations.add(new MoveDTO(fromRow, fromCol, toRow, toCol)); + } } + logger.info("Es wurden " + destinations.size() + " Ziele gefunden."); + } catch (Exception e) { + logger.severe("Fehler beim Holen der legalen Ziele: " + e.getMessage()); } return destinations; } public List getMoveListStringsGrouped() { + logger.info("Gruppiere Züge für Anzeige."); List result = new ArrayList<>(); StringBuilder sb = new StringBuilder(); for (int i = 0; i < moves.size(); i++) { @@ -57,11 +82,13 @@ public class ChessEngine { } public PieceDTO getPieceAt(String square) { + logger.info("Hole Figur an Feld: " + square); Piece piece = board.getPiece(Square.valueOf(square.toUpperCase())); return convertPieceToDTO(piece); } public BoardDTO getBoardAsDTO() { + logger.info("Erstelle DTO-Abbild des Boards"); PieceDTO[][] dtoBoard = new PieceDTO[8][8]; for (int rank = 8; rank >= 1; rank--) { for (int file = 0; file < 8; file++) { @@ -91,6 +118,26 @@ public class ChessEngine { } } + public void setPositionToMoveIndex(int idx) { + // Neues Board erzeugen + logger.info("Setze Board auf Zug-Index: " + idx); + board = new Board(); + for (int i = 0; i < idx; i++) { + board.doMove(moves.get(i)); + } + currentMoveIndex = idx; + } + + public int getCurrentMoveIndex() { + logger.info("Hole aktuellen Zug-Index: " + currentMoveIndex); + return currentMoveIndex; + } + + public int getMoveListSize() { + logger.info("Hole Anzahl gespielter Züge: " + moves.size()); + return moves.size(); + } + private PieceDTO convertPieceToDTO(Piece piece) { if (piece == null || piece.equals(Piece.NONE)) return null; String color = piece.name().startsWith("WHITE") ? "WHITE" : "BLACK"; @@ -100,19 +147,44 @@ public class ChessEngine { } public boolean isMated() { - return board.isMated(); + boolean mated = board.isMated(); + logger.info("isMated() = " + mated); + return mated; } public boolean isStalemate() { - return board.isStaleMate(); + boolean stale = board.isStaleMate(); + logger.info("isStalemate() = " + stale); + return stale; } public boolean isDraw() { - return board.isDraw(); + boolean draw = board.isDraw(); + logger.info("isDraw() = " + draw); + return draw; } public String getCurrentPlayer() { - return board.getSideToMove().toString(); // "WHITE" oder "BLACK" + String player = board.getSideToMove().toString(); + logger.info("Am Zug: " + player); + return player; + } + + public void logging() { + + // Eigener Handler nur für diese Klasse + ConsoleHandler handler = new ConsoleHandler(); + handler.setLevel(Level.ALL); + handler.setFormatter(new SimpleFormatter() { + @Override + public synchronized String format(LogRecord lr) { + return String.format("[%s] %s%n%n", lr.getLevel().getLocalizedName(), lr.getMessage()); + } + }); + logger.setUseParentHandlers(false); + logger.addHandler(handler); + + logger.info("ChessEngine wurde initialisiert."); } public void setPositionFromFEN(String fen) { diff --git a/schach/src/main/java/de/hs_mannheim/informatik/chess/view/GameGui.java b/schach/src/main/java/de/hs_mannheim/informatik/chess/view/GameGui.java index 1abb531..76f4b97 100644 --- a/schach/src/main/java/de/hs_mannheim/informatik/chess/view/GameGui.java +++ b/schach/src/main/java/de/hs_mannheim/informatik/chess/view/GameGui.java @@ -28,6 +28,11 @@ public class GameGui { private JButton flipBoardButton; private boolean isFlipped = false; + JButton btnFirst = new JButton("|<"); + JButton btnPrev = new JButton("<"); + JButton btnNext = new JButton(">"); + JButton btnLast = new JButton(">|"); + private JPanel moveListPanel; private JScrollPane moveListScroll; @@ -166,10 +171,7 @@ public class GameGui { buttonPanel.setBackground(new Color(0x0d1b2a)); // Grid oder Flow – je nach Geschmack buttonPanel.setLayout(new GridLayout(1, 4, 10, 0)); - JButton btnFirst = new JButton("|<"); - JButton btnPrev = new JButton("<"); - JButton btnNext = new JButton(">"); - JButton btnLast = new JButton(">|"); + // Style (optional) btnFirst.setBackground(new Color(0x212529)); btnFirst.setForeground(Color.WHITE); btnPrev.setBackground(new Color(0x212529)); btnPrev.setForeground(Color.WHITE); @@ -217,6 +219,11 @@ public class GameGui { this.isFlipped = flipped; } + public JButton getBtnFirst() { return btnFirst; } + public JButton getBtnPrev() { return btnPrev; } + public JButton getBtnNext() { return btnNext; } + public JButton getBtnLast() { return btnLast; } + public void updateBoard(BoardDTO boardDTO) { PieceDTO[][] board = boardDTO.getBoard(); if (!isFlipped) { diff --git a/schach/src/main/java/de/hs_mannheim/informatik/chess/view/MainGui.java b/schach/src/main/java/de/hs_mannheim/informatik/chess/view/MainGui.java index 2995c80..f770a47 100644 --- a/schach/src/main/java/de/hs_mannheim/informatik/chess/view/MainGui.java +++ b/schach/src/main/java/de/hs_mannheim/informatik/chess/view/MainGui.java @@ -42,10 +42,14 @@ public class MainGui { JButton btnMode1 = new JButton("Normal Mode"); JButton btnMode2 = new JButton("Mode 2 (coming soon)"); JButton btnMode3 = new JButton("Mode 3 (coming soon)"); + JButton btnCreative = new JButton("Creative Mode"); + JButton btnLoadGame = new JButton("Load Game (PGN)"); styleButton(btnMode1); styleButton(btnMode2); styleButton(btnMode3); + styleButton(btnCreative); + styleButton(btnLoadGame); gbc.gridy = 2; gbc.ipady = 25; mainPanel.add(btnMode1, gbc); @@ -55,6 +59,12 @@ public class MainGui { gbc.gridy = 4; mainPanel.add(btnMode3, gbc); + + gbc.gridy = 5; + mainPanel.add(btnCreative, gbc); + + gbc.gridy = 6; + mainPanel.add(btnLoadGame, gbc); frame.add(mainPanel); frame.setVisible(true);