javalabra.shakki.engine.player.Player.java Source code

Java tutorial

Introduction

Here is the source code for javalabra.shakki.engine.player.Player.java

Source

/*
 * 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);
}