NAME

Game::Durak::Bot - a seat at a level, playing from a view

VERSION

Version 0.01

SYNOPSIS

my $bot = Game::Durak::Bot->new(level => 3, seed => $seed);

my $move = $bot->choose($game->view($seat));
$game->apply($seat, $move);

Game::Durak::Bot->level_for(4);      # 3, the rung a consumer's level 4 gets
Game::Durak::Bot->hint($view);       # what the top rung would do

DESCRIPTION

A level and a seed. Everything else is Game::Durak::Search, and like that module this one never sees a game: choose takes the same view a consumer sends to a browser, so a bot cannot read a hand it is not holding however badly a caller wires it up.

The ladder is a mapping, not a list of behaviours

our @LADDER = (1, 1, 2, 3, 3);

A consumer with five bot levels gets three rungs, weakest first, because the engine has three and pretending otherwise would put two identical opponents on a leaderboard with different names. Which of the five maps to which rung is a judgement to be measured rather than declared, and bin/ladder is how: the mapping above is the one the measurement in docs/measured.md supports.

The list is written weakest first because hint reaches for the top and a consumer's level test asserts the order.

The word, and why a bot is reproducible

word_for hashes the bot's seed with the seat and the ply, so rung 1's choice and every tie-break above it are a function of the seed and the position. Two bots of the same rung in one deal are handed different words because the seat is in the hash, which is what stops a bot versus bot deal from being a mirror.

METHODS

level, seed

What the bot was built with. A missing level plays rung 1; a missing seed still works and plays the same deal every time, which is a test fixture and not a game.

choose

$bot->choose($view);

A move from the view's legal, or undef when there is nothing to do.

hint

Game::Durak::Bot->hint($view);

What the top rung would play, for a consumer that offers a nudge. A class method: a hint has no seed and no level of its own.

word_for

$bot->word_for($seat, $ply);

The 32-bit word for one position, hashed from the bot's seed with the seat and the ply. Public because a consumer that wants a bot's choice without building a view can ask for the same number, and because a test that wants to prove two seats differ has to be able to see it.

level_for

Game::Durak::Bot->level_for($n);

The rung a consumer's level maps to. Out of range clamps rather than dies, because a consumer's levels are not this module's to police.

levels

Three, from Game::Durak::Search.

SEE ALSO

Game::Durak::Search, Game::Durak.

AUTHOR

LNATION, <email@lnation.org>

LICENSE AND COPYRIGHT

This software is Copyright (c) 2026 by LNATION.

This is free software, licensed under the Artistic License 2.0.