This repository has been archived on 2021-02-18. You can view files and clone it, but cannot push or open issues or pull requests.
chess/src/main/java/dev/kske/chess/game/NaturalPlayer.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) {}
}