Skip to content

Commit

Permalink
Remove square pawn attack cached array (#209)
Browse files Browse the repository at this point in the history
Bench | 9546383

ELO | -0.70 +- 2.36 (95%)
SPRT | 10.0+0.1s Threads=1 Hash=32MB
LLR | 2.97 (-2.94, 2.94) [-5.00, 0.00]
Games | N: 40960 W: 10061 L: 10143 D: 20756
  • Loading branch information
ratosh authored May 2, 2020
1 parent 0a8b053 commit 49d17fe
Show file tree
Hide file tree
Showing 7 changed files with 20 additions and 70 deletions.
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name=pirarucu
group=ratosh
version=3.3.4
version=3.3.5
kotlin_version=1.3.70
detekt_version=1.0.0.RC6-3
4 changes: 2 additions & 2 deletions pirarucu-common/src/main/kotlin/pirarucu/eval/AttackInfo.kt
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ class AttackInfo {
val kingSquare = board.kingSquare[color]
while (tmpPieces != Bitboard.EMPTY) {
val fromSquare = Square.getSquare(tmpPieces)
val bitboard = BitboardMove.PAWN_ATTACKS[color][fromSquare] and mask and
val bitboard = BitboardMove.pawnAttacks(color, fromSquare) and mask and
BitboardMove.PINNED_MOVE_MASK[kingSquare][fromSquare]

attacksBitboard[color][Piece.PAWN] = attacksBitboard[color][Piece.PAWN] or
Expand Down Expand Up @@ -141,7 +141,7 @@ class AttackInfo {
private fun kingMoves(board: Board, color: Int) {
val fromSquare = board.kingSquare[color]
val theirKing = board.kingSquare[Color.invertColor(color)]
var moves = BitboardMove.KING_MOVES[fromSquare] and BitboardMove.KING_MOVES[theirKing].inv()
val moves = BitboardMove.KING_MOVES[fromSquare] and BitboardMove.KING_MOVES[theirKing].inv()

pieceMovement[color][fromSquare] = moves
attacksBitboard[color][Piece.KING] = moves
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ object PawnEvaluator {
val stack = FRONTSPAN_MASK[ourColor][pawnSquare] and ourPawns
val blockers = FRONTSPAN_MASK[ourColor][pawnSquare] and theirPawns
val neighbours = NEIGHBOURS_MASK[pawnSquare] and ourPawns
val defense = BitboardMove.PAWN_ATTACKS[theirColor][pawnSquare] and ourPawns
val defense = BitboardMove.pawnAttacks(theirColor, pawnSquare) and ourPawns
val phalanx = BitboardMove.NEIGHBOURS[pawnSquare] and ourPawns
val supporters = PASSED_MASK[theirColor][pawnSquare] and ourPawns
val dangerAdvance = attackInfo.attacksBitboard[theirColor][Piece.PAWN] and pawnMoves
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import pirarucu.move.BitboardMove
import pirarucu.move.Move
import pirarucu.move.MoveType
import pirarucu.tuning.TunableConstants
import kotlin.math.max

object StaticExchangeEvaluator {

Expand Down Expand Up @@ -148,8 +147,8 @@ object StaticExchangeEvaluator {
result = result or (BitboardMove.rookMoves(toSquare, occupied) and rooks)
}
return result or
(BitboardMove.PAWN_ATTACKS[Color.BLACK][toSquare] and board.pieceBitboard[Color.WHITE][Piece.PAWN]) or
(BitboardMove.PAWN_ATTACKS[Color.WHITE][toSquare] and board.pieceBitboard[Color.BLACK][Piece.PAWN]) or
(BitboardMove.pawnAttacks(Color.BLACK, toSquare) and board.pieceBitboard[Color.WHITE][Piece.PAWN]) or
(BitboardMove.pawnAttacks(Color.WHITE, toSquare) and board.pieceBitboard[Color.BLACK][Piece.PAWN]) or
(BitboardMove.KNIGHT_MOVES[toSquare] and
(board.pieceBitboard[Color.WHITE][Piece.KNIGHT] or board.pieceBitboard[Color.BLACK][Piece.KNIGHT])) or
(BitboardMove.KING_MOVES[toSquare] and
Expand Down
29 changes: 2 additions & 27 deletions pirarucu-common/src/main/kotlin/pirarucu/move/BitboardMove.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import pirarucu.board.Color
import pirarucu.board.File
import pirarucu.board.Rank
import pirarucu.board.Square
import pirarucu.game.GameConstants

object BitboardMove {

Expand All @@ -28,7 +27,6 @@ object BitboardMove {

val PAWN_MOVES = Array(Color.SIZE) { LongArray(Square.SIZE) }
val DOUBLE_PAWN_MOVES = Array(Color.SIZE) { LongArray(Square.SIZE) }
val PAWN_ATTACKS = Array(Color.SIZE) { LongArray(Square.SIZE) }
val KNIGHT_MOVES = LongArray(Square.SIZE)
val BISHOP_PSEUDO_MOVES = LongArray(Square.SIZE)
val ROOK_PSEUDO_MOVES = LongArray(Square.SIZE)
Expand All @@ -44,7 +42,6 @@ object BitboardMove {
init {
populateBetween()
populatePawnMoves()
populatePawnAttacks()
populateKnightMoves()
populateBishopMoves()
populateRookMoves()
Expand Down Expand Up @@ -157,30 +154,8 @@ object BitboardMove {
return result
}

private fun populatePawnAttacks() {
for (square in 0 until Square.SIZE) {
PAWN_ATTACKS[Color.WHITE][square] = getPawnAttack(Color.WHITE, square)
PAWN_ATTACKS[Color.BLACK][square] = getPawnAttack(Color.BLACK, square)
}
}

private fun getPawnAttack(color: Int, square: Int): Long {
var result = Bitboard.EMPTY

var possibleBitboard: Long = Bitboard.ALL
val file = File.getFile(square)
when (file) {
File.FILE_A -> possibleBitboard = Bitboard.NOT_FILE_H
File.FILE_H -> possibleBitboard = Bitboard.NOT_FILE_A
}

for (i in PAWN_ATTACK_STEP) {
val attackSquare = square + i * GameConstants.COLOR_FACTOR[color]
if (Square.isValid(attackSquare)) {
result = result or Bitboard.getBitboard(attackSquare) and possibleBitboard
}
}
return result
fun pawnAttacks(color: Int, square: Int): Long {
return pawnAttacks(color, Bitboard.getBitboard(square))
}

private fun populateKnightMoves() {
Expand Down
12 changes: 6 additions & 6 deletions pirarucu-common/src/main/kotlin/pirarucu/move/MoveGenerator.kt
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ class MoveGenerator(private val history: History) {

while (promotionAttacks != Bitboard.EMPTY) {
val toSquare = Square.getSquare(promotionAttacks)
var bitboard = BitboardMove.PAWN_ATTACKS[theirColor][toSquare] and pawnBitboard
var bitboard = BitboardMove.pawnAttacks(theirColor, toSquare) and pawnBitboard

while (bitboard != Bitboard.EMPTY) {
val fromSquare = Square.getSquare(bitboard)
Expand Down Expand Up @@ -202,7 +202,7 @@ class MoveGenerator(private val history: History) {

while (pawnAttacks != Bitboard.EMPTY) {
val toSquare = Square.getSquare(pawnAttacks)
var bitboard = BitboardMove.PAWN_ATTACKS[theirColor][toSquare] and pawnBitboard
var bitboard = BitboardMove.pawnAttacks(theirColor, toSquare) and pawnBitboard

while (bitboard != Bitboard.EMPTY) {
val fromSquare = Square.getSquare(bitboard)
Expand Down Expand Up @@ -269,7 +269,7 @@ class MoveGenerator(private val history: History) {
if (epPawnBitboard != Bitboard.EMPTY) {
val ourColor = board.colorToMove
var tmpPieces = board.pieceBitboard[ourColor][Piece.PAWN] and
BitboardMove.PAWN_ATTACKS[theirColor][epSquare]
BitboardMove.pawnAttacks(theirColor, epSquare)
while (tmpPieces != Bitboard.EMPTY) {
val fromSquare = Square.getSquare(tmpPieces)

Expand Down Expand Up @@ -373,7 +373,7 @@ class MoveGenerator(private val history: History) {
}
if (MoveType.TYPE_PASSANT == moveType) {
return toSquare == board.epSquare &&
toBitboard and BitboardMove.PAWN_ATTACKS[ourColor][fromSquare] != Bitboard.EMPTY
toBitboard and BitboardMove.pawnAttacks(ourColor, fromSquare) != Bitboard.EMPTY
}
val checkBitboard = board.basicEvalInfo.checkBitboard
val mask = when {
Expand All @@ -399,7 +399,7 @@ class MoveGenerator(private val history: History) {

return (toBitboard and bitboard != Bitboard.EMPTY)
}
(toBitboard and BitboardMove.PAWN_ATTACKS[ourColor][fromSquare] and mask != Bitboard.EMPTY)
(toBitboard and BitboardMove.pawnAttacks(ourColor, fromSquare) and mask != Bitboard.EMPTY)
}
Piece.KING -> {
if (MoveType.isCastling(moveType)) {
Expand Down Expand Up @@ -442,7 +442,7 @@ class MoveGenerator(private val history: History) {
theirPieceBitboard[Piece.QUEEN]) and gameBitboard
val rooks = (theirPieceBitboard[Piece.ROOK] or theirPieceBitboard[Piece.QUEEN]) and
gameBitboard
var result = (pawns and BitboardMove.PAWN_ATTACKS[ourColor][square]) or
var result = (pawns and BitboardMove.pawnAttacks(ourColor, square)) or
(knights and BitboardMove.KNIGHT_MOVES[square]) or
(BitboardMove.KING_MOVES[square] and theirPieceBitboard[Piece.KING])

Expand Down
36 changes: 6 additions & 30 deletions pirarucu-jvm/src/test/kotlin/pirarucu/move/BitboardMoveTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -25,36 +25,12 @@ class BitboardMoveTest {

@Test
fun testPawnAttack() {
assertEquals(BitboardMove.PAWN_ATTACKS[Color.WHITE][Square.A2], Bitboard.B3)
assertEquals(
BitboardMove.PAWN_ATTACKS[Color.WHITE][Square.A2],
BitboardMove.pawnAttacks(Color.WHITE, Bitboard.A2)
)
assertEquals(BitboardMove.PAWN_ATTACKS[Color.WHITE][Square.H2], Bitboard.G3)
assertEquals(
BitboardMove.PAWN_ATTACKS[Color.WHITE][Square.H2],
BitboardMove.pawnAttacks(Color.WHITE, Bitboard.H2)
)
assertEquals(BitboardMove.PAWN_ATTACKS[Color.WHITE][Square.B3], Bitboard.A4 or Bitboard.C4)
assertEquals(
BitboardMove.PAWN_ATTACKS[Color.WHITE][Square.B3],
BitboardMove.pawnAttacks(Color.WHITE, Bitboard.B3)
)
assertEquals(BitboardMove.PAWN_ATTACKS[Color.BLACK][Square.A2], Bitboard.B1)
assertEquals(
BitboardMove.PAWN_ATTACKS[Color.BLACK][Square.A2],
BitboardMove.pawnAttacks(Color.BLACK, Bitboard.A2)
)
assertEquals(BitboardMove.PAWN_ATTACKS[Color.BLACK][Square.H2], Bitboard.G1)
assertEquals(
BitboardMove.PAWN_ATTACKS[Color.BLACK][Square.H2],
BitboardMove.pawnAttacks(Color.BLACK, Bitboard.H2)
)
assertEquals(BitboardMove.PAWN_ATTACKS[Color.BLACK][Square.B3], Bitboard.A2 or Bitboard.C2)
assertEquals(
BitboardMove.PAWN_ATTACKS[Color.BLACK][Square.B3],
BitboardMove.pawnAttacks(Color.BLACK, Bitboard.B3)
)
assertEquals(BitboardMove.pawnAttacks(Color.WHITE, Square.A2), Bitboard.B3)
assertEquals(BitboardMove.pawnAttacks(Color.WHITE, Square.H2), Bitboard.G3)
assertEquals(BitboardMove.pawnAttacks(Color.WHITE, Square.B3), Bitboard.A4 or Bitboard.C4)
assertEquals(BitboardMove.pawnAttacks(Color.BLACK, Square.A2), Bitboard.B1)
assertEquals(BitboardMove.pawnAttacks(Color.BLACK, Square.H2), Bitboard.G1)
assertEquals(BitboardMove.pawnAttacks(Color.BLACK, Square.B3), Bitboard.A2 or Bitboard.C2)
}

@Test
Expand Down

2 comments on commit 49d17fe

@praveentml
Copy link

@praveentml praveentml commented on 49d17fe May 14, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @ratosh,
I am looking for instructions to build OpenBench for java chess engine. Could you please help me with instructions how to configure it ? Thanks in advance and eagerly waiting for your response.

@ratosh
Copy link
Owner Author

@ratosh ratosh commented on 49d17fe May 14, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey! GL with your Java chess engine! Please take a look at my Openbench fork, and please create issues there. Or contact me through Discord (Find me on TCEC channel)
First you need to setup your engine details on openbench openbench-repo\config.py, then you run the server using a docker-compose file (check root folder). To make client work you just need to:

  • Have a build python script in your engine repo: engine-repo\openbench\build.py
  • Define how to run your engine on client: openbech-repo\Client\Client.py

Please sign in to comment.