package Games::Sudoku::Component::Controller::Status; { use strict; use warnings; use Carp; our $VERSION = '0.02'; my $S_NULL = 0; my $S_OK = 1; my $S_REWIND = 2; my $S_SOLVED = 4; my $S_GIVEUP = 8; sub new { my $class = shift; my $this = bless {}, (ref $class || $class); my %options = ref $_[0] ? %{ $_[0] } : @_; $this->{status} = $S_NULL; $this->{changed} = 0; $this->{rewind_max} = $options{rewind_max} || 9; $this->{retry_max} = $options{retry_max} || 3; $this->{rewind} = 0; $this->{retry} = 0; $this; } sub clear { my $this = shift; $this->{status} = $S_NULL; $this->{rewind} = 0; $this->{retry} = 0; } sub turn_to_ok { $_[0]->{status} = $S_OK; $_[0]->{changed} = 1; } sub turn_to_rewind { $_[0]->{status} = $S_REWIND; $_[0]->{changed} = 1; } sub turn_to_solved { $_[0]->{status} = $S_SOLVED; $_[0]->{changed} = 1; } sub turn_to_giveup { $_[0]->{status} = $S_GIVEUP; $_[0]->{changed} = 1; } sub is_null { ($_[0]->{status} == $S_NULL); } sub is_ok { ($_[0]->{status} == $S_OK); } sub is_rewind { ($_[0]->{status} == $S_REWIND); } sub is_solved { ($_[0]->{status} == $S_SOLVED); } sub is_giveup { ($_[0]->{status} == $S_GIVEUP); } sub is_changed { my $prev = $_[0]->{changed}; $_[0]->{changed} = 0; $prev; } sub is_finished { $_[0]->{status} & ($S_GIVEUP|$S_SOLVED) } sub can_rewind { my $this = shift; ($this->{rewind}++ < $this->{rewind_max}); } sub can_retry { my $this = shift; $this->{rewind} = 0; ($this->{retry}++ < $this->{retry_max}); } } 1; __END__ =head1 NAME Games::Sudoku::Component::Controller::Status =head1 SYNOPSIS use Games::Sudoku::Component::Controller; my $c = Games::Sudoku::Component::Controller->new; until($c->status->is_finished) { $c->next; } =head1 DESCRIPTION This module is to hold a status of L. =head1 METHODS =head2 new Creates an object. Options are: =over 4 =item rewind_max (I) =item retry_max (I) Specifies how many times the controller can rewind/retry. See L. =back =head2 is_null Returns true if the controller has no special status. =head2 is_ok Returns true if the controller has some cells to do with next. =head2 is_rewind Returns true if the controller has failed to solve a puzzle and is rewinding. =head2 is_solved Returns true if the controller has solved a puzzle. =head2 is_giveup Returns true if the controller has finally given up to solve a puzzle. =head2 is_finished Returns true if the controller has solved a puzzle or given up to solve. =head2 is_changed Returns true if the status has just changed. Once checked, this flag will be turn off. =head2 turn_to_ok =head2 turn_to_rewind =head2 turn_to_solved =head2 turn_to_giveup Changes the status to something, respectively. =head2 can_rewind Returns true if the controller is still able to rewind. If the internal counter grows larger than C, this returns false. =head2 can_retry Returns true if the controller is still able to retry. If the internal counter grows larger than C, this returns false. =head2 clear Clears the status. =head1 SEE ALSO =over 4 =item L, =item L =back =head1 AUTHOR Kenichi Ishigaki, Eishigaki@cpan.orgE =head1 COPYRIGHT AND LICENSE Copyright (C) 2006 by Kenichi Ishigaki This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut