File Coverage

blib/lib/Games/Solitaire/Verify/State.pm
Criterion Covered Total %
statement 285 297 95.9
branch 75 86 87.2
condition n/a
subroutine 54 55 98.1
pod 18 18 100.0
total 432 456 94.7


line stmt bran cond sub pod time code
1             package Games::Solitaire::Verify::State;
2             $Games::Solitaire::Verify::State::VERSION = '0.2601';
3 18     18   968659 use warnings;
  18         37  
  18         1090  
4 18     18   91 use strict;
  18         30  
  18         519  
5              
6              
7 18     18   994 use parent 'Games::Solitaire::Verify::Base';
  18         626  
  18         105  
8              
9 18     18   3964 use Games::Solitaire::Verify::Exception ();
  18         38  
  18         378  
10 18     18   3187 use Games::Solitaire::Verify::Card ();
  18         86  
  18         472  
11 18     18   2845 use Games::Solitaire::Verify::Column ();
  18         43  
  18         348  
12 18     18   2852 use Games::Solitaire::Verify::Move ();
  18         38  
  18         372  
13 18     18   9429 use Games::Solitaire::Verify::Freecells ();
  18         62  
  18         527  
14 18     18   9754 use Games::Solitaire::Verify::Foundations ();
  18         53  
  18         735  
15 18     18   5544 use Games::Solitaire::Verify::VariantParams ();
  18         92  
  18         505  
16 18     18   5398 use Games::Solitaire::Verify::VariantsMap ();
  18         64  
  18         698  
17              
18 18     18   130 use List::Util qw(first);
  18         42  
  18         2009  
19 18     18   6932 use POSIX qw();
  18         81810  
  18         66239  
