File Coverage

lib/Games/Sudoku/Component/TkPlayer/Controller.pm
Criterion Covered Total %
statement 9 195 4.6
branch 0 50 0.0
condition 0 12 0.0
subroutine 3 22 13.6
pod 16 16 100.0
total 28 295 9.4


line stmt bran cond sub pod time code
1             package Games::Sudoku::Component::TkPlayer::Controller;
2             {
3 1     1   1368 use strict;
  1         2  
  1         39  
4 1     1   6 use warnings;
  1         2  
  1         31  
5 1     1   6 use Carp;
  1         2  
  1         3367  
6            
7             sub new {
8 0     0 1   my $class = shift;
9 0   0       my $this = bless {}, (ref $class || $class);
10            
11 0           $this;
12             }
13            
14             sub new_game {
15 0     0 1   my ($this, $mw, $sdk, $wgt) = @_;
16            
17 0           $mw->Busy(-recurse => 1);
18            
19 0           $sdk->clear;
20            
21 0           my $max = $sdk->table->size ** 2;
22 0           my $blank = int($max * .65);
23            
24 0           my $splash = $wgt->{splash};
25            
26 0           $splash->Show(-max => $max);
27 0           until($sdk->status->is_finished) {
28 0           $sdk->next;
29 0           $splash->progress($sdk->table->num_of_finished);
30 0           $splash->update;
31             }
32 0           $splash->progress($max);
33 0           $sdk->make_blank($blank);
34 0           $splash->Hide;
35            
36 0           my $size = $sdk->table->size;
37            
38 0           my $check = $this->{check_tmp}->();
39 0           $this->{check_tmp}->(0);
40 0           foreach my $row (1..$size) {
41 0           foreach my $col (1..$size) {
42 0           $this->_set_button($sdk, $wgt, $row, $col);
43             }
44             }
45 0           $this->{check_tmp}->($check);
46 0           $this->{message}->(q{Solve this!});
47            
48 0           $mw->Unbusy;
49             }
50            
51             sub load_game {
52 0     0 1   my ($this, $mw, $sdk, $wgt) = @_;
53            
54 0           $mw->Busy(-recurse => 1);
55            
56 0           my $file = $mw->getOpenFile;
57            
58 0 0 0       if (defined $file && -f $file) {
59 0           $sdk->clear;
60            
61 0           $sdk->load(file => $file);
62            
63 0           my $size = $sdk->table->size;
64            
65 0           my $check = $this->{check_tmp}->();
66 0           $this->{check_tmp}->(0);
67 0           foreach my $row (1..$size) {
68 0           foreach my $col (1..$size) {
69 0           $this->_set_button($sdk, $wgt, $row, $col);
70             }
71             }
72 0           $this->{check_tmp}->($check);
73 0           $this->{message}->(q{Loaded!});
74             }
75 0           $mw->Unbusy;
76             }
77            
78             sub save_game {
79 0     0 1   my ($this, $mw, $sdk, $wgt) = @_;
80            
81 0           $mw->Busy(-recurse => 1);
82            
83 0           my $file = $mw->getSaveFile;
84            
85 0 0 0       if (defined $file and open my $fh, '>', $file) {
86 0           print $fh $sdk->table->as_string;
87 0           close $fh;
88            
89 0           $this->{message}->(q{Saved!});
90             }
91            
92 0           $mw->Unbusy;
93             }
94            
95             sub lock {
96 0     0 1   my ($this, $mw, $sdk, $wgt) = @_;
97            
98 0           $mw->Busy(-recurse => 1);
99            
100 0           $sdk->table->lock_all;
101 0           $this->_update_lock_status($mw, $sdk, $wgt);
102 0           $this->{message}->(q{Locked});
103            
104 0           $mw->Unbusy;
105             }
106            
107             sub clear {
108 0     0 1   my ($this, $mw, $sdk, $wgt) = @_;
109            
110 0           $mw->Busy(-recurse => 1);
111            
112 0           $sdk->clear;
113 0           $this->unlock($mw, $sdk, $wgt);
114            
115 0           my $size = $sdk->table->size;
116            
117 0           my $check = $this->{check_tmp}->();
118 0           $this->{check_tmp}->(0);
119 0           foreach my $row (1..$size) {
120 0           foreach my $col (1..$size) {
121 0           $this->_set_button($sdk, $wgt, $row, $col);
122             }
123             }
124 0           $this->{check_tmp}->($check);
125 0           $this->{message}->(q{Cleared});
126            
127 0           $mw->Unbusy;
128             }
129            
130             sub unlock {
131 0     0 1   my ($this, $mw, $sdk, $wgt) = @_;
132            
133 0           $mw->Busy(-recurse => 1);
134            
135 0           $sdk->table->unlock_all;
136 0           $this->_update_lock_status($mw, $sdk, $wgt);
137 0           $this->{message}->(q{Unlocked});
138            
139 0           $mw->Unbusy;
140             }
141            
142             sub rewind_all {
143 0     0 1   my ($this, $mw, $sdk, $wgt) = @_;
144            
145 0           $mw->Busy(-recurse => 1);
146            
147 0           $sdk->rewind_all;
148 0           $sdk->status->turn_to_ok;
149            
150 0           my $size = $sdk->table->size;
151            
152 0           my $check = $this->{check_tmp}->();
153 0           $this->{check_tmp}->(0);
154 0           foreach my $row (1..$size) {
155 0           foreach my $col (1..$size) {
156 0           $this->_set_button($sdk, $wgt, $row, $col);
157             }
158             }
159 0           $this->{check_tmp}->($check);
160 0           $this->{message}->(q{Rewinded});
161            
162 0           $mw->Unbusy;
163             }
164            
165             sub _update_lock_status {
166 0     0     my ($this, $mw, $sdk, $wgt) = @_;
167            
168 0           $mw->Busy(-recurse => 1);
169            
170 0           my $table = $sdk->table;
171 0           my $size = $table->size;
172            
173 0           my $check = $this->{check_tmp}->();
174 0           $this->{check_tmp}->(0);
175 0           foreach my $row (1..$size) {
176 0           foreach my $col (1..$size) {
177 0           my $id = ($row - 1) * $size + ($col - 1);
178 0           $this->configure_button($wgt, $id,
179             $table->cell($row, $col)->is_locked
180             );
181             }
182             }
183 0           $this->{check_tmp}->($check);
184            
185 0           $mw->Unbusy;
186             }
187            
188             sub _set_button {
189 0     0     my ($this, $sdk, $wgt, $row, $col) = @_;
190            
191 0           my $value = $sdk->table->cell($row,$col)->value;
192 0           my $locked = $sdk->table->cell($row,$col)->is_locked;
193 0           my $size = $sdk->table->size;
194 0           my $id = ($row - 1) * $size + ($col - 1);
195            
196 0 0         $wgt->{buttons}->[$id]->configure(
197             -text => $value ? $value : ' ',
198             );
199 0           $this->configure_button($wgt, $id, $locked);
200            
201 0 0         if ( $this->{check_tmp}->() ) {
202 0 0         if ( $sdk->table->cell($row,$col)->tmpvalue ) {
203 0           $this->configure_button_color($wgt, $id, 'red');
204 0           $this->{message}->(q{might be wrong...});
205             }
206             else {
207 0           $this->configure_button_color($wgt, $id, 'gray');
208 0           $this->{message}->(q{hmm...});
209 0           $this->find_tmpvalue($sdk, $wgt);
210             }
211             }
212             else {
213 0           $this->configure_button_color($wgt, $id, 'gray');
214 0           $this->{message}->(q{hm...});
215             }
216             }
217            
218             sub find_tmpvalue {
219 0     0 1   my ($this, $mw, $sdk, $wgt) = @_;
220            
221 0           $mw->Busy(-recurse => 1);
222            
223 0           my $size = $sdk->table->size;
224            
225 0           $sdk->table->check_tmpvalue;
226            
227 0           my $check_on = $this->{check_tmp}->();
228 0           foreach my $row (1..$size) {
229 0           foreach my $col (1..$size) {
230 0           my $id = ($row - 1) * $size + ($col - 1);
231 0 0 0       $this->configure_button_color($wgt, $id,
232             $check_on && $sdk->table->cell($row,$col)->tmpvalue ?
233             'red' : 'gray',
234             );
235             }
236             }
237 0           $mw->Unbusy;
238             }
239            
240             sub find_next {
241 0     0 1   my ($this, $mw, $sdk, $wgt) = @_;
242            
243 0           $mw->Busy(-recurse => 1);
244            
245 0           my $next = $sdk->table->find_next;
246            
247 0 0         if ($next) {
248 0           my $size = $sdk->table->size;
249 0           my $row = $next->row;
250 0           my $col = $next->col;
251 0           my $id = ($row - 1) * $size + ($col - 1);
252 0           $this->configure_button_color($wgt, $id, 'yellow');
253 0           $this->{message}->(q{Try this.})
254             }
255             else {
256 0           $this->{message}->(q{I have no idea. Try some.})
257             }
258 0           $mw->Unbusy;
259             }
260            
261             sub configure_button {
262 0     0 1   my ($this, $wgt, $id, $locked) = @_;
263            
264 0 0         $wgt->{buttons}->[$id]->configure(
265             -font => [
266             -weight => $locked ? 'bold' : 'normal',
267             -family => 'courier',
268             -size => 25,
269             ],
270             -width => 2,
271             -height => 1,
272             );
273             }
274            
275             sub configure_button_color {
276 0     0 1   my ($this, $wgt, $id, $color) = @_;
277            
278 0 0         if ($color eq 'yellow') {
279 0           $wgt->{buttons}->[$id]->configure(
280             -activebackground => 'lightyellow',
281             -background => 'yellow',
282             );
283             }
284 0 0         if ($color eq 'red') {
285 0           $wgt->{buttons}->[$id]->configure(
286             -activebackground => 'orange',
287             -background => 'red',
288             );
289             }
290 0 0         if ($color eq 'gray') {
291 0           $wgt->{buttons}->[$id]->configure(
292             -activebackground => 'gray',
293             -background => 'darkgray',
294             );
295             }
296             }
297            
298             sub solve {
299 0     0 1   my ($this, $mw, $sdk, $wgt) = @_;
300            
301 0           $mw->Busy(-recurse => 1);
302            
303 0           my $status = $sdk->status;
304 0           $status->clear;
305            
306 0           until($status->is_finished) {
307 0           $this->_do_next($mw, $sdk, $wgt, 1);
308 0           $mw->update;
309             }
310 0 0         if ($status->is_solved) {
311 0           $this->{message}->(q{OK, here you are!});
312             }
313 0 0         if ($status->is_giveup) {
314 0           $this->{message}->(q{Sorry I can't solve!});
315             }
316 0           $mw->Unbusy;
317             }
318            
319             sub do_next {
320 0     0 1   my ($this, $mw, $sdk, $wgt) = @_;
321            
322 0           $mw->Busy(-recurse => 1);
323            
324 0           $this->_do_next($mw, $sdk, $wgt, 0);
325            
326 0           $mw->Unbusy;
327             }
328            
329             sub _do_next {
330 0     0     my ($this, $mw, $sdk, $wgt, $silent) = @_;
331            
332 0           my $item = $sdk->next;
333 0           my $status = $sdk->status;
334            
335 0 0         if ($status->is_ok) {
336 0 0         $this->_set_button($sdk, $wgt, $item->row, $item->col) if $item;
337 0 0         $this->{message}->(q{Your turn...}) unless $silent;
338             }
339 0 0         if ($status->is_rewind) {
340 0 0         $this->_set_button($sdk, $wgt, $item->row, $item->col) if $item;
341 0 0         $this->{message}->(q{mmm, we should rewind some...}) unless $silent;
342             }
343 0 0         if ($status->is_giveup) {
344 0 0         $this->{message}->(q{Sorry I can't solve!}) unless $silent;
345             }
346 0 0         if ($sdk->table->is_finished) {
347 0 0         $this->{message}->(q{OK, here you are!}) unless $silent;
348             }
349             }
350            
351             sub push_button {
352 0     0 1   my ($this, $sdk, $wgt, $row, $col) = @_;
353            
354 0 0         return if $sdk->table->cell($row,$col)->is_locked;
355            
356 0           my @allowed = $sdk->table->cell($row,$col)->allowed;
357            
358 0           my $allowed_only = $this->{allowed_only}->();
359            
360 0           $wgt->{selector}->set_allowed($allowed_only, @allowed);
361            
362 0           my $value = $wgt->{selector}->Show;
363            
364 0           $sdk->table->cell($row,$col)->value($value);
365            
366 0           $this->_set_button($sdk, $wgt, $row, $col);
367            
368 0 0         $this->{message}->('Conguratulations!') if $sdk->table->is_finished;
369             }
370            
371             sub quit {
372 0     0 1   my ($this, $mw) = @_;
373            
374 0           $mw->destroy;
375             }
376             }
377            
378             1;
379            
380             __END__