NAME

Game::Checkers::Rules - move generation over a raw position

VERSION

Version 0.01

SYNOPSIS

use Game::Checkers::Rules;

my $moves = Game::Checkers::Rules::generate($position, 'black');
Game::Checkers::Rules::apply($position, $moves->[0]);
Game::Checkers::Rules::unapply($position, $moves->[0]);

DESCRIPTION

Functions over a position arrayref, not an object, and the only part of the engine the search talks to. Nothing here allocates a blessed object, because Game::Checkers::Bot calls generate, apply and unapply millions of times for one move. Game::Checkers is the interface for everybody else.

The rules implemented

English draughts, also called American checkers:

  • A man moves one square diagonally forward and a king one square diagonally in any direction, always to an empty square.

  • A jump passes over an adjacent enemy piece to the empty square beyond. A man jumps forward only, a king in any direction.

  • Capture is compulsory: when any jump exists, the legal list is jumps and nothing else. Which jump is a free choice, because English draughts has no maximum capture rule.

  • A jump sequence continues while the piece that jumped can jump again, and the whole sequence is one move. A piece already jumped may not be jumped again in that sequence, and it stays on the board until the move ends, so it still blocks a landing square.

  • A man reaching the far row is crowned and the turn ends there, even when the new king could jump again.

Deciding the game is over is Game::Checkers's: this module answers what can be played, and "has_move" answers whether anything can.

THE RAW MOVE

A generated move is an unblessed arrayref whose layout is documented in "THE RAW MOVE" in Game::Checkers::Move. The constants RM_FROM, RM_TO, RM_PROMOTED, RM_PATH, RM_CAPTURES, RM_CAPTURED and RM_KING are defined there and re-exported here under the same names, so a caller may use either spelling.

FUNCTIONS

generate

All the legal moves for a side, as an arrayref of raw moves, with the compulsory capture rule already applied. The order is deterministic: ascending starting square, then ascending destination, then by path, so a client may index into the list and get the same move twice. The search reorders its own copy.

my $moves = Game::Checkers::Rules::generate($position, 'white');

apply

Applies a raw move to a position, in place, crowning the piece when the move says so. Returns the raw move, which is also the record "unapply" wants.

Game::Checkers::Rules::apply($position, $raw);

unapply

Takes a move back, in place, restoring every captured piece with the value it had so a jumped king comes back a king, and taking the crown off a piece the move promoted.

Game::Checkers::Rules::unapply($position, $raw);

has_move

True when the side has any move at all. It stops at the first one it finds, so it is the cheap way to ask whether a player has lost.

Game::Checkers::Rules::has_move($position, 'black');

progress

True when a move is a capture or a man move, which is what resets the no progress counter that draws a game nobody is winning.

Game::Checkers::Rules::progress($raw);

AUTHOR

LNATION, <email at lnation.org>

BUGS

Please report any bugs or feature requests to bug-game-checkers at rt.cpan.org, or through the web interface at https://rt.cpan.org/NoAuth/ReportBug.html?Queue=Game-Checkers. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.

SUPPORT

You can find documentation for this module with the perldoc command.

perldoc Game::Checkers

You can also look for information at:

ACKNOWLEDGEMENTS

LICENSE AND COPYRIGHT

This software is Copyright (c) 2026 by LNATION.

This is free software, licensed under:

The Artistic License 2.0 (GPL Compatible)