File Coverage

blib/lib/Chess/Game/MoveListEntry.pm
Criterion Covered Total %
statement 104 104 100.0
branch 28 54 51.8
condition 3 9 33.3
subroutine 23 23 100.0
pod 9 13 69.2
total 167 203 82.2


line stmt bran cond sub pod time code
1             =head1 NAME
2              
3             Chess::Game::MoveListEntry - a read-only class containing move data, used by
4             L to record a game.
5              
6             =head1 SYNOPSIS
7              
8             $entry = Chess::Game::MoveListEntry->new(1, $pawn, "e2", "e4", 0);
9             $one = $entry->get_move_num();
10             $pawn = $entry->get_piece();
11             $e2 = $entry->get_start_square();
12             $e4 = $entry->get_dest_square();
13             $false = $entry->is_capture();
14             $false = $entry->is_short_castle();
15             $false = $entry->is_long_castle();
16             $false = $entry->is_en_passant();
17              
18             =head1 DESCRIPTION
19              
20             The Chess module provides a framework for writing chess programs with Perl.
21             This class forms part of that framework, containing object data about a single
22             move.
23              
24             =head1 METHODS
25              
26             =head2 Construction
27              
28             =item new()
29              
30             Constructs a new MoveListEntry with the provided parameters. Requires four
31             scalar parameters containing move number, piece, start square and destination
32             square. Optionally takes a fifth parameter containing flags for the entry.
33             The following flags are recognized (but there are no exported constants for
34             them):
35              
36             MOVE_CAPTURE == 0x01
37             MOVE_CASTLE_SHORT == 0x02
38             MOVE_CASTLE_LONG == 0x04
39             MOVE_EN_PASSANT == 0x08
40              
41             $entry = Chess::Game::MoveListEntry->new(1, $pawn, "e2", "e4", 0);
42              
43             =head2 Class methods
44              
45             There are no class methods for this class.
46              
47             =head2 Object methods
48              
49             =item get_move_num()
50              
51             Takes no parameters. Returns the move number this entry was constructed with.
52              
53             =item get_piece()
54              
55             Takes no parameters. Returns the piece reference this entry was constructed
56             with.
57              
58             =item get_start_square()
59              
60             Takes no parameters. Returns the start square this entry was constructed with.
61              
62             =item get_dest_square()
63              
64             Takes no parameters. Returns the destination square this entry was constructed
65             with.
66              
67             =item is_capture()
68              
69             Takes no parameters. Returns true if the entry was recorded as a capture
70              
71             =item is_short_castle()
72              
73             Takes no parameters. Returns true if the entry was recorded as a short
74             (kingside) castle.
75              
76             =item is_long_castle()
77              
78             Takes no parameters. Returns true if the entry was recorded as a long
79             (queenside) castle.
80              
81             =item is_en_passant()
82              
83             Takes no parameters. Returns true if the entry was recorded as an 'en passant'
84             capture. L will also return true in this case.
85              
86             =head1 DIAGNOSTICS
87              
88             =item Invalid Chess::Game::MoveListEntry reference
89              
90             The program uses a reference to a MoveListEntry that was not obtained by
91             calling L. Ensure that all MoveListEntries in the program were
92             obtained either in this fashion, or through the container class,
93             L, and that the reference refers to a defined value.
94              
95             =head1 BUGS
96              
97             Please report any bugs to the author.
98              
99             =head1 AUTHOR
100              
101             Brian Richardson
102              
103             =head1 COPYRIGHT
104              
105             Copyright (c) 2002, 2005 Brian Richardson. All rights reserved. This module is
106             Free Software. It may be modified and redistributed under the same terms as
107             Perl itself.
108              
109             =cut
110             package Chess::Game::MoveListEntry;
111              
112 5     5   707 use Carp;
  5         13  
  5         365  
113 5     5   28 use strict;
  5         10  
  5         245  
