Merge branch 'Main' into JUnit-Tests

GitBranch
Justin 2025-06-22 15:26:18 +02:00
commit d23f7097f7
4 changed files with 131 additions and 19 deletions

View File

@ -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 -> { gui.getFlipBoardButton().addActionListener(e -> {
//ALLE Highlights und Borders zurücksetzen //ALLE Highlights und Borders zurücksetzen
for (int row = 0; row < 8; row++) { for (int row = 0; row < 8; row++) {
@ -134,7 +158,7 @@ public class Controller {
public void updateGuiBoard() { public void updateGuiBoard() {
BoardDTO board = engine.getBoardAsDTO(); 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 // 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) { private void resetFieldBackground(int row, int col) {
if ((row + col) % 2 == 0) { if ((row + col) % 2 == 0) {
gui.getField(row, col).setBackground(new Color(0x778da9)); gui.getField(row, col).setBackground(new Color(0x778da9));

View File

@ -1,6 +1,11 @@
package de.hs_mannheim.informatik.chess.model; package de.hs_mannheim.informatik.chess.model;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; 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.Board;
import com.github.bhlangonijr.chesslib.Piece; import com.github.bhlangonijr.chesslib.Piece;
@ -10,8 +15,12 @@ import com.github.bhlangonijr.chesslib.move.Move;
public class ChessEngine { public class ChessEngine {
private Board board; private Board board;
private List<Move> moves = new ArrayList<>(); private List<Move> moves = new ArrayList<>();
private static final Logger logger = Logger.getLogger(ChessEngine.class.getName());
private int currentMoveIndex = 0;
public ChessEngine() { public ChessEngine() {
logging();
board = new Board(); board = new Board();
} }
@ -21,28 +30,44 @@ public class ChessEngine {
Move libMove = new Move(Square.valueOf(from), Square.valueOf(to)); Move libMove = new Move(Square.valueOf(from), Square.valueOf(to));
if (board.legalMoves().contains(libMove)) { if (board.legalMoves().contains(libMove)) {
board.doMove(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; return true;
} }
logger.warning("Ungültiger Zug: " + libMove);
return false; return false;
} }
public List<MoveDTO> getLegalDestinations(String from) { public List<MoveDTO> getLegalDestinations(String from) {
logger.info("Hole legale Züge von: " + from);
List<MoveDTO> destinations = new ArrayList<>(); List<MoveDTO> destinations = new ArrayList<>();
Square fromSq = Square.valueOf(from.toUpperCase()); try {
for (Move move : board.legalMoves()) { Square fromSq = Square.valueOf(from.toUpperCase());
if (move.getFrom().equals(fromSq)) { for (Move move : board.legalMoves()) {
int fromRow = 8 - fromSq.getRank().ordinal() - 1; if (move.getFrom().equals(fromSq)) {
int fromCol = fromSq.getFile().ordinal(); int fromRow = 8 - fromSq.getRank().ordinal() - 1;
int toRow = 8 - move.getTo().getRank().ordinal() - 1; int fromCol = fromSq.getFile().ordinal();
int toCol = move.getTo().getFile().ordinal();; int toRow = 8 - move.getTo().getRank().ordinal() - 1;
destinations.add(new MoveDTO(fromRow, fromCol, toRow, toCol)); 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; return destinations;
} }
public List<String> getMoveListStringsGrouped() { public List<String> getMoveListStringsGrouped() {
logger.info("Gruppiere Züge für Anzeige.");
List<String> result = new ArrayList<>(); List<String> result = new ArrayList<>();
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
for (int i = 0; i < moves.size(); i++) { for (int i = 0; i < moves.size(); i++) {
@ -57,11 +82,13 @@ public class ChessEngine {
} }
public PieceDTO getPieceAt(String square) { public PieceDTO getPieceAt(String square) {
logger.info("Hole Figur an Feld: " + square);
Piece piece = board.getPiece(Square.valueOf(square.toUpperCase())); Piece piece = board.getPiece(Square.valueOf(square.toUpperCase()));
return convertPieceToDTO(piece); return convertPieceToDTO(piece);
} }
public BoardDTO getBoardAsDTO() { public BoardDTO getBoardAsDTO() {
logger.info("Erstelle DTO-Abbild des Boards");
PieceDTO[][] dtoBoard = new PieceDTO[8][8]; PieceDTO[][] dtoBoard = new PieceDTO[8][8];
for (int rank = 8; rank >= 1; rank--) { for (int rank = 8; rank >= 1; rank--) {
for (int file = 0; file < 8; file++) { 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) { private PieceDTO convertPieceToDTO(Piece piece) {
if (piece == null || piece.equals(Piece.NONE)) return null; if (piece == null || piece.equals(Piece.NONE)) return null;
String color = piece.name().startsWith("WHITE") ? "WHITE" : "BLACK"; String color = piece.name().startsWith("WHITE") ? "WHITE" : "BLACK";
@ -100,19 +147,44 @@ public class ChessEngine {
} }
public boolean isMated() { public boolean isMated() {
return board.isMated(); boolean mated = board.isMated();
logger.info("isMated() = " + mated);
return mated;
} }
public boolean isStalemate() { public boolean isStalemate() {
return board.isStaleMate(); boolean stale = board.isStaleMate();
logger.info("isStalemate() = " + stale);
return stale;
} }
public boolean isDraw() { public boolean isDraw() {
return board.isDraw(); boolean draw = board.isDraw();
logger.info("isDraw() = " + draw);
return draw;
} }
public String getCurrentPlayer() { 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) { public void setPositionFromFEN(String fen) {

View File

@ -28,6 +28,11 @@ public class GameGui {
private JButton flipBoardButton; private JButton flipBoardButton;
private boolean isFlipped = false; private boolean isFlipped = false;
JButton btnFirst = new JButton("|<");
JButton btnPrev = new JButton("<");
JButton btnNext = new JButton(">");
JButton btnLast = new JButton(">|");
private JPanel moveListPanel; private JPanel moveListPanel;
private JScrollPane moveListScroll; private JScrollPane moveListScroll;
@ -166,10 +171,7 @@ public class GameGui {
buttonPanel.setBackground(new Color(0x0d1b2a)); buttonPanel.setBackground(new Color(0x0d1b2a));
// Grid oder Flow je nach Geschmack // Grid oder Flow je nach Geschmack
buttonPanel.setLayout(new GridLayout(1, 4, 10, 0)); 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) // Style (optional)
btnFirst.setBackground(new Color(0x212529)); btnFirst.setForeground(Color.WHITE); btnFirst.setBackground(new Color(0x212529)); btnFirst.setForeground(Color.WHITE);
btnPrev.setBackground(new Color(0x212529)); btnPrev.setForeground(Color.WHITE); btnPrev.setBackground(new Color(0x212529)); btnPrev.setForeground(Color.WHITE);
@ -217,6 +219,11 @@ public class GameGui {
this.isFlipped = flipped; 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) { public void updateBoard(BoardDTO boardDTO) {
PieceDTO[][] board = boardDTO.getBoard(); PieceDTO[][] board = boardDTO.getBoard();
if (!isFlipped) { if (!isFlipped) {

View File

@ -42,10 +42,14 @@ public class MainGui {
JButton btnMode1 = new JButton("Normal Mode"); JButton btnMode1 = new JButton("Normal Mode");
JButton btnMode2 = new JButton("Mode 2 (coming soon)"); JButton btnMode2 = new JButton("Mode 2 (coming soon)");
JButton btnMode3 = new JButton("Mode 3 (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(btnMode1);
styleButton(btnMode2); styleButton(btnMode2);
styleButton(btnMode3); styleButton(btnMode3);
styleButton(btnCreative);
styleButton(btnLoadGame);
gbc.gridy = 2; gbc.ipady = 25; gbc.gridy = 2; gbc.ipady = 25;
mainPanel.add(btnMode1, gbc); mainPanel.add(btnMode1, gbc);
@ -56,6 +60,12 @@ public class MainGui {
gbc.gridy = 4; gbc.gridy = 4;
mainPanel.add(btnMode3, gbc); mainPanel.add(btnMode3, gbc);
gbc.gridy = 5;
mainPanel.add(btnCreative, gbc);
gbc.gridy = 6;
mainPanel.add(btnLoadGame, gbc);
frame.add(mainPanel); frame.add(mainPanel);
frame.setVisible(true); frame.setVisible(true);