NAME
Game::Schnapsen::Scoring - what a deal was worth, and to whom
VERSION
Version 0.01
SYNOPSIS
use Game::Schnapsen::Scoring qw(deal_result scale);
scale(40, 3); # 1, the opponent has 33 or more
scale(12, 2); # 2, Schneider
scale(0, 0); # 3, Schwarz
my $r = deal_result(
variant => 'schnapsen',
how => 'claim',
by => 'p1',
points => { p1 => 68, p2 => 20 },
tricks => { p1 => 5, p2 => 2 },
closed_by => undef,
close_state => undef,
last_trick => 'p1',
);
$r->{winner}; # 'p1'
$r->{game_points}; # 2, because p2 is Schneider
$r->{how}; # 'claim'
DESCRIPTION
A deal ends in one of five ways, and every branch below is quoted from the page it came from at the point it is implemented.
The scale, which both games share
Read off the opponent's cards:
the opponent has 33 or more card points ... 1 game point
fewer than 33 but at least one trick ...... 2 (Schneider)
no trick at all ........................... 3 (Schwarz)
Schwarz is a count of tricks and not of points. A player who takes one trick of two nines has no card points and is not Schwarz, and that is the likeliest off-by-one in the whole distribution.
Claiming, and claiming wrongly
Neither game ends a deal by arithmetic. A player who reaches 66 must say so, and Sixty-Six is explicit that a correct claim wins "even if it turns out that the opponent had reached 66 earlier". So the engine counts, and never goes out for anybody.
A claim that turns out to be wrong loses the deal:
Schnapsen: "the opponent scores 2 game points, or 3 game points if the false claim is made before the opponent has taken a trick".
Sixty-Six: "A player goes out prematurely, having fewer than 66 card points. The other player wins. 2 game points". Flat, with no Schwarz.
That is false_claim_schwarz.
Closing, which has three endings and not two
The closer goes out. The usual scale, but on which state of the opponent differs, and this is the divergence that is easiest to get subtly wrong:
Sixty-Six: "the score is based on the cards in the opponent's total tricks taken before and after closing".
Schnapsen: "the score is normally determined by the tricks the opponent had at the moment of closing".
The cards run out and the closer never went out. Both games read the moment of closing here, so close_counts_tricks_at must not reach this path: Schnapsen gives "2 points to the opponent, or 3 if the opponent had no tricks when the talon was closed", and Sixty-Six "2 or 3 game points, depending whether the opponent had any tricks at the moment of closing".
The opponent of the closer goes out first. Schnapsen treats this as any other failed close: "The same scores of 2 or 3 game points apply in the unusual case where the opponent of the player who closed reaches 66 and wins by claiming first." Sixty-Six caps it: "A player closes the talon, but the other player then wins by going out with 66 or more points (rare case): 2 game points". That is beaten_closer_flat.
The cards running out with no close and no claim
The two games have nothing in common here.
Schnapsen: "the player who takes the last trick wins the hand, scoring one game point, irrespective of the number of card points the players have taken". One, always. A player holding 90 of the 120 who loses the last trick scores nothing.
Sixty-Six: "the very last trick is worth 10 card points extra ... the player with the higher card point total wins. If the players have equal card point totals the hand is a draw." So the pack is worth 130, the usual scale applies, and a deal can be drawn, which nothing else on this engine's roster can do.
FUNCTIONS
Nothing is exported by default.
scale
scale($opponent_points, $opponent_tricks);
1, 2 or 3.
deal_result
deal_result(variant => ..., how => ..., by => ..., points => ..., tricks => ...,
closed_by => ..., close_state => ..., last_trick => ...);
how going in is claim or exhausted: what the players did. how coming back is what it amounted to, one of claim, closed_out, false_claim, beat_closer, failed_close, last_trick or drawn.
Returns winner, loser, game_points, how, drawn, and the points and tricks it decided on. For a drawn Sixty-Six deal winner and loser are undef and game_points is 0, and a caller has to carry that all the way out: the deal pays nobody, ends nothing, and is played again.
TARGET_POINTS, SCHNEIDER_AT, LAST_TRICK_BONUS, PENALTY, PENALTY_SCHWARZ
66, 33, 10, 2 and 3.
SEE ALSO
Game::Schnapsen::Deal, Game::Schnapsen::Variant.
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.