ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/kgsueme/bin/kgsueme
(Generate patch)

Comparing kgsueme/bin/kgsueme (file contents):
Revision 1.6 by elmex, Thu May 29 03:11:56 2003 UTC vs.
Revision 1.56 by pcg, Wed Jul 30 14:00:45 2003 UTC

1#!/usr/bin/perl -I../lib/ 1#!/usr/bin/perl
2 2
3#use PApp::Util qw(dumpval); # debug only 3use Glib;
4
5use Gtk; 4use Gtk2;
6use Gtk::Gdk;
7use Gtk;
8#use Gtk::Gdk::ImlibImage;
9use Gnome;
10init Gnome "kgsueme";
11
12 5
13use KGS::Protocol; 6use KGS::Protocol;
14use KGS::Listener::Debug; 7use KGS::Listener::Debug;
15 8
9use Audio::Data;
10use Audio::Play;
11
16use IO::Socket::INET; 12use IO::Socket::INET;
17 13use List::Util;
18use Errno; 14use Errno;
19 15
20init Gtk; 16use Storable;
17use Carp;
21 18
22$HACK = 1; # do NEVER enable. ;) 19init Gtk2;
23 20
24our $config; 21$SIG{QUIT} = sub { Carp::confess "SIGQUIT" };
25 22
26{ 23our $HACK = 1; # do NEVER enable. ;)
27 use Storable (); 24our $DEBUG_EXPOSE = 0;
28 use Scalar::Util ();
29 25
30 my $staterc = "$ENV{HOME}/.kgsueme"; 26if ($HACK) {
27 $KGS::debug = 1;
28}
31 29
32 my $state = -r $staterc ? Storable::retrieve($staterc) : {}; 30BEGIN {
33 my @widgets; 31 our $VERSION = "0.1";
34 32
35 $config = $state->{config} ||= {}; 33 our $config;
34 our $LIBDIR = ".";
36 35
37 # grr... more gtk+ brokenness 36 use KGS::Constants;
38 my %get = (
39 hpane_position => sub { ($_[0]->children)[0]->allocation->[2] },
40 vpane_position => sub { ($_[0]->children)[0]->allocation->[3] },
41 window_size => sub { [ @{$_[0]->allocation}[2,3] ] },
42 #window_pos => sub { die PApp::Util::dumpval [ $_[0]->get_root_origin ] },
43 clist_column_widths => sub {
44 $_[0]{column_widths};
45 },
46 );
47 37
48 my %set = ( 38 for (qw(util.pl gtk.pl chat.pl image.pl sound.pl user.pl gamelist.pl userlist.pl challenge.pl
49 hpane_position => sub { $_[0]->set_position($_[1]) }, 39 game.pl room.pl roomlist.pl app.pl)) {
50 vpane_position => sub { $_[0]->set_position($_[1]) }, 40 require (KGS::Constants::findfile "KGS/kgsueme/$_");
51 window_size => sub { $_[0]->set_default_size(@{$_[1]}) }, 41 die if $@;
52 #window_pos => sub { $_[0]->set_uposition(@{$_[1]}) if @{$_[1]} },
53 clist_column_widths => sub {
54 my ($w, $v) = @_;
55 $v->[$_] && $w->set_column_width($_, $v->[$_]) for 0..$#$v;
56 $w->{column_widths} = $v;
57 $w->signal_connect(resize_column => sub { $v->[$_[1]] = $_[2]; });
58 },
59 );
60
61 sub state {
62 my ($widget, $class, $instance, %attr) = @_;
63
64 while (my ($k, $v) = each %attr) {
65 my ($set, $get) = $k =~ /=/ ? split /=/, $k : ($k, $k);
66 $v = $state->{$class}{"*"}{$get} if exists $state->{$class}{"*"}{$get};
67 $v = $state->{$class}{$instance}{$get} if exists $state->{$class}{$instance}{$get};
68 $set{$get} ? $set{$get}->($widget, $v) : $widget->set($set => $v);
69 }
70
71 $widget = [$widget, $class, $instance, \%attr];
72 Scalar::Util::weaken $widget->[0];
73
74 @widgets = (grep $_->[0], @widgets, $widget);
75 }
76
77 sub save_state {
78 for (@widgets) {
79 if ($_->[0]) {
80 my ($widget, $class, $instance, $attr) = @$_;
81 while (my ($k, $v) = each %$attr) {
82 my ($set, $get) = $k =~ /=/ ? split /=/, $k : ($k, $k);
83 $v = $get{$get} ? $get{$get}->($widget) : $widget->get($get);
84
85 $state->{$class}{"*"}{$get} = $v;
86 $state->{$class}{$instance}{$get} = $v;
87 }
88 }
89 ::status("save_state", "layout saved");
90 }
91
92 Storable::nstore($state, $staterc);
93 } 42 }
94} 43}
95 44
96# make a clist unselectable 45our $app = new app;
97sub clist_autosort { 46
98 my $w = shift; 47if ($ENV{KGSUEME_DEBUG}) {
99 my ($c, $o) = (-1); 48 use KGS::Constants;
100 for (0..$w->columns-1) { 49
101 $w->signal_connect(click_column => sub { 50 for (19) {
102 if ($_[1] != $c) { 51 my $game = new game size => $_;
103 $c = $_[1]; 52
104 $o = 0; 53 if (1) {
105 } else { 54 my $data = Storable::retrieve "board2.dat";
106 $o = !$o; 55 while (my ($k, $v) = each %$data) {
56 $game->{$k} = $v;
107 } 57 }
108 $w->set_sort_column($c); 58 $game->event_update_tree;
109 $w->set_sort_type($o ? "descending" : "ascending");
110 $w->sort;
111 }); 59 }
112 }
113
114}
115 60
116{ 61 if (0) {
117 my $main = new kgsueme; 62 $game->{cur_board} = new KGS::Game::Board;
63 my @x = (
64 #MARK_B,
65 #MARK_W,
66 #MARK_GRAY_B | MARK_SMALL_W,
67 #MARK_GRAY_W | MARK_SMALL_B,
68 #MARK_W | MARK_TRIANGLE,
69 0, 0, 0,
70 );
71 for $x (0..18) {
72 for $y (0..18) {
73 $game->{cur_board}{board}[$x][$y] =
74 $x[rand @x];
75 }
76 }
118 77
119 my %context_id; 78 $game->{cur_board}{board}[0][0] = MARK_B;
120 79 $game->{cur_board}{board}[1][1] = MARK_GRAY_B | MARK_SMALL_W;
121 sub status { 80 $game->{cur_board}{board}[2][2] = MARK_W | MARK_TRIANGLE;
122 my ($type, $text) = @_; 81 $game->{cur_board}{board}[1][2] = MARK_B | MARK_LABEL;
123 82 $game->{cur_board}{label}[1][2] = "198";
124 $main->{status}->pop($context_id{$type}) if $context_id{$type}; 83 $game->{cur_board}{board}[0][2] = MARK_W | MARK_LABEL;
125 $main->{status}->push($context_id{$type} ||= $main->{status}->get_context_id($type), $text) if $text; 84 $game->{cur_board}{label}[0][2] = "AWA";
85 $game->{board}->set_board ($game->{cur_board});
86 }
87 $game->{window}->show_all;
126 } 88 }
127} 89}
128 90
129main Gtk; 91main Gtk2;
130 92
131############################################################################# 93$app->destroy;
132 94
133package kgsueme; 95Gtk2->main_iteration while Gtk2->events_pending;
134
135use base KGS::Listener;
136
137sub new {
138 my $self = shift;
139 $self = $self->SUPER::new(@_);
140
141 $self->{conn} = new KGS::Protocol;
142
143 KGS::Listener::Debug->new->listen($self->{conn}); #d# debug only :)
144
145 $self->listen($self->{conn});
146
147 $self->{roomlist} = new roomlist conn => $self->{conn};
148
149 $self->{window} = new Gtk::Window 'toplevel';
150 $self->{window}->set_title('kgsueme');
151 ::state $self->{window}, "main::window", undef, window_size => [400, 100];
152 $self->{window}->signal_connect(delete_event => sub { main_quit Gtk });
153
154 $self->{window}->add(my $vbox = new Gtk::VBox);
155
156 $vbox->pack_start(($buttonbox = new Gtk::HButtonBox), 0, 1, 0);
157 $buttonbox->set_spacing(0);
158
159 my $button = sub {
160 $buttonbox->add(my $button = new Gtk::Button $_[0]);
161 signal_connect $button clicked => $_[1];
162 };
163
164 $button->("Login", sub { $self->login; });
165 $button->("Roomlist", sub { $self->{roomlist}->show; });
166 $button->("Save Config & Layout", sub { ::save_state });
167 $button->("Quit", sub { main_quit Gtk });
168
169 $vbox->pack_start((my $hbox = new Gtk::HBox), 0, 1, 0);
170
171 $hbox->add(new Gtk::Label "Login");
172
173 $hbox->add($self->{login} = new_with_max_length Gtk::Entry 12);
174 $self->{login}->set_text($::config->{login});
175
176 if ($::HACK) {
177 $self->{login}->signal_connect(activate => sub {
178 $self->{conn}{name} = $self->{login}->get_text;
179 });
180 }
181
182 $hbox->add(new Gtk::Label "Password");
183 $hbox->add($self->{password} = new Gtk::Entry);
184 $self->{password}->set_visibility(0);
185
186 $vbox->pack_start(($self->{status} = new Gtk::Statusbar), 0, 1, 0);
187
188 $self->{window}->show_all;
189
190 $self;
191}
192
193sub login {
194 my ($self) = @_;
195
196 $self->{conn}->disconnect;
197
198 # initialize new socket and connection
199 my $sock = new IO::Socket::INET PeerHost => "kgs.kiseido.com", PeerPort => "2379"
200 or die;
201
202 $sock->blocking(1);
203 $self->{conn}->handshake($sock);
204 $sock->blocking(0);
205
206 my $input; $input = input_add Gtk::Gdk fileno $sock, "read", sub {
207 # this is dorked
208 my $buf;
209 if (0 >= sysread $sock, $buf, 16384
210 and !$!{EINTR} and !$!{EAGAIN}) {
211 input_remove Gtk::Gdk $input;
212 $self->event_disconnect;
213 }
214 $self->{conn}->feed_data($buf);
215 };
216
217 # now login
218 $self->{conn}->login($self->{login}->get_text, $self->{password}->get_text);
219}
220
221sub inject_login {
222 my ($self, $msg) = @_;
223
224 ::status("login", "logged in as '$self->{conn}{name}' with status '$msg->{result}'");
225 $::config->{login} = $self->{conn}{name};
226
227 if ($msg->{success}) {
228 warn "hiya\n";
229 for (keys %{$::config->{rooms}}) {
230 warn "hiya $_\n";
231 $self->{roomlist}->join_room($_);
232 }
233 }
234
235 warn PApp::Util::dumpval($::config);
236}
237
238sub event_disconnect { }
239
240#############################################################################
241
242package roomlist;
243
244use base KGS::Listener::Roomlist;
245
246sub new {
247 my $self = shift;
248 $self = $self->SUPER::new(@_);
249
250 $self->listen($self->{conn});
251
252 $self->{window} = new Gtk::Window 'toplevel';
253 $self->{window}->set_title('KGS Rooms');
254 ::state $self->{window}, "roomlist::window", undef, window_size => [400, 200];
255
256 $self->{window}->signal_connect(delete_event => sub { $self->{window}->hide });
257
258 $self->{window}->add(my $vbox = new Gtk::VBox);
259
260 $vbox->pack_start((my $sw = new Gtk::ScrolledWindow), 1, 1, 0);
261 $sw->set_policy("automatic", "always");
262
263 $sw->add($self->{roomlist} = new_with_titles Gtk::CList "Group", "Room Name", "Users", "Games", "Flags", "Channel");
264 $self->{roomlist}->set_selection_mode('multiple');
265 ::clist_autosort $self->{roomlist};
266 ::state $self->{roomlist}, "roomlist::roomlist", undef, clist_column_widths => [20, 200];
267
268 $self->{roomlist}->signal_connect(select_row => sub {
269 my $room = $self->{roomlist}->get_row_data($_[1])
270 or return;
271 $self->{roomlist}->unselect_all;
272 $self->join_room($room->{channel});
273 });
274
275 $self;
276}
277
278sub join_room {
279 my ($self, $channel) = @_;
280
281 $self->{room}{$channel} ||= room->new(channel => $channel, conn => $self->{conn}, users => {});
282 $self->{room}{$channel}->join;
283}
284
285sub show {
286 my ($self, $msg) = @_;
287
288 $self->msg(list_rooms => group => $_) for 0..5; # fetch all room names (should not!)
289 $self->{window}->show_all;
290}
291
292sub event_update {
293 my ($self) = @_;
294
295 $self->{event_update} ||= Gtk->timeout_add(200, sub {
296 my $l = $self->{roomlist};
297
298 $l->freeze;
299 my $pos = $l->get_vadjustment->get_value;
300 $l->clear;
301
302 my $row = 0;
303 for (values %{$self->{rooms}}) {
304 $l->append($_->{group}, $_->{name}, $_->{users}, $_->{games}, $_->{flags}, $_->{channel});
305 $l->set_row_data($row++, $_);
306 }
307 $l->sort;
308 $l->get_vadjustment->set_value($pos);
309 $l->thaw;
310
311 delete $self->{event_update};
312 0;
313 });
314}
315
316#############################################################################
317
318package room;
319
320use base KGS::Listener::Room;
321
322sub new {
323 my $self = shift;
324 $self = $self->SUPER::new(@_);
325
326 $self->listen($self->{conn});
327
328 $self->{window} = new Gtk::Window 'toplevel';
329 $self->{window}->set_title("KGS Room $self->{name}");
330 ::state $self->{window}, "room::window", $self->{name}, window_size => [600, 400];
331
332 $self->{window}->signal_connect(delete_event => sub { $self->part });
333
334 $self->{window}->add(my $hpane = new Gtk::HPaned);
335 ::state $hpane, "room::hpane", $self->{name}, hpane_position => 200;
336
337 $hpane->add(my $vpane = new Gtk::VPaned);
338 ::state $vpane, "room::vpane", $self->{name}, vpane_position => 200;
339
340 $vpane->add(my $sw = new Gtk::ScrolledWindow);
341 $sw->set_policy("automatic", "always");
342
343 $sw->add($self->{gamelist} = new_with_titles Gtk::CList "T", "Black", "White", "Rules", "Notes");
344 ::clist_autosort $self->{gamelist};
345 ::state $self->{gamelist}, "room::gamelist", $self->{name}, clist_column_widths => [20, 120, 120, 120];
346
347 $self->{gamelist}->signal_connect(select_row => sub {
348 my $game = $self->{gamelist}->get_row_data($_[1])
349 or return;
350 $self->{game}{$game->{channel}} ||= new game %$game, conn => $self->{conn};
351 $self->{game}{$game->{channel}}->join;
352 $self->{gamelist}->unselect_all;
353 });
354
355 $vpane->add(my $vbox = new Gtk::VBox);
356
357 $vbox->pack_start((my $sw = new Gtk::ScrolledWindow), 1, 1, 0);
358 $sw->set_policy("automatic", "always");
359
360 $sw->add($self->{text} = new Gtk::Text);
361
362 $vbox->pack_start(($self->{entry} = new Gtk::Entry), 0, 1, 0);
363 $self->{entry}->signal_connect(activate => sub {
364 my $text = $self->{entry}->get_text;
365 $self->say($text) if $text =~ /\S/;
366 $self->{entry}->set_text("");
367 });
368
369 $hpane->add(my $sw = new Gtk::ScrolledWindow);
370 $sw->set_policy("automatic", "always");
371
372 $sw->add($self->{userlist} = new_with_titles Gtk::CList "User", "Rank", "Flags");
373 ::clist_autosort $self->{userlist};
374 ::state $self->{userlist}, "room::userlist", $self->{name}, clist_column_widths => [120, 30];
375
376 $self;
377}
378
379sub event_update {
380 my ($self) = @_;
381
382 $self->{event_update} ||= Gtk->timeout_add(200, sub {
383 my $l = $self->{userlist};
384
385 $l->freeze;
386 my $pos = $l->get_vadjustment->get_value;
387 $l->clear;
388
389 my $row = 0;
390 for (values %{$self->{users}}) {
391 $l->append($_->{name});
392 $l->set_row_data($row++, $_);
393 }
394 $l->sort;
395 $l->get_vadjustment->set_value($pos);
396 $l->thaw;
397
398 delete $self->{event_update};
399 0;
400 });
401}
402
403sub event_update_games {
404 my ($self) = @_;
405
406 $self->{event_update_games} ||= Gtk->timeout_add(200, sub {
407 my $l = $self->{gamelist};
408
409 $l->freeze;
410 my $pos = $l->get_vadjustment->get_value;
411 $l->clear;
412
413 my $row = 0;
414 for (values %{$self->{games}}) {
415 $l->append($_->type, $_->user0, $_->user1, $_->rules, $_->notes);
416 $l->set_row_data($row++, $_);
417 }
418 $l->sort;
419 $l->get_vadjustment->set_value($pos);
420 $l->thaw;
421
422 delete $self->{event_update_games};
423 0;
424 });
425}
426
427sub join {
428 my ($self) = @_;
429 $self->SUPER::join;
430
431 $self->{window}->show_all;
432}
433
434sub part {
435 my ($self) = @_;
436 $self->SUPER::part;
437
438 delete $::config->{rooms}{$self->{channel}};
439 $self->{window}->hide_all;
440 $self->event_update;
441 $self->event_update_games;
442}
443
444sub event_join {
445 my ($self) = @_;
446 $self->SUPER::event_join;
447
448 $::config->{rooms}{$self->{channel}} = 1;
449}
450
451sub event_update_roominfo {
452 my ($self) = @_;
453
454 $self->{text}->insert(undef, undef, undef, "$self->{owner}: $self->{description}\n\n");
455}
456
457sub inject_msg_room {
458 my ($self, $msg) = @_;
459 return unless $self->{channel} == $msg->{channel};
460
461 $self->{text}->insert(undef, undef, undef, "$msg->{name}: $msg->{message}\n");
462}
463
464#############################################################################
465
466package game;
467
468use base KGS::Listener::Game;
469use base KGS::Game;
470
471sub new {
472 my $self = shift;
473 $self = $self->SUPER::new(@_);
474
475 $self->listen($self->{conn});
476
477 $self->{window} = new Gtk::Window 'toplevel';
478 $self->{window}->set_title("KGS Game ".$self->user0." ".$self->user1);
479 ::state $self->{window}, "game::window", undef, window_size => [600, 500];
480
481 $self->{window}->signal_connect(delete_event => sub { $self->part });
482
483 $self->{window}->add(my $hpane = new Gtk::HPaned);
484 ::state $hpane, "game::hpane", undef, hpane_position => 500;
485
486 $hpane->add(my $canvas = new Gnome::Canvas);
487 $self->{canvas} = $canvas;
488# $canvas->set_pixels_per_unit(300);
489 $canvas->set_scroll_region(0,0,400,400);
490 $self->{board} = [[]];
491# $canvas->style->bg('normal', $canvas->style->white);
492 {
493 my $croot = $canvas->root;
494 my $cgroup = $croot->new($croot, "Gnome::CanvasGroup");
495 my $w = 400;
496 my $pad = 26;
497 my $box = $cgroup->new($cgroup,"Gnome::CanvasRect",
498 x1 => 0, x2 => $w,
499 y1 => 0, y2 => $w,
500 outline_color => "green",
501 fill_color => "green",
502 width_pixels => 2,
503 );
504 my $box2 = $cgroup->new($cgroup,"Gnome::CanvasRect",
505 x1 => $pad, x2 => $w - $pad,
506 y1 => $pad, y2 => $w - $pad,
507 outline_color => "brown",
508 fill_color => "brown",
509 width_pixels => 2,
510 );
511 my @lines;
512 my $x1 = $pad * 2; # == my $y1 = 30;
513 my $x2 = $w - ($pad * 2); # == my $y2 = 270;
514 my $w = $x2 - $x1;
515 my $s = $self->{size} - 1;
516
517 for (my $i = 0; $i <= $s; $i++) { # one more iteration for the finishing lines
518 push @lines,
519 $cgroup->new($cgroup,"Gnome::CanvasLine",
520 points => [ $x1, $x1 + ($w/$s)*$i, $x1 + $w, $x1 + ($w/$s)*$i ],
521 fill_color => "darkbrown",
522 width_pixels => 1);
523 push @lines,
524 $cgroup->new($cgroup,"Gnome::CanvasLine",
525 points => [ $x1 + ($w/$s)*$i, $x1, $x1 + ($w/$s)*$i, $x1 + $w ],
526 fill_color => "darkbrown",
527 width_pixels => 1);
528 }
529 $self->{board_gfx}->{lines} = \@lines;
530 my $stones = [[]];
531 my $wf = ($w/$s);
532 for (my $x = 0; $x < $self->{size}; $x++) {
533 for (my $y = 0; $y < $self->{size}; $y++) {
534 $stones->[$x]->[$y]->[0] = # black stone
535 $cgroup->new($cgroup,"Gnome::CanvasEllipse",
536 x1 => $x1 + $wf*$x - ($wf/2.2), x2 => $x1 + $wf*$x + ($wf/2),
537 y1 => $x1 + $wf*$y - ($wf/2.2), y2 => $x1 + $wf*$y + ($wf/2),
538 fill_color => "black");
539 $stones->[$x]->[$y]->[0]->hide;
540 $stones->[$x]->[$y]->[1] = # black stone
541 $cgroup->new($cgroup,"Gnome::CanvasEllipse",
542 x1 => $x1 + $wf*$x - ($wf/2.2), x2 => $x1 + $wf*$x + ($wf/2),
543 y1 => $x1 + $wf*$y - ($wf/2.2), y2 => $x1 + $wf*$y + ($wf/2),
544 fill_color => "white");
545 $stones->[$x]->[$y]->[1]->hide;
546 }
547 }
548 $self->{board_gfx}->{stones} = $stones;
549
550 # smooth => 1,
551 # spline_steps => 50
552# $line->hide;
553 }
554$canvas->show();
555
556
557 $hpane->add(my $vpane = new Gtk::VPaned);
558 ::state $vpane, "game", $self->{name}, vpane_position => 80;
559
560 $vpane->add(my $sw = new Gtk::ScrolledWindow);
561 $sw->set_policy("automatic", "always");
562
563 $sw->add($self->{userlist} = new_with_titles Gtk::CList "User", "Rank", "Flags");
564 ::clist_autosort $self->{userlist};
565 ::state $self->{userlist}, "room::userlist", $self->{name}, clist_column_widths => [120, 30];
566
567 $vpane->add(my $vbox = new Gtk::VBox);
568
569 $vbox->pack_start((my $sw = new Gtk::ScrolledWindow), 1, 1, 0);
570 $sw->set_policy("automatic", "always");
571
572 $sw->add($self->{text} = new Gtk::Text);
573
574 $vbox->pack_start(($self->{entry} = new Gtk::Entry), 0, 1, 0);
575 $self->{entry}->signal_connect(activate => sub {
576 my $text = $self->{entry}->get_text;
577 # add message
578 $self->{entry}->set_text("");
579 });
580
581 $self;
582}
583
584sub event_update {
585 my ($self) = @_;
586
587 $self->{event_update} ||= Gtk->timeout_add(200, sub {
588 my $l = $self->{userlist};
589
590 $l->freeze;
591 my $pos = $l->get_vadjustment->get_value;
592 $l->clear;
593
594 my $row = 0;
595 for (values %{$self->{users}}) {
596 $l->append($_->{name});
597 $l->set_row_data($row++, $_);
598 }
599 $l->sort;
600 $l->get_vadjustment->set_value($pos);
601 $l->thaw;
602
603 delete $self->{event_update};
604 0;
605 });
606}
607
608sub join {
609 my ($self) = @_;
610 $self->SUPER::join;
611
612 $self->{window}->show_all;
613}
614
615sub part {
616 my ($self) = @_;
617 $self->SUPER::part;
618
619 $self->{window}->hide_all;
620 $self->event_update;
621}
622
623sub event_update_tree {
624 my ($self) = @_;
625
626# if (not defined $self->{board_pm}) {
627# $self->{board_pm} = new Gtk::Gdk::Pixmap ($self->{board}->window, 100, 100, -1);
628# $self->{board_pm}->draw_rectangle($self->{board}->style->white_gc, 1, 0, 0, 100, 100);
629# }
630# my $red = $self->{board}->window->get_colormap->color_alloc( { red => 65000, green => 0, blue => 0 } );
631# my $red_gc = new Gtk::Gdk::GC ( $self->{board}->window );
632# $red_gc->set_foreground( $red );
633#
634# my $px = $self->{board_pm};
635
636 for my $x (0 .. $self->{size} - 1) {
637 for my $y (0 .. $self->{size} - 1) {
638# $self->{board}[$x][$y] = 0;
639 $self->{board_gfx}->{stones}->[$x]->[$y]->[0]->hide;
640 $self->{board_gfx}->{stones}->[$x]->[$y]->[1]->hide;
641 }
642 }
643
644 for (0..$self->{node}) {
645 while (my ($k, $v) = each %{$self->{tree}[$_]}) {
646 if ($k eq "move7") {
647 if ($v->[1] < 255) {
648# $self->{board_gfx}->{stones}[$x][$y]->[0]->show;
649 ($v->[0] == 0) &&
650 $self->{board_gfx}->{stones}->[$v->[1]]->[$v->[2]]->[0]->show;
651 ($v->[0] == 1) &&
652 $self->{board_gfx}->{stones}->[$v->[1]]->[$v->[2]]->[1]->show;
653 # $self->{board}[$v->[1]][$v->[2]] = ($v->[0] + 1); # ("X", "O", "-")
654 # 0 1 2 (+1)
655 }
656 }
657 }
658 }
659}
660
661package KGS::Game::Board;
662package KGS::Game::Node;
663package KGS::Game::Tree;
664 96
6651; 971;
666 98
667 99
668

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines