From 593b0e9fbe8ee3fc1493795ec492312097fed673 Mon Sep 17 00:00:00 2001 From: Matias <3020772@tud.hs-mannheim.de> Date: Fri, 20 Jun 2025 11:43:42 +0200 Subject: [PATCH 01/12] =?UTF-8?q?Clock=20in=20SpielFrame=20erg=C3=A4nzt=20?= =?UTF-8?q?und=20ModeSelection=20integriert?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../de/mannheim/th/chess/domain/Game.java | 252 +++++++++--------- .../de/mannheim/th/chess/ui/MainFrame.java | 7 +- .../th/chess/ui/ModeSelectionFrame.java | 107 ++++++++ .../de/mannheim/th/chess/ui/SpielFrame.java | 81 +++--- .../java/de/mannheim/th/chess/utl/Clock.java | 154 ++++++----- 5 files changed, 368 insertions(+), 233 deletions(-) create mode 100644 src/main/java/de/mannheim/th/chess/ui/ModeSelectionFrame.java diff --git a/src/main/java/de/mannheim/th/chess/domain/Game.java b/src/main/java/de/mannheim/th/chess/domain/Game.java index a375d29..4d1ada5 100644 --- a/src/main/java/de/mannheim/th/chess/domain/Game.java +++ b/src/main/java/de/mannheim/th/chess/domain/Game.java @@ -10,6 +10,7 @@ import com.github.bhlangonijr.chesslib.move.Move; import com.github.bhlangonijr.chesslib.move.MoveList; import com.github.bhlangonijr.chesslib.pgn.PgnHolder; +import de.mannheim.th.chess.ui.SpielFrame; import de.mannheim.th.chess.utl.Clock; /** @@ -18,142 +19,155 @@ import de.mannheim.th.chess.utl.Clock; */ public class Game { - private Board board; - private Clock clock; + private Board board; + private Clock clock; + private SpielFrame sp; + private String modus; + private boolean rotieren, zuruecknahme; - private MoveList movelist; + private MoveList movelist; - /** - * Conststructs a new standard GameBoard. - */ - public Game() { - this.board = new Board(); + /** + * Conststructs a new standard GameBoard. + */ + public Game(String modus, boolean rotieren, boolean zuruecknahme) { + this.modus = modus; + this.rotieren = rotieren; + this.zuruecknahme = zuruecknahme; + + + this.board = new Board(); - this.movelist = new MoveList(); + this.movelist = new MoveList(); + + clock = new Clock(modus); + + sp = new SpielFrame(this); - clock = new Clock("blitz"); - clock.start(); + - } + } - /** - * Constructs a new standard GameBoard and applies the provides moves. - * - * @param movelist The list of moves that get played. - */ - public Game(MoveList movelist) { - this.board = new Board(); + /** + * Constructs a new standard GameBoard and applies the provides moves. + * + * @param movelist The list of moves that get played. + */ + public Game(MoveList movelist) { + this.board = new Board(); - this.movelist = movelist; + this.movelist = movelist; - for (Move move : movelist) { - this.board.doMove(move); - } + for (Move move : movelist) { + this.board.doMove(move); + } - // this.clockPlayer1 = new Clock(); - // this.clockPlayer2 = new Clock(); - } + // this.clockPlayer1 = new Clock(); + // this.clockPlayer2 = new Clock(); + } - /** - * Constructs a new GameBoard with the provided fen String as the positions. - * - * @param fen The fen String that provides the customs formation. - */ - public Game(String fen) { - this.board = new Board(); - this.board.loadFromFen(fen); + /** + * Constructs a new GameBoard with the provided fen String as the positions. + * + * @param fen The fen String that provides the customs formation. + */ + public Game(String fen) { + this.board = new Board(); + this.board.loadFromFen(fen); - this.movelist = new MoveList(); + this.movelist = new MoveList(); + //this.sp = new SpielFrame(); - // this.clockPlayer1 = new Clock(); - // this.clockPlayer2 = new Clock(); - } + // this.clockPlayer1 = new Clock(); + // this.clockPlayer2 = new Clock(); + } - /** - * Plays the move on the board and adds it to the movelist - * - * @param move the move to be played - */ - public void playMove(Move move) { - this.board.doMove(move); - this.movelist.add(move); - clock.pressClock(); - } + /** + * Plays the move on the board and adds it to the movelist + * + * @param move the move to be played + */ + public void playMove(Move move) { + this.board.doMove(move); + this.movelist.add(move); + clock.pressClock(); + } - /** - * Plays the move on the board and adds it to the movelist - * - * @param origin The square from wich it moves from. - * @param desination The square where it will move to. - */ - public void playMove(Square origin, Square desination) { - Move move = new Move(origin, desination); - this.board.doMove(move); - this.movelist.add(move); - - } - - public boolean isMate() { - return board.isMated(); - } - - public boolean isDraw() { - return board.isDraw(); - } - - public int getActivePlayer() { - if (board.getSideToMove() == Side.WHITE) { - return 1; - } - return 2; - } + /** + * Plays the move on the board and adds it to the movelist + * + * @param origin The square from wich it moves from. + * @param desination The square where it will move to. + */ + public void playMove(Square origin, Square desination) { + Move move = new Move(origin, desination); + this.board.doMove(move); + this.movelist.add(move); - /** - * Retrieves a list of legal moves originating from the specified square. - * - * @param square The square from which to retrieve legal moves. - * - * @return A list of legal moves that originate from the specified square. - */ - public List getLegalMoves(Square square) { - return this.board.legalMoves().stream() - .filter(move -> move.getFrom() == square) - .collect(Collectors.toList()); + } - } - - public void stopClock() { - clock.endGame(); - } + public boolean isMate() { + return board.isMated(); + } - /** - * Retrieves a list of all legal moveable squares from the current board state. - * - * @return a List of Square objects representing all legal moveable squares. - */ - public List getAllLegalMoveableSquares() { - return this.board.legalMoves().stream() - .map(move -> move.getFrom()) - .distinct() - .collect(Collectors.toList()); - } + public boolean isDraw() { + return board.isDraw(); + } - /** - * Retrieves a list of legal moveable squares for a given square. - * - * @param square the Square from which to retrieve legal moveable squares - * @return a List of Square objects representing the legal moveable squares - * from the specified square. - */ - public List getLegalMoveableSquares(Square square) { - return this.board.legalMoves().stream() - .filter(move -> move.getFrom() == square) - .map(move -> move.getTo()) - .collect(Collectors.toList()); - } + public int getActivePlayer() { + if (board.getSideToMove() == Side.WHITE) { + return 1; + } + return 2; + } - public String toFEN() { - board.toString(); - return board.getFen(); - } + /** + * Retrieves a list of legal moves originating from the specified square. + * + * @param square The square from which to retrieve legal moves. + * + * @return A list of legal moves that originate from the specified square. + */ + public List getLegalMoves(Square square) { + return this.board.legalMoves().stream().filter(move -> move.getFrom() == square).collect(Collectors.toList()); + + } + + public void stopClock() { + clock.endGame(); + } + + /** + * Retrieves a list of all legal moveable squares from the current board state. + * + * @return a List of Square objects representing all legal moveable squares. + */ + public List getAllLegalMoveableSquares() { + return this.board.legalMoves().stream().map(move -> move.getFrom()).distinct().collect(Collectors.toList()); + } + + /** + * Retrieves a list of legal moveable squares for a given square. + * + * @param square the Square from which to retrieve legal moveable squares + * @return a List of Square objects representing the legal moveable squares from + * the specified square. + */ + public List getLegalMoveableSquares(Square square) { + return this.board.legalMoves().stream().filter(move -> move.getFrom() == square).map(move -> move.getTo()) + .collect(Collectors.toList()); + } + + public String toFEN() { + board.toString(); + return board.getFen(); + } + + public void setModus(String modus) { + this.modus = modus; + } + + public Clock getClock() { + return this.clock; + } } diff --git a/src/main/java/de/mannheim/th/chess/ui/MainFrame.java b/src/main/java/de/mannheim/th/chess/ui/MainFrame.java index fc5a437..940cadc 100644 --- a/src/main/java/de/mannheim/th/chess/ui/MainFrame.java +++ b/src/main/java/de/mannheim/th/chess/ui/MainFrame.java @@ -22,8 +22,6 @@ import java.awt.Color; public class MainFrame extends JFrame { - private ArrayList spiele = new ArrayList<>(); - private static final long serialVersionUID = 1L; private JPanel contentPane; @@ -76,8 +74,7 @@ public class MainFrame extends JFrame { @Override public void actionPerformed(ActionEvent e) { - SpielFrame sp = new SpielFrame(); - spiele.add(sp); + ModeSelectionFrame ms = new ModeSelectionFrame(); } @@ -115,7 +112,7 @@ public class MainFrame extends JFrame { contentPane.add(Box.createVerticalStrut(15)); - JButton btnNewButton_2 = new JButton("Spiel beenden"); + JButton btnNewButton_2 = new JButton("App beenden"); btnNewButton_2.setBackground(Color.LIGHT_GRAY); btnNewButton_2.setForeground(Color.BLACK); diff --git a/src/main/java/de/mannheim/th/chess/ui/ModeSelectionFrame.java b/src/main/java/de/mannheim/th/chess/ui/ModeSelectionFrame.java new file mode 100644 index 0000000..a83f4a7 --- /dev/null +++ b/src/main/java/de/mannheim/th/chess/ui/ModeSelectionFrame.java @@ -0,0 +1,107 @@ +package de.mannheim.th.chess.ui; + +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.ArrayList; +import javax.swing.*; +import javax.swing.border.EmptyBorder; + +import de.mannheim.th.chess.domain.Game; + +public class ModeSelectionFrame extends JFrame { + + private static final long serialVersionUID = 1L; + private final JPanel contentPane; + private final ArrayList spiele = new ArrayList<>(); + + public ModeSelectionFrame() { + // Frame-Eigenschaften + setTitle("Modusauswahl"); + setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + setBounds(100, 100, 500, 500); + setResizable(true); + setAlwaysOnTop(true); + + // Panel konfigurieren + contentPane = new JPanel(); + contentPane.setBackground(new Color(90, 90, 90)); + contentPane.setBorder(new EmptyBorder(20, 20, 20, 20)); + contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.Y_AXIS)); + setContentPane(contentPane); + + // Überschrift + JLabel jl = new JLabel("Welchen Modus wollen Sie spielen?"); + jl.setFont(new Font("Calibri", Font.BOLD, 20)); + jl.setForeground(Color.BLACK); + jl.setAlignmentX(Component.CENTER_ALIGNMENT); + contentPane.add(jl); + contentPane.add(Box.createVerticalStrut(15)); + + // Modusauswahl + String[] modi = {"Blitz", "Schnellschach", "Klassisch"}; + JComboBox jcb1 = new JComboBox<>(modi); + jcb1 .setMaximumSize(new Dimension(150, 30)); + jcb1 .setAlignmentX(Component.CENTER_ALIGNMENT); + contentPane.add(jcb1 ); + contentPane.add(Box.createVerticalStrut(15)); + + // Spielbrettdrehen + JLabel jl2 = new JLabel("Soll das Spielbrett nach jedem Zug gedreht werden?"); + jl2 .setFont(new Font("Calibri", Font.BOLD, 20)); + jl2 .setForeground(Color.BLACK); + jl2 .setAlignmentX(Component.CENTER_ALIGNMENT); + contentPane.add(jl2 ); + + JCheckBox jb1 = new JCheckBox(); + jb1.setOpaque(false); + jb1.setFocusPainted(false); + jb1.setForeground(Color.BLACK); + jb1 .setAlignmentX(Component.CENTER_ALIGNMENT); + jb1 .setMaximumSize(new Dimension(30, 30)); + contentPane.add(jb1 ); + contentPane.add(Box.createVerticalStrut(15)); + + // Zurücknahmeoption + JLabel jl3 = new JLabel("Sollen Zurücknahmen erlaubt sein?"); + jl3.setFont(new Font("Calibri", Font.BOLD, 20)); + jl3.setForeground(Color.BLACK); + jl3.setAlignmentX(Component.CENTER_ALIGNMENT); + contentPane.add(jl3); + + JCheckBox jb2 = new JCheckBox(); + jb2.setOpaque(false); + jb2.setFocusPainted(false); + jb2.setForeground(Color.BLACK); + jb2.setAlignmentX(Component.CENTER_ALIGNMENT); + jb2.setMaximumSize(new Dimension(30, 30)); + contentPane.add(jb2); + contentPane.add(Box.createVerticalStrut(25)); + + // Spiel starten Button + JButton btnNewButton = new JButton("Spiel starten"); + btnNewButton .setBackground(Color.LIGHT_GRAY); + btnNewButton .setForeground(Color.BLACK); + btnNewButton .setFont(new Font("Tahoma", Font.BOLD, 16)); + btnNewButton .setAlignmentX(Component.CENTER_ALIGNMENT); + contentPane.add(btnNewButton ); + + // Button-Listener + btnNewButton .addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + String modus = (String) jcb1.getSelectedItem(); + boolean rotieren = jb1.isSelected(); + boolean zuruecknahme = jb2.isSelected(); + + Game game = new Game(modus, rotieren, zuruecknahme); + + spiele.add(game); + + dispose(); + } + }); + + setVisible(true); + } +} diff --git a/src/main/java/de/mannheim/th/chess/ui/SpielFrame.java b/src/main/java/de/mannheim/th/chess/ui/SpielFrame.java index 6fc32d8..3d722e2 100644 --- a/src/main/java/de/mannheim/th/chess/ui/SpielFrame.java +++ b/src/main/java/de/mannheim/th/chess/ui/SpielFrame.java @@ -8,14 +8,16 @@ import com.github.bhlangonijr.chesslib.move.Move; import de.mannheim.th.chess.App; import de.mannheim.th.chess.domain.Game; +import de.mannheim.th.chess.utl.Clock; import de.mannheim.th.chess.controller.ButtonMovePieceListener; import de.mannheim.th.chess.controller.ButtonSelectPieceListener; import de.mannheim.th.chess.controller.ButtonToNormalListener; -import java.awt.EventQueue; import java.awt.Font; import javax.swing.BorderFactory; +import javax.swing.Box; +import javax.swing.BoxLayout; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JFrame; @@ -25,6 +27,7 @@ import javax.swing.JSplitPane; import java.awt.BorderLayout; import java.awt.Color; +import java.awt.Component; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -39,6 +42,7 @@ public class SpielFrame extends JFrame { private HashMap belegungen = new HashMap<>(); private JPanel panelLinks, panelRechts, contentPane; private Game game; + private Clock clock; private BoardMode mode; private Square selectedSquare; @@ -50,12 +54,15 @@ public class SpielFrame extends JFrame { /** * Create the frame. */ - public SpielFrame() { + public SpielFrame(Game game) { - game = new Game(); + this.game = game; + this.clock = game.getClock(); + this.clock.start(); + mode = BoardMode.normal; - setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); setBounds(100, 100, 1920, 1080); setTitle("Schach"); setAlwaysOnTop(true); @@ -71,15 +78,43 @@ public class SpielFrame extends JFrame { // Rechtes Panel für Steuerung oder zusätzliche Eingaben panelRechts = new JPanel(); - panelRechts.setBackground(Color.LIGHT_GRAY); - + panelRechts.setBackground(new Color(90,90,90)); + panelRechts.setLayout(new BoxLayout(panelRechts, BoxLayout.Y_AXIS)); + + + JLabel pl1 = new JLabel("Player 1:"); + pl1.setFont(new Font("Calibri", Font.BOLD, 35)); + pl1.setForeground(Color.BLACK); + pl1.setAlignmentX(Component.LEFT_ALIGNMENT); + panelRechts.add(pl1); + + contentPane.add(Box.createVerticalStrut(15)); + + //Zeitangabe Player1 + JLabel clock1 = clock.getClock2(); + panelRechts.add(clock1); + + contentPane.add(Box.createVerticalStrut(15)); + + JLabel pl2 = new JLabel("Player 2:"); + pl2.setFont(new Font("Calibri", Font.BOLD, 35)); + pl2.setForeground(Color.BLACK); + pl2.setAlignmentX(Component.LEFT_ALIGNMENT); + panelRechts.add(pl2); + + //Zeitangabe Player2 + JLabel clock2 = clock.getClock1(); + panelRechts.add(clock2); + // JSplitPane horizontal (linke und rechte Hälfte) JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, panelLinks, panelRechts); - splitPane.setResizeWeight(0.70); - splitPane.setDividerSize(5); + splitPane.setResizeWeight(0.65); + splitPane.setBackground(Color.BLACK); + splitPane.setDividerSize(0); splitPane.setEnabled(false); contentPane.add(splitPane, BorderLayout.CENTER); + setVisible(true); } @@ -109,32 +144,6 @@ public class SpielFrame extends JFrame { panelLinks.revalidate(); panelLinks.repaint(); - // // Bild laden und Cursor im gesamten Frame setzen - // Image image = Toolkit.getDefaultToolkit().getImage(pfad); - // Image scaled = image.getScaledInstance(32, 32, Image.SCALE_SMOOTH); - // Cursor figurCursor = Toolkit.getDefaultToolkit().createCustomCursor(scaled, - // new Point(0, 0), - // "figurCursor"); - // setCursor(figurCursor); - - // }else - // { - // - // // wenn gerade Figur ausgewählt wird... - // buttonChoosed = (JButton) e.getSource(); - // symbolChoosed = belegungen.get(buttonChoosed); - // // System.out.println(symbolChoosed+" wurde gewählt."); - // // setzt cursor auf spielfigur für die animation - // String pfad = "src/main/resources/" + (int) symbolChoosed.toCharArray()[2] + - // ".png"; - // - // // Bild laden und Cursor im gesamten Frame setzen - // Image image = Toolkit.getDefaultToolkit().getImage(pfad); - // Image scaled = image.getScaledInstance(32, 32, Image.SCALE_SMOOTH); - // Cursor figurCursor = Toolkit.getDefaultToolkit().createCustomCursor(scaled, - // new Point(0, 0), - // "figurCursor"); - // setCursor(figurCursor); } private int mirrowedGrid(int i) { @@ -205,10 +214,10 @@ public class SpielFrame extends JFrame { for (int i = 0; i < 64; i++) { JButton b = buttons.get(i); if ((i / 8 + i % 8) % 2 == 0) { - logger.info("Helles Feld erstellt." + i); + //logger.info("Helles Feld erstellt." + i); b.setBackground(new Color(90, 90, 90)); } else { - logger.info("Dunkles Feld erstellt." + i); + //logger.info("Dunkles Feld erstellt." + i); b.setBackground(new Color(65, 65, 65)); } } diff --git a/src/main/java/de/mannheim/th/chess/utl/Clock.java b/src/main/java/de/mannheim/th/chess/utl/Clock.java index c575d06..84d794b 100644 --- a/src/main/java/de/mannheim/th/chess/utl/Clock.java +++ b/src/main/java/de/mannheim/th/chess/utl/Clock.java @@ -17,17 +17,21 @@ import javax.swing.Timer; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import de.mannheim.th.chess.ui.SpielFrame; + public class Clock extends Thread implements Runnable { private volatile boolean whiteToMove = true; private volatile boolean gameHasFinished = false; private static final Logger clockLogger = LogManager.getLogger(Clock.class); private int minutes; - + private StringBuilder clockShower; + private JLabel clock1, clock2; + public Clock(String mode) { + setMode(mode); - //run(); } - + public void pressClock() { whiteToMove = !whiteToMove; if (whiteToMove) { @@ -36,105 +40,109 @@ public class Clock extends Thread implements Runnable { clockLogger.info("Schwarz ist am Zug"); } } - + public void endGame() { gameHasFinished = true; } - + public void run() { - JFrame clockFrame = new JFrame("Clock"); - - JPanel player1Panel = new JPanel(); - player1Panel.setBackground(Color.BLACK); - JPanel player2Panel = new JPanel(); - player2Panel.setBackground(Color.BLACK); - clockFrame.setBounds(1000, 500, 10000, 10000); - clockFrame.setLayout(new BorderLayout()); - JLabel clock1 = new JLabel(" " + minutes + ":00 "); - clock1.setForeground(Color.WHITE); - clock1.setFont(new Font("Arial", Font.BOLD, 50)); - JLabel clock2 = new JLabel(" " + minutes + ":00 "); - clock2.setForeground(Color.WHITE); - clock2.setFont(new Font("Arial", Font.BOLD, 50)); - player1Panel.add(clock1); - player2Panel.add(clock2); - JSplitPane split = new JSplitPane(JSplitPane.VERTICAL_SPLIT, player1Panel, player2Panel); - split.setFont(new Font("Arial", Font.BOLD, 50)); - clockFrame.add(split); - +// JFrame clockFrame = new JFrame("Clock"); +// +// JPanel player1Panel = new JPanel(); +// player1Panel.setBackground(Color.BLACK); +// JPanel player2Panel = new JPanel(); +// player2Panel.setBackground(Color.BLACK); +// clockFrame.setBounds(1000, 500, 10000, 10000); +// clockFrame.setLayout(new BorderLayout()); + clock1 = new JLabel(" " + minutes + ":00 "); + clock1.setForeground(Color.BLACK); + clock1.setFont(new Font("Calibri", Font.BOLD, 35)); + clock2 = new JLabel(" " + minutes + ":00 "); + clock2.setForeground(Color.BLACK); + clock2.setFont(new Font("Calibri", Font.BOLD, 35)); +// player1Panel.add(clock1); +// player2Panel.add(clock2); +// JSplitPane split = new JSplitPane(JSplitPane.VERTICAL_SPLIT, player1Panel, player2Panel); +// split.setFont(new Font("Arial", Font.BOLD, 50)); +// clockFrame.add(split); + var min1 = new AtomicInteger(minutes); var sec1 = new AtomicInteger(0); var min2 = new AtomicInteger(minutes); var sec2 = new AtomicInteger(0); - clockFrame.pack(); - clockFrame.setVisible(true); var t = new Timer(1000, (ae) -> { - - if (!gameHasFinished) { - - StringBuilder clockShower = new StringBuilder(); - if (whiteToMove) { - if (sec1.intValue() == 00) { - sec1.set(60); - min1.decrementAndGet(); - } - if (min1.intValue() < 10) { - clockShower.append("0"); - } - clockShower.append(min1.get()); - clockShower.append(":"); - if (sec1.intValue() < 10) { - clockShower.append("0"); - } - clockShower.append(sec1.decrementAndGet()); - clock1.setText(clockShower.toString()); - } else { - if (sec2.intValue() == 00) { - sec2.set(60); - min2.decrementAndGet(); + if (!gameHasFinished) { + + clockShower = new StringBuilder(); + if (whiteToMove) { + if (sec1.intValue() == 00) { + sec1.set(60); + min1.decrementAndGet(); + } + if (min1.intValue() < 10) { + clockShower.append("0"); + } + clockShower.append(min1.get()); + clockShower.append(":"); + if (sec1.intValue() < 10) { + clockShower.append("0"); + } + clockShower.append(sec1.decrementAndGet()); + clock1.setText(clockShower.toString()); + + } else { + if (sec2.intValue() == 00) { + sec2.set(60); + min2.decrementAndGet(); + } + if (min2.intValue() < 10) { + clockShower.append("0"); + } + clockShower.append(min2.get()); + clockShower.append(":"); + if (sec2.intValue() < 10) { + clockShower.append("0"); + } + clockShower.append(sec2.decrementAndGet()); + clock2.setText(clockShower.toString()); } - if (min2.intValue() < 10) { - clockShower.append("0"); + //sp.repaint(); + if ((sec1.intValue() == 0 && min1.intValue() == 0) || (sec2.intValue() == 0 && min2.intValue() == 0)) { + endGame(); } - clockShower.append(min2.get()); - clockShower.append(":"); - if (sec2.intValue() < 10) { - clockShower.append("0"); - } - clockShower.append(sec2.decrementAndGet()); - clock2.setText(clockShower.toString()); } - clockFrame.repaint(); - if ((sec1.intValue() == 0 && min1.intValue() == 0) || (sec2.intValue() == 0 && min2.intValue() == 0)) { - endGame(); - } - } }); + }); t.start(); } - public static void main(String[] args) throws InterruptedException { - Clock st = new Clock("classic"); - st.start(); - st.pressClock(); - } - + private void setMode(String mode) { - switch(mode) { + switch (mode.toLowerCase()) { case "blitz": minutes = 5; clockLogger.info("Neue Blitz-Uhr wurde erstellt"); break; - case "rapid": + case "schnellschach": minutes = 10; clockLogger.info("Neue Schnellschach-Uhr wurde erstellt"); break; - case "classic": + case "klassisch": minutes = 120; clockLogger.info("Neue klassische Schachuhr wurde erstellt"); break; } } + public JLabel getClock1() { + + return clock1; + } + + public JLabel getClock2() { + + return clock2; + } + } \ No newline at end of file From fb40f3019b13ff260ba0ca08641e7cc3f5b268c7 Mon Sep 17 00:00:00 2001 From: Matias <3020772@tud.hs-mannheim.de> Date: Fri, 20 Jun 2025 13:16:01 +0200 Subject: [PATCH 02/12] =?UTF-8?q?Anzeige=20neben=20Spielbrett=20versch?= =?UTF-8?q?=C3=B6nert?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../de/mannheim/th/chess/domain/Game.java | 4 + .../de/mannheim/th/chess/ui/SpielFrame.java | 610 +++++++++++------- .../java/de/mannheim/th/chess/utl/Clock.java | 11 +- 3 files changed, 404 insertions(+), 221 deletions(-) diff --git a/src/main/java/de/mannheim/th/chess/domain/Game.java b/src/main/java/de/mannheim/th/chess/domain/Game.java index 4d1ada5..754160c 100644 --- a/src/main/java/de/mannheim/th/chess/domain/Game.java +++ b/src/main/java/de/mannheim/th/chess/domain/Game.java @@ -170,4 +170,8 @@ public class Game { public Clock getClock() { return this.clock; } + + public boolean isZuruecknahme() { + return zuruecknahme; + } } diff --git a/src/main/java/de/mannheim/th/chess/ui/SpielFrame.java b/src/main/java/de/mannheim/th/chess/ui/SpielFrame.java index 3d722e2..793fcfd 100644 --- a/src/main/java/de/mannheim/th/chess/ui/SpielFrame.java +++ b/src/main/java/de/mannheim/th/chess/ui/SpielFrame.java @@ -24,284 +24,456 @@ import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JSplitPane; +import javax.swing.JTextArea; +import javax.swing.JTextField; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; +import java.awt.Dimension; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.awt.GridLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; public class SpielFrame extends JFrame { - private static final Logger logger = LogManager.getLogger(App.class); + private static final Logger logger = LogManager.getLogger(App.class); - private static final long serialVersionUID = 1L; - private ArrayList buttons = new ArrayList<>(); - private HashMap belegungen = new HashMap<>(); - private JPanel panelLinks, panelRechts, contentPane; - private Game game; - private Clock clock; + private static final long serialVersionUID = 1L; + private ArrayList buttons = new ArrayList<>(); + private HashMap belegungen = new HashMap<>(); + private JPanel panelLinks, panelRechts, contentPane; + private Game game; + private Clock clock; - private BoardMode mode; - private Square selectedSquare; + private BoardMode mode; + private Square selectedSquare; - public enum BoardMode { - normal, pieceSelected, finished - } + public enum BoardMode { + normal, pieceSelected, finished + } - /** - * Create the frame. - */ - public SpielFrame(Game game) { + /** + * Create the frame. + */ + public SpielFrame(Game game) { - this.game = game; - this.clock = game.getClock(); - this.clock.start(); - - mode = BoardMode.normal; + this.game = game; + this.clock = game.getClock(); + this.clock.start(); - setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); - setBounds(100, 100, 1920, 1080); - setTitle("Schach"); - setAlwaysOnTop(true); + mode = BoardMode.normal; - contentPane = new JPanel(); - contentPane.setLayout(new BorderLayout()); - setContentPane(contentPane); + setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + setBounds(100, 100, 1920, 1080); + setTitle("Schach"); + setAlwaysOnTop(true); - // Linkes Panel mit GridLayout 8x8 für Schachbrett - panelLinks = new JPanel(new GridLayout(8, 8)); + contentPane = new JPanel(); + contentPane.setLayout(new BorderLayout()); + setContentPane(contentPane); - erstelleBrett(); + // Linkes Panel mit GridLayout 8x8 für Schachbrett + panelLinks = new JPanel(new GridLayout(8, 8)); - // Rechtes Panel für Steuerung oder zusätzliche Eingaben - panelRechts = new JPanel(); - panelRechts.setBackground(new Color(90,90,90)); - panelRechts.setLayout(new BoxLayout(panelRechts, BoxLayout.Y_AXIS)); - - - JLabel pl1 = new JLabel("Player 1:"); - pl1.setFont(new Font("Calibri", Font.BOLD, 35)); - pl1.setForeground(Color.BLACK); - pl1.setAlignmentX(Component.LEFT_ALIGNMENT); - panelRechts.add(pl1); - - contentPane.add(Box.createVerticalStrut(15)); - - //Zeitangabe Player1 - JLabel clock1 = clock.getClock2(); - panelRechts.add(clock1); - - contentPane.add(Box.createVerticalStrut(15)); - - JLabel pl2 = new JLabel("Player 2:"); - pl2.setFont(new Font("Calibri", Font.BOLD, 35)); - pl2.setForeground(Color.BLACK); - pl2.setAlignmentX(Component.LEFT_ALIGNMENT); - panelRechts.add(pl2); - - //Zeitangabe Player2 - JLabel clock2 = clock.getClock1(); - panelRechts.add(clock2); - - // JSplitPane horizontal (linke und rechte Hälfte) - JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, panelLinks, panelRechts); - splitPane.setResizeWeight(0.65); - splitPane.setBackground(Color.BLACK); - splitPane.setDividerSize(0); - splitPane.setEnabled(false); + erstelleBrett(); - contentPane.add(splitPane, BorderLayout.CENTER); - - setVisible(true); - } + // Rechtes Panel für Steuerung oder zusätzliche Eingaben + panelRechts = new JPanel(); + panelRechts.setBackground(new Color(90, 90, 90)); + panelRechts.setLayout(new BoxLayout(panelRechts, BoxLayout.Y_AXIS)); - public void setBoardMode(BoardMode bm) { - this.mode = bm; - } + // Panel für alle Eingaben von Player 2 + panelRechts.add(getUiPlayerTwo()); + + // Panel für Statistikanzeigen + panelRechts.add(getUiStatistik()); - public void setSelectedSquare(Square sq) { - this.selectedSquare = sq; - } + //Panel für alle Eingaben von Player 1 + panelRechts.add(getUiPlayerOne()); + + // JSplitPane horizontal (linke und rechte Hälfte) + JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, panelLinks, panelRechts); + splitPane.setResizeWeight(0.75); + splitPane.setBackground(Color.BLACK); + splitPane.setDividerSize(1); + splitPane.setEnabled(false); - public HashMap getBelegung() { - return this.belegungen; - } + contentPane.add(splitPane, BorderLayout.CENTER); - /** - * Erstellt alle Buttons und fügt sie dem Frame hinzu. - */ - public void erstelleBrett() { + setVisible(true); + } - this.clearButtons(); - this.setDefaultBackground(); - this.setButtonsActions(); + public void setBoardMode(BoardMode bm) { + this.mode = bm; + } - ladeBrett(); + public void setSelectedSquare(Square sq) { + this.selectedSquare = sq; + } - panelLinks.revalidate(); - panelLinks.repaint(); + public HashMap getBelegung() { + return this.belegungen; + } - } + /** + * Erstellt alle Buttons und fügt sie dem Frame hinzu. + */ + public void erstelleBrett() { - private int mirrowedGrid(int i) { - return 63 - (((i / 8) * 8) + (7 - i % 8)); - } + this.clearButtons(); + this.setDefaultBackground(); + this.setButtonsActions(); - /** - * holt sich FEN-Zeichenkette und extrahiert daraus die Positionen der Figuren - */ - private void ladeBrett() { - // System.out.println(game.toFEN()); + ladeBrett(); - char[] fen = game.toFEN().replaceAll("/", "").split(" ")[0].toCharArray(); - int i = 0; - for (int j = 0; j < fen.length; j++) { - if (Character.isDigit(fen[j])) { - int leerfelder = Character.getNumericValue(fen[j]); - for (int k = 0; k < leerfelder; k++) { - belegungen.put(buttons.get(i), "n-n"); - // buttons.get(i).setEnabled(false); // erstmal deaktivieren, weil leere Felder - // nicht ckickbar sein sollten. - i++; - } - continue; - } else if (fen[j] >= 65 && fen[j] <= 90) { // ein Großbuchstabe, also - belegungen.put(buttons.get(i), "w-" + fen[j]); - } else if (fen[j] >= 97 && fen[j] <= 122) { // ein Kleinbuchstabe, also - belegungen.put(buttons.get(i), "b-" + fen[j]); - // buttons.get(i).setEnabled(false); // erstmal deaktivieren, damit weiß - // beginnen kann - } - buttons.get(i).setIcon(new ImageIcon("src/main/resources/" + (int) fen[j] + ".png")); - buttons.get(i).setDisabledIcon(new ImageIcon("src/main/resources/" + (int) fen[j] + ".png")); + panelLinks.revalidate(); + panelLinks.repaint(); - i++; + } - } - } + private int mirrowedGrid(int i) { + return 63 - (((i / 8) * 8) + (7 - i % 8)); + } - /** - * Clears the existing buttons from the button list, panellinks and fills them - * with new blank ones. - */ - private void clearButtons() { - buttons.clear(); - panelLinks.removeAll(); + /** + * holt sich FEN-Zeichenkette und extrahiert daraus die Positionen der Figuren + */ + private void ladeBrett() { + // System.out.println(game.toFEN()); - for (int i = 0; i < 64; i++) { - JButton b = new JButton(); + char[] fen = game.toFEN().replaceAll("/", "").split(" ")[0].toCharArray(); + int i = 0; + for (int j = 0; j < fen.length; j++) { + if (Character.isDigit(fen[j])) { + int leerfelder = Character.getNumericValue(fen[j]); + for (int k = 0; k < leerfelder; k++) { + belegungen.put(buttons.get(i), "n-n"); + // buttons.get(i).setEnabled(false); // erstmal deaktivieren, weil leere Felder + // nicht ckickbar sein sollten. + i++; + } + continue; + } else if (fen[j] >= 65 && fen[j] <= 90) { // ein Großbuchstabe, also + belegungen.put(buttons.get(i), "w-" + fen[j]); + } else if (fen[j] >= 97 && fen[j] <= 122) { // ein Kleinbuchstabe, also + belegungen.put(buttons.get(i), "b-" + fen[j]); + // buttons.get(i).setEnabled(false); // erstmal deaktivieren, damit weiß + // beginnen kann + } + buttons.get(i).setIcon(new ImageIcon("src/main/resources/" + (int) fen[j] + ".png")); + buttons.get(i).setDisabledIcon(new ImageIcon("src/main/resources/" + (int) fen[j] + ".png")); - b.setEnabled(false); + i++; - // style - b.setFocusPainted(false); - b.setFont(new Font("Arial", Font.PLAIN, 30)); - b.setForeground(Color.WHITE); - b.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1)); - b.setName(i + ""); + } + } - buttons.add(b); - } - } + /** + * Clears the existing buttons from the button list, panellinks and fills them + * with new blank ones. + */ + private void clearButtons() { + buttons.clear(); + panelLinks.removeAll(); - /** - * Sets the default background color for the buttons in the grid. - */ - private void setDefaultBackground() { - for (int i = 0; i < 64; i++) { - JButton b = buttons.get(i); - if ((i / 8 + i % 8) % 2 == 0) { - //logger.info("Helles Feld erstellt." + i); - b.setBackground(new Color(90, 90, 90)); - } else { - //logger.info("Dunkles Feld erstellt." + i); - b.setBackground(new Color(65, 65, 65)); - } - } - } + for (int i = 0; i < 64; i++) { + JButton b = new JButton(); - /* - * Switches the button actions depending on the boardmode - */ - private void setButtonsActions() { + b.setEnabled(false); - List selectables; + // style + b.setFocusPainted(false); + b.setFont(new Font("Arial", Font.PLAIN, 30)); + b.setForeground(Color.WHITE); + b.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1)); + b.setName(i + ""); - switch (this.mode) { - case BoardMode.normal: - selectables = game.getAllLegalMoveableSquares(); + buttons.add(b); + } + } - for (Square square : selectables) { - JButton b = buttons.get(mirrowedGrid(square.ordinal())); - b.setEnabled(true); - // b.setBackground(Color.green); - b.addActionListener(new ButtonSelectPieceListener(this, square)); - } + /** + * Sets the default background color for the buttons in the grid. + */ + private void setDefaultBackground() { + for (int i = 0; i < 64; i++) { + JButton b = buttons.get(i); + if ((i / 8 + i % 8) % 2 == 0) { + // logger.info("Helles Feld erstellt." + i); + b.setBackground(new Color(90, 90, 90)); + } else { + // logger.info("Dunkles Feld erstellt." + i); + b.setBackground(new Color(65, 65, 65)); + } + } + } - break; + /* + * Switches the button actions depending on the boardmode + */ + private void setButtonsActions() { - case BoardMode.pieceSelected: + List selectables; - JButton s = buttons.get(mirrowedGrid(selectedSquare.ordinal())); - s.setEnabled(true); - s.setBackground(new Color(165, 42, 42)); - s.addActionListener(new ButtonToNormalListener(this)); // cancel action + switch (this.mode) { + case BoardMode.normal: + selectables = game.getAllLegalMoveableSquares(); - selectables = game.getLegalMoveableSquares(selectedSquare); + for (Square square : selectables) { + JButton b = buttons.get(mirrowedGrid(square.ordinal())); + b.setEnabled(true); + // b.setBackground(Color.green); + b.addActionListener(new ButtonSelectPieceListener(this, square)); + } - for ( + break; - Square square : selectables) { - JButton b = buttons.get(mirrowedGrid(square.ordinal())); - final Move move = new Move(selectedSquare, square); - b.setEnabled(true); - b.setBackground(new Color(230, 100, 100)); - b.addActionListener(new ButtonMovePieceListener(this, this.game, move)); - } + case BoardMode.pieceSelected: - break; + JButton s = buttons.get(mirrowedGrid(selectedSquare.ordinal())); + s.setEnabled(true); + s.setBackground(new Color(165, 42, 42)); + s.addActionListener(new ButtonToNormalListener(this)); // cancel action - case finished: - clearButtons(); - break; - default: - break; + selectables = game.getLegalMoveableSquares(selectedSquare); - } + for ( - for (JButton b : buttons) { - panelLinks.add(b); - } - } + Square square : selectables) { + JButton b = buttons.get(mirrowedGrid(square.ordinal())); + final Move move = new Move(selectedSquare, square); + b.setEnabled(true); + b.setBackground(new Color(230, 100, 100)); + b.addActionListener(new ButtonMovePieceListener(this, this.game, move)); + } - public void showDraw() { - JFrame frame = new JFrame("Result"); - frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - frame.setSize(300, 150); - frame.setLayout(null); + break; - JLabel jl = new JLabel("1/2 - 1/2"); - jl.setBounds(50, 30, 200, 25); - jl.setFont(new Font("Tahoma", Font.BOLD, 20)); - frame.add(jl); - frame.setVisible(true); + case finished: + clearButtons(); + break; + default: + break; - } + } - public void showWin(int player) { - JFrame frame = new JFrame("Result"); - frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - frame.setSize(300, 150); - frame.setLayout(null); + for (JButton b : buttons) { + panelLinks.add(b); + } + } - JLabel jl = new JLabel(String.format("%d - %d", player / 2, player % 2)); - jl.setBounds(50, 30, 200, 25); - jl.setFont(new Font("Tahoma", Font.BOLD, 20)); - frame.add(jl); - frame.setVisible(true); - } + public void showDraw() { + JFrame frame = new JFrame("Result"); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.setSize(300, 150); + frame.setLayout(null); + + JLabel jl = new JLabel("1/2 - 1/2"); + jl.setBounds(50, 30, 200, 25); + jl.setFont(new Font("Tahoma", Font.BOLD, 20)); + frame.add(jl); + frame.setVisible(true); + + } + + public void showWin(int player) { + JFrame frame = new JFrame("Result"); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.setSize(300, 150); + frame.setLayout(null); + + JLabel jl = new JLabel(String.format("%d - %d", player / 2, player % 2)); + jl.setBounds(50, 30, 200, 25); + jl.setFont(new Font("Tahoma", Font.BOLD, 20)); + frame.add(jl); + frame.setVisible(true); + } + + private JPanel getUiPlayerTwo() { + + JPanel playerTwo = new JPanel(); + playerTwo.setBackground(new Color(90, 90, 90)); + playerTwo.setLayout(new BoxLayout(playerTwo, BoxLayout.Y_AXIS)); + + playerTwo.add(Box.createVerticalStrut(15)); + + JLabel pl2 = new JLabel("Player 2:"); + pl2.setBorder(BorderFactory.createEmptyBorder(0, 20, 0, 0)); + pl2.setFont(new Font("Calibri", Font.BOLD, 35)); + pl2.setForeground(Color.BLACK); + pl2.setAlignmentX(Component.CENTER_ALIGNMENT); + playerTwo.add(pl2); + + playerTwo.add(Box.createVerticalStrut(10)); + + JLabel clock1 = clock.getClock2(); + playerTwo.add(clock1); + + playerTwo.add(Box.createVerticalStrut(10)); + + // Button zurücknahme und aufgeben für Player 2 + JPanel aufgebenUndo = new JPanel(); + aufgebenUndo.setBackground(new Color(90, 90, 90)); + aufgebenUndo.setLayout(new BoxLayout(aufgebenUndo, BoxLayout.X_AXIS)); + + if (game.isZuruecknahme()) { + JButton undo = new JButton("Zug zurücknehmen"); + undo.setBackground(Color.LIGHT_GRAY); + undo.setForeground(Color.BLACK); + undo.setFont(new Font("Tahoma", Font.BOLD, 16)); + undo.setAlignmentX(Component.CENTER_ALIGNMENT); + aufgebenUndo.add(undo); + + // Button-Listener + undo.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + + } + }); + } + + aufgebenUndo.add(Box.createHorizontalStrut(10)); + + JButton aufgeben = new JButton("Aufgeben"); + aufgeben.setBackground(Color.LIGHT_GRAY); + aufgeben.setForeground(Color.BLACK); + aufgeben.setFont(new Font("Tahoma", Font.BOLD, 16)); + aufgeben.setAlignmentX(Component.CENTER_ALIGNMENT); + aufgebenUndo.add(aufgeben); + + // Button-Listener + aufgeben.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + + } + }); + + aufgebenUndo.add(Box.createHorizontalStrut(10)); + + JButton safe = new JButton("Spielstand sichern"); + safe.setBackground(Color.LIGHT_GRAY); + safe.setForeground(Color.BLACK); + safe.setFont(new Font("Tahoma", Font.BOLD, 16)); + safe.setAlignmentX(Component.CENTER_ALIGNMENT); + aufgebenUndo.add(safe); + + // Button-Listener + safe.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + + } + }); + + playerTwo.add(aufgebenUndo); + + playerTwo.add(Box.createVerticalStrut(10)); + + return playerTwo; + } + + private JPanel getUiStatistik() { + + JPanel statistik = new JPanel(); + statistik.setBackground(new Color(90, 90, 90)); + statistik.setLayout(new BoxLayout(statistik, BoxLayout.Y_AXIS)); + + JTextArea ausgabe = new JTextArea(); + ausgabe.setEditable(false); + ausgabe.setBackground(new Color(75,75,75)); + ausgabe.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1)); + + statistik.add(ausgabe); + return statistik; + } + + private JPanel getUiPlayerOne() { + + JPanel playerOne = new JPanel(); + playerOne.setBackground(new Color(90, 90, 90)); + playerOne.setLayout(new BoxLayout(playerOne, BoxLayout.Y_AXIS)); + + playerOne.add(Box.createVerticalStrut(10)); + + // Button zurücknahme und aufgeben für Player 1 + JPanel aufgebenUndo = new JPanel(); + aufgebenUndo.setBackground(new Color(90, 90, 90)); + aufgebenUndo.setLayout(new BoxLayout(aufgebenUndo, BoxLayout.X_AXIS)); + + if (game.isZuruecknahme()) { + JButton undo = new JButton("Zug zurücknehmen"); + undo.setBackground(Color.LIGHT_GRAY); + undo.setForeground(Color.BLACK); + undo.setFont(new Font("Tahoma", Font.BOLD, 16)); + undo.setAlignmentX(Component.CENTER_ALIGNMENT); + aufgebenUndo.add(undo); + + // Button-Listener + undo.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + + } + }); + } + + aufgebenUndo.add(Box.createHorizontalStrut(10)); + + JButton aufgeben = new JButton("Aufgeben"); + aufgeben.setBackground(Color.LIGHT_GRAY); + aufgeben.setForeground(Color.BLACK); + aufgeben.setFont(new Font("Tahoma", Font.BOLD, 16)); + aufgeben.setAlignmentX(Component.CENTER_ALIGNMENT); + aufgebenUndo.add(aufgeben); + + // Button-Listener + aufgeben.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + + } + }); + + aufgebenUndo.add(Box.createHorizontalStrut(10)); + + JButton safe = new JButton("Spielstand sichern"); + safe.setBackground(Color.LIGHT_GRAY); + safe.setForeground(Color.BLACK); + safe.setFont(new Font("Tahoma", Font.BOLD, 16)); + safe.setAlignmentX(Component.CENTER_ALIGNMENT); + aufgebenUndo.add(safe); + + // Button-Listener + safe.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + + } + }); + + playerOne.add(aufgebenUndo); + + playerOne.add(Box.createVerticalStrut(10)); + + JLabel clock1 = clock.getClock1(); + playerOne.add(clock1); + + playerOne.add(Box.createVerticalStrut(10)); + + JLabel pl2 = new JLabel("Player 1:"); + pl2.setBorder(BorderFactory.createEmptyBorder(0, 20, 0, 0)); + pl2.setFont(new Font("Calibri", Font.BOLD, 35)); + pl2.setForeground(Color.BLACK); + pl2.setAlignmentX(Component.CENTER_ALIGNMENT); + playerOne.add(pl2); + + return playerOne; + } } diff --git a/src/main/java/de/mannheim/th/chess/utl/Clock.java b/src/main/java/de/mannheim/th/chess/utl/Clock.java index 84d794b..13bb9f6 100644 --- a/src/main/java/de/mannheim/th/chess/utl/Clock.java +++ b/src/main/java/de/mannheim/th/chess/utl/Clock.java @@ -5,9 +5,11 @@ package de.mannheim.th.chess.utl; */ import java.awt.BorderLayout; import java.awt.Color; +import java.awt.Component; import java.awt.Font; import java.util.concurrent.atomic.AtomicInteger; +import javax.swing.BorderFactory; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; @@ -54,12 +56,17 @@ public class Clock extends Thread implements Runnable { // player2Panel.setBackground(Color.BLACK); // clockFrame.setBounds(1000, 500, 10000, 10000); // clockFrame.setLayout(new BorderLayout()); - clock1 = new JLabel(" " + minutes + ":00 "); + clock1 = new JLabel("" + minutes + ":00 "); + clock1.setBorder(BorderFactory.createEmptyBorder(0, 40, 0, 0)); clock1.setForeground(Color.BLACK); clock1.setFont(new Font("Calibri", Font.BOLD, 35)); - clock2 = new JLabel(" " + minutes + ":00 "); + clock1.setAlignmentX(Component.CENTER_ALIGNMENT); + + clock2 = new JLabel("" + minutes + ":00 "); + clock2.setBorder(BorderFactory.createEmptyBorder(0, 40, 0, 0)); clock2.setForeground(Color.BLACK); clock2.setFont(new Font("Calibri", Font.BOLD, 35)); + clock2.setAlignmentX(Component.CENTER_ALIGNMENT); // player1Panel.add(clock1); // player2Panel.add(clock2); // JSplitPane split = new JSplitPane(JSplitPane.VERTICAL_SPLIT, player1Panel, player2Panel); From 0a46fc763f532d7c114238d61097db8073e0d10c Mon Sep 17 00:00:00 2001 From: Matias <3020772@tud.hs-mannheim.de> Date: Sat, 21 Jun 2025 12:14:05 +0200 Subject: [PATCH 03/12] =?UTF-8?q?Zug=20zur=C3=BCcknahme=20erstellt=20und?= =?UTF-8?q?=20in=20externe=20ButtonListener=20Klasse=20ausgelagert.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/ButtonMovePieceListener.java | 4 + .../controller/ButtonUndoMoveListener.java | 68 ++++++++++ .../de/mannheim/th/chess/domain/Game.java | 12 ++ .../de/mannheim/th/chess/ui/SpielFrame.java | 125 ++++++++++++------ .../java/de/mannheim/th/chess/utl/Clock.java | 8 +- 5 files changed, 173 insertions(+), 44 deletions(-) create mode 100644 src/main/java/de/mannheim/th/chess/controller/ButtonUndoMoveListener.java diff --git a/src/main/java/de/mannheim/th/chess/controller/ButtonMovePieceListener.java b/src/main/java/de/mannheim/th/chess/controller/ButtonMovePieceListener.java index 402fad5..6a80e19 100644 --- a/src/main/java/de/mannheim/th/chess/controller/ButtonMovePieceListener.java +++ b/src/main/java/de/mannheim/th/chess/controller/ButtonMovePieceListener.java @@ -1,5 +1,6 @@ package de.mannheim.th.chess.controller; +import java.awt.Color; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; @@ -23,6 +24,9 @@ public class ButtonMovePieceListener implements ActionListener { @Override public void actionPerformed(ActionEvent e) { this.game.playMove(this.mv); + sf.getUndo().setText("Zug zurücknehmen"); + sf.getUndo2().setText("Zug zurücknehmen"); + if (this.game.isDraw()) { this.game.stopClock(); this.sf.setBoardMode(BoardMode.finished); diff --git a/src/main/java/de/mannheim/th/chess/controller/ButtonUndoMoveListener.java b/src/main/java/de/mannheim/th/chess/controller/ButtonUndoMoveListener.java new file mode 100644 index 0000000..f99fae3 --- /dev/null +++ b/src/main/java/de/mannheim/th/chess/controller/ButtonUndoMoveListener.java @@ -0,0 +1,68 @@ +package de.mannheim.th.chess.controller; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import de.mannheim.th.chess.App; +import de.mannheim.th.chess.domain.Game; +import de.mannheim.th.chess.ui.SpielFrame; +import de.mannheim.th.chess.ui.SpielFrame.BoardMode; + +public class ButtonUndoMoveListener implements ActionListener { + + private static final Logger logger = LogManager.getLogger(App.class); + + private SpielFrame sf; + private Game game; + + public ButtonUndoMoveListener(SpielFrame sf, Game game) { + this.sf = sf; + this.game = game; + } + + @Override + public void actionPerformed(ActionEvent e) { + // TODO Auto-generated method stub + + Object source = e.getSource(); + + if (sf.getMode() != BoardMode.normal || !game.movesNotNull()) { + return; + } + + if (source == sf.getUndo()) { // Spieler 2 drückt seinen Button + if (sf.getUndo().getText().equals("Zug zurücknehmen") && game.getActivePlayer() == 1) { + sf.getUndo2().setText("Zurücknahme genehmigen?"); + sf.getUndo2().setEnabled(true); + logger.info("Spieler 2 hat zurücknahme angefordert."); + } else if (sf.getUndo().getText().equals("Zurücknahme genehmigen?")) { + logger.info("Zug zurücknehmen wurde von Spieler 2 genehmigt."); + sf.getUndo().setText("Zug zurücknehmen"); + sf.getUndo2().setText("Zug zurücknehmen"); + sf.getUndo2().setEnabled(false); + game.undo(); + sf.getClock().switchClock(); + sf.erstelleBrett(); + } + } else if (source == sf.getUndo2()) { // Spieler 1 drückt seinen Button + if (sf.getUndo2().getText().equals("Zug zurücknehmen") && game.getActivePlayer() == 2) { + sf.getUndo().setText("Zurücknahme genehmigen?"); + sf.getUndo().setEnabled(true); + logger.info("Spieler 1 hat zurücknahme angefordert."); + } else if (sf.getUndo2().getText().equals("Zurücknahme genehmigen?")) { + logger.info("Zug zurücknehmen wurde von Spieler 1 genehmigt."); + sf.getUndo2().setText("Zug zurücknehmen"); + sf.getUndo().setText("Zug zurücknehmen"); + sf.getUndo().setEnabled(false); + game.undo(); + sf.getClock().switchClock(); + sf.erstelleBrett(); + } + } + + } + +} diff --git a/src/main/java/de/mannheim/th/chess/domain/Game.java b/src/main/java/de/mannheim/th/chess/domain/Game.java index 754160c..edef36f 100644 --- a/src/main/java/de/mannheim/th/chess/domain/Game.java +++ b/src/main/java/de/mannheim/th/chess/domain/Game.java @@ -105,6 +105,11 @@ public class Game { this.movelist.add(move); } + + public void undo() { + this.board.undoMove(); + this.movelist.removeLast(); + } public boolean isMate() { return board.isMated(); @@ -174,4 +179,11 @@ public class Game { public boolean isZuruecknahme() { return zuruecknahme; } + + public boolean movesNotNull() { + if(movelist.getLast() != null) { + return true; + } + return false; + } } diff --git a/src/main/java/de/mannheim/th/chess/ui/SpielFrame.java b/src/main/java/de/mannheim/th/chess/ui/SpielFrame.java index 793fcfd..414f061 100644 --- a/src/main/java/de/mannheim/th/chess/ui/SpielFrame.java +++ b/src/main/java/de/mannheim/th/chess/ui/SpielFrame.java @@ -12,6 +12,7 @@ import de.mannheim.th.chess.utl.Clock; import de.mannheim.th.chess.controller.ButtonMovePieceListener; import de.mannheim.th.chess.controller.ButtonSelectPieceListener; import de.mannheim.th.chess.controller.ButtonToNormalListener; +import de.mannheim.th.chess.controller.ButtonUndoMoveListener; import java.awt.Font; @@ -46,15 +47,21 @@ public class SpielFrame extends JFrame { private ArrayList buttons = new ArrayList<>(); private HashMap belegungen = new HashMap<>(); private JPanel panelLinks, panelRechts, contentPane; + private JButton undo, undo2; private Game game; private Clock clock; private BoardMode mode; + private Zuruecknahme undoMove; private Square selectedSquare; public enum BoardMode { normal, pieceSelected, finished } + + public enum Zuruecknahme { + white, black, nobody + } /** * Create the frame. @@ -88,13 +95,13 @@ public class SpielFrame extends JFrame { // Panel für alle Eingaben von Player 2 panelRechts.add(getUiPlayerTwo()); - + // Panel für Statistikanzeigen panelRechts.add(getUiStatistik()); - //Panel für alle Eingaben von Player 1 + // Panel für alle Eingaben von Player 1 panelRechts.add(getUiPlayerOne()); - + // JSplitPane horizontal (linke und rechte Hälfte) JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, panelLinks, panelRechts); splitPane.setResizeWeight(0.75); @@ -104,21 +111,10 @@ public class SpielFrame extends JFrame { contentPane.add(splitPane, BorderLayout.CENTER); + setVisible(true); } - public void setBoardMode(BoardMode bm) { - this.mode = bm; - } - - public void setSelectedSquare(Square sq) { - this.selectedSquare = sq; - } - - public HashMap getBelegung() { - return this.belegungen; - } - /** * Erstellt alle Buttons und fügt sie dem Frame hinzu. */ @@ -177,6 +173,7 @@ public class SpielFrame extends JFrame { * with new blank ones. */ private void clearButtons() { + buttons.clear(); panelLinks.removeAll(); @@ -221,6 +218,7 @@ public class SpielFrame extends JFrame { switch (this.mode) { case BoardMode.normal: + selectables = game.getAllLegalMoveableSquares(); for (Square square : selectables) { @@ -321,7 +319,7 @@ public class SpielFrame extends JFrame { aufgebenUndo.setLayout(new BoxLayout(aufgebenUndo, BoxLayout.X_AXIS)); if (game.isZuruecknahme()) { - JButton undo = new JButton("Zug zurücknehmen"); + undo = new JButton("Zug zurücknehmen"); undo.setBackground(Color.LIGHT_GRAY); undo.setForeground(Color.BLACK); undo.setFont(new Font("Tahoma", Font.BOLD, 16)); @@ -329,13 +327,9 @@ public class SpielFrame extends JFrame { aufgebenUndo.add(undo); // Button-Listener - undo.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - - } - }); - } + undo.addActionListener(new ButtonUndoMoveListener(this, this.game)); + } + aufgebenUndo.add(Box.createHorizontalStrut(10)); @@ -377,18 +371,18 @@ public class SpielFrame extends JFrame { return playerTwo; } - + private JPanel getUiStatistik() { - + JPanel statistik = new JPanel(); statistik.setBackground(new Color(90, 90, 90)); statistik.setLayout(new BoxLayout(statistik, BoxLayout.Y_AXIS)); - + JTextArea ausgabe = new JTextArea(); ausgabe.setEditable(false); - ausgabe.setBackground(new Color(75,75,75)); + ausgabe.setBackground(new Color(75, 75, 75)); ausgabe.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1)); - + statistik.add(ausgabe); return statistik; } @@ -407,20 +401,16 @@ public class SpielFrame extends JFrame { aufgebenUndo.setLayout(new BoxLayout(aufgebenUndo, BoxLayout.X_AXIS)); if (game.isZuruecknahme()) { - JButton undo = new JButton("Zug zurücknehmen"); - undo.setBackground(Color.LIGHT_GRAY); - undo.setForeground(Color.BLACK); - undo.setFont(new Font("Tahoma", Font.BOLD, 16)); - undo.setAlignmentX(Component.CENTER_ALIGNMENT); - aufgebenUndo.add(undo); + undo2 = new JButton("Zug zurücknehmen"); + undo2.setBackground(Color.LIGHT_GRAY); + undo2.setForeground(Color.BLACK); + undo2.setFont(new Font("Tahoma", Font.BOLD, 16)); + undo2.setAlignmentX(Component.CENTER_ALIGNMENT); + aufgebenUndo.add(undo2); // Button-Listener - undo.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - - } - }); + undo2.addActionListener(new ButtonUndoMoveListener(this, this.game)); + } aufgebenUndo.add(Box.createHorizontalStrut(10)); @@ -456,10 +446,10 @@ public class SpielFrame extends JFrame { } }); - + playerOne.add(aufgebenUndo); - playerOne.add(Box.createVerticalStrut(10)); + playerOne.add(Box.createVerticalStrut(15)); JLabel clock1 = clock.getClock1(); playerOne.add(clock1); @@ -475,5 +465,56 @@ public class SpielFrame extends JFrame { return playerOne; } + + public void undoMove() { + + switch(this.undoMove) { + + case white: + + break; + + case black: + break; + + case nobody: + break; + + default: + break; + } + } + + public void setBoardMode(BoardMode bm) { + this.mode = bm; + } + + public void setSelectedSquare(Square sq) { + this.selectedSquare = sq; + } + + public HashMap getBelegung() { + return this.belegungen; + } + + public void setZuruecknahme(Zuruecknahme z) { + this.undoMove = z; + } + + public JButton getUndo() { + return undo; + } + + public JButton getUndo2() { + return undo2; + } + + public BoardMode getMode() { + return mode; + } + + public Clock getClock() { + return clock; + } } diff --git a/src/main/java/de/mannheim/th/chess/utl/Clock.java b/src/main/java/de/mannheim/th/chess/utl/Clock.java index 13bb9f6..80ea3df 100644 --- a/src/main/java/de/mannheim/th/chess/utl/Clock.java +++ b/src/main/java/de/mannheim/th/chess/utl/Clock.java @@ -59,13 +59,13 @@ public class Clock extends Thread implements Runnable { clock1 = new JLabel("" + minutes + ":00 "); clock1.setBorder(BorderFactory.createEmptyBorder(0, 40, 0, 0)); clock1.setForeground(Color.BLACK); - clock1.setFont(new Font("Calibri", Font.BOLD, 35)); + clock1.setFont(new Font("Calibri", Font.BOLD, 40)); clock1.setAlignmentX(Component.CENTER_ALIGNMENT); clock2 = new JLabel("" + minutes + ":00 "); clock2.setBorder(BorderFactory.createEmptyBorder(0, 40, 0, 0)); clock2.setForeground(Color.BLACK); - clock2.setFont(new Font("Calibri", Font.BOLD, 35)); + clock2.setFont(new Font("Calibri", Font.BOLD, 40)); clock2.setAlignmentX(Component.CENTER_ALIGNMENT); // player1Panel.add(clock1); // player2Panel.add(clock2); @@ -141,6 +141,10 @@ public class Clock extends Thread implements Runnable { break; } } + + public void switchClock() { + whiteToMove = !whiteToMove; + } public JLabel getClock1() { From cf4e465b10b3f846d510f0c880922df61f45ed94 Mon Sep 17 00:00:00 2001 From: Matias <3020772@tud.hs-mannheim.de> Date: Sat, 21 Jun 2025 15:28:32 +0200 Subject: [PATCH 04/12] Statistik ausgabe finished. Spiel laden und speichern funktioniert. --- quellen | 2 +- src/main/java/de/mannheim/th/chess/App.java | 1 - .../controller/ButtonAufgebenListener.java | 22 ++++++ .../controller/ButtonFileLoaderListener.java | 54 ++++++++++++++ .../controller/ButtonFileSaverListener.java | 61 ++++++++++++++++ .../controller/ButtonMovePieceListener.java | 8 ++- .../controller/ButtonToNormalListener.java | 2 + .../controller/ButtonUndoMoveListener.java | 2 + .../de/mannheim/th/chess/domain/Game.java | 24 +++++-- .../de/mannheim/th/chess/ui/GameWindow.java | 2 +- .../de/mannheim/th/chess/ui/MainFrame.java | 42 ++++------- .../th/chess/ui/ModeSelectionFrame.java | 32 ++++++++- .../de/mannheim/th/chess/ui/SpielFrame.java | 72 +++++++------------ 13 files changed, 239 insertions(+), 85 deletions(-) create mode 100644 src/main/java/de/mannheim/th/chess/controller/ButtonAufgebenListener.java create mode 100644 src/main/java/de/mannheim/th/chess/controller/ButtonFileLoaderListener.java create mode 100644 src/main/java/de/mannheim/th/chess/controller/ButtonFileSaverListener.java diff --git a/quellen b/quellen index 246b419..3733f13 100644 --- a/quellen +++ b/quellen @@ -1,2 +1,2 @@ JFileChoser in UI: (mit GPT) -Prompt: "Wie kann ich in swing in java Files aus einem Explorer auswählen?". \ No newline at end of file +Prompt: "Wie kann ich in swing in java Files aus einem Explorer auswählen und speichern?". \ No newline at end of file diff --git a/src/main/java/de/mannheim/th/chess/App.java b/src/main/java/de/mannheim/th/chess/App.java index 1e90163..297b276 100644 --- a/src/main/java/de/mannheim/th/chess/App.java +++ b/src/main/java/de/mannheim/th/chess/App.java @@ -20,7 +20,6 @@ public class App { * @param args */ public static void main(String[] args) { - logger.info("Hello World."); userinterface = new MainFrame(); } } diff --git a/src/main/java/de/mannheim/th/chess/controller/ButtonAufgebenListener.java b/src/main/java/de/mannheim/th/chess/controller/ButtonAufgebenListener.java new file mode 100644 index 0000000..cd14562 --- /dev/null +++ b/src/main/java/de/mannheim/th/chess/controller/ButtonAufgebenListener.java @@ -0,0 +1,22 @@ +package de.mannheim.th.chess.controller; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import javax.swing.JFrame; + +public class ButtonAufgebenListener extends JFrame implements ActionListener{ + + private static final long serialVersionUID = 1L; + + public ButtonAufgebenListener() { + + } + + @Override + public void actionPerformed(ActionEvent e) { + // TODO Auto-generated method stub + + } + +} diff --git a/src/main/java/de/mannheim/th/chess/controller/ButtonFileLoaderListener.java b/src/main/java/de/mannheim/th/chess/controller/ButtonFileLoaderListener.java new file mode 100644 index 0000000..29c8af3 --- /dev/null +++ b/src/main/java/de/mannheim/th/chess/controller/ButtonFileLoaderListener.java @@ -0,0 +1,54 @@ +package de.mannheim.th.chess.controller; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; + +import javax.swing.JFileChooser; +import javax.swing.JFrame; +import javax.swing.JOptionPane; + +import de.mannheim.th.chess.ui.ModeSelectionFrame; + +public class ButtonFileLoaderListener implements ActionListener{ + + private ModeSelectionFrame msf; + + public ButtonFileLoaderListener(ModeSelectionFrame msf) { + this.msf = msf; + + } + + @Override + public void actionPerformed(ActionEvent e) { + // TODO Auto-generated method stub + + JFileChooser dateiWaehler = new JFileChooser(); + JFrame jfFile = new JFrame(); + int auswahl = dateiWaehler.showOpenDialog(jfFile); + + if (auswahl == JFileChooser.APPROVE_OPTION) { + File ausgewaehlteDatei = dateiWaehler.getSelectedFile(); + JOptionPane.showMessageDialog(jfFile, "Gewählte Datei:\n" + ausgewaehlteDatei.getAbsolutePath()); + + try { + BufferedReader br = new BufferedReader(new FileReader(ausgewaehlteDatei)); + + msf.setFen(br.readLine()); + + } catch (FileNotFoundException e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + } catch (IOException e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + } + } + + } + +} diff --git a/src/main/java/de/mannheim/th/chess/controller/ButtonFileSaverListener.java b/src/main/java/de/mannheim/th/chess/controller/ButtonFileSaverListener.java new file mode 100644 index 0000000..2dc2860 --- /dev/null +++ b/src/main/java/de/mannheim/th/chess/controller/ButtonFileSaverListener.java @@ -0,0 +1,61 @@ +package de.mannheim.th.chess.controller; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.util.List; + +import javax.swing.JFileChooser; +import javax.swing.JFrame; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import com.github.bhlangonijr.chesslib.move.Move; + +import de.mannheim.th.chess.App; +import de.mannheim.th.chess.domain.Game; + +public class ButtonFileSaverListener implements ActionListener{ + + private static final Logger logger = LogManager.getLogger(App.class); + + private Game g; + private JFrame sf; + + public ButtonFileSaverListener(JFrame sf, Game g) { + this.sf = sf; + this.g = g; + } + + @Override + public void actionPerformed(ActionEvent e) { + + logger.info("Spiel wird gespeichert."); + + JFileChooser chooser = new JFileChooser(); + chooser.setCurrentDirectory(new File(System.getProperty("user.home") + "/Documents")); + + chooser.setDialogTitle("Datei speichern"); + int userSelection = chooser.showSaveDialog(sf); + + if (userSelection == JFileChooser.APPROVE_OPTION) { + File fileToSave = chooser.getSelectedFile(); + + try (BufferedWriter writer = new BufferedWriter(new FileWriter(fileToSave))) { + + writer.write(g.getFen()); + + logger.info(g.getFen()); + } catch (IOException e1) { + e1.printStackTrace(); + } + } else { + logger.info("Speichern fehlgeschlagen."); + } + } + +} diff --git a/src/main/java/de/mannheim/th/chess/controller/ButtonMovePieceListener.java b/src/main/java/de/mannheim/th/chess/controller/ButtonMovePieceListener.java index 6a80e19..e558354 100644 --- a/src/main/java/de/mannheim/th/chess/controller/ButtonMovePieceListener.java +++ b/src/main/java/de/mannheim/th/chess/controller/ButtonMovePieceListener.java @@ -24,8 +24,6 @@ public class ButtonMovePieceListener implements ActionListener { @Override public void actionPerformed(ActionEvent e) { this.game.playMove(this.mv); - sf.getUndo().setText("Zug zurücknehmen"); - sf.getUndo2().setText("Zug zurücknehmen"); if (this.game.isDraw()) { this.game.stopClock(); @@ -39,5 +37,11 @@ public class ButtonMovePieceListener implements ActionListener { this.sf.setBoardMode(BoardMode.normal); this.sf.setCursor(null); this.sf.erstelleBrett(); + + if (game.getLastMove() != null) { + char[] z = game.getLastMove().toString().toCharArray(); + String moveString = String.valueOf(z[0]) + String.valueOf(z[1]) + " -> " + String.valueOf(z[2]) + String.valueOf(z[3]); + sf.appendText(moveString); + } } } diff --git a/src/main/java/de/mannheim/th/chess/controller/ButtonToNormalListener.java b/src/main/java/de/mannheim/th/chess/controller/ButtonToNormalListener.java index c4261de..ce83e28 100644 --- a/src/main/java/de/mannheim/th/chess/controller/ButtonToNormalListener.java +++ b/src/main/java/de/mannheim/th/chess/controller/ButtonToNormalListener.java @@ -3,6 +3,7 @@ package de.mannheim.th.chess.controller; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import de.mannheim.th.chess.domain.Game; import de.mannheim.th.chess.ui.SpielFrame; import de.mannheim.th.chess.ui.SpielFrame.BoardMode; @@ -19,6 +20,7 @@ public class ButtonToNormalListener implements ActionListener { this.sf.setSelectedSquare(null); this.sf.setCursor(null); this.sf.erstelleBrett(); + } } diff --git a/src/main/java/de/mannheim/th/chess/controller/ButtonUndoMoveListener.java b/src/main/java/de/mannheim/th/chess/controller/ButtonUndoMoveListener.java index f99fae3..6ecbca8 100644 --- a/src/main/java/de/mannheim/th/chess/controller/ButtonUndoMoveListener.java +++ b/src/main/java/de/mannheim/th/chess/controller/ButtonUndoMoveListener.java @@ -45,6 +45,7 @@ public class ButtonUndoMoveListener implements ActionListener { sf.getUndo2().setEnabled(false); game.undo(); sf.getClock().switchClock(); + sf.deleteLastAusgabe(); sf.erstelleBrett(); } } else if (source == sf.getUndo2()) { // Spieler 1 drückt seinen Button @@ -59,6 +60,7 @@ public class ButtonUndoMoveListener implements ActionListener { sf.getUndo().setEnabled(false); game.undo(); sf.getClock().switchClock(); + sf.deleteLastAusgabe(); sf.erstelleBrett(); } } diff --git a/src/main/java/de/mannheim/th/chess/domain/Game.java b/src/main/java/de/mannheim/th/chess/domain/Game.java index edef36f..1cc4649 100644 --- a/src/main/java/de/mannheim/th/chess/domain/Game.java +++ b/src/main/java/de/mannheim/th/chess/domain/Game.java @@ -3,6 +3,9 @@ package de.mannheim.th.chess.domain; import java.util.List; import java.util.stream.Collectors; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + import com.github.bhlangonijr.chesslib.Board; import com.github.bhlangonijr.chesslib.Side; import com.github.bhlangonijr.chesslib.Square; @@ -10,6 +13,7 @@ import com.github.bhlangonijr.chesslib.move.Move; import com.github.bhlangonijr.chesslib.move.MoveList; import com.github.bhlangonijr.chesslib.pgn.PgnHolder; +import de.mannheim.th.chess.App; import de.mannheim.th.chess.ui.SpielFrame; import de.mannheim.th.chess.utl.Clock; @@ -18,6 +22,8 @@ import de.mannheim.th.chess.utl.Clock; * Steuerung davon. */ public class Game { + + private static final Logger logger = LogManager.getLogger(App.class); private Board board; private Clock clock; @@ -30,13 +36,16 @@ public class Game { /** * Conststructs a new standard GameBoard. */ - public Game(String modus, boolean rotieren, boolean zuruecknahme) { + public Game(String modus, boolean rotieren, boolean zuruecknahme, String fen) { this.modus = modus; this.rotieren = rotieren; this.zuruecknahme = zuruecknahme; - this.board = new Board(); + + if(fen == null) fen = board.getFen(); + + this.board.loadFromFen(fen); this.movelist = new MoveList(); @@ -44,8 +53,6 @@ public class Game { sp = new SpielFrame(this); - - } /** @@ -186,4 +193,13 @@ public class Game { } return false; } + + public String getFen() { + return this.board.getFen(); + } + + public Move getLastMove() { + logger.info(this.movelist.getLast().toString()); + return this.movelist.getLast(); + } } diff --git a/src/main/java/de/mannheim/th/chess/ui/GameWindow.java b/src/main/java/de/mannheim/th/chess/ui/GameWindow.java index d220a5c..7fa393f 100644 --- a/src/main/java/de/mannheim/th/chess/ui/GameWindow.java +++ b/src/main/java/de/mannheim/th/chess/ui/GameWindow.java @@ -7,7 +7,7 @@ import de.mannheim.th.chess.domain.Game; */ public class GameWindow{ - private Game gamelogic = new Game(); + //private Game gamelogic = new Game(); public GameWindow() { diff --git a/src/main/java/de/mannheim/th/chess/ui/MainFrame.java b/src/main/java/de/mannheim/th/chess/ui/MainFrame.java index 940cadc..37d8e99 100644 --- a/src/main/java/de/mannheim/th/chess/ui/MainFrame.java +++ b/src/main/java/de/mannheim/th/chess/ui/MainFrame.java @@ -3,12 +3,23 @@ package de.mannheim.th.chess.ui; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.border.EmptyBorder; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import de.mannheim.th.chess.App; +import de.mannheim.th.chess.domain.Game; + import javax.swing.JLabel; import javax.swing.JOptionPane; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.io.BufferedReader; import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; import java.util.ArrayList; import javax.swing.Box; @@ -21,6 +32,8 @@ import java.awt.Font; import java.awt.Color; public class MainFrame extends JFrame { + + private static final Logger logger = LogManager.getLogger(App.class); private static final long serialVersionUID = 1L; private JPanel contentPane; @@ -83,35 +96,6 @@ public class MainFrame extends JFrame { contentPane.add(Box.createVerticalStrut(15)); - JButton btnNewButton_1 = new JButton("Vergangenes Spiel laden"); - - btnNewButton_1.setBackground(Color.LIGHT_GRAY); - btnNewButton_1.setForeground(Color.BLACK); - btnNewButton_1.setFont(new Font("Tahoma", Font.BOLD, 16)); - btnNewButton_1.setAlignmentX(Component.CENTER_ALIGNMENT); - btnNewButton_1.addActionListener(new ActionListener() { - - - @Override - public void actionPerformed(ActionEvent e) { - JFileChooser dateiWaehler = new JFileChooser(); - JFrame jfFile = new JFrame(); - int auswahl = dateiWaehler.showOpenDialog(jfFile); - - if (auswahl == JFileChooser.APPROVE_OPTION) { - File ausgewaehlteDatei = dateiWaehler.getSelectedFile(); - JOptionPane.showMessageDialog(jfFile, "Gewählte Datei:\n" + ausgewaehlteDatei.getAbsolutePath()); - - // Uebergabe zu Logik zum extrahieren der Daten - } - } - - }); - - contentPane.add(btnNewButton_1); - - contentPane.add(Box.createVerticalStrut(15)); - JButton btnNewButton_2 = new JButton("App beenden"); btnNewButton_2.setBackground(Color.LIGHT_GRAY); diff --git a/src/main/java/de/mannheim/th/chess/ui/ModeSelectionFrame.java b/src/main/java/de/mannheim/th/chess/ui/ModeSelectionFrame.java index a83f4a7..fb15899 100644 --- a/src/main/java/de/mannheim/th/chess/ui/ModeSelectionFrame.java +++ b/src/main/java/de/mannheim/th/chess/ui/ModeSelectionFrame.java @@ -3,17 +3,30 @@ package de.mannheim.th.chess.ui; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; import java.util.ArrayList; import javax.swing.*; import javax.swing.border.EmptyBorder; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import de.mannheim.th.chess.App; +import de.mannheim.th.chess.controller.ButtonFileLoaderListener; import de.mannheim.th.chess.domain.Game; public class ModeSelectionFrame extends JFrame { + + private static final Logger logger = LogManager.getLogger(App.class); private static final long serialVersionUID = 1L; private final JPanel contentPane; private final ArrayList spiele = new ArrayList<>(); + private String fen; public ModeSelectionFrame() { // Frame-Eigenschaften @@ -76,6 +89,19 @@ public class ModeSelectionFrame extends JFrame { jb2.setAlignmentX(Component.CENTER_ALIGNMENT); jb2.setMaximumSize(new Dimension(30, 30)); contentPane.add(jb2); + + contentPane.add(Box.createVerticalStrut(15)); + + JButton btnNewButton_1 = new JButton("Vergangenes Spiel laden"); + + btnNewButton_1.setBackground(Color.LIGHT_GRAY); + btnNewButton_1.setForeground(Color.BLACK); + btnNewButton_1.setFont(new Font("Tahoma", Font.BOLD, 16)); + btnNewButton_1.setAlignmentX(Component.CENTER_ALIGNMENT); + btnNewButton_1.addActionListener(new ButtonFileLoaderListener(this)); + + contentPane.add(btnNewButton_1); + contentPane.add(Box.createVerticalStrut(25)); // Spiel starten Button @@ -94,7 +120,7 @@ public class ModeSelectionFrame extends JFrame { boolean rotieren = jb1.isSelected(); boolean zuruecknahme = jb2.isSelected(); - Game game = new Game(modus, rotieren, zuruecknahme); + Game game = new Game(modus, rotieren, zuruecknahme, fen); spiele.add(game); @@ -104,4 +130,8 @@ public class ModeSelectionFrame extends JFrame { setVisible(true); } + + public void setFen(String fen) { + this.fen = fen; + } } diff --git a/src/main/java/de/mannheim/th/chess/ui/SpielFrame.java b/src/main/java/de/mannheim/th/chess/ui/SpielFrame.java index 414f061..86d2d5c 100644 --- a/src/main/java/de/mannheim/th/chess/ui/SpielFrame.java +++ b/src/main/java/de/mannheim/th/chess/ui/SpielFrame.java @@ -9,6 +9,8 @@ import com.github.bhlangonijr.chesslib.move.Move; import de.mannheim.th.chess.App; import de.mannheim.th.chess.domain.Game; import de.mannheim.th.chess.utl.Clock; +import de.mannheim.th.chess.controller.ButtonAufgebenListener; +import de.mannheim.th.chess.controller.ButtonFileSaverListener; import de.mannheim.th.chess.controller.ButtonMovePieceListener; import de.mannheim.th.chess.controller.ButtonSelectPieceListener; import de.mannheim.th.chess.controller.ButtonToNormalListener; @@ -48,6 +50,7 @@ public class SpielFrame extends JFrame { private HashMap belegungen = new HashMap<>(); private JPanel panelLinks, panelRechts, contentPane; private JButton undo, undo2; + private JTextArea ausgabe; private Game game; private Clock clock; @@ -110,7 +113,6 @@ public class SpielFrame extends JFrame { splitPane.setEnabled(false); contentPane.add(splitPane, BorderLayout.CENTER); - setVisible(true); } @@ -235,7 +237,7 @@ public class SpielFrame extends JFrame { JButton s = buttons.get(mirrowedGrid(selectedSquare.ordinal())); s.setEnabled(true); s.setBackground(new Color(165, 42, 42)); - s.addActionListener(new ButtonToNormalListener(this)); // cancel action + s.addActionListener(new ButtonToNormalListener(this)); selectables = game.getLegalMoveableSquares(selectedSquare); @@ -341,12 +343,7 @@ public class SpielFrame extends JFrame { aufgebenUndo.add(aufgeben); // Button-Listener - aufgeben.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - - } - }); + aufgeben.addActionListener(new ButtonAufgebenListener()); aufgebenUndo.add(Box.createHorizontalStrut(10)); @@ -358,12 +355,7 @@ public class SpielFrame extends JFrame { aufgebenUndo.add(safe); // Button-Listener - safe.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - - } - }); + safe.addActionListener(new ButtonFileSaverListener(this, this.game)); playerTwo.add(aufgebenUndo); @@ -378,14 +370,31 @@ public class SpielFrame extends JFrame { statistik.setBackground(new Color(90, 90, 90)); statistik.setLayout(new BoxLayout(statistik, BoxLayout.Y_AXIS)); - JTextArea ausgabe = new JTextArea(); + ausgabe = new JTextArea(); ausgabe.setEditable(false); ausgabe.setBackground(new Color(75, 75, 75)); ausgabe.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1)); + ausgabe.setFont(new Font("Calibri", Font.BOLD, 26)); + ausgabe.setForeground(Color.BLACK); + ausgabe.setText("\n Bisherige Züge:\n"); statistik.add(ausgabe); return statistik; } + + public void appendText(String text) { + ausgabe.append(" "+ text + "\n"); + } + + public void deleteLastAusgabe() { + String[] ausgabe = this.ausgabe.getText().split("\n"); + String textNeu = ""; + for(int i=0;i Date: Mon, 23 Jun 2025 11:16:07 +0200 Subject: [PATCH 05/12] =?UTF-8?q?Ausgabe=20letzter=20Z=C3=BCge=20zu=20verb?= =?UTF-8?q?essern=20angefangen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../th/chess/controller/ButtonMovePieceListener.java | 11 +++++++++-- src/main/java/de/mannheim/th/chess/ui/SpielFrame.java | 9 +++++++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/main/java/de/mannheim/th/chess/controller/ButtonMovePieceListener.java b/src/main/java/de/mannheim/th/chess/controller/ButtonMovePieceListener.java index e558354..5484860 100644 --- a/src/main/java/de/mannheim/th/chess/controller/ButtonMovePieceListener.java +++ b/src/main/java/de/mannheim/th/chess/controller/ButtonMovePieceListener.java @@ -39,8 +39,15 @@ public class ButtonMovePieceListener implements ActionListener { this.sf.erstelleBrett(); if (game.getLastMove() != null) { - char[] z = game.getLastMove().toString().toCharArray(); - String moveString = String.valueOf(z[0]) + String.valueOf(z[1]) + " -> " + String.valueOf(z[2]) + String.valueOf(z[3]); + char[] z = game.getLastMove().toString().toCharArray(); + String moveString = ""; + if(game.getActivePlayer() == 1) { + moveString = " " + String.valueOf(z[0]) + String.valueOf(z[1]) + " -> " + String.valueOf(z[2]) + String.valueOf(z[3]); + }else if(game.getActivePlayer() == 2){ + moveString = String.valueOf(z[0]) + String.valueOf(z[1]) + " -> " + String.valueOf(z[2]) + String.valueOf(z[3]+" "); + } + + sf.appendText(moveString); } } diff --git a/src/main/java/de/mannheim/th/chess/ui/SpielFrame.java b/src/main/java/de/mannheim/th/chess/ui/SpielFrame.java index 86d2d5c..9595f09 100644 --- a/src/main/java/de/mannheim/th/chess/ui/SpielFrame.java +++ b/src/main/java/de/mannheim/th/chess/ui/SpielFrame.java @@ -26,6 +26,7 @@ import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; +import javax.swing.JScrollPane; import javax.swing.JSplitPane; import javax.swing.JTextArea; import javax.swing.JTextField; @@ -377,8 +378,12 @@ public class SpielFrame extends JFrame { ausgabe.setFont(new Font("Calibri", Font.BOLD, 26)); ausgabe.setForeground(Color.BLACK); ausgabe.setText("\n Bisherige Züge:\n"); - - statistik.add(ausgabe); + + JScrollPane scrollPane = new JScrollPane(ausgabe); + scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); + + statistik.add(scrollPane); + return statistik; } From d4e56ea2b6ad6d8f859662e2dab624c95e4da767 Mon Sep 17 00:00:00 2001 From: Your Name Date: Mon, 23 Jun 2025 18:30:34 +0200 Subject: [PATCH 06/12] =?UTF-8?q?Ausgabe=20von=20gezogenen=20Z=C3=BCgen=20?= =?UTF-8?q?versch=C3=B6nert.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/ButtonMovePieceListener.java | 11 +-- .../de/mannheim/th/chess/domain/Game.java | 4 + .../de/mannheim/th/chess/ui/SpielFrame.java | 84 +++++++++++-------- 3 files changed, 52 insertions(+), 47 deletions(-) diff --git a/src/main/java/de/mannheim/th/chess/controller/ButtonMovePieceListener.java b/src/main/java/de/mannheim/th/chess/controller/ButtonMovePieceListener.java index 5484860..ccd1178 100644 --- a/src/main/java/de/mannheim/th/chess/controller/ButtonMovePieceListener.java +++ b/src/main/java/de/mannheim/th/chess/controller/ButtonMovePieceListener.java @@ -1,6 +1,5 @@ package de.mannheim.th.chess.controller; -import java.awt.Color; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; @@ -39,16 +38,8 @@ public class ButtonMovePieceListener implements ActionListener { this.sf.erstelleBrett(); if (game.getLastMove() != null) { - char[] z = game.getLastMove().toString().toCharArray(); - String moveString = ""; - if(game.getActivePlayer() == 1) { - moveString = " " + String.valueOf(z[0]) + String.valueOf(z[1]) + " -> " + String.valueOf(z[2]) + String.valueOf(z[3]); - }else if(game.getActivePlayer() == 2){ - moveString = String.valueOf(z[0]) + String.valueOf(z[1]) + " -> " + String.valueOf(z[2]) + String.valueOf(z[3]+" "); - } - - sf.appendText(moveString); + sf.aktualisiereAusgabe(); } } } diff --git a/src/main/java/de/mannheim/th/chess/domain/Game.java b/src/main/java/de/mannheim/th/chess/domain/Game.java index 1cc4649..fd05817 100644 --- a/src/main/java/de/mannheim/th/chess/domain/Game.java +++ b/src/main/java/de/mannheim/th/chess/domain/Game.java @@ -202,4 +202,8 @@ public class Game { logger.info(this.movelist.getLast().toString()); return this.movelist.getLast(); } + + public MoveList getMoveList() { + return this.movelist; + } } diff --git a/src/main/java/de/mannheim/th/chess/ui/SpielFrame.java b/src/main/java/de/mannheim/th/chess/ui/SpielFrame.java index 9595f09..d2e18d1 100644 --- a/src/main/java/de/mannheim/th/chess/ui/SpielFrame.java +++ b/src/main/java/de/mannheim/th/chess/ui/SpielFrame.java @@ -5,6 +5,7 @@ import org.apache.logging.log4j.Logger; import com.github.bhlangonijr.chesslib.Square; import com.github.bhlangonijr.chesslib.move.Move; +import com.github.bhlangonijr.chesslib.move.MoveList; import de.mannheim.th.chess.App; import de.mannheim.th.chess.domain.Game; @@ -56,16 +57,11 @@ public class SpielFrame extends JFrame { private Clock clock; private BoardMode mode; - private Zuruecknahme undoMove; private Square selectedSquare; public enum BoardMode { normal, pieceSelected, finished } - - public enum Zuruecknahme { - white, black, nobody - } /** * Create the frame. @@ -114,7 +110,7 @@ public class SpielFrame extends JFrame { splitPane.setEnabled(false); contentPane.add(splitPane, BorderLayout.CENTER); - + setVisible(true); } @@ -176,7 +172,7 @@ public class SpielFrame extends JFrame { * with new blank ones. */ private void clearButtons() { - + buttons.clear(); panelLinks.removeAll(); @@ -221,7 +217,7 @@ public class SpielFrame extends JFrame { switch (this.mode) { case BoardMode.normal: - + selectables = game.getAllLegalMoveableSquares(); for (Square square : selectables) { @@ -238,7 +234,7 @@ public class SpielFrame extends JFrame { JButton s = buttons.get(mirrowedGrid(selectedSquare.ordinal())); s.setEnabled(true); s.setBackground(new Color(165, 42, 42)); - s.addActionListener(new ButtonToNormalListener(this)); + s.addActionListener(new ButtonToNormalListener(this)); selectables = game.getLegalMoveableSquares(selectedSquare); @@ -331,8 +327,7 @@ public class SpielFrame extends JFrame { // Button-Listener undo.addActionListener(new ButtonUndoMoveListener(this, this.game)); - } - + } aufgebenUndo.add(Box.createHorizontalStrut(10)); @@ -375,30 +370,49 @@ public class SpielFrame extends JFrame { ausgabe.setEditable(false); ausgabe.setBackground(new Color(75, 75, 75)); ausgabe.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1)); - ausgabe.setFont(new Font("Calibri", Font.BOLD, 26)); + ausgabe.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 20)); ausgabe.setForeground(Color.BLACK); - ausgabe.setText("\n Bisherige Züge:\n"); - + ausgabe.setText("\n Bisherige Züge:\n"); + JScrollPane scrollPane = new JScrollPane(ausgabe); scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); - + statistik.add(scrollPane); - + return statistik; } - - public void appendText(String text) { - ausgabe.append(" "+ text + "\n"); + + public void aktualisiereAusgabe() { + StringBuilder sb = new StringBuilder(); + sb.append("\n Bisherige Züge:\n"); + sb.append(" +------------------+------------------+\n"); + sb.append(" | Player 1: | Player 2: |\n"); + sb.append(" +------------------+------------------+\n"); + + MoveList l = game.getMoveList(); + for (int i = 0; i < l.size(); i += 2) { + String p1 = l.get(i).toString(); + String p2 = (i + 1 < l.size()) ? l.get(i + 1).toString() : ""; + sb.append(String.format(" | %-17s| %-17s|\n", p1, p2)); + sb.append(" +------------------+------------------+\n"); + } + + ausgabe.setText(sb.toString()); } - + + public void deleteLastAusgabe() { - String[] ausgabe = this.ausgabe.getText().split("\n"); - String textNeu = ""; - for(int i=0;i getBelegung() { return this.belegungen; } - - public void setZuruecknahme(Zuruecknahme z) { - this.undoMove = z; - } - + public JButton getUndo() { return undo; } - + public JButton getUndo2() { return undo2; } - + public BoardMode getMode() { return mode; } - + public Clock getClock() { return clock; } From 452a39bf6bfa066253c4aa98a2280e5440a46d75 Mon Sep 17 00:00:00 2001 From: Your Name Date: Mon, 23 Jun 2025 18:35:08 +0200 Subject: [PATCH 07/12] default Konstruktor wiederhergestellt --- src/main/java/de/mannheim/th/chess/domain/Game.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/main/java/de/mannheim/th/chess/domain/Game.java b/src/main/java/de/mannheim/th/chess/domain/Game.java index fd05817..c59d48a 100644 --- a/src/main/java/de/mannheim/th/chess/domain/Game.java +++ b/src/main/java/de/mannheim/th/chess/domain/Game.java @@ -32,6 +32,14 @@ public class Game { private boolean rotieren, zuruecknahme; private MoveList movelist; + + public Game() { + + this.board = new Board(); + this.movelist = new MoveList(); + clock = new Clock("blitz"); + clock.start(); + } /** * Conststructs a new standard GameBoard. From e8bb9e1eee97553fcecd6b499e9183e797047010 Mon Sep 17 00:00:00 2001 From: Your Name Date: Mon, 23 Jun 2025 19:56:37 +0200 Subject: [PATCH 08/12] =?UTF-8?q?Augabe=20gezogener=20Figuren=20mit=20Unic?= =?UTF-8?q?odeanzeige=20erg=C3=A4nzt,=20bzw=20ernuert.=20JUnit=20test=20da?= =?UTF-8?q?zu=20inklusive.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../de/mannheim/th/chess/domain/Game.java | 11 +++++++++- .../de/mannheim/th/chess/ui/MainFrame.java | 9 --------- .../de/mannheim/th/chess/ui/SpielFrame.java | 20 ++++++------------- .../de/mannheim/th/chess/domain/GameTest.java | 9 +++++++++ .../mannheim/th/chess/ui/SpielFrameTest.java | 12 +++++++++++ 5 files changed, 37 insertions(+), 24 deletions(-) create mode 100644 src/test/java/de/mannheim/th/chess/ui/SpielFrameTest.java diff --git a/src/main/java/de/mannheim/th/chess/domain/Game.java b/src/main/java/de/mannheim/th/chess/domain/Game.java index c59d48a..f713aac 100644 --- a/src/main/java/de/mannheim/th/chess/domain/Game.java +++ b/src/main/java/de/mannheim/th/chess/domain/Game.java @@ -177,9 +177,13 @@ public class Game { return this.board.legalMoves().stream().filter(move -> move.getFrom() == square).map(move -> move.getTo()) .collect(Collectors.toList()); } + + public String getUnicodeFromMove(Move move) { + return board.getPiece(move.getTo()).getFanSymbol().toUpperCase(); + } public String toFEN() { - board.toString(); + //board.toString(); return board.getFen(); } @@ -214,4 +218,9 @@ public class Game { public MoveList getMoveList() { return this.movelist; } + + public Board getBoard() { + // TODO Auto-generated method stub + return this.board; + } } diff --git a/src/main/java/de/mannheim/th/chess/ui/MainFrame.java b/src/main/java/de/mannheim/th/chess/ui/MainFrame.java index 37d8e99..73c5010 100644 --- a/src/main/java/de/mannheim/th/chess/ui/MainFrame.java +++ b/src/main/java/de/mannheim/th/chess/ui/MainFrame.java @@ -8,24 +8,15 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import de.mannheim.th.chess.App; -import de.mannheim.th.chess.domain.Game; import javax.swing.JLabel; -import javax.swing.JOptionPane; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -import java.io.BufferedReader; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileReader; -import java.io.IOException; -import java.util.ArrayList; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.JButton; -import javax.swing.JFileChooser; import java.awt.Component; import java.awt.Font; diff --git a/src/main/java/de/mannheim/th/chess/ui/SpielFrame.java b/src/main/java/de/mannheim/th/chess/ui/SpielFrame.java index d2e18d1..cea6abf 100644 --- a/src/main/java/de/mannheim/th/chess/ui/SpielFrame.java +++ b/src/main/java/de/mannheim/th/chess/ui/SpielFrame.java @@ -30,18 +30,16 @@ import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JSplitPane; import javax.swing.JTextArea; -import javax.swing.JTextField; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; -import java.awt.Dimension; + import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.awt.GridLayout; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; + public class SpielFrame extends JFrame { @@ -385,16 +383,10 @@ public class SpielFrame extends JFrame { public void aktualisiereAusgabe() { StringBuilder sb = new StringBuilder(); sb.append("\n Bisherige Züge:\n"); - sb.append(" +------------------+------------------+\n"); - sb.append(" | Player 1: | Player 2: |\n"); - sb.append(" +------------------+------------------+\n"); MoveList l = game.getMoveList(); - for (int i = 0; i < l.size(); i += 2) { - String p1 = l.get(i).toString(); - String p2 = (i + 1 < l.size()) ? l.get(i + 1).toString() : ""; - sb.append(String.format(" | %-17s| %-17s|\n", p1, p2)); - sb.append(" +------------------+------------------+\n"); + for (Move m: l) { + sb.append(" "+game.getUnicodeFromMove(m)+": "+m.toString()+"\n"); } ausgabe.setText(sb.toString()); @@ -405,10 +397,10 @@ public class SpielFrame extends JFrame { String[] zeilen = ausgabe.getText().split("\n"); //es müssen immer mind 5 Zeilen existieren, dass also 1 Zug löschbar ist - if (zeilen.length <= 5) return; + if (zeilen.length <= 2) return; StringBuilder sb = new StringBuilder(); - for (int i = 0; i < zeilen.length - 2; i++) { + for (int i = 0; i < zeilen.length - 1; i++) { sb.append(zeilen[i]).append("\n"); } diff --git a/src/test/java/de/mannheim/th/chess/domain/GameTest.java b/src/test/java/de/mannheim/th/chess/domain/GameTest.java index cdf123e..9a154e5 100644 --- a/src/test/java/de/mannheim/th/chess/domain/GameTest.java +++ b/src/test/java/de/mannheim/th/chess/domain/GameTest.java @@ -52,4 +52,13 @@ public class GameTest { controllList = Arrays.asList(Square.H1, Square.A1); assertEquals(controllList, game.getAllLegalMoveableSquares()); } + + @Test + void getUnicodeFromMoveTest() { + + Game g = new Game(); + Move m = new Move(Square.A2, Square.A4); + g.getBoard().doMove(m); + assertEquals("♙", g.getUnicodeFromMove(m)); + } } diff --git a/src/test/java/de/mannheim/th/chess/ui/SpielFrameTest.java b/src/test/java/de/mannheim/th/chess/ui/SpielFrameTest.java new file mode 100644 index 0000000..0950947 --- /dev/null +++ b/src/test/java/de/mannheim/th/chess/ui/SpielFrameTest.java @@ -0,0 +1,12 @@ +package de.mannheim.th.chess.ui; + +import org.junit.jupiter.api.Test; + +class SpielFrameTest { + + @Test + void mirrowedGridTest() { + + } + +} From 724cde3fd0b48480948b244b8a948a6c241156a3 Mon Sep 17 00:00:00 2001 From: stuckd Date: Tue, 24 Jun 2025 10:17:48 +0200 Subject: [PATCH 09/12] . --- .../de/mannheim/th/chess/domain/Game.java | 81 ++++++++++++++----- .../de/mannheim/th/chess/ui/SpielFrame.java | 60 +++++++++++++- 2 files changed, 120 insertions(+), 21 deletions(-) diff --git a/src/main/java/de/mannheim/th/chess/domain/Game.java b/src/main/java/de/mannheim/th/chess/domain/Game.java index f713aac..c75b421 100644 --- a/src/main/java/de/mannheim/th/chess/domain/Game.java +++ b/src/main/java/de/mannheim/th/chess/domain/Game.java @@ -7,6 +7,8 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import com.github.bhlangonijr.chesslib.Board; +import com.github.bhlangonijr.chesslib.Piece; +import com.github.bhlangonijr.chesslib.Rank; import com.github.bhlangonijr.chesslib.Side; import com.github.bhlangonijr.chesslib.Square; import com.github.bhlangonijr.chesslib.move.Move; @@ -151,11 +153,16 @@ public class Game { public List getLegalMoves(Square square) { return this.board.legalMoves().stream().filter(move -> move.getFrom() == square).collect(Collectors.toList()); - } - - public void stopClock() { - clock.endGame(); - } + } + + public void stopClock() { + clock.endGame(); + } + + public boolean isPromotionMove(Move move) { + return ((move.getTo().getRank().equals(Rank.RANK_8) || move.getTo().getRank().equals(Rank.RANK_1)) && + (board.getPiece(move.getFrom()) == Piece.BLACK_PAWN || board.getPiece(move.getFrom()) == Piece.WHITE_PAWN)); + } /** * Retrieves a list of all legal moveable squares from the current board state. @@ -166,21 +173,55 @@ public class Game { return this.board.legalMoves().stream().map(move -> move.getFrom()).distinct().collect(Collectors.toList()); } - /** - * Retrieves a list of legal moveable squares for a given square. - * - * @param square the Square from which to retrieve legal moveable squares - * @return a List of Square objects representing the legal moveable squares from - * the specified square. - */ - public List getLegalMoveableSquares(Square square) { - return this.board.legalMoves().stream().filter(move -> move.getFrom() == square).map(move -> move.getTo()) - .collect(Collectors.toList()); - } - - public String getUnicodeFromMove(Move move) { - return board.getPiece(move.getTo()).getFanSymbol().toUpperCase(); - } + /** + * Retrieves a list of legal moveable squares for a given square. + * + * @param square the Square from which to retrieve legal moveable squares + * @return a List of Square objects representing the legal moveable squares + * from the specified square. + */ + public List getLegalMoveableSquares(Square square) { + return this.board.legalMoves().stream() + .filter(move -> move.getFrom() == square) + .map(move -> move.getTo()) + .collect(Collectors.toList()); + } + + public void doPromotionMove(int piece, Square origin, Square destination) { + System.out.println(piece); + Piece promotedTo; + switch(piece) { + case 7: + promotedTo = Piece.BLACK_KNIGHT; + break; + case 4: + promotedTo = Piece.BLACK_QUEEN; + break; + case 5: + promotedTo = Piece.BLACK_ROOK; + break; + case 6: + promotedTo = Piece.BLACK_BISHOP; + break; + case 3: + promotedTo = Piece.WHITE_KNIGHT; + break; + case 0: + promotedTo = Piece.WHITE_QUEEN; + break; + case 1: + promotedTo = Piece.WHITE_ROOK; + break; + case 2: + promotedTo = Piece.WHITE_BISHOP; + break; + default: + promotedTo = Piece.WHITE_QUEEN; + } + Move promotionMove = new Move(origin, destination, promotedTo); + board.doMove(promotionMove); + movelist.add(promotionMove); + } public String toFEN() { //board.toString(); diff --git a/src/main/java/de/mannheim/th/chess/ui/SpielFrame.java b/src/main/java/de/mannheim/th/chess/ui/SpielFrame.java index cea6abf..3ef0be7 100644 --- a/src/main/java/de/mannheim/th/chess/ui/SpielFrame.java +++ b/src/main/java/de/mannheim/th/chess/ui/SpielFrame.java @@ -3,6 +3,7 @@ package de.mannheim.th.chess.ui; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import com.github.bhlangonijr.chesslib.Piece; import com.github.bhlangonijr.chesslib.Square; import com.github.bhlangonijr.chesslib.move.Move; import com.github.bhlangonijr.chesslib.move.MoveList; @@ -24,6 +25,7 @@ import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.ImageIcon; import javax.swing.JButton; +import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; @@ -243,7 +245,32 @@ public class SpielFrame extends JFrame { final Move move = new Move(selectedSquare, square); b.setEnabled(true); b.setBackground(new Color(230, 100, 100)); - b.addActionListener(new ButtonMovePieceListener(this, this.game, move)); + for (ActionListener al : b.getActionListeners()) { + b.removeActionListener(al); + } + b.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + if(game.isPromotionMove(move)) { + game.doPromotionMove(showPromotion(), selectedSquare, square); + + } else { + game.playMove(move); + } + if (game.isDraw()) { + game.stopClock(); + mode = BoardMode.finished; + showDraw(); + } else if (game.isMate()) { + game.stopClock(); + mode = BoardMode.finished; + showWin(game.getActivePlayer()); + } + mode = BoardMode.normal; + setCursor(null); + erstelleBrett(); + } + }); } break; @@ -287,6 +314,37 @@ public class SpielFrame extends JFrame { frame.add(jl); frame.setVisible(true); } + + private int showPromotion() { + final int[] result = {-1}; + + + JDialog dialog = new JDialog(this, "Wähle eine Figur", true); + dialog.setLayout(new GridLayout(2, 2)); + dialog.setSize(300, 200); + + int[] pictures = {81, 82, 66, 78, 113, 114, 98, 110}; + + + for (int i = 0; i < 4; i++) { + int index = (game.getActivePlayer() - 1) * 4 + i; + JButton jb = new JButton(); + jb.setIcon(new ImageIcon("src/main/resources/" + pictures[index] + ".png")); + int selectedPiece = index; + jb.addActionListener(e -> { + System.out.println("Test"); + result[0] = selectedPiece; + dialog.dispose(); + }); + dialog.add(jb); + } + + dialog.setLocationRelativeTo(null); + dialog.setVisible(true); + + return result[0]; + } + private JPanel getUiPlayerTwo() { From d5cfa77e09f8148df9dab4f05fe9a187e6f77342 Mon Sep 17 00:00:00 2001 From: dstuck Date: Sat, 21 Jun 2025 15:54:17 +0200 Subject: [PATCH 10/12] undo last merge --- .../de/mannheim/th/chess/ui/SpielFrame.java | 86 ++++++------------- 1 file changed, 28 insertions(+), 58 deletions(-) diff --git a/src/main/java/de/mannheim/th/chess/ui/SpielFrame.java b/src/main/java/de/mannheim/th/chess/ui/SpielFrame.java index 3ef0be7..1f25c89 100644 --- a/src/main/java/de/mannheim/th/chess/ui/SpielFrame.java +++ b/src/main/java/de/mannheim/th/chess/ui/SpielFrame.java @@ -238,48 +238,19 @@ public class SpielFrame extends JFrame { selectables = game.getLegalMoveableSquares(selectedSquare); - for ( - - Square square : selectables) { - JButton b = buttons.get(mirrowedGrid(square.ordinal())); - final Move move = new Move(selectedSquare, square); - b.setEnabled(true); - b.setBackground(new Color(230, 100, 100)); - for (ActionListener al : b.getActionListeners()) { - b.removeActionListener(al); - } - b.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - if(game.isPromotionMove(move)) { - game.doPromotionMove(showPromotion(), selectedSquare, square); - - } else { - game.playMove(move); - } - if (game.isDraw()) { - game.stopClock(); - mode = BoardMode.finished; - showDraw(); - } else if (game.isMate()) { - game.stopClock(); - mode = BoardMode.finished; - showWin(game.getActivePlayer()); - } - mode = BoardMode.normal; - setCursor(null); - erstelleBrett(); - } - }); - } - - break; - - case finished: - clearButtons(); - break; - default: - break; + for (Square square : selectables) { + JButton b = buttons.get(mirrowedGrid(square.ordinal())); + final Move move = new Move(selectedSquare, square); + b.setEnabled(true); + b.setBackground(new Color(230, 100, 100)); + b.addActionListener(new ButtonMovePieceListener(this, this.game, move)); + } + break; + case finished: + clearButtons(); + break; + default: + break; } @@ -323,24 +294,23 @@ public class SpielFrame extends JFrame { dialog.setLayout(new GridLayout(2, 2)); dialog.setSize(300, 200); - int[] pictures = {81, 82, 66, 78, 113, 114, 98, 110}; - + int[] pictures = { 81, 82, 66, 78, 113, 114, 98, 110 }; - for (int i = 0; i < 4; i++) { - int index = (game.getActivePlayer() - 1) * 4 + i; - JButton jb = new JButton(); - jb.setIcon(new ImageIcon("src/main/resources/" + pictures[index] + ".png")); - int selectedPiece = index; - jb.addActionListener(e -> { - System.out.println("Test"); - result[0] = selectedPiece; - dialog.dispose(); - }); - dialog.add(jb); - } + for (int i = 0; i < 4; i++) { + int index = (game.getActivePlayer() - 1) * 4 + i; + JButton jb = new JButton(); + jb.setIcon(new ImageIcon("src/main/resources/" + pictures[index] + ".png")); + int selectedPiece = index; + jb.addActionListener(e -> { + System.out.println("Test"); + result[0] = selectedPiece; + dialog.dispose(); + }); + dialog.add(jb); + } - dialog.setLocationRelativeTo(null); - dialog.setVisible(true); + dialog.setLocationRelativeTo(null); + dialog.setVisible(true); return result[0]; } From cbad409db75f6b5a7d2acc6b6431c9f308d43d15 Mon Sep 17 00:00:00 2001 From: dstuck Date: Sat, 21 Jun 2025 16:09:55 +0200 Subject: [PATCH 11/12] kida fixed promotion --- .../controller/ButtonMovePieceListener.java | 7 +- .../de/mannheim/th/chess/domain/Game.java | 114 ++++++++++++------ 2 files changed, 79 insertions(+), 42 deletions(-) diff --git a/src/main/java/de/mannheim/th/chess/controller/ButtonMovePieceListener.java b/src/main/java/de/mannheim/th/chess/controller/ButtonMovePieceListener.java index ccd1178..83de36c 100644 --- a/src/main/java/de/mannheim/th/chess/controller/ButtonMovePieceListener.java +++ b/src/main/java/de/mannheim/th/chess/controller/ButtonMovePieceListener.java @@ -22,8 +22,11 @@ public class ButtonMovePieceListener implements ActionListener { @Override public void actionPerformed(ActionEvent e) { - this.game.playMove(this.mv); - + if (game.isPromotionMove(this.mv)) + game.doPromotionMove(this.sf.showPromotion(), mv.getFrom(), mv.getTo()); + else + this.game.playMove(this.mv); + if (this.game.isDraw()) { this.game.stopClock(); this.sf.setBoardMode(BoardMode.finished); diff --git a/src/main/java/de/mannheim/th/chess/domain/Game.java b/src/main/java/de/mannheim/th/chess/domain/Game.java index c75b421..963e154 100644 --- a/src/main/java/de/mannheim/th/chess/domain/Game.java +++ b/src/main/java/de/mannheim/th/chess/domain/Game.java @@ -127,6 +127,33 @@ public class Game { this.board.undoMove(); this.movelist.removeLast(); } + /** + * Plays the move on the board and adds it to the movelist + * + * @param origin The square from wich it moves from. + * @param desination The square where it will move to. + */ + public void playMove(Square origin, Square desination) { + Move move = new Move(origin, desination); + this.board.doMove(move); + this.movelist.add(move); + + } + + public boolean isMate() { + return board.isMated(); + } + + public boolean isDraw() { + return board.isDraw(); + } + + public int getActivePlayer() { + if (board.getSideToMove() == Side.WHITE) { + return 1; + } + return 2; + } public boolean isMate() { return board.isMated(); @@ -154,15 +181,15 @@ public class Game { return this.board.legalMoves().stream().filter(move -> move.getFrom() == square).collect(Collectors.toList()); } - + public void stopClock() { - clock.endGame(); + clock.endGame(); } - + public boolean isPromotionMove(Move move) { - return ((move.getTo().getRank().equals(Rank.RANK_8) || move.getTo().getRank().equals(Rank.RANK_1)) && - (board.getPiece(move.getFrom()) == Piece.BLACK_PAWN || board.getPiece(move.getFrom()) == Piece.WHITE_PAWN)); - } + return ((move.getTo().getRank().equals(Rank.RANK_8) || move.getTo().getRank().equals(Rank.RANK_1)) && + (board.getPiece(move.getFrom()) == Piece.BLACK_PAWN || board.getPiece(move.getFrom()) == Piece.WHITE_PAWN)); + } /** * Retrieves a list of all legal moveable squares from the current board state. @@ -186,41 +213,40 @@ public class Game { .map(move -> move.getTo()) .collect(Collectors.toList()); } - + public void doPromotionMove(int piece, Square origin, Square destination) { - System.out.println(piece); - Piece promotedTo; - switch(piece) { - case 7: - promotedTo = Piece.BLACK_KNIGHT; - break; - case 4: - promotedTo = Piece.BLACK_QUEEN; - break; - case 5: - promotedTo = Piece.BLACK_ROOK; - break; - case 6: - promotedTo = Piece.BLACK_BISHOP; - break; - case 3: - promotedTo = Piece.WHITE_KNIGHT; - break; - case 0: - promotedTo = Piece.WHITE_QUEEN; - break; - case 1: - promotedTo = Piece.WHITE_ROOK; - break; - case 2: - promotedTo = Piece.WHITE_BISHOP; - break; - default: - promotedTo = Piece.WHITE_QUEEN; - } - Move promotionMove = new Move(origin, destination, promotedTo); - board.doMove(promotionMove); - movelist.add(promotionMove); + System.out.println(piece); + Piece promotedTo; + switch (piece) { + case 7: + promotedTo = Piece.BLACK_KNIGHT; + break; + case 4: + promotedTo = Piece.BLACK_QUEEN; + break; + case 5: + promotedTo = Piece.BLACK_ROOK; + break; + case 6: + promotedTo = Piece.BLACK_BISHOP; + break; + case 3: + promotedTo = Piece.WHITE_KNIGHT; + break; + case 0: + promotedTo = Piece.WHITE_QUEEN; + break; + case 1: + promotedTo = Piece.WHITE_ROOK; + break; + case 2: + promotedTo = Piece.WHITE_BISHOP; + break; + default: + promotedTo = Piece.WHITE_QUEEN; + } + Move promotionMove = new Move(origin, destination, promotedTo); + playMove(promotionMove); } public String toFEN() { @@ -264,4 +290,12 @@ public class Game { // TODO Auto-generated method stub return this.board; } + public String toFEN() { + board.toString(); + return board.getFen(); + } + + public Square getSelectedSquare() { + return this.getSelectedSquare(); + } } From 5e81b65f512244993e3096d337349ec3fe7b3674 Mon Sep 17 00:00:00 2001 From: stuckd Date: Tue, 24 Jun 2025 10:24:42 +0200 Subject: [PATCH 12/12] fix --- .../de/mannheim/th/chess/domain/Game.java | 295 ++++---- .../de/mannheim/th/chess/ui/SpielFrame.java | 687 +++++++++--------- 2 files changed, 480 insertions(+), 502 deletions(-) diff --git a/src/main/java/de/mannheim/th/chess/domain/Game.java b/src/main/java/de/mannheim/th/chess/domain/Game.java index 963e154..953e759 100644 --- a/src/main/java/de/mannheim/th/chess/domain/Game.java +++ b/src/main/java/de/mannheim/th/chess/domain/Game.java @@ -24,109 +24,105 @@ import de.mannheim.th.chess.utl.Clock; * Steuerung davon. */ public class Game { - - private static final Logger logger = LogManager.getLogger(App.class); - private Board board; - private Clock clock; - private SpielFrame sp; - private String modus; - private boolean rotieren, zuruecknahme; + private static final Logger logger = LogManager.getLogger(App.class); - private MoveList movelist; - - public Game() { - - this.board = new Board(); - this.movelist = new MoveList(); - clock = new Clock("blitz"); - clock.start(); - } + private Board board; + private Clock clock; + private SpielFrame sp; + private String modus; + private boolean rotieren, zuruecknahme; - /** - * Conststructs a new standard GameBoard. - */ - public Game(String modus, boolean rotieren, boolean zuruecknahme, String fen) { - this.modus = modus; - this.rotieren = rotieren; - this.zuruecknahme = zuruecknahme; - - this.board = new Board(); - - if(fen == null) fen = board.getFen(); - - this.board.loadFromFen(fen); + private MoveList movelist; - this.movelist = new MoveList(); - - clock = new Clock(modus); - - sp = new SpielFrame(this); + public Game() { - } + this.board = new Board(); + this.movelist = new MoveList(); + clock = new Clock("blitz"); + clock.start(); + } - /** - * Constructs a new standard GameBoard and applies the provides moves. - * - * @param movelist The list of moves that get played. - */ - public Game(MoveList movelist) { - this.board = new Board(); + /** + * Conststructs a new standard GameBoard. + */ + public Game(String modus, boolean rotieren, boolean zuruecknahme, String fen) { + this.modus = modus; + this.rotieren = rotieren; + this.zuruecknahme = zuruecknahme; - this.movelist = movelist; + this.board = new Board(); - for (Move move : movelist) { - this.board.doMove(move); - } + if (fen == null) + fen = board.getFen(); - // this.clockPlayer1 = new Clock(); - // this.clockPlayer2 = new Clock(); - } + this.board.loadFromFen(fen); - /** - * Constructs a new GameBoard with the provided fen String as the positions. - * - * @param fen The fen String that provides the customs formation. - */ - public Game(String fen) { - this.board = new Board(); - this.board.loadFromFen(fen); + this.movelist = new MoveList(); - this.movelist = new MoveList(); - //this.sp = new SpielFrame(); + clock = new Clock(modus); - // this.clockPlayer1 = new Clock(); - // this.clockPlayer2 = new Clock(); - } + sp = new SpielFrame(this); - /** - * Plays the move on the board and adds it to the movelist - * - * @param move the move to be played - */ - public void playMove(Move move) { - this.board.doMove(move); - this.movelist.add(move); - clock.pressClock(); - } + } - /** - * Plays the move on the board and adds it to the movelist - * - * @param origin The square from wich it moves from. - * @param desination The square where it will move to. - */ - public void playMove(Square origin, Square desination) { - Move move = new Move(origin, desination); - this.board.doMove(move); - this.movelist.add(move); + /** + * Constructs a new standard GameBoard and applies the provides moves. + * + * @param movelist The list of moves that get played. + */ + public Game(MoveList movelist) { + this.board = new Board(); + + this.movelist = movelist; + + for (Move move : movelist) { + this.board.doMove(move); + } + + // this.clockPlayer1 = new Clock(); + // this.clockPlayer2 = new Clock(); + } + + /** + * Constructs a new GameBoard with the provided fen String as the positions. + * + * @param fen The fen String that provides the customs formation. + */ + public Game(String fen) { + this.board = new Board(); + this.board.loadFromFen(fen); + + this.movelist = new MoveList(); + // this.sp = new SpielFrame(); + + // this.clockPlayer1 = new Clock(); + // this.clockPlayer2 = new Clock(); + } + + /** + * Plays the move on the board and adds it to the movelist + * + * @param move the move to be played + */ + public void playMove(Move move) { + this.board.doMove(move); + this.movelist.add(move); + clock.pressClock(); + } + + /** + * Plays the move on the board and adds it to the movelist + * + * @param origin The square from wich it moves from. + * @param desination The square where it will move to. + */ + + public void undo() { + this.board.undoMove(); + this.movelist.removeLast(); + } - } - - public void undo() { - this.board.undoMove(); - this.movelist.removeLast(); - } /** * Plays the move on the board and adds it to the movelist * @@ -155,30 +151,15 @@ public class Game { return 2; } - public boolean isMate() { - return board.isMated(); - } - - public boolean isDraw() { - return board.isDraw(); - } - - public int getActivePlayer() { - if (board.getSideToMove() == Side.WHITE) { - return 1; - } - return 2; - } - - /** - * Retrieves a list of legal moves originating from the specified square. - * - * @param square The square from which to retrieve legal moves. - * - * @return A list of legal moves that originate from the specified square. - */ - public List getLegalMoves(Square square) { - return this.board.legalMoves().stream().filter(move -> move.getFrom() == square).collect(Collectors.toList()); + /** + * Retrieves a list of legal moves originating from the specified square. + * + * @param square The square from which to retrieve legal moves. + * + * @return A list of legal moves that originate from the specified square. + */ + public List getLegalMoves(Square square) { + return this.board.legalMoves().stream().filter(move -> move.getFrom() == square).collect(Collectors.toList()); } @@ -191,14 +172,14 @@ public class Game { (board.getPiece(move.getFrom()) == Piece.BLACK_PAWN || board.getPiece(move.getFrom()) == Piece.WHITE_PAWN)); } - /** - * Retrieves a list of all legal moveable squares from the current board state. - * - * @return a List of Square objects representing all legal moveable squares. - */ - public List getAllLegalMoveableSquares() { - return this.board.legalMoves().stream().map(move -> move.getFrom()).distinct().collect(Collectors.toList()); - } + /** + * Retrieves a list of all legal moveable squares from the current board state. + * + * @return a List of Square objects representing all legal moveable squares. + */ + public List getAllLegalMoveableSquares() { + return this.board.legalMoves().stream().map(move -> move.getFrom()).distinct().collect(Collectors.toList()); + } /** * Retrieves a list of legal moveable squares for a given square. @@ -249,47 +230,43 @@ public class Game { playMove(promotionMove); } - public String toFEN() { - //board.toString(); - return board.getFen(); - } + public void setModus(String modus) { + this.modus = modus; + } - public void setModus(String modus) { - this.modus = modus; - } + public Clock getClock() { + return this.clock; + } - public Clock getClock() { - return this.clock; - } + public boolean isZuruecknahme() { + return zuruecknahme; + } - public boolean isZuruecknahme() { - return zuruecknahme; - } - - public boolean movesNotNull() { - if(movelist.getLast() != null) { - return true; - } - return false; - } - - public String getFen() { - return this.board.getFen(); - } - - public Move getLastMove() { - logger.info(this.movelist.getLast().toString()); - return this.movelist.getLast(); - } - - public MoveList getMoveList() { - return this.movelist; - } + public boolean movesNotNull() { + if (movelist.getLast() != null) { + return true; + } + return false; + } + + public String getFen() { + return this.board.getFen(); + } + + public Move getLastMove() { + logger.info(this.movelist.getLast().toString()); + return this.movelist.getLast(); + } + + public MoveList getMoveList() { + return this.movelist; + } + + public Board getBoard() { + // TODO Auto-generated method stub + return this.board; + } - public Board getBoard() { - // TODO Auto-generated method stub - return this.board; - } public String toFEN() { board.toString(); return board.getFen(); @@ -298,4 +275,8 @@ public class Game { public Square getSelectedSquare() { return this.getSelectedSquare(); } + + public String getUnicodeFromMove(Move move) { + return board.getPiece(move.getTo()).getFanSymbol().toUpperCase(); + } } diff --git a/src/main/java/de/mannheim/th/chess/ui/SpielFrame.java b/src/main/java/de/mannheim/th/chess/ui/SpielFrame.java index 1f25c89..c433e5a 100644 --- a/src/main/java/de/mannheim/th/chess/ui/SpielFrame.java +++ b/src/main/java/de/mannheim/th/chess/ui/SpielFrame.java @@ -42,201 +42,200 @@ import java.util.HashMap; import java.util.List; import java.awt.GridLayout; - public class SpielFrame extends JFrame { - private static final Logger logger = LogManager.getLogger(App.class); + private static final Logger logger = LogManager.getLogger(App.class); - private static final long serialVersionUID = 1L; - private ArrayList buttons = new ArrayList<>(); - private HashMap belegungen = new HashMap<>(); - private JPanel panelLinks, panelRechts, contentPane; - private JButton undo, undo2; - private JTextArea ausgabe; - private Game game; - private Clock clock; + private static final long serialVersionUID = 1L; + private ArrayList buttons = new ArrayList<>(); + private HashMap belegungen = new HashMap<>(); + private JPanel panelLinks, panelRechts, contentPane; + private JButton undo, undo2; + private JTextArea ausgabe; + private Game game; + private Clock clock; - private BoardMode mode; - private Square selectedSquare; + private BoardMode mode; + private Square selectedSquare; - public enum BoardMode { - normal, pieceSelected, finished - } + public enum BoardMode { + normal, pieceSelected, finished + } - /** - * Create the frame. - */ - public SpielFrame(Game game) { + /** + * Create the frame. + */ + public SpielFrame(Game game) { - this.game = game; - this.clock = game.getClock(); - this.clock.start(); + this.game = game; + this.clock = game.getClock(); + this.clock.start(); - mode = BoardMode.normal; + mode = BoardMode.normal; - setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); - setBounds(100, 100, 1920, 1080); - setTitle("Schach"); - setAlwaysOnTop(true); + setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + setBounds(100, 100, 1920, 1080); + setTitle("Schach"); + setAlwaysOnTop(true); - contentPane = new JPanel(); - contentPane.setLayout(new BorderLayout()); - setContentPane(contentPane); + contentPane = new JPanel(); + contentPane.setLayout(new BorderLayout()); + setContentPane(contentPane); - // Linkes Panel mit GridLayout 8x8 für Schachbrett - panelLinks = new JPanel(new GridLayout(8, 8)); + // Linkes Panel mit GridLayout 8x8 für Schachbrett + panelLinks = new JPanel(new GridLayout(8, 8)); - erstelleBrett(); + erstelleBrett(); - // Rechtes Panel für Steuerung oder zusätzliche Eingaben - panelRechts = new JPanel(); - panelRechts.setBackground(new Color(90, 90, 90)); - panelRechts.setLayout(new BoxLayout(panelRechts, BoxLayout.Y_AXIS)); + // Rechtes Panel für Steuerung oder zusätzliche Eingaben + panelRechts = new JPanel(); + panelRechts.setBackground(new Color(90, 90, 90)); + panelRechts.setLayout(new BoxLayout(panelRechts, BoxLayout.Y_AXIS)); - // Panel für alle Eingaben von Player 2 - panelRechts.add(getUiPlayerTwo()); + // Panel für alle Eingaben von Player 2 + panelRechts.add(getUiPlayerTwo()); - // Panel für Statistikanzeigen - panelRechts.add(getUiStatistik()); + // Panel für Statistikanzeigen + panelRechts.add(getUiStatistik()); - // Panel für alle Eingaben von Player 1 - panelRechts.add(getUiPlayerOne()); + // Panel für alle Eingaben von Player 1 + panelRechts.add(getUiPlayerOne()); - // JSplitPane horizontal (linke und rechte Hälfte) - JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, panelLinks, panelRechts); - splitPane.setResizeWeight(0.75); - splitPane.setBackground(Color.BLACK); - splitPane.setDividerSize(1); - splitPane.setEnabled(false); + // JSplitPane horizontal (linke und rechte Hälfte) + JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, panelLinks, panelRechts); + splitPane.setResizeWeight(0.75); + splitPane.setBackground(Color.BLACK); + splitPane.setDividerSize(1); + splitPane.setEnabled(false); - contentPane.add(splitPane, BorderLayout.CENTER); + contentPane.add(splitPane, BorderLayout.CENTER); - setVisible(true); - } + setVisible(true); + } - /** - * Erstellt alle Buttons und fügt sie dem Frame hinzu. - */ - public void erstelleBrett() { + /** + * Erstellt alle Buttons und fügt sie dem Frame hinzu. + */ + public void erstelleBrett() { - this.clearButtons(); - this.setDefaultBackground(); - this.setButtonsActions(); + this.clearButtons(); + this.setDefaultBackground(); + this.setButtonsActions(); - ladeBrett(); + ladeBrett(); - panelLinks.revalidate(); - panelLinks.repaint(); + panelLinks.revalidate(); + panelLinks.repaint(); - } + } - private int mirrowedGrid(int i) { - return 63 - (((i / 8) * 8) + (7 - i % 8)); - } + private int mirrowedGrid(int i) { + return 63 - (((i / 8) * 8) + (7 - i % 8)); + } - /** - * holt sich FEN-Zeichenkette und extrahiert daraus die Positionen der Figuren - */ - private void ladeBrett() { - // System.out.println(game.toFEN()); + /** + * holt sich FEN-Zeichenkette und extrahiert daraus die Positionen der Figuren + */ + private void ladeBrett() { + // System.out.println(game.toFEN()); - char[] fen = game.toFEN().replaceAll("/", "").split(" ")[0].toCharArray(); - int i = 0; - for (int j = 0; j < fen.length; j++) { - if (Character.isDigit(fen[j])) { - int leerfelder = Character.getNumericValue(fen[j]); - for (int k = 0; k < leerfelder; k++) { - belegungen.put(buttons.get(i), "n-n"); - // buttons.get(i).setEnabled(false); // erstmal deaktivieren, weil leere Felder - // nicht ckickbar sein sollten. - i++; - } - continue; - } else if (fen[j] >= 65 && fen[j] <= 90) { // ein Großbuchstabe, also - belegungen.put(buttons.get(i), "w-" + fen[j]); - } else if (fen[j] >= 97 && fen[j] <= 122) { // ein Kleinbuchstabe, also - belegungen.put(buttons.get(i), "b-" + fen[j]); - // buttons.get(i).setEnabled(false); // erstmal deaktivieren, damit weiß - // beginnen kann - } - buttons.get(i).setIcon(new ImageIcon("src/main/resources/" + (int) fen[j] + ".png")); - buttons.get(i).setDisabledIcon(new ImageIcon("src/main/resources/" + (int) fen[j] + ".png")); + char[] fen = game.toFEN().replaceAll("/", "").split(" ")[0].toCharArray(); + int i = 0; + for (int j = 0; j < fen.length; j++) { + if (Character.isDigit(fen[j])) { + int leerfelder = Character.getNumericValue(fen[j]); + for (int k = 0; k < leerfelder; k++) { + belegungen.put(buttons.get(i), "n-n"); + // buttons.get(i).setEnabled(false); // erstmal deaktivieren, weil leere Felder + // nicht ckickbar sein sollten. + i++; + } + continue; + } else if (fen[j] >= 65 && fen[j] <= 90) { // ein Großbuchstabe, also + belegungen.put(buttons.get(i), "w-" + fen[j]); + } else if (fen[j] >= 97 && fen[j] <= 122) { // ein Kleinbuchstabe, also + belegungen.put(buttons.get(i), "b-" + fen[j]); + // buttons.get(i).setEnabled(false); // erstmal deaktivieren, damit weiß + // beginnen kann + } + buttons.get(i).setIcon(new ImageIcon("src/main/resources/" + (int) fen[j] + ".png")); + buttons.get(i).setDisabledIcon(new ImageIcon("src/main/resources/" + (int) fen[j] + ".png")); - i++; + i++; - } - } + } + } - /** - * Clears the existing buttons from the button list, panellinks and fills them - * with new blank ones. - */ - private void clearButtons() { + /** + * Clears the existing buttons from the button list, panellinks and fills them + * with new blank ones. + */ + private void clearButtons() { - buttons.clear(); - panelLinks.removeAll(); + buttons.clear(); + panelLinks.removeAll(); - for (int i = 0; i < 64; i++) { - JButton b = new JButton(); + for (int i = 0; i < 64; i++) { + JButton b = new JButton(); - b.setEnabled(false); + b.setEnabled(false); - // style - b.setFocusPainted(false); - b.setFont(new Font("Arial", Font.PLAIN, 30)); - b.setForeground(Color.WHITE); - b.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1)); - b.setName(i + ""); + // style + b.setFocusPainted(false); + b.setFont(new Font("Arial", Font.PLAIN, 30)); + b.setForeground(Color.WHITE); + b.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1)); + b.setName(i + ""); - buttons.add(b); - } - } + buttons.add(b); + } + } - /** - * Sets the default background color for the buttons in the grid. - */ - private void setDefaultBackground() { - for (int i = 0; i < 64; i++) { - JButton b = buttons.get(i); - if ((i / 8 + i % 8) % 2 == 0) { - // logger.info("Helles Feld erstellt." + i); - b.setBackground(new Color(90, 90, 90)); - } else { - // logger.info("Dunkles Feld erstellt." + i); - b.setBackground(new Color(65, 65, 65)); - } - } - } + /** + * Sets the default background color for the buttons in the grid. + */ + private void setDefaultBackground() { + for (int i = 0; i < 64; i++) { + JButton b = buttons.get(i); + if ((i / 8 + i % 8) % 2 == 0) { + // logger.info("Helles Feld erstellt." + i); + b.setBackground(new Color(90, 90, 90)); + } else { + // logger.info("Dunkles Feld erstellt." + i); + b.setBackground(new Color(65, 65, 65)); + } + } + } - /* - * Switches the button actions depending on the boardmode - */ - private void setButtonsActions() { + /* + * Switches the button actions depending on the boardmode + */ + private void setButtonsActions() { - List selectables; + List selectables; - switch (this.mode) { - case BoardMode.normal: + switch (this.mode) { + case BoardMode.normal: - selectables = game.getAllLegalMoveableSquares(); + selectables = game.getAllLegalMoveableSquares(); - for (Square square : selectables) { - JButton b = buttons.get(mirrowedGrid(square.ordinal())); - b.setEnabled(true); - // b.setBackground(Color.green); - b.addActionListener(new ButtonSelectPieceListener(this, square)); - } + for (Square square : selectables) { + JButton b = buttons.get(mirrowedGrid(square.ordinal())); + b.setEnabled(true); + // b.setBackground(Color.green); + b.addActionListener(new ButtonSelectPieceListener(this, square)); + } - break; + break; - case BoardMode.pieceSelected: + case BoardMode.pieceSelected: - JButton s = buttons.get(mirrowedGrid(selectedSquare.ordinal())); - s.setEnabled(true); - s.setBackground(new Color(165, 42, 42)); - s.addActionListener(new ButtonToNormalListener(this)); + JButton s = buttons.get(mirrowedGrid(selectedSquare.ordinal())); + s.setEnabled(true); + s.setBackground(new Color(165, 42, 42)); + s.addActionListener(new ButtonToNormalListener(this)); - selectables = game.getLegalMoveableSquares(selectedSquare); + selectables = game.getLegalMoveableSquares(selectedSquare); for (Square square : selectables) { JButton b = buttons.get(mirrowedGrid(square.ordinal())); @@ -252,47 +251,46 @@ public class SpielFrame extends JFrame { default: break; - } + } - for (JButton b : buttons) { - panelLinks.add(b); - } - } + for (JButton b : buttons) { + panelLinks.add(b); + } + } - public void showDraw() { - JFrame frame = new JFrame("Result"); - frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - frame.setSize(300, 150); - frame.setLayout(null); + public void showDraw() { + JFrame frame = new JFrame("Result"); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.setSize(300, 150); + frame.setLayout(null); - JLabel jl = new JLabel("1/2 - 1/2"); - jl.setBounds(50, 30, 200, 25); - jl.setFont(new Font("Tahoma", Font.BOLD, 20)); - frame.add(jl); - frame.setVisible(true); + JLabel jl = new JLabel("1/2 - 1/2"); + jl.setBounds(50, 30, 200, 25); + jl.setFont(new Font("Tahoma", Font.BOLD, 20)); + frame.add(jl); + frame.setVisible(true); - } + } - public void showWin(int player) { - JFrame frame = new JFrame("Result"); - frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - frame.setSize(300, 150); - frame.setLayout(null); + public void showWin(int player) { + JFrame frame = new JFrame("Result"); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.setSize(300, 150); + frame.setLayout(null); - JLabel jl = new JLabel(String.format("%d - %d", player / 2, player % 2)); - jl.setBounds(50, 30, 200, 25); - jl.setFont(new Font("Tahoma", Font.BOLD, 20)); - frame.add(jl); - frame.setVisible(true); - } - - private int showPromotion() { - final int[] result = {-1}; + JLabel jl = new JLabel(String.format("%d - %d", player / 2, player % 2)); + jl.setBounds(50, 30, 200, 25); + jl.setFont(new Font("Tahoma", Font.BOLD, 20)); + frame.add(jl); + frame.setVisible(true); + } - - JDialog dialog = new JDialog(this, "Wähle eine Figur", true); - dialog.setLayout(new GridLayout(2, 2)); - dialog.setSize(300, 200); + public int showPromotion() { + final int[] result = { -1 }; + + JDialog dialog = new JDialog(this, "Wähle eine Figur", true); + dialog.setLayout(new GridLayout(2, 2)); + dialog.setSize(300, 200); int[] pictures = { 81, 82, 66, 78, 113, 114, 98, 110 }; @@ -312,224 +310,223 @@ public class SpielFrame extends JFrame { dialog.setLocationRelativeTo(null); dialog.setVisible(true); - return result[0]; - } - + return result[0]; + } - private JPanel getUiPlayerTwo() { + private JPanel getUiPlayerTwo() { - JPanel playerTwo = new JPanel(); - playerTwo.setBackground(new Color(90, 90, 90)); - playerTwo.setLayout(new BoxLayout(playerTwo, BoxLayout.Y_AXIS)); + JPanel playerTwo = new JPanel(); + playerTwo.setBackground(new Color(90, 90, 90)); + playerTwo.setLayout(new BoxLayout(playerTwo, BoxLayout.Y_AXIS)); - playerTwo.add(Box.createVerticalStrut(15)); + playerTwo.add(Box.createVerticalStrut(15)); - JLabel pl2 = new JLabel("Player 2:"); - pl2.setBorder(BorderFactory.createEmptyBorder(0, 20, 0, 0)); - pl2.setFont(new Font("Calibri", Font.BOLD, 35)); - pl2.setForeground(Color.BLACK); - pl2.setAlignmentX(Component.CENTER_ALIGNMENT); - playerTwo.add(pl2); + JLabel pl2 = new JLabel("Player 2:"); + pl2.setBorder(BorderFactory.createEmptyBorder(0, 20, 0, 0)); + pl2.setFont(new Font("Calibri", Font.BOLD, 35)); + pl2.setForeground(Color.BLACK); + pl2.setAlignmentX(Component.CENTER_ALIGNMENT); + playerTwo.add(pl2); - playerTwo.add(Box.createVerticalStrut(10)); + playerTwo.add(Box.createVerticalStrut(10)); - JLabel clock1 = clock.getClock2(); - playerTwo.add(clock1); + JLabel clock1 = clock.getClock2(); + playerTwo.add(clock1); - playerTwo.add(Box.createVerticalStrut(10)); + playerTwo.add(Box.createVerticalStrut(10)); - // Button zurücknahme und aufgeben für Player 2 - JPanel aufgebenUndo = new JPanel(); - aufgebenUndo.setBackground(new Color(90, 90, 90)); - aufgebenUndo.setLayout(new BoxLayout(aufgebenUndo, BoxLayout.X_AXIS)); + // Button zurücknahme und aufgeben für Player 2 + JPanel aufgebenUndo = new JPanel(); + aufgebenUndo.setBackground(new Color(90, 90, 90)); + aufgebenUndo.setLayout(new BoxLayout(aufgebenUndo, BoxLayout.X_AXIS)); - if (game.isZuruecknahme()) { - undo = new JButton("Zug zurücknehmen"); - undo.setBackground(Color.LIGHT_GRAY); - undo.setForeground(Color.BLACK); - undo.setFont(new Font("Tahoma", Font.BOLD, 16)); - undo.setAlignmentX(Component.CENTER_ALIGNMENT); - aufgebenUndo.add(undo); + if (game.isZuruecknahme()) { + undo = new JButton("Zug zurücknehmen"); + undo.setBackground(Color.LIGHT_GRAY); + undo.setForeground(Color.BLACK); + undo.setFont(new Font("Tahoma", Font.BOLD, 16)); + undo.setAlignmentX(Component.CENTER_ALIGNMENT); + aufgebenUndo.add(undo); - // Button-Listener - undo.addActionListener(new ButtonUndoMoveListener(this, this.game)); - } + // Button-Listener + undo.addActionListener(new ButtonUndoMoveListener(this, this.game)); + } - aufgebenUndo.add(Box.createHorizontalStrut(10)); + aufgebenUndo.add(Box.createHorizontalStrut(10)); - JButton aufgeben = new JButton("Aufgeben"); - aufgeben.setBackground(Color.LIGHT_GRAY); - aufgeben.setForeground(Color.BLACK); - aufgeben.setFont(new Font("Tahoma", Font.BOLD, 16)); - aufgeben.setAlignmentX(Component.CENTER_ALIGNMENT); - aufgebenUndo.add(aufgeben); + JButton aufgeben = new JButton("Aufgeben"); + aufgeben.setBackground(Color.LIGHT_GRAY); + aufgeben.setForeground(Color.BLACK); + aufgeben.setFont(new Font("Tahoma", Font.BOLD, 16)); + aufgeben.setAlignmentX(Component.CENTER_ALIGNMENT); + aufgebenUndo.add(aufgeben); - // Button-Listener - aufgeben.addActionListener(new ButtonAufgebenListener()); + // Button-Listener + aufgeben.addActionListener(new ButtonAufgebenListener()); - aufgebenUndo.add(Box.createHorizontalStrut(10)); + aufgebenUndo.add(Box.createHorizontalStrut(10)); - JButton safe = new JButton("Spielstand sichern"); - safe.setBackground(Color.LIGHT_GRAY); - safe.setForeground(Color.BLACK); - safe.setFont(new Font("Tahoma", Font.BOLD, 16)); - safe.setAlignmentX(Component.CENTER_ALIGNMENT); - aufgebenUndo.add(safe); + JButton safe = new JButton("Spielstand sichern"); + safe.setBackground(Color.LIGHT_GRAY); + safe.setForeground(Color.BLACK); + safe.setFont(new Font("Tahoma", Font.BOLD, 16)); + safe.setAlignmentX(Component.CENTER_ALIGNMENT); + aufgebenUndo.add(safe); - // Button-Listener - safe.addActionListener(new ButtonFileSaverListener(this, this.game)); + // Button-Listener + safe.addActionListener(new ButtonFileSaverListener(this, this.game)); - playerTwo.add(aufgebenUndo); + playerTwo.add(aufgebenUndo); - playerTwo.add(Box.createVerticalStrut(10)); + playerTwo.add(Box.createVerticalStrut(10)); - return playerTwo; - } + return playerTwo; + } - private JPanel getUiStatistik() { + private JPanel getUiStatistik() { - JPanel statistik = new JPanel(); - statistik.setBackground(new Color(90, 90, 90)); - statistik.setLayout(new BoxLayout(statistik, BoxLayout.Y_AXIS)); + JPanel statistik = new JPanel(); + statistik.setBackground(new Color(90, 90, 90)); + statistik.setLayout(new BoxLayout(statistik, BoxLayout.Y_AXIS)); - ausgabe = new JTextArea(); - ausgabe.setEditable(false); - ausgabe.setBackground(new Color(75, 75, 75)); - ausgabe.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1)); - ausgabe.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 20)); - ausgabe.setForeground(Color.BLACK); - ausgabe.setText("\n Bisherige Züge:\n"); + ausgabe = new JTextArea(); + ausgabe.setEditable(false); + ausgabe.setBackground(new Color(75, 75, 75)); + ausgabe.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1)); + ausgabe.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 20)); + ausgabe.setForeground(Color.BLACK); + ausgabe.setText("\n Bisherige Züge:\n"); - JScrollPane scrollPane = new JScrollPane(ausgabe); - scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); + JScrollPane scrollPane = new JScrollPane(ausgabe); + scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); - statistik.add(scrollPane); + statistik.add(scrollPane); - return statistik; - } + return statistik; + } - public void aktualisiereAusgabe() { - StringBuilder sb = new StringBuilder(); - sb.append("\n Bisherige Züge:\n"); + public void aktualisiereAusgabe() { + StringBuilder sb = new StringBuilder(); + sb.append("\n Bisherige Züge:\n"); - MoveList l = game.getMoveList(); - for (Move m: l) { - sb.append(" "+game.getUnicodeFromMove(m)+": "+m.toString()+"\n"); - } + MoveList l = game.getMoveList(); + for (Move m : l) { + sb.append(" " + game.getUnicodeFromMove(m) + ": " + m.toString() + "\n"); + } - ausgabe.setText(sb.toString()); - } + ausgabe.setText(sb.toString()); + } + public void deleteLastAusgabe() { + String[] zeilen = ausgabe.getText().split("\n"); - public void deleteLastAusgabe() { - String[] zeilen = ausgabe.getText().split("\n"); + // es müssen immer mind 5 Zeilen existieren, dass also 1 Zug löschbar ist + if (zeilen.length <= 2) + return; - //es müssen immer mind 5 Zeilen existieren, dass also 1 Zug löschbar ist - if (zeilen.length <= 2) return; + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < zeilen.length - 1; i++) { + sb.append(zeilen[i]).append("\n"); + } - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < zeilen.length - 1; i++) { - sb.append(zeilen[i]).append("\n"); - } + ausgabe.setText(sb.toString()); + } - ausgabe.setText(sb.toString()); - } + private JPanel getUiPlayerOne() { - private JPanel getUiPlayerOne() { + JPanel playerOne = new JPanel(); + playerOne.setBackground(new Color(90, 90, 90)); + playerOne.setLayout(new BoxLayout(playerOne, BoxLayout.Y_AXIS)); - JPanel playerOne = new JPanel(); - playerOne.setBackground(new Color(90, 90, 90)); - playerOne.setLayout(new BoxLayout(playerOne, BoxLayout.Y_AXIS)); + playerOne.add(Box.createVerticalStrut(10)); - playerOne.add(Box.createVerticalStrut(10)); + // Button zurücknahme und aufgeben für Player 1 + JPanel aufgebenUndo = new JPanel(); + aufgebenUndo.setBackground(new Color(90, 90, 90)); + aufgebenUndo.setLayout(new BoxLayout(aufgebenUndo, BoxLayout.X_AXIS)); - // Button zurücknahme und aufgeben für Player 1 - JPanel aufgebenUndo = new JPanel(); - aufgebenUndo.setBackground(new Color(90, 90, 90)); - aufgebenUndo.setLayout(new BoxLayout(aufgebenUndo, BoxLayout.X_AXIS)); + if (game.isZuruecknahme()) { + undo2 = new JButton("Zug zurücknehmen"); + undo2.setBackground(Color.LIGHT_GRAY); + undo2.setForeground(Color.BLACK); + undo2.setFont(new Font("Tahoma", Font.BOLD, 16)); + undo2.setAlignmentX(Component.CENTER_ALIGNMENT); + aufgebenUndo.add(undo2); - if (game.isZuruecknahme()) { - undo2 = new JButton("Zug zurücknehmen"); - undo2.setBackground(Color.LIGHT_GRAY); - undo2.setForeground(Color.BLACK); - undo2.setFont(new Font("Tahoma", Font.BOLD, 16)); - undo2.setAlignmentX(Component.CENTER_ALIGNMENT); - aufgebenUndo.add(undo2); + // Button-Listener + undo2.addActionListener(new ButtonUndoMoveListener(this, this.game)); - // Button-Listener - undo2.addActionListener(new ButtonUndoMoveListener(this, this.game)); + } - } + aufgebenUndo.add(Box.createHorizontalStrut(10)); - aufgebenUndo.add(Box.createHorizontalStrut(10)); + JButton aufgeben = new JButton("Aufgeben"); + aufgeben.setBackground(Color.LIGHT_GRAY); + aufgeben.setForeground(Color.BLACK); + aufgeben.setFont(new Font("Tahoma", Font.BOLD, 16)); + aufgeben.setAlignmentX(Component.CENTER_ALIGNMENT); + aufgebenUndo.add(aufgeben); - JButton aufgeben = new JButton("Aufgeben"); - aufgeben.setBackground(Color.LIGHT_GRAY); - aufgeben.setForeground(Color.BLACK); - aufgeben.setFont(new Font("Tahoma", Font.BOLD, 16)); - aufgeben.setAlignmentX(Component.CENTER_ALIGNMENT); - aufgebenUndo.add(aufgeben); + // Button-Listener + aufgeben.addActionListener(new ButtonAufgebenListener()); - // Button-Listener - aufgeben.addActionListener(new ButtonAufgebenListener()); + aufgebenUndo.add(Box.createHorizontalStrut(10)); - aufgebenUndo.add(Box.createHorizontalStrut(10)); + JButton safe = new JButton("Spielstand sichern"); + safe.setBackground(Color.LIGHT_GRAY); + safe.setForeground(Color.BLACK); + safe.setFont(new Font("Tahoma", Font.BOLD, 16)); + safe.setAlignmentX(Component.CENTER_ALIGNMENT); + aufgebenUndo.add(safe); - JButton safe = new JButton("Spielstand sichern"); - safe.setBackground(Color.LIGHT_GRAY); - safe.setForeground(Color.BLACK); - safe.setFont(new Font("Tahoma", Font.BOLD, 16)); - safe.setAlignmentX(Component.CENTER_ALIGNMENT); - aufgebenUndo.add(safe); + // Button-Listener + safe.addActionListener(new ButtonFileSaverListener(this, this.game)); - // Button-Listener - safe.addActionListener(new ButtonFileSaverListener(this, this.game)); + playerOne.add(aufgebenUndo); - playerOne.add(aufgebenUndo); + playerOne.add(Box.createVerticalStrut(15)); - playerOne.add(Box.createVerticalStrut(15)); + JLabel clock1 = clock.getClock1(); + playerOne.add(clock1); - JLabel clock1 = clock.getClock1(); - playerOne.add(clock1); + playerOne.add(Box.createVerticalStrut(10)); - playerOne.add(Box.createVerticalStrut(10)); + JLabel pl2 = new JLabel("Player 1:"); + pl2.setBorder(BorderFactory.createEmptyBorder(0, 20, 0, 0)); + pl2.setFont(new Font("Calibri", Font.BOLD, 35)); + pl2.setForeground(Color.BLACK); + pl2.setAlignmentX(Component.CENTER_ALIGNMENT); + playerOne.add(pl2); - JLabel pl2 = new JLabel("Player 1:"); - pl2.setBorder(BorderFactory.createEmptyBorder(0, 20, 0, 0)); - pl2.setFont(new Font("Calibri", Font.BOLD, 35)); - pl2.setForeground(Color.BLACK); - pl2.setAlignmentX(Component.CENTER_ALIGNMENT); - playerOne.add(pl2); + return playerOne; + } - return playerOne; - } + public void setBoardMode(BoardMode bm) { + this.mode = bm; + } - public void setBoardMode(BoardMode bm) { - this.mode = bm; - } + public void setSelectedSquare(Square sq) { + this.selectedSquare = sq; + } - public void setSelectedSquare(Square sq) { - this.selectedSquare = sq; - } + public HashMap getBelegung() { + return this.belegungen; + } - public HashMap getBelegung() { - return this.belegungen; - } + public JButton getUndo() { + return undo; + } - public JButton getUndo() { - return undo; - } + public JButton getUndo2() { + return undo2; + } - public JButton getUndo2() { - return undo2; - } + public BoardMode getMode() { + return mode; + } - public BoardMode getMode() { - return mode; - } - - public Clock getClock() { - return clock; - } + public Clock getClock() { + return clock; + } }