1 | #!/opt/bin/perl |
1 | #!/usr/bin/perl -I../lib/ |
2 | |
2 | |
3 | use PApp::Util qw(dumpval); # debug only |
3 | #use PApp::Util qw(dumpval); # debug only |
4 | |
4 | |
5 | use Gtk; |
5 | use Gtk; |
6 | use Gtk::Gdk; |
6 | use Gtk::Gdk; |
|
|
7 | #use Gtk::Gdk::Pixbuf; |
|
|
8 | use Gtk::Gdk::ImlibImage; |
|
|
9 | |
|
|
10 | use Gnome; |
7 | |
11 | |
8 | use KGS::Protocol; |
12 | use KGS::Protocol; |
9 | use KGS::Listener::Debug; |
13 | use KGS::Listener::Debug; |
10 | |
14 | |
11 | use IO::Socket::INET; |
15 | use IO::Socket::INET; |
12 | |
16 | |
13 | use Errno; |
17 | use Errno; |
14 | |
18 | |
15 | init Gtk; |
19 | init Gnome "kgsueme"; |
16 | |
20 | |
17 | $HACK = 1; # do NEVER enable. ;) |
21 | $HACK = 1; # do NEVER enable. ;) |
18 | |
22 | |
19 | our $config; |
23 | our $config; |
|
|
24 | our $IMGDIR = "images"; |
|
|
25 | |
|
|
26 | sub load_img { |
|
|
27 | # new_from_file Gtk::Gdk::Pixbuf "$IMGDIR/$_[0]" |
|
|
28 | load_image Gtk::Gdk::ImlibImage "$IMGDIR/$_[0]" |
|
|
29 | or die "$IMGDIR/$_[0]: $!"; |
|
|
30 | } |
|
|
31 | |
|
|
32 | our @black_img = load_img "b-01.png"; |
|
|
33 | our @white_img = map +(load_img "w-0$_.png"), 1,2,3,4,5; |
|
|
34 | our $board_img = load_img "woodgrain-01.jpg"; |
20 | |
35 | |
21 | { |
36 | { |
22 | use Storable (); |
37 | use Storable (); |
23 | use Scalar::Util (); |
38 | use Scalar::Util (); |
24 | |
39 | |
… | |
… | |
71 | |
86 | |
72 | sub save_state { |
87 | sub save_state { |
73 | for (@widgets) { |
88 | for (@widgets) { |
74 | if ($_->[0]) { |
89 | if ($_->[0]) { |
75 | my ($widget, $class, $instance, $attr) = @$_; |
90 | my ($widget, $class, $instance, $attr) = @$_; |
|
|
91 | |
|
|
92 | $widget->realize; |
|
|
93 | |
76 | while (my ($k, $v) = each %$attr) { |
94 | while (my ($k, $v) = each %$attr) { |
77 | my ($set, $get) = $k =~ /=/ ? split /=/, $k : ($k, $k); |
95 | my ($set, $get) = $k =~ /=/ ? split /=/, $k : ($k, $k); |
78 | $v = $get{$get} ? $get{$get}->($widget) : $widget->get($get); |
96 | $v = $get{$get} ? $get{$get}->($widget) : $widget->get($get); |
79 | |
97 | |
80 | $state->{$class}{"*"}{$get} = $v; |
98 | $state->{$class}{"*"}{$get} = $v; |
… | |
… | |
137 | |
155 | |
138 | KGS::Listener::Debug->new->listen($self->{conn}); #d# debug only :) |
156 | KGS::Listener::Debug->new->listen($self->{conn}); #d# debug only :) |
139 | |
157 | |
140 | $self->listen($self->{conn}); |
158 | $self->listen($self->{conn}); |
141 | |
159 | |
|
|
160 | $self->{roomlist} = new roomlist conn => $self->{conn}; |
|
|
161 | |
142 | $self->{window} = new Gtk::Window 'toplevel'; |
162 | $self->{window} = new Gtk::Window 'toplevel'; |
143 | $self->{window}->set_title('kgsueme'); |
163 | $self->{window}->set_title('kgsueme'); |
144 | ::state $self->{window}, "main::window", undef, window_size => [400, 100]; |
164 | ::state $self->{window}, "main::window", undef, window_size => [400, 100]; |
145 | $self->{window}->signal_connect(delete_event => sub { main_quit Gtk }); |
165 | $self->{window}->signal_connect(delete_event => sub { main_quit Gtk; 1 }); |
146 | |
166 | |
147 | $self->{window}->add(my $vbox = new Gtk::VBox); |
167 | $self->{window}->add(my $vbox = new Gtk::VBox); |
148 | |
168 | |
149 | $vbox->pack_start(($self->{buttonbox} = new Gtk::HButtonBox), 0, 1, 0); |
169 | $vbox->pack_start(($buttonbox = new Gtk::HButtonBox), 0, 1, 0); |
|
|
170 | $buttonbox->set_spacing(0); |
150 | |
171 | |
151 | my $button = sub { |
172 | my $button = sub { |
152 | $self->{buttonbox}->add(my $button = new Gtk::Button $_[0]); |
173 | $buttonbox->add(my $button = new Gtk::Button $_[0]); |
153 | signal_connect $button clicked => $_[1]; |
174 | signal_connect $button clicked => $_[1]; |
154 | }; |
175 | }; |
155 | |
176 | |
156 | $button->("Login", sub { |
177 | $button->("Login", sub { $self->login; }); |
157 | $self->login; |
178 | $button->("Roomlist", sub { $self->{roomlist}->show; }); |
158 | }); |
|
|
159 | $button->("Roomlist", sub { |
|
|
160 | $self->{roomlist} ||= new roomlist conn => $self->{conn}; |
|
|
161 | $self->{roomlist}->show; |
|
|
162 | }); |
|
|
163 | $button->("Save Config & Layout", sub { ::save_state }); |
179 | $button->("Save Config & Layout", sub { ::save_state }); |
|
|
180 | $button->("Quit", sub { main_quit Gtk }); |
164 | |
181 | |
165 | $vbox->pack_start((my $hbox = new Gtk::HBox), 0, 1, 0); |
182 | $vbox->pack_start((my $hbox = new Gtk::HBox), 0, 1, 0); |
166 | |
183 | |
167 | $hbox->add(new Gtk::Label "Login"); |
184 | $hbox->add(new Gtk::Label "Login"); |
168 | |
185 | |
… | |
… | |
218 | my ($self, $msg) = @_; |
235 | my ($self, $msg) = @_; |
219 | |
236 | |
220 | ::status("login", "logged in as '$self->{conn}{name}' with status '$msg->{result}'"); |
237 | ::status("login", "logged in as '$self->{conn}{name}' with status '$msg->{result}'"); |
221 | $::config->{login} = $self->{conn}{name}; |
238 | $::config->{login} = $self->{conn}{name}; |
222 | |
239 | |
223 | $self->{window}->show_all; |
240 | if ($msg->{success}) { |
|
|
241 | for (keys %{$::config->{rooms}}) { |
|
|
242 | $self->{roomlist}->join_room($_); |
|
|
243 | } |
|
|
244 | } |
|
|
245 | |
|
|
246 | warn PApp::Util::dumpval($::config); |
224 | } |
247 | } |
225 | |
248 | |
226 | sub event_disconnect { } |
249 | sub event_disconnect { } |
227 | |
250 | |
228 | ############################################################################# |
251 | ############################################################################# |
… | |
… | |
239 | |
262 | |
240 | $self->{window} = new Gtk::Window 'toplevel'; |
263 | $self->{window} = new Gtk::Window 'toplevel'; |
241 | $self->{window}->set_title('KGS Rooms'); |
264 | $self->{window}->set_title('KGS Rooms'); |
242 | ::state $self->{window}, "roomlist::window", undef, window_size => [400, 200]; |
265 | ::state $self->{window}, "roomlist::window", undef, window_size => [400, 200]; |
243 | |
266 | |
244 | $self->{window}->signal_connect(delete_event => sub { hide $self->{window} }); |
267 | $self->{window}->signal_connect(delete_event => sub { $self->{window}->hide; 1 }); |
245 | |
268 | |
246 | $self->{window}->add(my $vbox = new Gtk::VBox); |
269 | $self->{window}->add(my $vbox = new Gtk::VBox); |
247 | |
270 | |
248 | $vbox->pack_start((my $sw = new Gtk::ScrolledWindow), 1, 1, 0); |
271 | $vbox->pack_start((my $sw = new Gtk::ScrolledWindow), 1, 1, 0); |
249 | $sw->set_policy("automatic", "always"); |
272 | $sw->set_policy("automatic", "always"); |
… | |
… | |
254 | ::state $self->{roomlist}, "roomlist::roomlist", undef, clist_column_widths => [20, 200]; |
277 | ::state $self->{roomlist}, "roomlist::roomlist", undef, clist_column_widths => [20, 200]; |
255 | |
278 | |
256 | $self->{roomlist}->signal_connect(select_row => sub { |
279 | $self->{roomlist}->signal_connect(select_row => sub { |
257 | my $room = $self->{roomlist}->get_row_data($_[1]) |
280 | my $room = $self->{roomlist}->get_row_data($_[1]) |
258 | or return; |
281 | or return; |
259 | $self->{room}{$room->{channel}} ||= new room %$room, conn => $self->{conn}, users => {}; |
|
|
260 | $self->{room}{$room->{channel}}->join; |
|
|
261 | $self->{roomlist}->unselect_all; |
282 | $self->{roomlist}->unselect_all; |
|
|
283 | $self->join_room($room->{channel}); |
262 | }); |
284 | }); |
263 | |
285 | |
264 | $self; |
286 | $self; |
|
|
287 | } |
|
|
288 | |
|
|
289 | sub join_room { |
|
|
290 | my ($self, $channel) = @_; |
|
|
291 | |
|
|
292 | $self->{room}{$channel} ||= room->new(channel => $channel, conn => $self->{conn}, users => {}); |
|
|
293 | $self->{room}{$channel}->join; |
265 | } |
294 | } |
266 | |
295 | |
267 | sub show { |
296 | sub show { |
268 | my ($self, $msg) = @_; |
297 | my ($self, $msg) = @_; |
269 | |
298 | |
270 | $self->msg(list_rooms => group => $_) for 0..5; # fetch all room names (should not!) |
299 | $self->msg(list_rooms => group => $_) for 0..5; # fetch all room names (should not!) |
271 | $self->{window}->show_all; |
300 | $self->{window}->show_all; |
272 | } |
301 | } |
273 | |
302 | |
274 | sub event_update { |
303 | sub event_update_rooms { |
275 | my ($self) = @_; |
304 | my ($self) = @_; |
276 | |
305 | |
277 | $self->{event_update} ||= Gtk->timeout_add(200, sub { |
306 | $self->{event_update} ||= Gtk->timeout_add(200, sub { |
278 | my $l = $self->{roomlist}; |
307 | my $l = $self->{roomlist}; |
279 | |
308 | |
… | |
… | |
309 | |
338 | |
310 | $self->{window} = new Gtk::Window 'toplevel'; |
339 | $self->{window} = new Gtk::Window 'toplevel'; |
311 | $self->{window}->set_title("KGS Room $self->{name}"); |
340 | $self->{window}->set_title("KGS Room $self->{name}"); |
312 | ::state $self->{window}, "room::window", $self->{name}, window_size => [600, 400]; |
341 | ::state $self->{window}, "room::window", $self->{name}, window_size => [600, 400]; |
313 | |
342 | |
314 | $self->{window}->signal_connect(delete_event => sub { $self->part }); |
343 | $self->{window}->signal_connect(delete_event => sub { $self->part; 1 }); |
315 | |
344 | |
316 | $self->{window}->add(my $hpane = new Gtk::HPaned); |
345 | $self->{window}->add(my $hpane = new Gtk::HPaned); |
317 | ::state $hpane, "room::hpane", $self->{name}, hpane_position => 200; |
346 | ::state $hpane, "room::hpane", $self->{name}, hpane_position => 200; |
318 | |
347 | |
319 | $hpane->add(my $vpane = new Gtk::VPaned); |
348 | $hpane->add(my $vpane = new Gtk::VPaned); |
… | |
… | |
356 | ::state $self->{userlist}, "room::userlist", $self->{name}, clist_column_widths => [120, 30]; |
385 | ::state $self->{userlist}, "room::userlist", $self->{name}, clist_column_widths => [120, 30]; |
357 | |
386 | |
358 | $self; |
387 | $self; |
359 | } |
388 | } |
360 | |
389 | |
361 | sub event_update { |
390 | sub event_update_users { |
362 | my ($self) = @_; |
391 | my ($self) = @_; |
363 | |
392 | |
364 | $self->{event_update} ||= Gtk->timeout_add(200, sub { |
393 | $self->{event_update} ||= Gtk->timeout_add(200, sub { |
365 | my $l = $self->{userlist}; |
394 | my $l = $self->{userlist}; |
366 | |
395 | |
… | |
… | |
415 | |
444 | |
416 | sub part { |
445 | sub part { |
417 | my ($self) = @_; |
446 | my ($self) = @_; |
418 | $self->SUPER::part; |
447 | $self->SUPER::part; |
419 | |
448 | |
|
|
449 | delete $::config->{rooms}{$self->{channel}}; |
420 | $self->{window}->hide_all; |
450 | $self->{window}->hide_all; |
421 | $self->event_update; |
451 | $self->event_update; |
422 | $self->event_update_games; |
452 | $self->event_update_games; |
423 | } |
453 | } |
424 | |
454 | |
|
|
455 | sub event_join { |
|
|
456 | my ($self) = @_; |
|
|
457 | $self->SUPER::event_join; |
|
|
458 | |
|
|
459 | $::config->{rooms}{$self->{channel}} = 1; |
|
|
460 | } |
|
|
461 | |
425 | sub event_update_roominfo { |
462 | sub event_update_roominfo { |
426 | my ($self) = @_; |
463 | my ($self) = @_; |
427 | |
464 | |
428 | $self->{text}->insert(undef, undef, undef, "$self->{owner}: $self->{description}\n\n"); |
465 | $self->{text}->insert(undef, undef, undef, "\n$self->{owner}: $self->{description}\n"); |
429 | } |
466 | } |
430 | |
467 | |
431 | sub inject_msg_room { |
468 | sub inject_msg_room { |
432 | my ($self, $msg) = @_; |
469 | my ($self, $msg) = @_; |
433 | return unless $self->{channel} == $msg->{channel}; |
470 | return unless $self->{channel} == $msg->{channel}; |
434 | |
471 | |
435 | $self->{text}->insert(undef, undef, undef, "$msg->{name}: $msg->{message}\n"); |
472 | $self->{text}->insert(undef, undef, undef, "\n$msg->{name}: $msg->{message}"); |
436 | } |
473 | } |
437 | |
474 | |
438 | ############################################################################# |
475 | ############################################################################# |
439 | |
476 | |
440 | package game; |
477 | package game; |
|
|
478 | |
|
|
479 | use KGS::Constants; |
|
|
480 | use KGS::Game::Board; |
441 | |
481 | |
442 | use base KGS::Listener::Game; |
482 | use base KGS::Listener::Game; |
443 | use base KGS::Game; |
483 | use base KGS::Game; |
444 | |
484 | |
445 | sub new { |
485 | sub new { |
… | |
… | |
450 | |
490 | |
451 | $self->{window} = new Gtk::Window 'toplevel'; |
491 | $self->{window} = new Gtk::Window 'toplevel'; |
452 | $self->{window}->set_title("KGS Game ".$self->user0." ".$self->user1); |
492 | $self->{window}->set_title("KGS Game ".$self->user0." ".$self->user1); |
453 | ::state $self->{window}, "game::window", undef, window_size => [600, 500]; |
493 | ::state $self->{window}, "game::window", undef, window_size => [600, 500]; |
454 | |
494 | |
455 | $self->{window}->signal_connect(delete_event => sub { $self->part }); |
495 | $self->{window}->signal_connect(delete_event => sub { $self->part; 1 }); |
456 | |
496 | |
457 | $self->{window}->add(my $hpane = new Gtk::HPaned); |
497 | $self->{window}->add(my $hpane = new Gtk::HPaned); |
458 | ::state $hpane, "game::hpane", undef, hpane_position => 500; |
498 | ::state $hpane, "game::hpane", undef, hpane_position => 500; |
459 | |
499 | |
460 | $hpane->add(my $board = new Gtk::Table $self->{size}, $self->{size}, 1); |
500 | $::config{aa} = 0; |
|
|
501 | $self->{canvas} = $::config{aa} ? new_aa Gnome::Canvas : new Gnome::Canvas; |
|
|
502 | $hpane->add($self->{canvas}); |
461 | |
503 | |
462 | for my $x (0 .. $self->{size} - 1) { |
504 | { |
|
|
505 | my $line_colour = $::config{line_colour} || "darkbrown"; |
|
|
506 | my $border = 0.1; |
|
|
507 | my $ofs = 0.5 / $self->{size}; |
|
|
508 | |
|
|
509 | $self->{canvas}->set_pixels_per_unit(1000); |
|
|
510 | $self->{canvas}->set_scroll_region(-$border,-$border,1+$border,1+$border); |
|
|
511 | |
|
|
512 | $self->{canvas}->signal_connect(size_allocate => sub { |
|
|
513 | my ($w, $h) = @{$_[1]}[2,3]; |
|
|
514 | |
|
|
515 | $self->{canvas}->set_pixels_per_unit(($w > $h ? $h : $w)/(1+$border*2)); |
|
|
516 | |
|
|
517 | 1; |
|
|
518 | }); |
|
|
519 | |
|
|
520 | my $croot = $self->{canvas}->root; |
|
|
521 | my $cgroup = $croot; #->new($croot, "Gnome::CanvasGroup"); |
|
|
522 | |
|
|
523 | if ($::board_img) { |
|
|
524 | $cgroup->new($cgroup, "Gnome::CanvasImage", |
|
|
525 | x => -$border, y => -$border, |
|
|
526 | width => 1+$border*2, height => 1+$border*2, |
|
|
527 | image => $::board_img, |
|
|
528 | anchor => "nw" |
|
|
529 | ); |
|
|
530 | } else { |
|
|
531 | $cgroup->new($cgroup, "Gnome::CanvasRect", |
|
|
532 | x1 => -$border, x2 => 1+$border, |
|
|
533 | y1 => -$border, y2 => 1+$border, |
|
|
534 | outline_color => "black", |
|
|
535 | fill_color => "brown", |
|
|
536 | width_pixels => 2, |
|
|
537 | ); |
|
|
538 | } |
|
|
539 | |
|
|
540 | my $a = "A"; |
|
|
541 | for my $i (1 .. $self->{size}) { # one more iteration for the last lines |
|
|
542 | my $k = $i / $self->{size} - $ofs; |
|
|
543 | |
|
|
544 | $cgroup->new($cgroup, "Gnome::CanvasLine", |
|
|
545 | points => [ $k,$ofs, $k,1-$ofs ], |
|
|
546 | fill_color => $line_colour, |
|
|
547 | width_pixels => 1); |
|
|
548 | |
|
|
549 | $cgroup->new($cgroup, "Gnome::CanvasLine", |
|
|
550 | points => [ $ofs,$k, 1-$ofs,$k ], |
|
|
551 | fill_color => $line_colour, |
|
|
552 | width_pixels => 1); |
|
|
553 | |
|
|
554 | for ( [$k,-$border*0.5,$a], [$k,1+$border*0.5,$a], [-$border*0.5,$k,$i], [1+$border*0.5,$k,$i] ) { |
|
|
555 | my ($x, $y, $text) = @$_; |
|
|
556 | |
|
|
557 | my $text = $cgroup->new($cgroup, "Gnome::CanvasText", |
|
|
558 | x => 0, y => 0, text => $text, |
|
|
559 | justification => "center", |
|
|
560 | anchor => "center", |
|
|
561 | font => $::config{aa} ? "-*-helvetica-medium-r-*--34-*" : "-*-helvetica-bold-r-*--17-*", |
|
|
562 | fill_color => $line_colour); |
|
|
563 | |
|
|
564 | $text->affine_relative($border*0.015,0, 0,$border*0.015, $x,$y); |
|
|
565 | } |
|
|
566 | |
|
|
567 | $a++; |
|
|
568 | } |
|
|
569 | |
|
|
570 | my $stones = [[]]; |
|
|
571 | |
463 | for my $y (0 .. $self->{size} - 1) { |
572 | for my $x (1 .. $self->{size}) { |
464 | my $cell = new Gtk::Label; |
573 | my $xk = $x / $self->{size} - $ofs; |
465 | $board->attach_defaults($cell, $x, $x + 1, $y, $y + 1); |
574 | for my $y (1 .. $self->{size}) { |
466 | $self->{board}[$x][$y] = $cell; |
575 | my $yk = $y / $self->{size} - $ofs; |
|
|
576 | |
|
|
577 | my $col = $stones->[$x-1][$y-1] = []; |
|
|
578 | |
|
|
579 | if (1) { |
|
|
580 | $col->[0] = |
|
|
581 | $cgroup->new($cgroup, "Gnome::CanvasImage", |
|
|
582 | x => $xk, y => $yk, |
|
|
583 | width => $ofs*2, height => $ofs*2, |
|
|
584 | image => $::black_img[int rand @::black_img], |
|
|
585 | anchor => "center"); |
|
|
586 | $col->[1] = |
|
|
587 | $cgroup->new($cgroup, "Gnome::CanvasImage", |
|
|
588 | x => $xk, y => $yk, |
|
|
589 | width => $ofs*2, height => $ofs*2, |
|
|
590 | image => $::white_img[int rand @::white_img], |
|
|
591 | anchor => "center"); |
|
|
592 | } else { |
|
|
593 | die "need pixmaps\n"; |
|
|
594 | # too large, scale has NO effect |
|
|
595 | $col->[0] = |
|
|
596 | $cgroup->new($cgroup, "Gnome::CanvasEllipse", |
|
|
597 | x1 => $xk, x2 => $xk + 0.001, |
|
|
598 | y1 => $yk, y2 => $yk + 0.001, |
|
|
599 | outline_color => "black", width_pixels => 2, |
|
|
600 | fill_color => "black"); |
|
|
601 | $col->[1] = |
|
|
602 | $cgroup->new($cgroup, "Gnome::CanvasEllipse", |
|
|
603 | x1 => $xk, x2 => $xk + 0.001, |
|
|
604 | y1 => $yk, y2 => $yk + 0.001, |
|
|
605 | outline_color => "black", width_pixels => 2, |
|
|
606 | fill_color => "white"); |
|
|
607 | } |
467 | } |
608 | } |
|
|
609 | } |
|
|
610 | |
|
|
611 | $self->{board_gfx}{stones} = $stones; |
468 | } |
612 | } |
469 | |
613 | |
470 | $hpane->add(my $vpane = new Gtk::VPaned); |
614 | $hpane->add(my $vpane = new Gtk::VPaned); |
471 | ::state $vpane, "game", $self->{name}, vpane_position => 80; |
615 | ::state $vpane, "game", $self->{name}, vpane_position => 80; |
472 | |
616 | |
… | |
… | |
492 | }); |
636 | }); |
493 | |
637 | |
494 | $self; |
638 | $self; |
495 | } |
639 | } |
496 | |
640 | |
497 | sub event_update { |
641 | sub event_update_users { |
498 | my ($self) = @_; |
642 | my ($self) = @_; |
499 | |
643 | |
500 | $self->{event_update} ||= Gtk->timeout_add(200, sub { |
644 | room::event_update_users $self; |
501 | my $l = $self->{userlist}; |
|
|
502 | |
|
|
503 | $l->freeze; |
|
|
504 | my $pos = $l->get_vadjustment->get_value; |
|
|
505 | $l->clear; |
|
|
506 | |
|
|
507 | my $row = 0; |
|
|
508 | for (values %{$self->{users}}) { |
|
|
509 | $l->append($_->{name}); |
|
|
510 | $l->set_row_data($row++, $_); |
|
|
511 | } |
|
|
512 | $l->sort; |
|
|
513 | $l->get_vadjustment->set_value($pos); |
|
|
514 | $l->thaw; |
|
|
515 | |
|
|
516 | delete $self->{event_update}; |
|
|
517 | 0; |
|
|
518 | }); |
|
|
519 | } |
645 | } |
520 | |
646 | |
521 | sub join { |
647 | sub join { |
522 | my ($self) = @_; |
648 | my ($self) = @_; |
523 | $self->SUPER::join; |
649 | $self->SUPER::join; |
… | |
… | |
534 | } |
660 | } |
535 | |
661 | |
536 | sub event_update_tree { |
662 | sub event_update_tree { |
537 | my ($self) = @_; |
663 | my ($self) = @_; |
538 | |
664 | |
|
|
665 | my $board = new KGS::Game::Board $self->{size}; |
|
|
666 | $board->interpret_path ($self->get_path); |
|
|
667 | |
539 | for my $x (0 .. $self->{size} - 1) { |
668 | for my $x (0 .. $self->{size} - 1) { |
540 | for my $y (0 .. $self->{size} - 1) { |
669 | for my $y (0 .. $self->{size} - 1) { |
541 | $self->{board}[$x][$y]->set_text(""); |
670 | my $v = $board->{board}[$x][$y]; |
542 | } |
|
|
543 | } |
|
|
544 | |
671 | |
545 | for (0..$self->{node}) { |
672 | $v & MARK_B |
546 | while (my ($k, $v) = each %{$self->{tree}[$_]}) { |
673 | ? $self->{board_gfx}->{stones}->[$x][$y][0]->show |
547 | if ($k eq "move7") { |
674 | : $self->{board_gfx}->{stones}->[$x][$y][0]->hide; |
548 | if ($v->[1] < 255) { |
675 | $v & MARK_W |
549 | $self->{board}[$v->[1]][$v->[2]]->set_text(("X", "O", "-")[$v->[0]]); |
676 | ? $self->{board_gfx}->{stones}->[$x][$y][1]->show |
550 | } |
677 | : $self->{board_gfx}->{stones}->[$x][$y][1]->hide; |
551 | } |
678 | } |
552 | } |
|
|
553 | } |
679 | } |
|
|
680 | |
|
|
681 | $self->{text}->backward_delete($self->{text}->get_length); |
|
|
682 | $self->{text}->insert(undef, undef, undef, $board->{comment}.PApp::Util::dumpval([$board->{time},$board->{captures}])); |
554 | } |
683 | } |
555 | |
684 | |
556 | 1; |
685 | 1; |
557 | |
686 | |
558 | |
687 | |