Chess-Plisco

 view release on metacpan or  search on metacpan

lib/Chess/Plisco/Engine/Tree.pm  view on Meta::CPAN

#! /bin/false

# Copyright (C) 2021-2026 Guido Flohr <guido.flohr@cantanea.com>,
# all rights reserved.

# This program is free software. It comes without any warranty, to
# the extent permitted by applicable law. You can redistribute it
# and/or modify it under the terms of the Do What the Fuck You Want
# to Public License, Version 2, as published by Sam Hocevar. See
# http://www.wtfpl.net/ for more details.

package Chess::Plisco::Engine::Tree;
$Chess::Plisco::Engine::Tree::VERSION = 'v1.0.3';
use strict;
use integer;

use Locale::TextDomain ('Chess-Plisco');
use List::Util qw(min);

use Chess::Plisco qw(:all);
# Macros from Chess::Plisco::Macro are already expanded here!
use Chess::Plisco::Engine::Position qw(CP_POS_REVERSIBLE_CLOCK CP_POS_POPCOUNT);
use Chess::Plisco::Engine::Constants;

use Time::HiRes qw(tv_interval ualarm gettimeofday);

use constant DEBUG => $ENV{DEBUG_PLISCO_TREE};

use constant CP_POS_SIGNATURE => Chess::Plisco::Engine::Position::CP_POS_SIGNATURE();
use constant CP_POS_REVERSIBLE_CLOCK => Chess::Plisco::Engine::Position::CP_POS_REVERSIBLE_CLOCK();

use Chess::Plisco::Engine::TranspositionTable;

# These values get stored in the upper 32 bits of a moves so that they are
# searched first.
use constant MOVE_ORDERING_PV => 1 << 62;
use constant MOVE_ORDERING_TT => 1 << 61;

use constant SAFETY_MARGIN => 300;
use constant UALARM_INTERVAL => 500 * SAFETY_MARGIN;

use constant WDL_LOSS => -2;
use constant WDL_BLESSED_LOSS => -1;
use constant WDL_DRAW => 0;
use constant WDL_CURSED_WIN => 1;
use constant WDL_WIN => 2;

# For all combinations of promotion piece and captured piece, calculate a
# value suitable for sorting.  We choose the raw material balance minus the
# piece that moves.  That way, captures that the queen makes are less
# "attractive" than captures that the rook makes.
my @move_values = (0) x 369;


# MVV-LVA values. Looked up via the captured and moving piece ($move & 0x3f).
my @mvv_lva;

# Usually only queen promotions and sometimes promotions to a knight are
# interesting. This mask is used to filter them out.
use constant GOOD_PROMO_MASK => (1 << (CP_QUEEN)) | (1 << (CP_KNIGHT));

my ($self_tb_cardinality, $self_tb_probe_depth);

sub new {
	my ($class, %options) = @_;

	my $position = $options{position};
	my $signatures = $options{signatures};

	# Make sure that the reversible clock does not look beyond the known
	# positions.  This will simplify the detection of a draw by repetition.
	if ($position->[CP_POS_REVERSIBLE_CLOCK] >= @$signatures) {
		$position->[CP_POS_REVERSIBLE_CLOCK] = @$signatures - 1;
	}

	no integer;

	my @killers = map { [] } 0 .. MAX_PLY - 1;
	my $self = {
		position => $position,
		signatures => $signatures,



( run in 0.793 second using v1.01-cache-2.11-cpan-8f98c5d2c55 )