127 lines
3.9 KiB
Java
127 lines
3.9 KiB
Java
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.<br>
|
|
* <br>
|
|
* Project: <strong>Chess</strong><br>
|
|
* File: <strong>NaturalPlayer.java</strong><br>
|
|
* Created: <strong>06.07.2019</strong><br>
|
|
*
|
|
* @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<Move> 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 -> 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<Move> 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<Move> 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) {}
|
|
}
|