Package nl.zoidberg.calculon.notation

Source Code of nl.zoidberg.calculon.notation.PGNUtils

/**
* 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.notation;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;

import nl.zoidberg.calculon.engine.BitBoard;
import nl.zoidberg.calculon.engine.CheckDetector;
import nl.zoidberg.calculon.engine.EngineUtils;
import nl.zoidberg.calculon.engine.MoveGenerator;
import nl.zoidberg.calculon.engine.BitBoard.BitBoardMove;
import nl.zoidberg.calculon.model.Game;
import nl.zoidberg.calculon.model.Piece;

public class PGNUtils {

  private PGNUtils() {
  }

  public static void applyMove(BitBoard bitBoard, String move) {
    String algMove = PGNUtils.toPgnMoveMap(bitBoard).get(move);
    bitBoard.makeMove(bitBoard.getMove(algMove));
  }
 
  public static void applyMoves(BitBoard bitBoard, String[] moves) {
    for(String s: moves) {
      applyMove(bitBoard, s);
    }
  }
 
  public static Map<String, String> toPgnMoveMap(BitBoard bitBoard) {
    List<BitBoardMove> allMoves = new MoveGenerator(bitBoard).getAllRemainingMoves();
    Map<String, String> rv = new HashMap<String, String>();
   
    for(BitBoardMove intMove: allMoves) {
      rv.put(translateMove(bitBoard, intMove.getAlgebraic()), intMove.getAlgebraic());
    }
    for(String pgnMove: new HashSet<String>(rv.keySet())) {
      if(pgnMove.endsWith("+") || pgnMove.endsWith("#")) {
        rv.put(pgnMove.substring(0, pgnMove.length()-1), rv.get(pgnMove));
      }
    }
    return rv;
  }

  private static String getCheckNotation(BitBoard b) {
    if( ! CheckDetector.isPlayerToMoveInCheck(b)) {
      return "";
    }
    if(b.getResult() == Game.RES_BLACK_WIN || b.getResult() == Game.RES_WHITE_WIN) {
      return "#";
    }
    return  "+";
  }
 
  /**
   * Translate a simple algebraic move (e.g. G1F3) into its PGN equivalent (e.g. Nf3).
   *
   * @param board
   * @param simpleAlgebraic
   * @return
   */
  public static String translateMove(BitBoard bitBoard, String simpleAlgebraic) {
    if (simpleAlgebraic.startsWith("O-")) {
      BitBoardMove bbMove = bitBoard.getMove(simpleAlgebraic);
      bitBoard.makeMove(bbMove);
      String rv = simpleAlgebraic + getCheckNotation(bitBoard);
      bitBoard.unmakeMove();
      return rv;
    }

    int fromFile = EngineUtils.FILES.indexOf(simpleAlgebraic.charAt(0));
    int fromRank = EngineUtils.RANKS.indexOf(simpleAlgebraic.charAt(1));
    int toFile = EngineUtils.FILES.indexOf(simpleAlgebraic.charAt(2));
    int toRank = EngineUtils.RANKS.indexOf(simpleAlgebraic.charAt(3));

    byte movePiece = bitBoard.getColoredPiece(1L<<(fromRank<<3)<<fromFile);
   
    if (movePiece == Piece.EMPTY) {
      throw new RuntimeException("Move from empty square: " + simpleAlgebraic);
    }

    StringBuffer move = new StringBuffer();
    boolean testClash = false;
    switch (movePiece & Piece.MASK_TYPE) {
    case Piece.KNIGHT:
      move.append("N");
      testClash = true;
      break;
    case Piece.BISHOP:
      move.append("B");
      testClash = true;
      break;
    case Piece.ROOK:
      move.append("R");
      testClash = true;
      break;
    case Piece.QUEEN:
      move.append("Q");
      testClash = true;
      break;
    case Piece.KING:
      if(fromFile == 4 && toFile == 6) {
        bitBoard.makeMove(bitBoard.getMove(simpleAlgebraic));
        String rv = "O-O" + getCheckNotation(bitBoard);
        bitBoard.unmakeMove();
        return rv;
      } else if(fromFile == 4 && toFile == 2) {
        bitBoard.makeMove(bitBoard.getMove(simpleAlgebraic));
        String rv = "O-O-O" + getCheckNotation(bitBoard);
        bitBoard.unmakeMove();
        return rv;
      } else {
        move.append("K");
      }
      break;
    }

    if (testClash) {
      String fromSquare = simpleAlgebraic.substring(0, 2);
      List<BitBoardMove> m = new MoveGenerator(bitBoard).getAllRemainingMoves();
      List<String> clashingPieces = new ArrayList<String>();
      for (BitBoardMove key : m) {
        if (key.getAlgebraic().startsWith("O-")) {
          continue;
        }
        if (!simpleAlgebraic.substring(2, 4).equals(key.getAlgebraic().substring(2, 4))) {
          continue;
        }
        String pieceSquare = key.getAlgebraic().substring(0, 2);
        if (fromSquare.equals(pieceSquare) || bitBoard.getColoredPiece(BitBoard.coordToPosition(pieceSquare)) != movePiece) {
          continue;
        }
        clashingPieces.add(key.getAlgebraic());
      }

      if (clashingPieces.size() != 0) {
        boolean sameFile = false;
        boolean sameRank = false;
        for (String clash : clashingPieces) {
          if (clash.charAt(0) == simpleAlgebraic.charAt(0)) {
            sameFile = true;
          }
          if (clash.charAt(1) == simpleAlgebraic.charAt(1)) {
            sameRank = true;
          }
        }
        if (!sameFile) {
          move.append(Character
              .toLowerCase(simpleAlgebraic.charAt(0)));
        } else if (!sameRank) {
          move.append(simpleAlgebraic.charAt(1));
        } else {
          move.append(simpleAlgebraic.substring(0, 2).toLowerCase());
        }
      }
    }

    byte targetPiece = bitBoard.getPiece(1L<<(toRank<<3)<<toFile);
    if (targetPiece != 0) {
      if ((movePiece & Piece.MASK_TYPE) == Piece.PAWN) {
        move.append(Character.toLowerCase(simpleAlgebraic.charAt(0)));
      }
      move.append("x");
    } else if ((movePiece & Piece.MASK_TYPE) == Piece.PAWN && toFile != fromFile) {
      // En passant
      move.append(Character.toLowerCase(simpleAlgebraic.charAt(0)))
          .append("x");
    }

    move.append(Character.toLowerCase(simpleAlgebraic.charAt(2))).append(simpleAlgebraic.charAt(3));
    bitBoard.makeMove(bitBoard.getMove(simpleAlgebraic));

    if (simpleAlgebraic.indexOf('=') >= 0) {
      move.append(simpleAlgebraic.substring(simpleAlgebraic.indexOf('=')));
    }

    if (CheckDetector.isPlayerToMoveInCheck(bitBoard)) {
      move.append(getCheckNotation(bitBoard));
    }

    bitBoard.unmakeMove();
    return move.toString();
  }
}
TOP

Related Classes of nl.zoidberg.calculon.notation.PGNUtils

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.