Added tool panel and event system for check notification
+ GameEvent and GameEventListener + Check detection and notification in Board and BoardPanel + Tool panel in Chess with a restart button
This commit is contained in:
parent
4b274e3d0f
commit
30074f385e
@ -1,8 +1,13 @@
|
|||||||
package dev.kske.chess;
|
package dev.kske.chess;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import dev.kske.chess.event.GameEvent;
|
||||||
|
import dev.kske.chess.event.GameEvent.GameEventType;
|
||||||
|
import dev.kske.chess.event.GameEventListener;
|
||||||
import dev.kske.chess.piece.Bishop;
|
import dev.kske.chess.piece.Bishop;
|
||||||
import dev.kske.chess.piece.King;
|
import dev.kske.chess.piece.King;
|
||||||
import dev.kske.chess.piece.Knight;
|
import dev.kske.chess.piece.Knight;
|
||||||
@ -24,9 +29,12 @@ public class Board {
|
|||||||
private Piece[][] boardArr;
|
private Piece[][] boardArr;
|
||||||
private Map<Color, Position> kingPos;
|
private Map<Color, Position> kingPos;
|
||||||
|
|
||||||
|
private List<GameEventListener> gameEventListeners;
|
||||||
|
|
||||||
public Board() {
|
public Board() {
|
||||||
boardArr = new Piece[8][8];
|
boardArr = new Piece[8][8];
|
||||||
kingPos = new HashMap<>();
|
kingPos = new HashMap<>();
|
||||||
|
gameEventListeners = new ArrayList<>();
|
||||||
initializeDefaultPositions();
|
initializeDefaultPositions();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,6 +60,13 @@ public class Board {
|
|||||||
revert(move, capturePiece);
|
revert(move, capturePiece);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: detecting checkmate
|
||||||
|
// Check for check on the opposite team
|
||||||
|
Color oppositeColor = piece.getColor() == Color.WHITE ? Color.BLACK : Color.WHITE;
|
||||||
|
if (checkCheck(oppositeColor))
|
||||||
|
notifyListeners(new GameEvent(this, GameEventType.CHECK, oppositeColor));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -80,6 +95,14 @@ public class Board {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void registerGameEventListener(GameEventListener listener) {
|
||||||
|
gameEventListeners.add(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void notifyListeners(GameEvent evt) {
|
||||||
|
gameEventListeners.forEach(listener -> listener.onGameEvent(evt));
|
||||||
|
}
|
||||||
|
|
||||||
public Piece get(Position pos) {
|
public Piece get(Position pos) {
|
||||||
return boardArr[pos.x][pos.y];
|
return boardArr[pos.x][pos.y];
|
||||||
}
|
}
|
||||||
@ -107,7 +130,7 @@ public class Board {
|
|||||||
/**
|
/**
|
||||||
* Initialized the board array with the default chess pieces and positions.
|
* Initialized the board array with the default chess pieces and positions.
|
||||||
*/
|
*/
|
||||||
private void initializeDefaultPositions() {
|
public void initializeDefaultPositions() {
|
||||||
// Initialize pawns
|
// Initialize pawns
|
||||||
for (int i = 0; i < 8; i++) {
|
for (int i = 0; i < 8; i++) {
|
||||||
boardArr[i][1] = new Pawn(Color.BLACK, this);
|
boardArr[i][1] = new Pawn(Color.BLACK, this);
|
||||||
@ -143,6 +166,11 @@ public class Board {
|
|||||||
boardArr[2][7] = new Bishop(Color.WHITE, this);
|
boardArr[2][7] = new Bishop(Color.WHITE, this);
|
||||||
boardArr[5][0] = new Bishop(Color.BLACK, this);
|
boardArr[5][0] = new Bishop(Color.BLACK, this);
|
||||||
boardArr[5][7] = new Bishop(Color.WHITE, this);
|
boardArr[5][7] = new Bishop(Color.WHITE, this);
|
||||||
|
|
||||||
|
// Clear all other tiles
|
||||||
|
for (int i = 0; i < 8; i++)
|
||||||
|
for (int j = 2; j < 6; j++)
|
||||||
|
boardArr[i][j] = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -13,8 +13,11 @@ import java.io.File;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.swing.JOptionPane;
|
||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
|
|
||||||
|
import dev.kske.chess.event.GameEvent;
|
||||||
|
import dev.kske.chess.event.GameEventListener;
|
||||||
import dev.kske.chess.piece.Piece;
|
import dev.kske.chess.piece.Piece;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -27,7 +30,7 @@ import dev.kske.chess.piece.Piece;
|
|||||||
* this must be added to a parent component that allows the child to decide the
|
* this must be added to a parent component that allows the child to decide the
|
||||||
* size.
|
* size.
|
||||||
*/
|
*/
|
||||||
public class BoardPanel extends JPanel {
|
public class BoardPanel extends JPanel implements GameEventListener {
|
||||||
|
|
||||||
private static final long serialVersionUID = 6771148331334310216L;
|
private static final long serialVersionUID = 6771148331334310216L;
|
||||||
|
|
||||||
@ -37,14 +40,11 @@ public class BoardPanel extends JPanel {
|
|||||||
|
|
||||||
private Board board;
|
private Board board;
|
||||||
|
|
||||||
static {
|
|
||||||
loadPieceTextures();
|
|
||||||
}
|
|
||||||
|
|
||||||
public BoardPanel(Board board) {
|
public BoardPanel(Board board) {
|
||||||
this();
|
this();
|
||||||
setSize(getPreferredSize());
|
setSize(getPreferredSize());
|
||||||
setBoard(board);
|
setBoard(board);
|
||||||
|
if (textures == null) loadPieceTextures();
|
||||||
}
|
}
|
||||||
|
|
||||||
public BoardPanel() {
|
public BoardPanel() {
|
||||||
@ -99,6 +99,23 @@ public class BoardPanel extends JPanel {
|
|||||||
g.drawImage(getPieceTexture(board.getBoardArr()[i][j]), i * tileSize, j * tileSize, this);
|
g.drawImage(getPieceTexture(board.getBoardArr()[i][j]), i * tileSize, j * tileSize, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onGameEvent(GameEvent evt) {
|
||||||
|
switch (evt.getEventType()) {
|
||||||
|
case CHECK:
|
||||||
|
JOptionPane.showMessageDialog(this, evt.getColor().toString() + " in check!");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverts the board to its initial state
|
||||||
|
*/
|
||||||
|
public void reset() {
|
||||||
|
board.initializeDefaultPositions();
|
||||||
|
repaint();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load every PNG file inside the res/pieces directory.
|
* Load every PNG file inside the res/pieces directory.
|
||||||
* The filenames without extensions are used as keys in the map textures.
|
* The filenames without extensions are used as keys in the map textures.
|
||||||
@ -140,5 +157,10 @@ public class BoardPanel extends JPanel {
|
|||||||
|
|
||||||
public Board getBoard() { return board; }
|
public Board getBoard() { return board; }
|
||||||
|
|
||||||
public void setBoard(Board board) { this.board = board; }
|
public void setBoard(Board board) {
|
||||||
|
this.board = board;
|
||||||
|
|
||||||
|
// Register this BoardPanel as a GameEventListener to the board
|
||||||
|
board.registerGameEventListener(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,9 @@ package dev.kske.chess;
|
|||||||
import java.awt.BorderLayout;
|
import java.awt.BorderLayout;
|
||||||
import java.awt.EventQueue;
|
import java.awt.EventQueue;
|
||||||
|
|
||||||
|
import javax.swing.JButton;
|
||||||
import javax.swing.JFrame;
|
import javax.swing.JFrame;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -46,13 +48,19 @@ public class Chess {
|
|||||||
private void initialize() {
|
private void initialize() {
|
||||||
mframe = new JFrame();
|
mframe = new JFrame();
|
||||||
mframe.setResizable(false);
|
mframe.setResizable(false);
|
||||||
mframe.setBounds(100, 100, 729, 737);
|
mframe.setBounds(100, 100, 494, 565);
|
||||||
mframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
mframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||||
|
|
||||||
BoardPanel boardPanel = new BoardPanel(new Board());
|
BoardPanel boardPanel = new BoardPanel(new Board());
|
||||||
boardPanel.setLayout(null);
|
boardPanel.setLayout(null);
|
||||||
mframe.getContentPane().add(boardPanel, BorderLayout.CENTER);
|
mframe.getContentPane().add(boardPanel, BorderLayout.CENTER);
|
||||||
|
|
||||||
|
JPanel toolPanel = new JPanel();
|
||||||
|
mframe.getContentPane().add(toolPanel, BorderLayout.NORTH);
|
||||||
|
|
||||||
|
JButton btnRestart = new JButton("Restart");
|
||||||
|
btnRestart.addActionListener((evt) -> boardPanel.reset());
|
||||||
|
toolPanel.add(btnRestart);
|
||||||
mframe.pack();
|
mframe.pack();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
38
src/dev/kske/chess/event/GameEvent.java
Normal file
38
src/dev/kske/chess/event/GameEvent.java
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
package dev.kske.chess.event;
|
||||||
|
|
||||||
|
import java.util.EventObject;
|
||||||
|
|
||||||
|
import dev.kske.chess.Board;
|
||||||
|
import dev.kske.chess.piece.Piece.Color;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Project: <strong>Chess</strong><br>
|
||||||
|
* File: <strong>GameEvent.java</strong><br>
|
||||||
|
* Created: <strong>03.07.2019</strong><br>
|
||||||
|
* Author: <strong>Kai S. K. Engelbart</strong>
|
||||||
|
*/
|
||||||
|
public class GameEvent extends EventObject {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = -6783035746521826589L;
|
||||||
|
|
||||||
|
private final Board source;
|
||||||
|
private final GameEventType eventType;
|
||||||
|
private final Color color;
|
||||||
|
|
||||||
|
public GameEvent(Board source, GameEventType eventType, Color color) {
|
||||||
|
super(source);
|
||||||
|
this.source = source;
|
||||||
|
this.eventType = eventType;
|
||||||
|
this.color = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Board getSource() { return source; }
|
||||||
|
|
||||||
|
public GameEventType getEventType() { return eventType; }
|
||||||
|
|
||||||
|
public Color getColor() { return color; }
|
||||||
|
|
||||||
|
public static enum GameEventType {
|
||||||
|
CHECK, CHECKMATE
|
||||||
|
}
|
||||||
|
}
|
12
src/dev/kske/chess/event/GameEventListener.java
Normal file
12
src/dev/kske/chess/event/GameEventListener.java
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
package dev.kske.chess.event;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Project: <strong>Chess</strong><br>
|
||||||
|
* File: <strong>GameEventListener.java</strong><br>
|
||||||
|
* Created: <strong>03.07.2019</strong><br>
|
||||||
|
* Author: <strong>Kai S. K. Engelbart</strong>
|
||||||
|
*/
|
||||||
|
public interface GameEventListener {
|
||||||
|
|
||||||
|
void onGameEvent(GameEvent evt);
|
||||||
|
}
|
Reference in New Issue
Block a user