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 javalabra.shakki.engine.player; import javalabra.shakki.engine.move.MoveTransision; import javalabra.shakki.engine.move.MoveStatus; import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterables; import java.util.ArrayList; import java.util.Collection; import java.util.List; import javalabra.shakki.engine.board.Board; import javalabra.shakki.engine.move.Move; import javalabra.shakki.engine.pieces.King; import javalabra.shakki.engine.pieces.Piece; import javalabra.shakki.engine.pieces.PieceColor; /** *Pelaaja-luokka. */ public abstract class Player { protected final Board board; protected final King playerKing; protected final Collection<Move> legalMoves; private final boolean isInCheck; Player(final Board board, final Collection<Move> legalMoves, final Collection<Move> opponentsMoves) { this.board = board; this.playerKing = establishKing(); this.legalMoves = ImmutableList .copyOf(Iterables.concat(legalMoves, calculateKingCastles(legalMoves, opponentsMoves))); this.isInCheck = !Player.calculateAttacksOnTile(this.playerKing.getPiecePosition(), opponentsMoves) .isEmpty(); } /** * Metodi varmistaa, ett pelaajan kuningas on laudalla. * * @return King, palauttaa pelaajan kuninkaan */ protected King establishKing() { for (final Piece piece : getActivePieces()) { if (piece.getPieceType().isKing()) { return (King) piece; } } throw new RuntimeException("Should not reach here! Not a valid board!"); } /** * Metodi mritt siirrot, joilla psee kyseiseen ruutuun. * * @param tile ruutu, johon kohdistuvat hykkykset halutaan selvitt * @param moves lpi kytvt siirrot * * @return palauttaa listan siirroista, joilla psee annettuun ruutuun */ public 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); } /** * Metodi kertoo, onko pelaajalla siirtoja, joilla hn voi paeta shakkia. * * return true, jos siirtoja on */ protected boolean hasEscapeMoves() { for (final Move move : this.legalMoves) { final MoveTransision transision = makeMove(move); if (transision.getMoveStatus().isDone()) { return true; } } return false; } public King getPlayerKing() { return this.playerKing; } public Collection<Move> getLegalMoves() { return this.legalMoves; } /** * Tarkistaa, onko siirto laillinen. * * @param move tarkistettava siirto * * @return true, jos siirto laillinen */ public boolean isMoveLegal(final Move move) { return !(move.isCastlingMove() && isInCheck()) && this.legalMoves.contains(move); } /** * Tarkistaa, onko pelaaja shakissa. * * @return true, jos shakki */ public boolean isInCheck() { return this.isInCheck; } /** * Tarkistaa, onko pelaaja matissa. * * @return true, jos matti */ public boolean isInCheckMate() { return this.isInCheck && !hasEscapeMoves(); } /** * Metodi kertoo, onko peli ptynyt tasapeliin eli tilanteeseen, * jossa jompi kumpi pelaajista ei pysty tekemn yhtkn siirtoa. * * @return true, jos tasapeli */ public boolean isStaleMate() { return !this.isInCheck && !hasEscapeMoves(); } /** * Metodi palauttaa MoveTransision-olion, joka kertoo, voidaanko siirto tehd ilman, * ett siirron tehneen pelaajan kuningas j uhatuksi. Mikli siirto voidaan tehd, * saadaan siirron jlkeisen pelilaudan tilaa koskevat tiedot MoveTransision-olion * transisionBoard-attribuutista. * * @param move siirto, jonka laillisuus halutaan tarkistaa * * @return MoveTransision-olio, josta selvi siirron laillisuus */ public MoveTransision makeMove(final Move move) { if (!isMoveLegal(move)) { return new MoveTransision(this.board, move, MoveStatus.ILLEGAL); } final Board transisionBoard = move.execute(); final Collection<Move> kingAttacks = calculateAttacksOnTile( transisionBoard.currentPlayer().getOpponent().getPlayerKing().getPiecePosition(), transisionBoard.currentPlayer().getLegalMoves()); if (!kingAttacks.isEmpty()) { return new MoveTransision(this.board, move, MoveStatus.LEAVES_PLAYER_IN_CHECK); } return new MoveTransision(transisionBoard, move, MoveStatus.DONE); } public abstract Collection<Piece> getActivePieces(); public abstract PieceColor getPieceColor(); public abstract Player getOpponent(); /** * Metodi kertoo, onko pelaajan mahdollista tehd tornitus-nimist erikoissiirtoa. * * @param playersLegalMoves pelaajan mahdolliset siirrot * @param opponentsLegalMoves vastustajan mahdolliset siirrot * * @return palauttaa listan mahdollisista tornitussiirroista (nit on enintn kaksi) */ public abstract Collection<Move> calculateKingCastles(Collection<Move> playersLegalMoves, Collection<Move> opponentsLegalMoves); }