A chess library for Gleam
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

Incrementally update zobrist hash to improve performance

+64 -21
+16
src/starfish/internal/hash.gleam
··· 22 22 }) 23 23 } 24 24 25 + pub fn toggle_piece( 26 + hash: Int, 27 + position: Int, 28 + piece: board.Piece, 29 + colour: board.Colour, 30 + ) -> Int { 31 + int.bitwise_exclusive_or( 32 + generated.hash_for_piece(piece, colour, position), 33 + hash, 34 + ) 35 + } 36 + 37 + pub fn toggle_to_move(hash: Int) -> Int { 38 + int.bitwise_exclusive_or(hash, generated.black_to_move_hash) 39 + } 40 + 25 41 pub type Table = 26 42 iv.Array(Entry) 27 43
+48 -21
src/starfish/internal/move.gleam
··· 467 467 en_passant_square: _, 468 468 half_moves:, 469 469 full_moves:, 470 - zobrist_hash:, 470 + zobrist_hash: previous_hash, 471 471 previous_positions:, 472 472 attack_information: _, 473 473 white_king_position:, 474 474 black_king_position:, 475 475 ) = game 476 476 477 - let assert board.Occupied(piece:, colour:) = board.get(board, from) 478 - as "Tried to apply castle move from invalid position" 479 - 480 - let castling = case colour { 477 + let castling = case to_move { 481 478 board.Black -> 482 479 game.Castling(..castling, black_kingside: False, black_queenside: False) 483 480 board.White -> ··· 490 487 False -> #(7, 5) 491 488 } 492 489 490 + let rook_from = rook_rank * 8 + rook_file_from 491 + let rook_to = rook_rank * 8 + rook_file_to 492 + 493 493 let board = 494 494 board 495 495 |> dict.delete(from) 496 - |> dict.delete(rook_rank * 8 + rook_file_from) 497 - |> dict.insert(to, #(piece, colour)) 498 - |> dict.insert(rook_rank * 8 + rook_file_to, #(board.Rook, colour)) 496 + |> dict.delete(rook_from) 497 + |> dict.insert(to, #(board.King, to_move)) 498 + |> dict.insert(rook_to, #(board.Rook, to_move)) 499 + 500 + let zobrist_hash = 501 + previous_hash 502 + |> hash.toggle_to_move 503 + |> hash.toggle_piece(from, board.King, to_move) 504 + |> hash.toggle_piece(to, board.King, to_move) 505 + |> hash.toggle_piece(rook_from, board.Rook, to_move) 506 + |> hash.toggle_piece(rook_to, board.Rook, to_move) 499 507 500 508 let en_passant_square = None 501 509 ··· 520 528 } 521 529 522 530 let half_moves = half_moves + 1 523 - let previous_positions = [zobrist_hash, ..previous_positions] 524 - 525 - // TODO: Update incrementally 526 - let zobrist_hash = hash.hash(board, to_move) 531 + let previous_positions = [previous_hash, ..previous_positions] 527 532 528 533 let king_position = case to_move { 529 534 board.Black -> black_king_position ··· 562 567 en_passant_square:, 563 568 half_moves:, 564 569 full_moves:, 565 - zobrist_hash:, 570 + zobrist_hash: previous_hash, 566 571 previous_positions:, 567 572 attack_information: _, 568 573 white_king_position:, ··· 579 584 580 585 let one_way_move = capture || piece == board.Pawn 581 586 587 + let zobrist_hash = 588 + previous_hash 589 + |> hash.toggle_to_move 590 + |> hash.toggle_piece(from, piece, colour) 591 + 582 592 let piece = case promotion { 583 593 None -> piece 584 594 Some(piece) -> piece 595 + } 596 + 597 + let zobrist_hash = hash.toggle_piece(zobrist_hash, to, piece, colour) 598 + 599 + let zobrist_hash = case board.get(board, to) { 600 + board.Occupied(piece:, colour:) -> 601 + hash.toggle_piece(zobrist_hash, to, piece, colour) 602 + board.Empty | board.OffBoard -> zobrist_hash 585 603 } 586 604 587 605 let board = ··· 589 607 |> dict.delete(from) 590 608 |> dict.insert(to, #(piece, colour)) 591 609 592 - let board = case en_passant, en_passant_square, colour { 593 - True, Some(square), board.White -> dict.delete(board, square - 8) 594 - True, Some(square), board.Black -> dict.delete(board, square + 8) 595 - _, _, _ -> board 610 + let #(board, zobrist_hash) = case en_passant, en_passant_square, colour { 611 + True, Some(square), board.White -> { 612 + let ep_square = square - 8 613 + #( 614 + dict.delete(board, ep_square), 615 + hash.toggle_piece(zobrist_hash, ep_square, board.Pawn, board.Black), 616 + ) 617 + } 618 + True, Some(square), board.Black -> { 619 + let ep_square = square + 8 620 + #( 621 + dict.delete(board, ep_square), 622 + hash.toggle_piece(zobrist_hash, ep_square, board.Pawn, board.White), 623 + ) 624 + } 625 + _, _, _ -> #(board, zobrist_hash) 596 626 } 597 627 598 628 let en_passant_square = case piece, to - from { ··· 613 643 614 644 let #(half_moves, previous_positions) = case one_way_move { 615 645 True -> #(0, []) 616 - False -> #(half_moves + 1, [zobrist_hash, ..previous_positions]) 646 + False -> #(half_moves + 1, [previous_hash, ..previous_positions]) 617 647 } 618 648 619 649 let white_king_position = case from == white_king_position { ··· 625 655 True -> to 626 656 False -> black_king_position 627 657 } 628 - 629 - // TODO: Update incrementally 630 - let zobrist_hash = hash.hash(board, to_move) 631 658 632 659 let king_position = case to_move { 633 660 board.Black -> black_king_position