20              
21             __PACKAGE__->mk_acc_ref(
22             [
23             qw(
24             _columns
25             _freecells
26             _foundations
27             _variant
28             _variant_params
29             _temp_move
30             )
31             ]
32             );
33              
34              
35             sub set_freecells
36             {
37 274     274 1 679 my ( $self, $freecells ) = @_;
38              
39 274         730 $self->_freecells($freecells);
40              
41 274         476 return ();
42             }
43              
44             sub _assign_freecells_from_string
45             {
46 272     272   528 my $self = shift;
47 272         673 my $string = shift;
48              
49 272         790 $self->set_freecells(
50             Games::Solitaire::Verify::Freecells->new(
51             {
52             count => $self->num_freecells(),
53             string => $string,
54             }
55             )
56             );
57              
58 272         753 return ();
59             }
60              
61              
62             sub add_column
63             {
64 2246     2246 1 4441 my ( $self, $col ) = @_;
65              
66 2246         3322 push @{ $self->_columns() }, $col;
  2246         6698  
67              
68 2246         6912 return ();
69             }
70              
71              
72             sub set_foundations
73             {
74 281     281 1 618 my ( $self, $foundations ) = @_;
75              
76 281         883 $self->_foundations($foundations);
77              
78 281         504 return ();
79             }
80              
81             sub _get_suits_seq
82             {
83 0     0   0 my $class = shift;
84              
85 0         0 return Games::Solitaire::Verify::Card->get_suits_seq();
86             }
87              
88             sub _from_string
89             {
90 266     266   627 my ( $self, $str ) = @_;
91              
92 266         506 my $rank_re = '[0A1-9TJQK]';
93              
94 266 50       1689 if ( $str !~ m{\A(Foundations:[^\n]*)\n}gms )
95             {
96 0         0 Games::Solitaire::Verify::Exception::Parse::State::Foundations->throw(
97             error => "Wrong Foundations", );
98             }
99 266         872 my $founds_s = $1;
100              
101 266         846 $self->set_foundations(
102             Games::Solitaire::Verify::Foundations->new(
103             {
104             num_decks => $self->num_decks(),
105             string => $founds_s,
106             }
107             )
108             );
109              
110 266 50       1858 if ( $str !~ m{\G(Freecells:[^\n]*)\n}gms )
111             {
112 0         0 Games::Solitaire::Verify::Exception::Parse::State::Freecells->throw(
113             error => "Wrong Freecell String", );
114             }
115 266         891 $self->_assign_freecells_from_string($1);
116              
117 266         765 foreach my $col_idx ( 0 .. ( $self->num_columns() - 1 ) )
118             {
119 2128 100       12917 if ( $str !~ m{\G(:[^\n]*)\n}msg )
120             {
121 2         41 Games::Solitaire::Verify::Exception::Parse::State::Column->throw(
122             error => "Cannot parse column",
123             index => $col_idx,
124             );
125             }
126 2126         6205 my $column_str = $1;
127              
128 2126         8493 $self->add_column(
129             Games::Solitaire::Verify::Column->new(
130             {
131             string => $column_str,
132             }
133             )
134             );
135             }
136              
137 264         1259 return ();
138             }
139              
140             sub _fill_non_custom_variant
141             {
142 272     272   451 my $self = shift;
143 272         484 my $variant = shift;
144              
145 272         984 my $variants_map = Games::Solitaire::Verify::VariantsMap->new();
146              
147 272         822 my $params = $variants_map->get_variant_by_id($variant);
148              
149 272 50       749 if ( !defined($params) )
150             {
151 0         0 Games::Solitaire::Verify::Exception::Variant::Unknown->throw(
152             error => "Unknown/Unsupported Variant",
153             variant => $variant,
154             );
155             }
156 272         748 $self->_variant_params($params);
157 272         764 $self->_variant($variant);
158              
159 272         806 return ();
160             }
161              
162             sub _set_variant
163             {
164 281     281   519 my $self = shift;
165 281         525 my $args = shift;
166              
167 281         629 my $variant = $args->{variant};
168              
169 281 100       1081 if ( $variant eq "custom" )
170             {
171 9         37 $self->_variant($variant);
172 9         28 $self->_variant_params( $args->{variant_params} );
173             }
174             else
175             {
176 272         763 $self->_fill_non_custom_variant($variant);
177             }
178              
179 281         570 return ();
180             }
181              
182             sub _init
183             {
184 281     281   594 my ( $self, $args ) = @_;
185              
186             # Set the variant
187 281         952 $self->_set_variant($args);
188              
189 281         715 $self->_columns( [] );
190              
191 281 100       791 if ( exists( $args->{string} ) )
192             {
193 272         768 return $self->_from_string( $args->{string} );
194             }
195 9         20 return ();
196             }
197              
198              
199             sub get_freecell
200             {
201 1939     1939 1 3368 my ( $self, $index ) = @_;
202              
203 1939         5516 return $self->_freecells()->cell($index);
204             }
205              
206              
207             sub set_freecell
208             {
209 590     590 1 1280 my ( $self, $index, $card ) = @_;
210              
211 590         1798 return $self->_freecells->assign( $index, $card );
212             }
213              
214              
215             sub get_foundation_value
216             {
217 866     866 1 1588 my ( $self, $suit, $idx ) = @_;
218              
219 866         2692 return $self->_foundations()->value( $suit, $idx );
220             }
221              
222              
223             sub increment_foundation_value
224             {
225 833     833 1 1467 my ( $self, $suit, $idx ) = @_;
226              
227 833         2476 $self->_foundations()->increment( $suit, $idx );
228              
229 833         1265 return ();
230             }
231              
232              
233             sub num_decks
234             {
235 1066     1066 1 1688 my $self = shift;
236              
237 1066         5575 return $self->_variant_params->num_decks();
238             }
239              
240              
241             sub num_freecells
242             {
243 487     487 1 772 my $self = shift;
244              
245 487         3071 return $self->_variant_params->num_freecells();
246             }
247              
248              
249             sub num_empty_freecells
250             {
251 489     489 1 779 my $self = shift;
252              
253 489         1639 return $self->_freecells->num_empty();
254             }
255              
256              
257             sub num_columns
258             {
259 1168     1168 1 1772 my $self = shift;
260              
261 1168         4400 return $self->_variant_params->num_columns();
262             }
263              
264              
265             sub get_column
266             {
267 13203     13203 1 19220 my $self = shift;
268 13203         19738 my $index = shift;
269              
270 13203         35281 return $self->_columns->[$index];
271             }
272              
273              
274             sub num_empty_columns
275             {
276 452     452 1 761 my $self = shift;
277              
278 452         902 my $count = 0;
279              
280 452         1035 foreach my $idx ( 0 .. ( $self->num_columns() - 1 ) )
281             {
282 3776 100       6740 if ( !$self->get_column($idx)->len() )
283             {
284 328         697 ++$count;
285             }
286             }
287 452         1799 return $count;
288             }
289              
290              
291             sub clone
292             {
293 7     7 1 47 my $self = shift;
294              
295 7         23 my $variant = $self->_variant;
296 7 100       48 my $copy = Games::Solitaire::Verify::State->new(
297             {
298             variant => $variant,
299             (
300             ( $variant eq "custom" )
301             ? ( variant_params => $self->_variant_params() )
302             : ()
303             ),
304             }
305             );
306              
307 7         24 foreach my $idx ( 0 .. ( $self->num_columns() - 1 ) )
308             {
309 56         169 $copy->add_column( $self->get_column($idx)->clone() );
310             }
311              
312 7         45 $copy->set_foundations( $self->_foundations()->clone() );
313              
314 7         33 $copy->_freecells( $self->_freecells()->clone() );
315              
316 7         33 return $copy;
317             }
318              
319              
320             # Returns 0 on success, else the error.
321             sub _can_put_into_empty_column
322             {
323 225     225   478 my ( $self, $card ) = @_;
324              
325 225 100       876 if ( $self->_variant_params->empty_stacks_filled_by() eq "kings" )
326             {
327 13 100       47 if ( $card->rank() != 13 )
328             {
329             return
330 2         65 Games::Solitaire::Verify::Exception::Move::Dest::Col::OnlyKingsCanFillEmpty
331             ->new(
332             error => "Non-king on an empty stack",
333             move => $self->_temp_move(),
334             );
335             }
336             }
337 223         690 return 0;
338             }
339              
340             sub _is_matching_color
341             {
342 1422     1422   2421 my ( $self, $parent, $child ) = @_;
343              
344 1422         3400 my $rules = $self->_variant_params()->rules();
345 1422         3107 my $sbb = $self->_variant_params()->seq_build_by();
346              
347 1422 50       4731 my $verdict = (
    100          
    100          
348             ( $rules eq "simple_simon" ) ? 0
349             : ( $sbb eq "alt_color" ) ? ( $parent->color() eq $child->color() )
350             : ( $sbb eq "suit" ) ? ( $parent->suit() ne $child->suit() )
351             : 0
352             );
353              
354 1422 100       3147 if ($verdict)
355             {
356             return
357 3         109 Games::Solitaire::Verify::Exception::Move::Dest::Col::NonMatchSuits
358             ->new(
359             seq_build_by => $sbb,
360             move => $self->_temp_move(),
361             );
362             }
363              
364 1419         3459 return 0;
365             }
366              
367             sub _can_put_on_top
368             {
369 1425     1425   2691 my ( $self, $parent, $child ) = @_;
370              
371 1425 100       4466 if ( $parent->rank() != $child->rank() + 1 )
372             {
373             return
374 3         175 Games::Solitaire::Verify::Exception::Move::Dest::Col::RankMismatch
375             ->new(
376             error => "Rank mismatch between parent and child cards",
377             move => $self->_temp_move(),
378             );
379             }
380              
381 1422 100       3059 if ( my $ret = $self->_is_matching_color( $parent, $child ) )
382             {
383 3         16 return $ret;
384             }
385              
386 1419         4295 return 0;
387             }
388              
389             sub _can_put_on_column
390             {
391 1088     1088   2235 my ( $self, $col_idx, $card ) = @_;
392              
393             return (
394 1088 100       2301 ( $self->get_column($col_idx)->len() == 0 )
395             ? $self->_can_put_into_empty_column($card)
396             : $self->_can_put_on_top( $self->get_column($col_idx)->top(), $card )
397             );
398             }
399              
400             sub _calc_freecell_max_seq_move
401             {
402 451     451   831 my ( $self, $args ) = @_;
403 451 50       1400 my $to_empty = ( defined( $args->{to_empty} ) ? $args->{to_empty} : 0 );
404              
405 451         1038 return ( ( $self->num_empty_freecells() + 1 )
406             << ( $self->num_empty_columns() - $to_empty ) );
407             }
408              
409             sub _calc_empty_stacks_filled_by_any_card_max_seq_move
410             {
411 451     451   881 my ( $self, $args ) = @_;
412              
413 451         1048 return $self->_calc_freecell_max_seq_move($args);
414             }
415              
416             sub _calc_max_sequence_move
417             {
418 615     615   1164 my ( $self, $args ) = @_;
419              
420 615 100       2864 return +( $self->_variant_params->sequence_move() eq "unlimited" )
    100          
421             ? POSIX::INT_MAX()
422             : ( $self->_variant_params->empty_stacks_filled_by() eq "any" )
423             ? $self->_calc_empty_stacks_filled_by_any_card_max_seq_move($args)
424             : ( $self->num_empty_freecells() + 1 );
425             }
426              
427             sub _is_sequence_in_column
428             {
429 625     625   1448 my ( $self, $source_idx, $num_cards, $num_seq_components_ref ) = @_;
430              
431 625         1201 my $col = $self->get_column($source_idx);
432 625         1279 my $len = $col->len();
433              
434 625         1803 my $rules = $self->_variant_params()->rules();
435              
436 625         1008 my $num_comps = 1;
437              
438 625         1772 foreach my $card_idx ( 0 .. ( $num_cards - 2 ) )
439             {
440 562         1341 my $parent = $col->pos( $len - 1 - $card_idx - 1 );
441 562         1226 my $child = $col->pos( $len - 1 - $card_idx );
442              
443 562 100       1188 if ( $self->_can_put_on_top( $parent, $child ) )
444             {
445             return
446 1         26 Games::Solitaire::Verify::Exception::Move::Src::Col::NonSequence
447             ->new(
448             move => $self->_temp_move(),
449             pos => $card_idx,
450             );
451             }
452              
453             $num_comps += (
454 561 100       1601 ( $rules eq "simple_simon" )
    100          
455             ? ( ( $parent->suit() ne $child->suit() ) ? 1 : 0 )
456             : 1
457             );
458             }
459              
460 624         1109 ${$num_seq_components_ref} = $num_comps;
  624         1155  
461              
462 624         1772 return 0;
463             }
464              
465              
466             sub clear_freecell
467             {
468 578     578 1 1178 my ( $self, $index ) = @_;
469              
470 578         1795 return $self->_freecells->clear($index);
471             }
472              
473             sub verify_and_perform_move
474             {
475 2458     2458 1 14497 my ( $self, $move ) = @_;
476              
477 2458 50       12788 if ( my $method =
478             $self->can( "_mv_" . $move->source_type . "_to_" . $move->dest_type ) )
479             {
480 2458         5441 $self->_temp_move($move);
481 2458         4783 my $ret = $method->($self);
482 2458         14150 $self->_temp_move( undef() );
483 2458         8894 return $ret;
484             }
485             else
486             {
487 0         0 die "Cannot handle this move type";
488             }
489             }
490              
491             sub _mv_stack_to_foundation
492             {
493 657     657   926 my $self = shift;
494              
495 657         1075 my $move = $self->_temp_move();
496              
497 657         1111 my $col_idx = $move->source();
498 657         1416 my $card = $self->get_column($col_idx)->top();
499              
500 657         1352 my $rank = $card->rank();
501 657         1322 my $suit = $card->suit();
502              
503 657     657   1494 my $f_idx = first { $self->get_foundation_value( $suit, $_ ) == $rank - 1 }
504 657         3421 ( 0 .. ( $self->num_decks() - 1 ) );
505              
506 657 100       2505 if ( defined($f_idx) )
507             {
508 656         1265 $self->get_column($col_idx)->pop();
509 656         1623 $self->increment_foundation_value( $suit, $f_idx );
510 656         2123 return 0;
511             }
512             else
513             {
514             return
515 1         7 Games::Solitaire::Verify::Exception::Move::Dest::Foundation->new(
516             move => $move );
517             }
518             }
519              
520             sub _mv_stack_seq_to_foundation
521             {
522 7     7   14 my $self = shift;
523              
524 7         17 my $move = $self->_temp_move();
525              
526 7         26 my $rules = $self->_variant_params()->rules();
527              
528 7 100       24 if ( $rules ne "simple_simon" )
529             {
530             return
531 1         13 Games::Solitaire::Verify::Exception::Move::Variant::Unsupported
532             ->new( move => $move );
533             }
534              
535 6         15 my $col_idx = $move->source();
536              
537 6         12 my $num_seq_components;
538 6         19 my $verdict =
539             $self->_is_sequence_in_column( $col_idx, 13, \$num_seq_components, );
540              
541 6 50       20 if ($verdict)
542             {
543 0         0 return $verdict;
544             }
545              
546 6 100       19 if ( $num_seq_components != 1 )
547             {
548             return
549 1         23 Games::Solitaire::Verify::Exception::Move::Src::Col::NotTrueSeq
550             ->new( move => $move );
551             }
552              
553 5         16 my $card = $self->get_column($col_idx)->top();
554              
555 5         17 my $suit = $card->suit();
556              
557 5     5   20 my $f_idx = first { $self->get_foundation_value( $suit, $_ ) == 0 }
558 5         111 ( 0 .. ( $self->num_decks() - 1 ) );
559              
560 5 50       30 if ( defined($f_idx) )
561             {
562 5         16 foreach my $card_idx ( 1 .. 13 )
563             {
564 65         133 $self->get_column($col_idx)->pop();
565 65         138 $self->increment_foundation_value( $suit, $f_idx );
566             }
567 5         22 return 0;
568             }
569             else
570             {
571             return
572 0         0 Games::Solitaire::Verify::Exception::Move::Dest::Foundation->new(
573             move => $move );
574             }
575             }
576              
577             sub _mv_stack_to_freecell
578             {
579 589     589   889 my $self = shift;
580 589         1055 my $move = $self->_temp_move();
581              
582 589         1119 my $col_idx = $move->source();
583 589         1648 my $fc_idx = $move->dest();
584              
585 589 100       1777 if ( !$self->get_column($col_idx)->len() )
586             {
587             return
588 1         26 Games::Solitaire::Verify::Exception::Move::Src::Col::NoCards->new(
589             move => $move, );
590             }
591              
592 588 100       1531 if ( defined( $self->get_freecell($fc_idx) ) )
593             {
594 1         31 return Games::Solitaire::Verify::Exception::Move::Dest::Freecell->new(
595             move => $move, );
596             }
597              
598 587         1267 $self->set_freecell( $fc_idx, $self->get_column($col_idx)->pop() );
599              
600 587         1172 return 0;
601             }
602              
603             sub _mv_stack_to_stack
604             {
605 620     620   959 my $self = shift;
606 620         1154 my $move = $self->_temp_move();
607              
608 620         1187 my $source = $move->source();
609 620         1110 my $dest = $move->dest();
610 620         3088 my $num_cards = $move->num_cards();
611              
612             # Source column
613 620         1426 my $sc = $self->get_column($source);
614 620         1212 my $dc = $self->get_column($dest);
615              
616 620         1854 my $source_len = $sc->len();
617              
618 620 100       2187 if ( $source_len < $num_cards )
619             {
620             return
621 1         25 Games::Solitaire::Verify::Exception::Move::Src::Col::NotEnoughCards
622             ->new( move => $move, );
623             }
624              
625 619         1000 my $num_seq_components;
626 619 100       1633 if (
627             my $verdict = $self->_is_sequence_in_column(
628             $source, $num_cards, \$num_seq_components,
629             )
630             )
631             {
632 1         32 return $verdict;
633             }
634              
635 618 100       1756 if (
636             my $verdict = $self->_can_put_on_column(
637             $dest, $sc->pos( $source_len - $num_cards )
638             )
639             )
640             {
641 3         13 return $verdict;
642             }
643              
644             # Now let's see if we have enough resources
645             # to move the cards.
646              
647 615 100       1672 if (
648             $num_seq_components > $self->_calc_max_sequence_move(
649             {
650             to_empty => ( $dc->len() == 0 ),
651             }
652             )
653             )
654             {
655             return
656 3         73 Games::Solitaire::Verify::Exception::Move::NotEnoughEmpties->new(
657             move => $move, );
658             }
659              
660             # Now let's actually move them.
661 612         2302 $dc->append_cards( $sc->popN($num_cards) );
662              
663 612         1593 return 0;
664             }
665              
666             sub _mv_freecell_to_foundation
667             {
668 114     114   179 my $self = shift;
669 114         204 my $move = $self->_temp_move();
670              
671 114         214 my $fc_idx = $move->source();
672 114         237 my $card = $self->get_freecell($fc_idx);
673              
674 114 100       268 if ( !defined($card) )
675             {
676             return
677 1         7 Games::Solitaire::Verify::Exception::Move::Src::Freecell::Empty
678             ->new( move => $move, );
679             }
680              
681 113         273 my $rank = $card->rank();
682 113         270 my $suit = $card->suit();
683              
684 113     113   246 my $f_idx = first { $self->get_foundation_value( $suit, $_ ) == $rank - 1 }
685 113         561 ( 0 .. ( $self->num_decks() - 1 ) );
686              
687 113 100       420 if ( defined($f_idx) )
688             {
689 112         276 $self->clear_freecell($fc_idx);
690 112         267 $self->increment_foundation_value( $suit, $f_idx );
691 112         341 return 0;
692             }
693             else
694             {
695             return
696 1         23 Games::Solitaire::Verify::Exception::Move::Dest::Foundation->new(
697             move => $move );
698             }
699             }
700              
701             sub _mv_freecell_to_stack
702             {
703 471     471   828 my $self = shift;
704 471         944 my $move = $self->_temp_move();
705              
706 471         902 my $fc_idx = $move->source();
707 471         936 my $col_idx = $move->dest();
708              
709 471         1119 my $card = $self->get_freecell($fc_idx);
710              
711 471 100       1178 if ( !defined($card) )
712             {
713             return
714 1         23 Games::Solitaire::Verify::Exception::Move::Src::Freecell::Empty
715             ->new( move => $move, );
716             }
717              
718 470 100       1173 if ( my $verdict = $self->_can_put_on_column( $col_idx, $card ) )
719             {
720 4         11 return $verdict;
721             }
722              
723 466         1084 $self->get_column($col_idx)->push($card);
724 466         1309 $self->clear_freecell($fc_idx);
725              
726 466         990 return 0;
727             }
728              
729              
730             my @SS = ( @{ Games::Solitaire::Verify::Card->get_suits_seq() } );
731              
732             sub verify_contents
733             {
734 16     16 1 37 my ( $self, $args ) = @_;
735              
736 16         35 my $MAX_RANK = $args->{max_rank};
737 16         45 my $found = {};
738             my $register = sub {
739 832     832   1959 my $card = shift;
740 832 50       1857 if ( $card->rank > $MAX_RANK )
741             {
742 0         0 die Games::Solitaire::Verify::Exception::State::TooHighRank->new(
743             cards => [$card], );
744             }
745 832         1502 my $s = $card->fast_s;
746 832 50       2335 if ( ( ++$found->{$s} ) > 1 )
747             {
748 0         0 die Games::Solitaire::Verify::Exception::State::ExtraCards->new(
749             cards => [$card], );
750             }
751 832         1292 return ();
752 16         91 };
753 16         49 for my $fc ( 0 .. $self->num_freecells - 1 )
754             {
755 64         111 my $card = $self->get_freecell($fc);
756 64 100       139 if ( defined $card )
757             {
758 14         40 $register->($card);
759             }
760             }
761 16         45 foreach my $suit (@SS)
762             {
763 64         130 for my $rank ( 1 .. $self->get_foundation_value( $suit, 0 ) )
764             {
765 0         0 $register->(
766             Games::Solitaire::Verify::Card->new(
767             {
768             string => (
769             Games::Solitaire::Verify::Card->rank_to_string(
770             $rank)
771             . $suit
772             )
773             }
774             ),
775             );
776             }
777             }
778              
779 16         47 foreach my $idx ( 0 .. ( $self->num_columns() - 1 ) )
780             {
781 132         268 my $col = $self->get_column($idx);
782 132         278 for my $pos ( 0 .. $col->len - 1 )
783             {
784 818         1401 $register->( $col->pos($pos) );
785             }
786             }
787              
788 16 50       64 if ( scalar( keys %$found ) != $MAX_RANK * 4 )
789             {
790 0         0 die Games::Solitaire::Verify::Exception::State::MissingCards->new(
791             cards => [], );
792             }
793              
794 16         259 return ();
795             }
796              
797              
798             sub to_string
799             {
800 2226     2226 1 3469 my $self = shift;
801              
802             return join(
803             "\n",
804             (
805 22606         43473 map { $_->to_string() } $self->_foundations(),
806             $self->_freecells(),
807 2226         5461 @{ $self->_columns() }
  2226         5197  
808             ),
809             ""
810             );
811             }
812              
813             1; # End of Games::Solitaire::Verify::State
814              
815             __END__