File Coverage

blib/lib/Chess/Plisco/Engine/TranspositionTable.pm
Criterion Covered Total %
statement 57 57 100.0
branch 18 18 100.0
condition 6 6 100.0
subroutine 13 13 100.0
pod 0 5 0.0
total 94 99 94.9


line stmt bran cond sub pod time code
1             #! /bin/false
2              
3             # Copyright (C) 2021 Guido Flohr ,
4             # all rights reserved.
5              
6             # This program is free software. It comes without any warranty, to
7             # the extent permitted by applicable law. You can redistribute it
8             # and/or modify it under the terms of the Do What the Fuck You Want
9             # to Public License, Version 2, as published by Sam Hocevar. See
10             # http://www.wtfpl.net/ for more details.
11              
12             package Chess::Plisco::Engine::TranspositionTable;
13             $Chess::Plisco::Engine::TranspositionTable::VERSION = '0.4';
14 11     11   57535 use strict;
  11         30  
  11         322  
15 11     11   472 use integer;
  11         31  
  11         64  
16              
17 11     11   607 use Chess::Plisco::Engine::Tree;
  11         28  
  11         252  
18              
19 11     11   49 use constant TT_ENTRY_SIZE => 16;
  11         21  
  11         506  
20              
21 11     11   54 use constant TT_SCORE_EXACT => 0;
  11         22  
  11         413  
22 11     11   56 use constant TT_SCORE_ALPHA => 1;
  11         20  
  11         448  
23 11     11   48 use constant TT_SCORE_BETA => 2;
  11         27  
  11         620  
24              
25             our @EXPORT = qw(TT_SCORE_EXACT TT_SCORE_ALPHA TT_SCORE_BETA);
26              
27 11     11   66 use base qw(Exporter);
  11         20  
  11         4645  
28              
29             sub new {
30 308     308 0 5989 my ($class, $size) = @_;
31              
32 308         723 my $self = [];
33 308         779 bless $self, $class;
34              
35 308         1106 return $self->resize($size);
36             }
37              
38             sub clear {
39 310     310 0 650 my ($self) = @_;
40              
41 310         644 my $size = @$self;
42              
43 310         1280 $#$self = 0;
44 310         828 $#$self = $size;
45              
46 310         541 return $self;
47             }
48              
49             sub resize {
50 309     309 0 1809 my ($self, $size) = @_;
51              
52 309         1215 $self->clear;
53 309         27103 $#$self = (1024 * 1024 / TT_ENTRY_SIZE) - 1;
54              
55 309         3328 return $self;
56             }
57              
58             sub probe {
59 1482449     1482449 0 2462751 my ($self, $lookup_key, $depth, $alpha, $beta, $bestmove) = @_;
60              
61 1482449 100       3889211 my $entry = $self->[$lookup_key % scalar @$self] or return;
62              
63 569325         1232803 my ($stored_key, $payload) = @$entry;
64 569325 100       1338293 return if $stored_key != $lookup_key;
65              
66 174685         507418 my ($edepth, $flags, $value, $move) = unpack 's4', $payload;
67 174685 100       359057 $$bestmove = $move if $move;
68              
69 174685 100       329973 if ($edepth >= $depth) {
70 161005 100       299219 if ($flags == TT_SCORE_EXACT) {
71 108555 100       254177 if ($value <= Chess::Plisco::Engine::Tree::MATE
    100          
72             + Chess::Plisco::Engine::Tree::MAX_PLY) {
73 18         40 $value += ($edepth - $depth);
74             } elsif ($value >= -Chess::Plisco::Engine::Tree::MATE
75             - Chess::Plisco::Engine::Tree::MAX_PLY) {
76 31         64 $value -= ($edepth - $depth);
77             }
78              
79 108555         251567 return $value;
80             }
81              
82 52450 100 100     145958 if (($flags == TT_SCORE_ALPHA) && ($value <= $alpha)) {
83 7992         22289 return $alpha;
84             }
85              
86 44458 100 100     134322 if (($flags == TT_SCORE_BETA) && ($value >= $beta)) {
87 14392         38227 return $beta;
88             }
89             }
90              
91 43746         95176 return;
92             }
93              
94             sub store {
95 895588     895588 0 1426637 my ($self, $key, $depth, $flags, $value, $move) = @_;
96              
97             # Replacement scheme is currently replace-always. We must make sure that
98             # only the significant bits of the best move are stored.
99 895588         2389541 my $payload = pack 's4', $depth, $flags, $value, $move & 0x7fff;
100              
101 895588         2750202 $self->[$key % scalar @$self] = [$key, $payload];
102             }
103              
104             1;