All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.netsensia.rivalchess.util.ChessBoardConversion.kt Maven / Gradle / Ivy

There is a newer version: 36.0.0
Show newest version
package com.netsensia.rivalchess.util

import com.netsensia.rivalchess.consts.*
import com.netsensia.rivalchess.engine.board.EngineBoard
import com.netsensia.rivalchess.engine.board.isCheck
import com.netsensia.rivalchess.engine.board.makeMove
import com.netsensia.rivalchess.engine.board.unMakeMove
import com.netsensia.rivalchess.engine.type.EngineMove
import com.netsensia.rivalchess.model.Move
import com.netsensia.rivalchess.model.Square
import com.netsensia.rivalchess.model.SquareOccupant
import com.netsensia.rivalchess.model.util.FenUtils.getBoardModel

fun getBitRefFromBoardRef(boardRef: Square) = 63 - 8 * boardRef.yRank - boardRef.xFile

fun getBitRefFromBoardRef(xFile: Int, yRank: Int) = 63 - 8 * yRank - xFile

fun getMoveRefFromCompactMove(move: Int): Move {
    val from = move shr 16 and 63
    val to = move and 63
    val boardRefFrom = Square.fromBitRef(from)
    val boardRefTo = Square.fromBitRef(to)
    val promotionPieceCode = move and PROMOTION_PIECE_TOSQUARE_MASK_FULL
    return if (promotionPieceCode != 0) {
        when (promotionPieceCode) {
            PROMOTION_PIECE_TOSQUARE_MASK_QUEEN -> Move(boardRefFrom, boardRefTo, if (to >= 56) SquareOccupant.WQ else SquareOccupant.BQ)
            PROMOTION_PIECE_TOSQUARE_MASK_ROOK -> Move(boardRefFrom, boardRefTo, if (to >= 56) SquareOccupant.WR else SquareOccupant.BR)
            PROMOTION_PIECE_TOSQUARE_MASK_KNIGHT -> Move(boardRefFrom, boardRefTo, if (to >= 56) SquareOccupant.WN else SquareOccupant.BN)
            PROMOTION_PIECE_TOSQUARE_MASK_BISHOP -> Move(boardRefFrom, boardRefTo, if (to >= 56) SquareOccupant.WB else SquareOccupant.BB)
            else -> throw RuntimeException("Unexpected error")
        }
    } else Move(boardRefFrom, boardRefTo, SquareOccupant.NONE)
}

fun getSimpleAlgebraicMoveFromCompactMove(compactMove: Int): String {
    if (compactMove == 0) return "zero"
    val from = compactMove shr 16 and 63
    val to = compactMove and 63
    val move = getMoveRefFromCompactMove(compactMove)
    val pp = if (move.promotedPiece == SquareOccupant.NONE) "" else move.promotedPiece.toChar().toString().trim { it <= ' ' }
    return getSimpleAlgebraicFromBitRef(from) + getSimpleAlgebraicFromBitRef(to) + pp
}

fun getSimpleAlgebraicFromBitRef(bitRef: Int): String {
    val boardRef = Square.fromBitRef(bitRef)
    val a = (boardRef.xFile + 97).toChar()
    return "" + a + (7 - boardRef.yRank + 1)
}

@kotlin.ExperimentalUnsignedTypes
fun getPgnMoveFromCompactMove(move: Int, fen: String?): String {
    val board = EngineBoard()
    board.setBoard(getBoardModel(fen!!))
    var pgnMove = ""
    val to = move and 63
    val from = move ushr 16 and 63
    val promotionPiece = move and PROMOTION_PIECE_TOSQUARE_MASK_FULL
    when (board.getBitboardTypeOfPieceOnSquare(from)) {
        BITBOARD_WN, BITBOARD_BN -> pgnMove = "N"
        BITBOARD_WK, BITBOARD_BK -> pgnMove = "K"
        BITBOARD_WQ, BITBOARD_BQ -> pgnMove = "Q"
        BITBOARD_WB, BITBOARD_BB -> pgnMove = "B"
        BITBOARD_WR, BITBOARD_BR -> pgnMove = "R"
    }
    var qualifier = ' '
    val legalMoves = board.moveGenerator().generateLegalMoves().moves
    var moveCount = 0
    var legalMove = legalMoves[moveCount] and 0x00FFFFFF
    while (legalMove != 0) {
        val legalMoveTo = legalMove and 63
        val legalMoveFrom = legalMove ushr 16 and 63
        if (legalMoveTo == to) {
            if (board.getBitboardTypeOfPieceOnSquare(legalMoveFrom) == board.getBitboardTypeOfPieceOnSquare(from)) {
                if (legalMoveFrom != from) {
                    qualifier = if (legalMoveFrom % 8 == from % 8) ('1'.toInt() + from / 8).toChar()
                    else ('a'.toInt() + (7 - from % 8)).toChar()
                }
            }
        }
        moveCount++
        legalMove = legalMoves[moveCount] and 0x00FFFFFF
    }
    if (qualifier != ' ') pgnMove += qualifier
    if (board.getBitboardTypeOfPieceOnSquare(to) != -1) {
        if (board.getBitboardTypeOfPieceOnSquare(from) in arrayOf(BITBOARD_WP, BITBOARD_BP)) {
            pgnMove += ('a'.toInt() + (7 - from % 8)).toChar()
        }
        pgnMove += "x"
    }
    pgnMove += getSimpleAlgebraicFromBitRef(to)
    if (promotionPiece != 0) {
        when (promotionPiece) {
            PROMOTION_PIECE_TOSQUARE_MASK_QUEEN -> pgnMove += "=Q"
            PROMOTION_PIECE_TOSQUARE_MASK_KNIGHT -> pgnMove += "=N"
            PROMOTION_PIECE_TOSQUARE_MASK_BISHOP -> pgnMove += "=B"
            PROMOTION_PIECE_TOSQUARE_MASK_ROOK -> pgnMove += "=R"
        }
    }
    if (board.makeMove(move)) {
        if (board.isCheck(board.mover)) pgnMove += "+"
        board.unMakeMove()
    }
    return pgnMove
}

fun getEngineMoveFromSimpleAlgebraic(s: String): EngineMove {
    val fromX = s.toUpperCase()[0].toInt() - 65
    val fromY = 7 - (s.toUpperCase()[1].toInt() - 49)
    val toX = s.toUpperCase()[2].toInt() - 65
    val toY = 7 - (s.toUpperCase()[3].toInt() - 49)
    val fromBitRef = getBitRefFromBoardRef(Square.fromCoords(fromX, fromY))
    var toBitRef = getBitRefFromBoardRef(Square.fromCoords(toX, toY))
    val l = s.length
    if (l == 5) {
        when (s.toUpperCase()[4]) {
            'Q' -> toBitRef = toBitRef or PROMOTION_PIECE_TOSQUARE_MASK_QUEEN
            'R' -> toBitRef = toBitRef or PROMOTION_PIECE_TOSQUARE_MASK_ROOK
            'N' -> toBitRef = toBitRef or PROMOTION_PIECE_TOSQUARE_MASK_KNIGHT
            'B' -> toBitRef = toBitRef or PROMOTION_PIECE_TOSQUARE_MASK_BISHOP
        }
    }
    return EngineMove(fromBitRef shl 16 or toBitRef)
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy