Package nl.zoidberg.calculon.engine

Source Code of nl.zoidberg.calculon.engine.KingMoveGenerator

/**
* Calculon - A Java chess-engine.
*
* Copyright (C) 2008-2009 Barry Smith
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
* implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
package nl.zoidberg.calculon.engine;

import java.util.List;

import nl.zoidberg.calculon.engine.BitBoard.BitBoardMove;
import nl.zoidberg.calculon.model.Piece;

public class KingMoveGenerator extends PieceMoveGenerator {

  private static final long EMPTY_WKS = 3L<<5;
  private static final long EMPTY_WQS = 7L<<1;
  private static final long EMPTY_BKS = 3L<<61;
  private static final long EMPTY_BQS = 7L<<57;

  // Pre-generated king moves
  public static final long[] KING_MOVES = new long[64];
  static {
        KING_MOVES[0] = 0b00000000_00000000_00000000_00000000_00000000_00000000_00000011_00000010L;
        KING_MOVES[1] = 0b00000000_00000000_00000000_00000000_00000000_00000000_00000111_00000101L;
        KING_MOVES[2] = 0b00000000_00000000_00000000_00000000_00000000_00000000_00001110_00001010L;
        KING_MOVES[3] = 0b00000000_00000000_00000000_00000000_00000000_00000000_00011100_00010100L;
        KING_MOVES[4] = 0b00000000_00000000_00000000_00000000_00000000_00000000_00111000_00101000L;
        KING_MOVES[5] = 0b00000000_00000000_00000000_00000000_00000000_00000000_01110000_01010000L;
        KING_MOVES[6] = 0b00000000_00000000_00000000_00000000_00000000_00000000_11100000_10100000L;
        KING_MOVES[7] = 0b00000000_00000000_00000000_00000000_00000000_00000000_11000000_01000000L;
        KING_MOVES[8] = 0b00000000_00000000_00000000_00000000_00000000_00000011_00000010_00000011L;
        KING_MOVES[9] = 0b00000000_00000000_00000000_00000000_00000000_00000111_00000101_00000111L;
        KING_MOVES[10] = 0b00000000_00000000_00000000_00000000_00000000_00001110_00001010_00001110L;
        KING_MOVES[11] = 0b00000000_00000000_00000000_00000000_00000000_00011100_00010100_00011100L;
        KING_MOVES[12] = 0b00000000_00000000_00000000_00000000_00000000_00111000_00101000_00111000L;
        KING_MOVES[13] = 0b00000000_00000000_00000000_00000000_00000000_01110000_01010000_01110000L;
        KING_MOVES[14] = 0b00000000_00000000_00000000_00000000_00000000_11100000_10100000_11100000L;
        KING_MOVES[15] = 0b00000000_00000000_00000000_00000000_00000000_11000000_01000000_11000000L;
        KING_MOVES[16] = 0b00000000_00000000_00000000_00000000_00000011_00000010_00000011_00000000L;
        KING_MOVES[17] = 0b00000000_00000000_00000000_00000000_00000111_00000101_00000111_00000000L;
        KING_MOVES[18] = 0b00000000_00000000_00000000_00000000_00001110_00001010_00001110_00000000L;
        KING_MOVES[19] = 0b00000000_00000000_00000000_00000000_00011100_00010100_00011100_00000000L;
        KING_MOVES[20] = 0b00000000_00000000_00000000_00000000_00111000_00101000_00111000_00000000L;
        KING_MOVES[21] = 0b00000000_00000000_00000000_00000000_01110000_01010000_01110000_00000000L;
        KING_MOVES[22] = 0b00000000_00000000_00000000_00000000_11100000_10100000_11100000_00000000L;
        KING_MOVES[23] = 0b00000000_00000000_00000000_00000000_11000000_01000000_11000000_00000000L;
        KING_MOVES[24] = 0b00000000_00000000_00000000_00000011_00000010_00000011_00000000_00000000L;
        KING_MOVES[25] = 0b00000000_00000000_00000000_00000111_00000101_00000111_00000000_00000000L;
        KING_MOVES[26] = 0b00000000_00000000_00000000_00001110_00001010_00001110_00000000_00000000L;
        KING_MOVES[27] = 0b00000000_00000000_00000000_00011100_00010100_00011100_00000000_00000000L;
        KING_MOVES[28] = 0b00000000_00000000_00000000_00111000_00101000_00111000_00000000_00000000L;
        KING_MOVES[29] = 0b00000000_00000000_00000000_01110000_01010000_01110000_00000000_00000000L;
        KING_MOVES[30] = 0b00000000_00000000_00000000_11100000_10100000_11100000_00000000_00000000L;
        KING_MOVES[31] = 0b00000000_00000000_00000000_11000000_01000000_11000000_00000000_00000000L;
        KING_MOVES[32] = 0b00000000_00000000_00000011_00000010_00000011_00000000_00000000_00000000L;
        KING_MOVES[33] = 0b00000000_00000000_00000111_00000101_00000111_00000000_00000000_00000000L;
        KING_MOVES[34] = 0b00000000_00000000_00001110_00001010_00001110_00000000_00000000_00000000L;
        KING_MOVES[35] = 0b00000000_00000000_00011100_00010100_00011100_00000000_00000000_00000000L;
        KING_MOVES[36] = 0b00000000_00000000_00111000_00101000_00111000_00000000_00000000_00000000L;
        KING_MOVES[37] = 0b00000000_00000000_01110000_01010000_01110000_00000000_00000000_00000000L;
        KING_MOVES[38] = 0b00000000_00000000_11100000_10100000_11100000_00000000_00000000_00000000L;
        KING_MOVES[39] = 0b00000000_00000000_11000000_01000000_11000000_00000000_00000000_00000000L;
        KING_MOVES[40] = 0b00000000_00000011_00000010_00000011_00000000_00000000_00000000_00000000L;
        KING_MOVES[41] = 0b00000000_00000111_00000101_00000111_00000000_00000000_00000000_00000000L;
        KING_MOVES[42] = 0b00000000_00001110_00001010_00001110_00000000_00000000_00000000_00000000L;
        KING_MOVES[43] = 0b00000000_00011100_00010100_00011100_00000000_00000000_00000000_00000000L;
        KING_MOVES[44] = 0b00000000_00111000_00101000_00111000_00000000_00000000_00000000_00000000L;
        KING_MOVES[45] = 0b00000000_01110000_01010000_01110000_00000000_00000000_00000000_00000000L;
        KING_MOVES[46] = 0b00000000_11100000_10100000_11100000_00000000_00000000_00000000_00000000L;
        KING_MOVES[47] = 0b00000000_11000000_01000000_11000000_00000000_00000000_00000000_00000000L;
        KING_MOVES[48] = 0b00000011_00000010_00000011_00000000_00000000_00000000_00000000_00000000L;
        KING_MOVES[49] = 0b00000111_00000101_00000111_00000000_00000000_00000000_00000000_00000000L;
        KING_MOVES[50] = 0b00001110_00001010_00001110_00000000_00000000_00000000_00000000_00000000L;
        KING_MOVES[51] = 0b00011100_00010100_00011100_00000000_00000000_00000000_00000000_00000000L;
        KING_MOVES[52] = 0b00111000_00101000_00111000_00000000_00000000_00000000_00000000_00000000L;
        KING_MOVES[53] = 0b01110000_01010000_01110000_00000000_00000000_00000000_00000000_00000000L;
        KING_MOVES[54] = 0b11100000_10100000_11100000_00000000_00000000_00000000_00000000_00000000L;
        KING_MOVES[55] = 0b11000000_01000000_11000000_00000000_00000000_00000000_00000000_00000000L;
        KING_MOVES[56] = 0b00000010_00000011_00000000_00000000_00000000_00000000_00000000_00000000L;
        KING_MOVES[57] = 0b00000101_00000111_00000000_00000000_00000000_00000000_00000000_00000000L;
        KING_MOVES[58] = 0b00001010_00001110_00000000_00000000_00000000_00000000_00000000_00000000L;
        KING_MOVES[59] = 0b00010100_00011100_00000000_00000000_00000000_00000000_00000000_00000000L;
        KING_MOVES[60] = 0b00101000_00111000_00000000_00000000_00000000_00000000_00000000_00000000L;
        KING_MOVES[61] = 0b01010000_01110000_00000000_00000000_00000000_00000000_00000000_00000000L;
        KING_MOVES[62] = 0b10100000_11100000_00000000_00000000_00000000_00000000_00000000_00000000L;
        KING_MOVES[63] = 0b01000000_11000000_00000000_00000000_00000000_00000000_00000000_00000000L;
  }

    private void generateCaptureMoves(BitBoard bitBoard, long kingPos, List<BitBoardMove> rv) {
        byte player = bitBoard.getPlayer();
        long kingMoves = KING_MOVES[Long.numberOfTrailingZeros(kingPos)];
        kingMoves &= bitBoard.getBitmapOppColor(player);
        while(kingMoves != 0) {
          long nextMove = Long.lowestOneBit(kingMoves);
          kingMoves ^= nextMove;
          BitBoardMove bbMove = BitBoard.generateCapture(
              kingPos, nextMove, player, Piece.KING, bitBoard.getPiece(nextMove));
          bitBoard.makeMove(bbMove);
            if( ! CheckDetector.isPlayerJustMovedInCheck(bitBoard)) {
                rv.add(bbMove);
            }
          bitBoard.unmakeMove();
        }
    }

  @Override
  public void generateMoves(BitBoard bitBoard, boolean alreadyInCheck, long potentialPins, List<BitBoardMove> rv) {
    byte player = bitBoard.getPlayer();

    // There can be only one...
    long king = bitBoard.getBitmapColor(player) & bitBoard.getBitmapKings();
    long emptyMoves = KING_MOVES[Long.numberOfTrailingZeros(king)]&(~bitBoard.getAllPieces());

    while(emptyMoves != 0) {
      long nextMove = Long.lowestOneBit(emptyMoves);
      emptyMoves ^= nextMove;
      BitBoardMove bbMove = BitBoard.generateMove(king, nextMove, player, Piece.KING);
      bitBoard.makeMove(bbMove);
            if( ! CheckDetector.isPlayerJustMovedInCheck(bitBoard)) {
                rv.add(bbMove);
            }
      bitBoard.unmakeMove();
    }

    byte castleFlags = bitBoard.getCastlingOptions();
    if(player == Piece.WHITE && ! alreadyInCheck) {
      if((castleFlags & BitBoard.CASTLE_WKS) != 0 && (bitBoard.getAllPieces() & EMPTY_WKS) == 0) {
                if( ! isIntermediateCheck(bitBoard, king, king<<1, player)) {
                  if(isCastlingPossible(bitBoard, player, BitBoard.CASTLE_WKS)) {
                        rv.add(BitBoard.generateCastling(BitBoard.CASTLE_WKS));
                  }
                }
      }
      if((castleFlags & BitBoard.CASTLE_WQS) != 0 && (bitBoard.getAllPieces() & EMPTY_WQS) == 0) {
                if( ! isIntermediateCheck(bitBoard, king, king>>>1, player)) {
                  if(isCastlingPossible(bitBoard, player, BitBoard.CASTLE_WQS)) {
                        rv.add(BitBoard.generateCastling(BitBoard.CASTLE_WQS));
                  }
                }
      }
    } else if(player == Piece.BLACK && ! alreadyInCheck) {
      if((castleFlags & BitBoard.CASTLE_BKS) != 0 && (bitBoard.getAllPieces() & EMPTY_BKS) == 0) {
                if( ! isIntermediateCheck(bitBoard, king, king<<1, player)) {
                  if(isCastlingPossible(bitBoard, player, BitBoard.CASTLE_BKS)) {
                        rv.add(BitBoard.generateCastling(BitBoard.CASTLE_BKS));
                  }
                }
      }
      if((castleFlags & BitBoard.CASTLE_BQS) != 0 && (bitBoard.getAllPieces() & EMPTY_BQS) == 0) {
                if( ! isIntermediateCheck(bitBoard, king, king>>>1, player)) {
                  if(isCastlingPossible(bitBoard, player, BitBoard.CASTLE_BQS)) {
                        rv.add(BitBoard.generateCastling(BitBoard.CASTLE_BQS));
                  }
                }
      }
    }

    while(king != 0) {
      long nextPiece = Long.lowestOneBit(king);
      king ^= nextPiece;
      this.generateCaptureMoves(bitBoard, nextPiece, rv);
    }
  }

  // Bit twiddling routines...
  private boolean isCastlingPossible(BitBoard bitBoard, byte player, short castleDir) {
    BitBoardMove bbMove = BitBoard.generateCastling(castleDir);
    bitBoard.makeMove(bbMove);
        boolean rv = ! CheckDetector.isPlayerJustMovedInCheck(bitBoard);
    bitBoard.unmakeMove();
    return rv;
  }

  private boolean isIntermediateCheck(BitBoard bitBoard, long fromSquare, long toSquare, byte player) {
    BitBoardMove bbMove = BitBoard.generateMove(fromSquare, toSquare, player, Piece.KING);
    bitBoard.makeMove(bbMove);
        boolean rv = CheckDetector.isPlayerJustMovedInCheck(bitBoard);
    bitBoard.unmakeMove();
    return rv;
  }
}
TOP

Related Classes of nl.zoidberg.calculon.engine.KingMoveGenerator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.