152 lines
4.1 KiB
Java
152 lines
4.1 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::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) {}
|
|
}
|