package dev.kske.chess.game; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.util.List; import java.util.stream.Collectors; import javax.swing.JComboBox; import javax.swing.JOptionPane; import dev.kske.chess.board.Move; import dev.kske.chess.board.Piece; import dev.kske.chess.board.Piece.Color; import dev.kske.chess.board.Position; import dev.kske.chess.ui.OverlayComponent; /** * Enables the user to make moves in a {@link Game} by clicking on a * {@link Piece} and then selecting one of the highlighted positions as the move * destination.
*
* Project: Chess
* File: NaturalPlayer.java
* Created: 06.07.2019
* * @since Chess v0.1-alpha * @author Kai S. K. Engelbart */ public class NaturalPlayer extends Player implements MouseListener { private final OverlayComponent overlayComponent; private boolean moveRequested; private Piece selectedPiece; private List possibleMoves; /** * Creates an instance of {@link NaturalPlayer}. * * @param game the game in which this player will be used * @param color the piece color this player will control * @param overlayComponent the overlay component that will be used to * display * possible moves to the user */ public NaturalPlayer( Game game, Color color, OverlayComponent overlayComponent ) { super(game, color); this.overlayComponent = overlayComponent; name = "Player"; moveRequested = false; overlayComponent.addMouseListener(this); } @Override public void requestMove() { moveRequested = true; } @Override public void cancelMove() { moveRequested = false; } @Override public void disconnect() { overlayComponent.removeMouseListener(this); } @Override public void mousePressed(MouseEvent evt) { if (!moveRequested) return; if (selectedPiece == null) { // Get selected Piece final Position pos = new Position( evt.getPoint().x / overlayComponent.getTileSize(), evt.getPoint().y / overlayComponent.getTileSize() ); selectedPiece = board.get(pos); // Check if a piece was selected if (selectedPiece != null) // Discard selection if the piece has the wrong color if (selectedPiece.getColor() == color.opposite()) selectedPiece = null; else { // Generate all moves possible with the selected piece and // display their // destinations possibleMoves = selectedPiece.getMoves(pos); overlayComponent.displayDots( possibleMoves.stream().map(Move::getDest).collect(Collectors.toList()) ); } } else { Position dest = new Position( evt.getPoint().x / overlayComponent.getTileSize(), evt.getPoint().y / overlayComponent.getTileSize() ); // Get all moves leading to the specified destination List selectedMoves = possibleMoves.stream() .filter(m -> m.getDest().equals(dest)) .collect(Collectors.toList()); if (!selectedMoves.isEmpty()) { Move move; // Process pawn promotion if necessary if (selectedMoves.size() > 1) { // Let the user select a promotion piece JComboBox comboBox = new JComboBox<>(selectedMoves.toArray(new Move[0])); JOptionPane.showMessageDialog( overlayComponent, comboBox, "Select a promotion", JOptionPane.QUESTION_MESSAGE ); move = selectedMoves.get(comboBox.getSelectedIndex()); } else move = selectedMoves.get(0); // Tell the game to execute the move moveRequested = false; game.onMove(NaturalPlayer.this, move); } // Discard the selection overlayComponent.clearDots(); selectedPiece = null; possibleMoves = null; } } @Override public void mouseClicked(MouseEvent e) {} @Override public void mouseReleased(MouseEvent e) {} @Override public void mouseEntered(MouseEvent e) {} @Override public void mouseExited(MouseEvent e) {} }