NAME

Game::Schnapsen::Card - a card is an integer, and everything else is derived

VERSION

Version 0.01

SYNOPSIS

use Game::Schnapsen::Card qw(rank_of suit_of power_of points_of name_of id_of);

rank_of(1);          # 'A'
suit_of(1);          # 'S'
points_of(1);        # 11
name_of(1);          # 'AS'
id_of('AS');         # 1

points_of(6);        # 0, a nine
name_of(24);         # '9C'

DESCRIPTION

Cards are integers 1 to 24, suit-major, six ranks to a suit: 1 to 6 are spades ace to nine, 7 to 12 hearts, 13 to 18 diamonds, 19 to 24 clubs. A hand is therefore a list of small integers and a deal is a permutation.

One id space for both games

Schnapsen is played with twenty cards and Sixty-Six with twenty-four, but Schnapsen's pack is this pack with the four nines removed rather than a separate numbering. So this module never needs to know which game is being played: Game::Schnapsen::Deck filters. One id space means one notation, one set of test vectors, and no arithmetic that means different things in different games.

The ten beats the king

This is the trap in the marriage family, and it is stated here as a rank order rather than left to fall out of the arithmetic. A ranking built from the card point values happens to get it right, because ten is worth 10 and a king 4. A ranking built from the ordinary sequence of a pack gets it wrong, and nothing would notice until somebody lost a trick they had won. power_of is the authority, and it is derived from the order of the rank list and from nothing else.

Card points

An ace 11, a ten 10, a king 4, a queen 3, a jack 2, a nine nothing. Both published rulesets give the same table, so it is implemented once.

The nine being worth nothing is why both packs hold the same 120 card points. The extra four cards in Sixty-Six change how long a deal runs, not what it is worth, and Sixty-Six's 130 comes from the ten it pays for the last trick rather than from the larger pack.

FUNCTIONS

Nothing is exported by default.

rank_of

One of A, T, K, Q, J, 9. Dies for an id that is not a card.

suit_of

One of S, H, D, C.

power_of

How the card ranks within its suit, 5 for an ace down to 0 for a nine. Higher wins. Two cards in a trick are never equal, because the pack holds no duplicates, so a comparison of two powers never has to break a tie.

points_of

What the card is worth to whoever takes the trick.

name_of

Two characters, rank then suit: AS, TD, QH, 9C. The suit is a letter and never a glyph: a consumer that encodes a view to JSON and embeds it in a page gets mojibake out of a glyph, so glyphs belong in the consumer.

long_name_of

ace of spades, for a sentence.

id_of

The id for a name, or undef. Case insensitive. This one parses input, so it returns undef rather than dying.

ids_of_ranks

ids_of_ranks([qw(A T K Q J)]);   # the twenty-card pack

The ids whose rank is in the list, in id order. How Game::Schnapsen::Deck builds a variant's pack.

ranks, suits

The rank and suit lists, ranks in descending order of trick power.

CARDS

24, as a constant: the full pack, before any variant removes anything.

SEE ALSO

Game::Schnapsen::Deck, 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.