NAME

Game::Oware::Error - a refused move, returned rather than thrown

VERSION

Version 0.01

SYNOPSIS

my $out = $game->play('p1', 4);

if (ref $out && $out->error) {
    print $out->code;        # must_feed
    print $out->message;     # your opponent has no seeds, so you ...
    print "@{ $out->legal }" # 5
}

DESCRIPTION

throw is a deliberate lie

It builds an object and returns it. Nothing here ever dies, because a player choosing a house they may not play is an ordinary event in a game and not a fault in the program.

die is reserved for programmer error: a seat that does not exist, a house index outside 0 to 11, an unknown variant, a log that does not replay. The distinction is the house rule and it is what lets a caller write if (ref $out && $out->error) without an eval anywhere.

One flag per refusal, and a predicate for each

@FLAGS and %MESSAGE live in a BEGIN block because has runs at compile time, so the list has to exist before the accessors are declared from it.

error is always true, so a caller can test it without knowing which flag came back.

Every flag must be reachable from a real refusal

A flag nothing can produce becomes, downstream, a sentence in a catalogue that no player will ever see and a translator will still be asked to translate. t/13-flags.t asserts that every flag this class declares is produced by some position, and the way to break that test on purpose is to add a sixth flag and watch it fail.

must_feed carries the moves that would have worked

It is the one refusal whose reason cannot be read off the board at a glance, so it is the one that fills legal. A player who has just been told "you must feed" needs to know which of their houses reach, and counting seeds to work it out is not something a game should ask of them.

PROPERTIES

not_your_turn

The seat is not the one on turn.

not_your_house

The house belongs to the other seat.

empty_house

The house has no seeds in it.

must_feed

The opponent is starved and this move does not reach them.

game_over

The game has already finished.

error

Always 1.

message

The sentence for the flag.

What the seat could have played instead. Filled for must_feed, empty otherwise.

METHODS

throw

Game::Oware::Error->throw('must_feed', legal => [ 5 ]);

Builds and returns the error. Dies only if the flag is not one this class declares, which is programmer error.

code

The flag that is set, as a string.

flags

An arrayref of every flag this class declares.

messages

A copy of the whole flag-to-sentence table. A consumer that has to present these in another language wants this rather than the individual messages.

stringify

code: message, for a log line.

SEE ALSO

Game::Oware

AUTHOR

LNATION <email@lnation.org>

LICENSE AND COPYRIGHT

This software is Copyright (c) 2026 by LNATION <email@lnation.org>.

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