NAME

Game::Schnapsen::Bot - an opponent

VERSION

Version 0.01

SYNOPSIS

my $bot = Game::Schnapsen::Bot->new(level => 2, seed => $game->seed);

while (!$game->over) {
    my $seat = $game->turn;
    my $move = $bot->choose($game, $seat);
    $game->apply($seat, $move);
}

DESCRIPTION

Picks one of the moves the game is already offering. It never constructs a move of its own, so it cannot play an illegal one however wrong its judgement is.

It is given the game, and passes on only what a player could see

choose takes the whole game, because it has to ask what is legal. What it hands to Game::Schnapsen::Search is its own hand and the public state: the trump, the phase, the count of cards left in the talon, the turn-up, its own card points, and the opponent's card points and trick count, which are public because both players count openly in this family.

The opponent's hand and the order of the talon are never passed on, and Game::Schnapsen::Search's signatures cannot accept them anyway. That is the defence; this method is the place it could be undone, so it is kept short enough to read in one go.

The order it decides in

An exchange first, because taking the turn-up for the lowest trump is never worse. Then a marriage, because twenty or forty is free once a trick has been taken, and declaring before claiming can put the claim over the line. Then a claim, then a close, then the card to play. A draw is what is left when nothing else applies, which is Sixty-Six declining to close.

Claiming is conservative, always

The rules offer a claim on timing alone, so a bot that guessed would hand over two or three game points and make a level ladder meaningless. This one claims only on a real 66, at every level, and the bot gate asserts zero false claims across every match it plays.

The ladder

@LADDER is a bag rather than a list: repeats weight it, and it is sorted weakest first because a caller wanting the strongest rung reaches for the last element. A consumer draws one rung per match from it.

The rungs shipped are the ones that were measured to differ. More search is not automatically better, and a ladder whose rungs play alike is a ladder that says something untrue about the opponent a player is facing.

METHODS

new

Game::Schnapsen::Bot->new(level => 2, seed => $seed);

level, seed

The rung it plays at, and the seed its tie-breaks are drawn from.

choose

$bot->choose($game, $seat);

One of the moves $game->legal($seat) offered, or undef if there are none or the match is over.

seed_for

A deterministic value per seat and ply, so that two bots in one match do not play identically and neither calls rand.

levels

How many levels the search offers.

SEE ALSO

Game::Schnapsen::Search, Game::Schnapsen.

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.