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:
		| @@ -1,8 +1,13 @@ | ||||
| package dev.kske.chess; | ||||
|  | ||||
| import java.util.ArrayList; | ||||
| import java.util.HashMap; | ||||
| import java.util.List; | ||||
| 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.King; | ||||
| import dev.kske.chess.piece.Knight; | ||||
| @@ -24,9 +29,12 @@ public class Board { | ||||
| 	private Piece[][]				boardArr; | ||||
| 	private Map<Color, Position>	kingPos; | ||||
|  | ||||
| 	private List<GameEventListener> gameEventListeners; | ||||
|  | ||||
| 	public Board() { | ||||
| 		boardArr		= new Piece[8][8]; | ||||
| 		kingPos	= new HashMap<>(); | ||||
| 		gameEventListeners	= new ArrayList<>(); | ||||
| 		initializeDefaultPositions(); | ||||
| 	} | ||||
|  | ||||
| @@ -52,6 +60,13 @@ public class Board { | ||||
| 				revert(move, capturePiece); | ||||
| 				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; | ||||
| 		} | ||||
| 	} | ||||
| @@ -80,6 +95,14 @@ public class Board { | ||||
| 		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) { | ||||
| 		return boardArr[pos.x][pos.y]; | ||||
| 	} | ||||
| @@ -107,7 +130,7 @@ public class Board { | ||||
| 	/** | ||||
| 	 * Initialized the board array with the default chess pieces and positions. | ||||
| 	 */ | ||||
| 	private void initializeDefaultPositions() { | ||||
| 	public void initializeDefaultPositions() { | ||||
| 		// Initialize pawns | ||||
| 		for (int i = 0; i < 8; i++) { | ||||
| 			boardArr[i][1]	= new Pawn(Color.BLACK, this); | ||||
| @@ -143,6 +166,11 @@ public class Board { | ||||
| 		boardArr[2][7]	= new Bishop(Color.WHITE, this); | ||||
| 		boardArr[5][0]	= new Bishop(Color.BLACK, 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.Map; | ||||
|  | ||||
| import javax.swing.JOptionPane; | ||||
| import javax.swing.JPanel; | ||||
|  | ||||
| import dev.kske.chess.event.GameEvent; | ||||
| import dev.kske.chess.event.GameEventListener; | ||||
| 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 | ||||
|  * size. | ||||
|  */ | ||||
| public class BoardPanel extends JPanel { | ||||
| public class BoardPanel extends JPanel implements GameEventListener { | ||||
|  | ||||
| 	private static final long serialVersionUID = 6771148331334310216L; | ||||
|  | ||||
| @@ -37,14 +40,11 @@ public class BoardPanel extends JPanel { | ||||
|  | ||||
| 	private Board board; | ||||
|  | ||||
| 	static { | ||||
| 		loadPieceTextures(); | ||||
| 	} | ||||
|  | ||||
| 	public BoardPanel(Board board) { | ||||
| 		this(); | ||||
| 		setSize(getPreferredSize()); | ||||
| 		setBoard(board); | ||||
| 		if (textures == null) loadPieceTextures(); | ||||
| 	} | ||||
|  | ||||
| 	public BoardPanel() { | ||||
| @@ -99,6 +99,23 @@ public class BoardPanel extends JPanel { | ||||
| 					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. | ||||
| 	 * 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 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.EventQueue; | ||||
|  | ||||
| import javax.swing.JButton; | ||||
| import javax.swing.JFrame; | ||||
| import javax.swing.JPanel; | ||||
|  | ||||
|  | ||||
| /** | ||||
| @@ -46,13 +48,19 @@ public class Chess { | ||||
| 	private void initialize() { | ||||
| 		mframe = new JFrame(); | ||||
| 		mframe.setResizable(false); | ||||
| 		mframe.setBounds(100, 100, 729, 737); | ||||
| 		mframe.setBounds(100, 100, 494, 565); | ||||
| 		mframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); | ||||
|  | ||||
| 		BoardPanel boardPanel = new BoardPanel(new Board()); | ||||
| 		boardPanel.setLayout(null); | ||||
| 		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(); | ||||
| 	} | ||||
|  | ||||
| } | ||||
|   | ||||
							
								
								
									
										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