NAME
Game::Shogi - shogi, Japanese chess, where a captured piece changes sides
VERSION
Version 0.01
SYNOPSIS
use Game::Shogi;
my $game = Game::Shogi->new; # an even game
my $give = Game::Shogi->new(handicap => 'bishop'); # White without its bishop, moving first
if (my $refusal = $game->play('7g7f')) {
print $refusal->message, "\n";
}
print $_->usi, "\n" for $game->legal;
$game->undo;
print $game->sfen, "\n";
if (my $r = $game->result) { print $r->how, ' ', $r->winner // 'draw', "\n" }
my $again = Game::Shogi->from_log($game->log);
DESCRIPTION
Shogi is played by two on a board of nine by nine squares, twenty pieces a side. A piece that is captured goes into its captor's hand and may be dropped back onto the board as the captor's own.
This is the game: a board, the moves made on it, and how it ended. Every rule is the board's, Game::Shogi::Engine; this class keeps the game and says why a move was refused. A refused move comes back as a Game::Shogi::Error and is never thrown.
A side is 'b' for Black, who moves first in an even game, and 'w' for White. A move is a USI string (7g7f, 8h2b+, P*5e) or a Game::Shogi::Move.
It is the engine behind the Shogi at https://peer2peergames.com.
CONSTRUCTOR
new
Game::Shogi->new
Game::Shogi->new(handicap => 'rook')
Game::Shogi->new(sfen => $sfen, cap => 300)
An even game; a handicap game from Game::Shogi::Handicap, White without those pieces and to move; or a game from any position. cap is the move count at which the game is drawn (500, the Japan Shogi Association's). Croaks for a handicap that is not one, a handicap and a position together, or a position the board refuses.
A misspelt argument name is not caught: Object::Proto::Sugar drops an unknown name, or reads the arguments by position, so handicapp would start an even game. Check handicap after construction when it matters.
from_log
my $game = Game::Shogi->from_log($log, cap => 300);
The game a "log" writes, replayed move by move. Croaks, naming the move, when one is refused.
ATTRIBUTES
handicap
The handicap's name, or undef for a game without one.
THE POSITION
board
A copy of the board, a Game::Shogi::Engine. Changing it changes nothing here.
start
The SFEN the game started from.
sfen
The position now, as SFEN.
side
The side to move, 'b' or 'w'.
turn
The side to move, or undef once the game is over.
status
'active' or 'finished'.
move_number
The board's move number: 1 at the start, and one more for each move by either side.
in_check
True when the side to move is in check.
can_declare
True when the side to move may declare the impasse now.
hand
my $hand = $game->hand('b'); # { P => 2, R => 1 }
A side's pieces in hand, only those it has.
legal
Every legal move of the side to move, as Game::Shogi::Moves; none once the game is over.
moves
The moves made, as USI strings, oldest first.
history
The keys of the positions the game has stood in before this one, oldest first, which a search needs to see a repetition coming.
PLAYING
Each of these returns 0 when it is done, or a Game::Shogi::Error saying why it was refused.
play
my $refusal = $game->play('7g7f');
Makes a move. A move that breaks a rule is refused with the first rule it breaks: not_your_piece, not_in_hand, cannot_reach, occupied, promote_not_allowed, promote_required, dead_piece, two_pawns, in_check or pawn_drop_mate; bad_move for a string that is not a move; game_over once the game is over. A move that ends the game sets "result".
undo
Takes back the last move, and any ending it made. Refused with nothing_to_undo before the first move, and with game_over after a resignation or a declaration, which are not moves.
resign
$game->resign('b');
The side to move resigns, and the other wins. not_your_turn for the other side; game_over once the game is over.
declare
The side to move declares the impasse and wins: its king and ten other pieces in the enemy camp, not in check, and 28 points as Black or 27 as White. cannot_declare, with the condition that failed, otherwise.
THE END
result
A Game::Shogi::Result, or undef while the game is on: mate, no_move and perpetual_check are losses for the side they name, sennichite and cap are draws, and resign and impasse_declared are what a side did.
winner
The result's winner: 'b', 'w', or undef while the game is on or for a draw.
THE LOG
log
{ start => $sfen, moves => [ '7g7f', ... ], handicap => 'rook' }
What a game needs to be played again: the start, the moves as USI, and the handicap when there was one.
record
The game written down by Game::Shogi::Notation: each move with its side, its Hodges and its Japanese.
to_text
my $text = $game->to_text;
The game as a string, from which "from_text" builds the same game again: the handicap when there was one, the start as SFEN, the cap, every move as USI, and a resignation or a declaration, which the moves cannot show. Two games with the same history write the same string.
from_text
my $again = Game::Shogi->from_text($text);
A new game built from a string "to_text" wrote, by replaying its moves and then its ending. A string that is not one to_text writes croaks with a sentence naming what is wrong: a missing or unknown line, a cap that is not a number, a move the replay refuses by its number, or an ending refused.
THE RULES THIS DISTRIBUTION CHOSE
Where the rules of shogi leave a choice, or differ between tournament play and casual play, this is the choice made here.
- An illegal move is refused, not lost
-
Tournament play loses a game for an illegal move. Here "play" refuses it and says why, and the side to move moves again.
- Perpetual check loses
-
The fourth time a position repeats, the side that gave check with every one of its moves in the cycle loses (
perpetual_check). Any other fourfold repetition is a draw (sennichite), with no replay. - The impasse is the 27-point declaration
-
On its turn a side may declare when its king is in the enemy camp, ten of its other pieces are there, it is not in check, and it has 28 points (Black) or 27 (White), counting a rook or bishop as five and every other piece as one, from the pieces in the camp and in hand. A correct declaration wins (
impasse_declared); see "declare". - A game that nobody ends is drawn at 500 moves
-
The JSA's rule (
cap). A side in check at the cap plays on until it is not.capin "new" changes the number. - Black moves first in an even game
-
The furigoma, the toss that decides who takes Black, is left to the caller. In a handicap game the giver plays White and moves first.
SEE ALSO
Game::Shogi::Engine, the board and its rules; Game::Shogi::Notation; Game::Shogi::Handicap.
Games::Shogi describes the boards and pieces of shogi's large variants. It has no move generator and no search.
AUTHOR
LNATION <email@lnation.org>
BUGS
Please report any bugs or feature requests to bug-game-shogi at rt.cpan.org, or through the web interface at https://rt.cpan.org/NoAuth/ReportBug.html?Queue=Game-Shogi. 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::Shogi
You can also look for information at:
RT: CPAN's request tracker (report bugs here)
Search CPAN
ACKNOWLEDGEMENTS
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 (GPL Compatible)