diff --git a/schach/src/main/java/de/hs_mannheim/informatik/chess/controller/PgnController.java b/schach/src/main/java/de/hs_mannheim/informatik/chess/controller/PgnController.java index 76d7ad2..83baabd 100644 --- a/schach/src/main/java/de/hs_mannheim/informatik/chess/controller/PgnController.java +++ b/schach/src/main/java/de/hs_mannheim/informatik/chess/controller/PgnController.java @@ -1,5 +1,202 @@ package de.hs_mannheim.informatik.chess.controller; +import java.awt.Color; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.ArrayList; +import java.util.List; + +import javax.swing.BorderFactory; + +import de.hs_mannheim.informatik.chess.model.ChessEngine; +import de.hs_mannheim.informatik.chess.model.MoveDTO; +import de.hs_mannheim.informatik.chess.model.PieceDTO; +import de.hs_mannheim.informatik.chess.model.BoardDTO; +import de.hs_mannheim.informatik.chess.view.PgnGui; + public class PgnController { + PgnGui gui; + ChessEngine engine; + private int selectedRow = -1, selectedCol = -1; + private List highlightedFields = new ArrayList<>(); + + public PgnController(PgnGui pgngui, ChessEngine engine) { + this.gui = pgngui; + this.engine = engine; + initListeners(); + updateGuiBoard(); + } + + private int flipRow(int row) { + return gui.isFlipped() ? 7 - row : row; + } + private int flipCol(int col) { + return gui.isFlipped() ? 7 - col : col; + } + + private void initListeners() { + for (int row = 0; row < 8; row++) { + for (int col = 0; col < 8; col++) { + final int r = row, c = col; + gui.getField(row, col).addMouseListener(new MouseAdapter() { + public void mousePressed(MouseEvent e) { + handleClick(r, c); + } + }); + } + } + + // 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++) { + for (int col = 0; col < 8; col++) { + resetFieldBackground(row, col); + gui.getField(row, col).setBorder(null); + } + } + highlightedFields.clear(); + selectedRow = -1; + selectedCol = -1; + + // 2. Flip-Zustand ändern + gui.setFlipped(!gui.isFlipped()); + + // 3. Board neu zeichnen + updateGuiBoard(); + }); + + + } + + private void handleClick(int guiRow, int guiCol) { + int modelRow = flipRow(guiRow); + int modelCol = flipCol(guiCol); + + //Figur am Feld + BoardDTO boardDTO = engine.getBoardAsDTO(); + PieceDTO piece = boardDTO.getBoard()[modelRow][modelCol]; + + //Ist eine Figur da und hat sie die aktuelle Farbe + String amZug = engine.getCurrentPlayer(); // "WHITE" oder "BLACK" + if (selectedRow == -1 && selectedCol == -1) { + if (piece == null || !piece.getColor().equals(amZug)) { + // Falsche Farbe oder leeres Feld -> abbrechen, keine Highlights! + return; + } + + selectedRow = modelRow; + selectedCol = modelCol; + gui.getField(guiRow, guiCol).setBorder(BorderFactory.createLineBorder(new Color(0x1b263b), 7)); + + String fromSquare = coordToChessNotation(modelRow, modelCol); + List moves = engine.getLegalDestinations(fromSquare); + + for (MoveDTO move : moves) { + int guiToRow = gui.isFlipped() ? 7 - move.getToRow() : move.getToRow(); + int guiToCol = gui.isFlipped() ? 7 - move.getToCol() : move.getToCol(); + gui.getField(guiToRow, guiToCol).setBackground(new Color( 27, 38, 59 )); + highlightedFields.add(new int[]{guiToRow, guiToCol}); + } + } else { + for (int[] xy : highlightedFields) { + resetFieldBackground(xy[0], xy[1]); + } + highlightedFields.clear(); + int oldGuiRow = gui.isFlipped() ? 7 - selectedRow : selectedRow; + int oldGuiCol = gui.isFlipped() ? 7 - selectedCol : selectedCol; + gui.getField(oldGuiRow, oldGuiCol).setBorder(null); + + MoveDTO move = new MoveDTO(selectedRow, selectedCol, modelRow, modelCol); + handleMove(move); + selectedRow = -1; + selectedCol = -1; + } + } + + private void handleMove(MoveDTO move) { + BoardDTO boardDTO = engine.getBoardAsDTO(); + PieceDTO piece = boardDTO.getBoard()[move.getFromRow()][move.getFromCol()]; + boolean isPawn = piece != null && piece.getType().equals("PAWN"); + boolean isWhitePromotion = isPawn && piece.getColor().equals("WHITE") && move.getToRow() == 0; + boolean isBlackPromotion = isPawn && piece.getColor().equals("BLACK") && move.getToRow() == 7; + + boolean success = false; + + if (isWhitePromotion || isBlackPromotion) { + String color = piece.getColor().equals("WHITE") ? "Weiß" : "Schwarz"; + String promotion = gui.showPromotionDialog(color); + success = engine.moveWithPromotion(move, promotion); + if (!success) { + gui.displayMessage("Ungültiger Promotionszug!"); + return; + } + } else { + success = engine.move(move); + if (!success) { + gui.displayMessage("Ungültiger Zug!"); + return; + } + } + + updateGuiBoard(); + gui.updateMoveList(engine.getMoveListStringsGrouped()); + + // ---- HIER ist die Matt/Patt/Remis-Prüfung ---- + if (engine.isMated()) { + String winner = engine.getCurrentPlayer().equals("WHITE") ? "SCHWARZ" : "WEIß"; + gui.displayMessage(winner + " hat gewonnen (Schachmatt)!"); + } else if (engine.isStalemate() || engine.isDraw()) { + gui.displayMessage("Remis! (Stalemate oder andere Regel)"); + } + } + + + public void updateGuiBoard() { + BoardDTO board = engine.getBoardAsDTO(); + gui.updateBoard(board); + } + + // Hilfsmethode, um von Koordinaten (row/col) auf z.B. "E2" zu kommen + private String coordToChessNotation(int modelRow, int modelCol) { + char file = (char)('A' + modelCol); + int rank = 8 - modelRow; + return "" + file + rank; + } + + + private void resetFieldBackground(int row, int col) { + Color LIGHT = new Color(0xe0e1dd); + Color DARK = new Color(0x778da9); + if ((row + col) % 2 == 0) { + gui.getField(row, col).setBackground(LIGHT); + } else { + gui.getField(row, col).setBackground(DARK); + } + } } +