84 lines
2.3 KiB
Nim
84 lines
2.3 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)
|
|
func `==`*(a, b: ZobristKey): bool = a.uint64 == 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..772:
|
|
result[i] = ZobristKey(prng.next())
|
|
# Eight numbers to indicate the file of a valid
|
|
# En passant square, if any
|
|
for i in 773..780:
|
|
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] * 64 + 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[773 + file] |