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/dev/kske/chess/game/NaturalPlayer.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) {}
}