CPG/Chess/nimfish/nimfishpkg/zobrist.nim

83 lines
2.2 KiB
Nim

# Copyright 2024 Mattia Giambirtone & All Contributors
#
# 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.
## Implementation of Zobrist hashing
import std/random
import pieces
type
ZobristKey* = distinct uint64
## A zobrist key
func `xor`*(a, b: ZobristKey): ZobristKey = ZobristKey(a.uint64 xor b.uint64)
proc computeZobristKeys: array[781, ZobristKey] =
## Precomputes our zobrist keys
var prng = initRand(69420) # Nice.
# One for each piece on each square
for i in 0..767:
result[i] = ZobristKey(prng.next())
# One to indicate that it is black's turn
# to move
result[768] = ZobristKey(prng.next())
# Four numbers to indicate castling rights
for i in 769..773:
result[i] = ZobristKey(prng.next())
# Eight numbers to indicate the file of a valid
# En passant square, if any
for i in 774..781:
result[i] = ZobristKey(prng.next())
let ZOBRIST_KEYS = computeZobristKeys()
const PIECE_TO_INDEX = [[0, 1, 2, 3, 4, 5], [6, 7, 8, 9, 10, 11]]
proc getKey*(piece: Piece, square: Square): ZobristKey =
let index = PIECE_TO_INDEX[piece.color.int][piece.kind.int] + square.int
return ZOBRIST_KEYS[index]
proc getBlackToMoveKey*: ZobristKey = ZOBRIST_KEYS[768]
proc getQueenSideCastlingKey*(color: PieceColor): ZobristKey =
case color:
of White:
return ZOBRIST_KEYS[769]
of Black:
return ZOBRIST_KEYS[771]
else:
discard
proc getKingSideCastlingKey*(color: PieceColor): ZobristKey =
case color:
of White:
return ZOBRIST_KEYS[770]
of Black:
return ZOBRIST_KEYS[772]
else:
discard
proc getEnPassantKey*(file: SomeInteger): ZobristKey = ZOBRIST_KEYS[774 + file]