File Coverage

lib/Games/Checkers/MoveLocationConstructor.pm
Criterion Covered Total %
statement 15 87 17.2
branch 0 32 0.0
condition 0 45 0.0
subroutine 5 16 31.2
pod 0 11 0.0
total 20 191 10.4


line stmt bran cond sub pod time code
1             # Games::Checkers, Copyright (C) 1996-2012 Mikhael Goikhman, migo@cpan.org
2             #
3             # This program is free software: you can redistribute it and/or modify
4             # it under the terms of the GNU General Public License as published by
5             # the Free Software Foundation, either version 3 of the License, or
6             # (at your option) any later version.
7             #
8             # This program is distributed in the hope that it will be useful,
9             # but WITHOUT ANY WARRANTY; without even the implied warranty of
10             # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11             # GNU General Public License for more details.
12             #
13             # You should have received a copy of the GNU General Public License
14             # along with this program. If not, see .
15              
16 1     1   6 use strict;
  1         2  
  1         20  
17 1     1   3 use warnings;
  1         2  
  1         22  
18              
19             package Games::Checkers::MoveLocationConstructor;
20              
21 1     1   4 use Games::Checkers::Constants;
  1         1  
  1         4  
22 1     1   5 use Games::Checkers::Board;
  1         1  
  1         16  
23 1     1   3 use Games::Checkers::MoveConstants;
  1         2  
  1         3  
24              
25             sub new ($$$) {
26 0     0 0   my $class = shift;
27 0           my $board = shift;
28 0           my $color = shift;
29              
30 0           my $self = {
31             color => $color,
32             destin => [],
33             src => NL,
34             piece => 0,
35             must_beat => $board->can_color_beat($color),
36             orig_board => $board,
37             };
38 0           bless $self, $class;
39              
40 0           return $self;
41             }
42            
43             sub init_work_board ($) {
44 0     0 0   my $self = shift;
45              
46             return $self->{work_board}
47             ? $self->{work_board}->copy($self->{orig_board})
48 0 0         : ($self->{work_board} = $self->{orig_board}->clone);
49             }
50              
51             sub source ($$) {
52 0     0 0   my $self = shift;
53 0           my $loc = shift;
54              
55 0           my $board = $self->{orig_board};
56             return Err
57             if $loc == NL
58             || !$board->occup($loc)
59             || $board->color($loc) != $self->{color}
60             || $self->{must_beat} && !$board->can_piece_beat($loc)
61 0 0 0       || !$self->{must_beat} && !$board->can_piece_step($loc);
      0        
      0        
      0        
      0        
      0        
62              
63 0           $self->{piece} = $board->piece($self->{src} = $loc);
64 0           $self->{destin} = [];
65 0           $self->init_work_board;
66              
67 0           return Ok;
68             }
69              
70             sub add_dst ($$) {
71 0     0 0   my $self = shift;
72 0           my $dst = shift;
73              
74 0 0 0       return Err if $self->{src} == NL || @{$self->{destin}} == 100;
  0            
75              
76 0 0         my $board = $self->{work_board} or die "Internal";
77 0 0         if ($self->{must_beat}) {
78 0 0         die "Internal" unless $board->occup($self->dst_1);
79 0 0         return Err unless $board->can_piece_beat($self->dst_1, $dst);
80             } else {
81 0 0         return Err if @{$self->{destin}} > 0;
  0            
82 0 0         return Err unless $board->can_piece_step($self->{src}, $dst);
83             }
84 0           push @{$self->{destin}}, $dst;
  0            
85 0           $self->apply_last_dst;
86              
87 0           return Ok;
88             }
89              
90             sub del_dst ($) {
91 0     0 0   my $self = shift;
92 0 0 0       return NL if $self->{src} == NL || @{$self->{destin}} == 0;
  0            
93 0           my $dst = pop @{$self->{destin}};
  0            
94 0           $self->reapply_all;
95 0           return $dst;
96             }
97              
98             sub can_create_move ($) {
99 0     0 0   my $self = shift;
100             return $self->{must_beat} && @{$self->{destin}} > 0
101             && $self->{work_board}->can_piece_beat($self->dst_1) == No
102 0   0       || !$self->{must_beat} && @{$self->{destin}} == 1;
103             }
104              
105             sub create_move ($) {
106 0     0 0   my $self = shift;
107             return NO_MOVE if $self->{src} == NL
108 0           || $self->{must_beat} && @{$self->{destin}} < 1
109 0 0 0       || !$self->{must_beat} && @{$self->{destin}} != 1;
  0   0        
      0        
      0        
110             return new Games::Checkers::Move(
111 0           $self->{must_beat}, $self->{src}, $self->{destin});
112             }
113              
114             sub apply_last_dst ($) {
115 0     0 0   my $self = shift;
116              
117 0           my $board = $self->{work_board};
118 0           my $src = $self->dst_2;
119 0           my $dst = $self->dst_1;
120 0           $board->clr($src);
121 0           $board->set($dst, $self->{color}, $self->{piece});
122 0 0         $board->clr($board->enclosed_figure($src, $dst)) if $self->{must_beat};
123 0 0 0       if ($self->{piece} == Pawn && $board->is_crowning->[$self->{color}][$dst]) {
124 0           $board->cnv($dst);
125 0           $self->{piece} ^= 1;
126             }
127             }
128              
129             sub reapply_all ($) {
130 0     0 0   my $self = shift;
131              
132 0           my $board = $self->init_work_board;
133 0 0 0       return if $self->{src} == NL || @{$self->{destin}} == 0;
  0            
134              
135 0           $self->{piece} = $board->piece($self->{src});
136 0           my $destin = $self->{destin};
137 0           $self->{destin} = [];
138 0           while (@$destin) {
139 0           push @{$self->{destin}}, shift @$destin;
  0            
140 0           $self->apply_last_dst;
141             }
142             }
143              
144             sub dst_1 ($) {
145 0     0 0   my $self = shift;
146 0 0         return @{$self->{destin}} == 0 ? $self->{src} : $self->{destin}->[-1];
  0            
147             }
148              
149             sub dst_2 ($) {
150 0     0 0   my $self = shift;
151 0 0         return @{$self->{destin}} == 1 ? $self->{src} : $self->{destin}->[-2];
  0            
152             }
153              
154             1;