114              
115 5         550 use constant OBJECT_FIELDS => (
116             move_num => 0,
117             piece_ref => undef,
118             from_sq => '',
119             dest_sq => '',
120             flags => 0x0,
121             promoted_to => undef
122 5     5   28 );
  5         7  
123              
124             # Chess::Game uses these flags as well
125 5     5   30 use constant MOVE_CAPTURE => 0x01;
  5         13  
  5         233  
126 5     5   33 use constant MOVE_CASTLE_SHORT => 0x02;
  5         10  
  5         245  
127 5     5   27 use constant MOVE_CASTLE_LONG => 0x04;
  5         15  
  5         212  
128 5     5   24 use constant MOVE_EN_PASSANT => 0x08;
  5         9  
  5         300  
129 5     5   25 use constant MOVE_PROMOTE => 0x10;
  5         8  
  5         6427  
130              
131             {
132             my @_move_list_entries = ( );
133             my %_object_fields = OBJECT_FIELDS;
134              
135             sub _get_entry {
136 18448     18448   22069 my ($i) = @_;
137 18448         31791 return $_move_list_entries[$i];
138             }
139              
140             sub new {
141 2794     2794 1 4823 my ($caller, $move_num, $r_piece, $from, $dest, $flags) = @_;
142 2794   33     10119 my $class = ref($caller) || $caller;
143 2794         15941 my $obj_data = { %_object_fields };
144 2794         5541 $obj_data->{move_num} = $move_num;
145 2794 50       5594 croak "Invalid Chess::Piece reference" unless ($r_piece);
146 2794         3501 $obj_data->{piece_ref} = $r_piece;
147 2794         4227 $obj_data->{from_sq} = $from;
148 2794         3857 $obj_data->{dest_sq} = $dest;
149 2794 100       5888 $obj_data->{flags} = defined($flags) ? $flags & 0x1f : 0x0;
150 2794         3865 push @_move_list_entries, $obj_data;
151 2794         3597 my $i = $#_move_list_entries;
152 2794         12864 return bless \$i, $class;
153             }
154              
155             sub clone {
156 3     3 0 6 my ($self) = @_;
157 3   33     14 my $class = ref($self) || croak "Invalid Chess::Game::MoveListEntry reference";
158 3   33     5 my $obj_data = { %{$_move_list_entries[$$self]} } || croak "Invalid Chess:Game::MoveListEntry reference";
159 3 50       23 if (my $r_piece = $obj_data->{piece_ref}) {
160 3 50       56 $r_piece = $r_piece->clone() if ($r_piece->can('clone'));
161 3         8 $obj_data->{piece_ref} = $r_piece;
162             }
163 3         6 push @_move_list_entries, $obj_data;
164 3         7 my $i = $#_move_list_entries;
165 3         19 return bless \$i, $class;
166             }
167              
168             sub DESTROY {
169 6     6   38 my ($self) = @_;
170 6 50       96 $_move_list_entries[$$self] = undef if (ref($self));
171             }
172             }
173              
174             sub get_move_num {
175 203     203 1 1433 my ($self) = @_;
176 203 50       548 croak "Invalid Chess::Game::MoveListEntry reference" unless (ref($self));
177 203         702 my $obj_data = _get_entry($$self);
178 203 50       486 croak "Invalid Chess::Game::MoveListEntry reference" unless ($obj_data);
179 203         613 return $obj_data->{move_num};
180             }
181              
182             sub get_piece {
183 2652     2652 1 4744 my ($self) = @_;
184 2652 50       5860 croak "Invalid Chess::Game::MoveListEntry reference" unless (ref($self));
185 2652         4853 my $obj_data = _get_entry($$self);
186 2652 50       5292 croak "Invalid Chess::Game::MoveListEntry reference" unless ($obj_data);
187 2652         10704 return $obj_data->{piece_ref};
188             }
189              
190             sub get_start_square {
191 2596     2596 1 3426 my ($self) = @_;
192 2596 50       5147 croak "Invalid Chess::Game::MoveListEntry reference" unless (ref($self));
193 2596         4136 my $obj_data = _get_entry($$self);
194 2596 50       5350 croak "Invalid Chess::Game::MoveListEntry reference" unless ($obj_data);
195 2596         8205 return $obj_data->{from_sq};
196             }
197              
198             sub get_dest_square {
199 2603     2603 1 3071 my ($self) = @_;
200 2603 50       5141 croak "Invalid Chess::Game::MoveListEntry reference" unless (ref($self));
201 2603         4344 my $obj_data = _get_entry($$self);
202 2603 50       4986 croak "Invalid Chess::Game::MoveListEntry reference" unless ($obj_data);
203 2603         7752 return $obj_data->{dest_sq};
204             }
205              
206             sub is_capture {
207 2597     2597 1 4203 my ($self) = @_;
208 2597 50       5120 croak "Invalid Chess::Game::MoveListEntry reference" unless (ref($self));
209 2597         4082 my $obj_data = _get_entry($$self);
210 2597 50       5781 croak "Invalid Chess::Game::MoveListEntry reference" unless (ref($self));
211 2597         14879 return $obj_data->{flags} & MOVE_CAPTURE;
212             }
213              
214             sub is_short_castle {
215 2596     2596 1 3750 my ($self) = @_;
216 2596 50       5707 croak "Invalid Chess::Game::MoveListEntry reference" unless (ref($self));
217 2596         6262 my $obj_data = _get_entry($$self);
218 2596 50       5429 croak "Invalid Chess::Game::MoveListEntry reference" unless (ref($self));
219 2596         8234 return $obj_data->{flags} & MOVE_CASTLE_SHORT;
220             }
221              
222             sub is_long_castle {
223 2596     2596 1 3772 my ($self) = @_;
224 2596 50       4939 croak "Invalid Chess::Game::MoveListEntry reference" unless (ref($self));
225 2596         6528 my $obj_data = _get_entry($$self);
226 2596 50       10426 croak "Invalid Chess::Game::MoveListEntry reference" unless (ref($self));
227 2596         8436 return $obj_data->{flags} & MOVE_CASTLE_LONG;
228             }
229              
230             sub is_en_passant {
231 2593     2593 1 3021 my ($self) = @_;
232 2593 50       5385 croak "Invalid Chess::Game::MoveListEntry reference" unless (ref($self));
233 2593         4234 my $obj_data = _get_entry($$self);
234 2593 50       5253 croak "Invalid Chess::Game::MoveListEntry reference" unless (ref($self));
235 2593         8391 return $obj_data->{flags} & MOVE_EN_PASSANT;
236             }
237              
238             sub is_promotion {
239 7     7 0 663 my ($self) = @_;
240 7 50       26 croak "Invalid Chess::Game::MoveListEntry reference" unless (ref($self));
241 7         50 my $obj_data = _get_entry($$self);
242 7 50       26 croak "Invalid Chess::Game::MoveListEntry reference" unless (ref($self));
243 7         59 return $obj_data->{flags} & MOVE_PROMOTE;
244             }
245              
246             sub get_promoted_to {
247 2     2 0 4 my ($self) = @_;
248 2 50       9 croak "Invalid Chess::Game::MoveListEntry reference" unless (ref($self));
249 2         5 my $obj_data = _get_entry($$self);
250 2 50       8 croak "Invalid Chess::Game::MoveListEntry reference" unless (ref($self));
251 2         9 return $obj_data->{promoted_to};
252             }
253              
254             sub set_promoted_to {
255 3     3 0 8 my ($self, $new_piece) = @_;
256 3 50       9 croak "Invalid Chess::Game::MoveListEntry reference" unless (ref($self));
257 3         9 my $obj_data = _get_entry($$self);
258 3 50       12 croak "Invalid Chess::Game::MoveListEntry reference" unless (ref($self));
259 3         13 $obj_data->{promoted_to} = $new_piece;
260             }
261              
262             1;