Java tutorial
/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package chess_.engine.classic.player; import chess_.engine.Alliance; import chess_.engine.classic.board.Board; import chess_.engine.classic.board.Move; import chess_.engine.classic.board.Move.MoveStatus; import chess_.engine.classic.board.MoveTransition; import chess_.engine.classic.pieces.King; import chess_.engine.classic.pieces.Piece; import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterables; import java.util.ArrayList; import java.util.Collection; import java.util.List; /** * * @author moham */ public abstract class Player { protected final Board board; protected final King playerKing; protected final Collection<Move> legalMoves; protected final boolean isInCheck; Player(final Board board, final Collection<Move> playerLegals, final Collection<Move> opponentLegals) { this.board = board; this.playerKing = establishKing(); this.legalMoves = ImmutableList .copyOf(Iterables.concat(playerLegals, calculateKingCastles(playerLegals, opponentLegals))); this.isInCheck = !Player.calculateAttacksOnTile(this.playerKing.getPiecePosition(), opponentLegals) .isEmpty(); } public boolean isMoveLegal(final Move move) { return !(move.isCastlingMove() && isInCheck()) && this.legalMoves.contains(move); } public boolean isInCheck() { return this.isInCheck; } public boolean isInCheckMate() { return this.isInCheck && !hasEscapeMoves(); } public boolean isInStaleMate() { return !this.isInCheck && !hasEscapeMoves(); } public boolean isCastled() { return this.playerKing.isCastled(); } public boolean isKingSideCastleCapable() { return this.playerKing.isKingSideCastleCapable(); } public boolean isQueenSideCastleCapable() { return this.playerKing.isQueenSideCastleCapable(); } public King getPlayerKing() { return this.playerKing; } protected King establishKing() { for (final Piece piece : getActivePieces()) { if (piece.getPieceType().isKing()) { return (King) piece; } } throw new RuntimeException( "Should not reach here! " + this.getAlliance() + " king could not be established!"); } protected boolean hasEscapeMoves() { for (final Move move : getLegalMoves()) { final MoveTransition transition = makeMove(move); if (transition.getMoveStatus().isDone()) { return true; } } return false; } public Collection<Move> getLegalMoves() { return this.legalMoves; } static Collection<Move> calculateAttacksOnTile(final int tile, final Collection<Move> moves) { final List<Move> attackMoves = new ArrayList<>(); for (final Move move : moves) { if (tile == move.getDestinationCoordinate()) { attackMoves.add(move); } } return ImmutableList.copyOf(attackMoves); } public MoveTransition makeMove(final Move move) { if (!isMoveLegal(move)) { return new MoveTransition(this.board, this.board, move, MoveStatus.ILLEGAL_MOVE); } final Board transitionedBoard = move.execute(); final Collection<Move> kingAttacks = Player.calculateAttacksOnTile( transitionedBoard.currentPlayer().getOpponent().getPlayerKing().getPiecePosition(), transitionedBoard.currentPlayer().getLegalMoves()); if (!kingAttacks.isEmpty()) { return new MoveTransition(this.board, this.board, move, MoveStatus.LEAVES_PLAYER_IN_CHECK); } return new MoveTransition(this.board, transitionedBoard, move, MoveStatus.DONE); } public MoveTransition unMakeMove(final Move move) { return new MoveTransition(this.board, move.undo(), move, MoveStatus.DONE); } public abstract Collection<Piece> getActivePieces(); public abstract Alliance getAlliance(); public abstract Player getOpponent(); protected abstract Collection<Move> calculateKingCastles(Collection<Move> playerLegals, Collection<Move> opponentLegals); }