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

Comparing kgsueme/kgsueme/game.pl (file contents):
Revision 1.112 by root, Mon May 31 18:18:26 2004 UTC vs.
Revision 1.121 by root, Wed Jun 2 04:39:07 2004 UTC

34sub configure { 34sub configure {
35 my ($self, $timesys, $main, $interval, $count) = @_; 35 my ($self, $timesys, $main, $interval, $count) = @_;
36 36
37 if ($timesys == TIMESYS_ABSOLUTE) { 37 if ($timesys == TIMESYS_ABSOLUTE) {
38 $self->{format} = sub { 38 $self->{format} = sub {
39 if ($_[0] <= 0) { 39 if ($_[0] < 0) {
40 "TIMEOUT"; 40 "TIMEOUT";
41 } else { 41 } else {
42 util::format_time $_[0]; 42 util::format_time $_[0];
43 } 43 }
44 }; 44 };
45 45
46 } elsif ($timesys == TIMESYS_BYO_YOMI) { 46 } elsif ($timesys == TIMESYS_BYO_YOMI) {
47 my $low = $interval * $count; 47 my $low = $interval * $count;
48 48
49 $self->{format} = sub { 49 $self->{format} = sub {
50 if ($_[0] <= 0) { 50 if ($_[0] < 0) {
51 "TIMEOUT"; 51 "TIMEOUT";
52 } elsif ($_[0] > $low) { 52 } elsif ($_[0] > $low) {
53 util::format_time $_[0] - $low; 53 util::format_time $_[0] - $low;
54 } else { 54 } else {
55 sprintf "%s (%d)", 55 sprintf "%s (%d)",
58 } 58 }
59 }; 59 };
60 60
61 } elsif ($timesys == TIMESYS_CANADIAN) { 61 } elsif ($timesys == TIMESYS_CANADIAN) {
62 $self->{format} = sub { 62 $self->{format} = sub {
63 if ($_[0] <= 0) { 63 if ($_[0] < 0) {
64 "TIMEOUT"; 64 "TIMEOUT";
65 } elsif (!$self->{moves}) { 65 } elsif (!$self->{moves}) {
66 util::format_time $_[0] - $low; 66 util::format_time $_[0] - $low;
67 } else { 67 } else {
68 my $time = int (($_[0] - 1) % $interval + 1); 68 my $time = int (($_[0] - 1) % $interval + 1);
133 133
134### USER PANEL ############################################################## 134### USER PANEL ##############################################################
135 135
136package game::userpanel; 136package game::userpanel;
137 137
138use KGS::Constants;
139
138use Glib::Object::Subclass 140use Glib::Object::Subclass
139 Gtk2::HBox, 141 Gtk2::Frame,
140 properties => [ 142 properties => [
141 Glib::ParamSpec->IV ("colour", "colour", "User Colour", 0, 1, 0, [qw(construct-only writable)]), 143 Glib::ParamSpec->IV ("colour", "colour", "User Colour",
144 COLOUR_BLACK, COLOUR_WHITE, COLOUR_BLACK,
145 [qw(construct-only readable writable)]),
142 ]; 146 ];
143 147
144sub INIT_INSTANCE { 148sub INIT_INSTANCE {
145 my ($self) = @_; 149 my ($self) = @_;
146 150
147 $self->add (my $vbox = new Gtk2::VBox); 151 $self->add (my $vbox = new Gtk2::VBox);
148 152
149 $vbox->add ($self->{name} = new Gtk2::Label $self->{name}); 153 $vbox->pack_start (($self->{name} = new Gtk2::Label "-"), 1, 1, 0);
150 $vbox->add ($self->{info} = new Gtk2::Label ""); 154 $vbox->pack_start (($self->{info} = new Gtk2::Label "-"), 1, 1, 0);
151 $vbox->add ($self->{clock} = new game::goclock); Scalar::Util::weaken $self->{clock}; 155 $vbox->pack_start (($self->{clock} = new game::goclock), 1, 1, 0);
152 156
153 $vbox->add ($self->{imagebox} = new Gtk2::VBox); 157 $vbox->add ($self->{imagebox} = new Gtk2::VBox);
154 158
155 $self; 159 $self;
156} 160}
214 218
215use POSIX qw(ceil); 219use POSIX qw(ceil);
216 220
217sub new { 221sub new {
218 my ($self, %arg) = @_; 222 my ($self, %arg) = @_;
223
219 $self = $self->Glib::Object::new; 224 $self = $self->Glib::Object::new;
220 $self->{$_} = delete $arg{$_} for keys %arg; 225 $self->{$_} = delete $arg{$_} for keys %arg;
221 226
222 gtk::state $self, "game::window", undef, window_size => [600, 500]; 227 gtk::state $self, "game::window", undef, window_size => [620, 460];
223 228
224 $self->signal_connect (destroy => sub { 229 $self->signal_connect (destroy => sub {
225 $self->unlisten; 230 $self->unlisten;
226 delete $self->{app}{game}{$self->{channel}}; 231 delete $self->{app}{game}{$self->{channel}};
227 %{$_[0]} = (); 232 %{$_[0]} = ();
228 });#d# 233 });#d#
229 234
230 $self->add (my $hpane = new Gtk2::HPaned); 235 $self->add (my $hpane = new Gtk2::HPaned);
231 gtk::state $hpane, "game::hpane", undef, position => 500; 236 gtk::state $hpane, "game::hpane", undef, position => 420;
232 237
233 # LEFT PANE 238 # LEFT PANE
234 239
235 $hpane->pack1 (($self->{left} = new Gtk2::VBox), 1, 0); 240 $hpane->pack1 (($self->{left} = new Gtk2::VBox), 1, 0);
236 241
237 $self->{boardbox} = new Gtk2::VBox;
238
239 $hpane->pack1((my $vbox = new Gtk2::VBox), 1, 1); 242 $hpane->pack1((my $vbox = new Gtk2::VBox), 1, 1);
240 243
241 # board box (aspect/canvas) 244 # board box (aspect/canvas)
242 245
243 #$self->{boardbox}->pack_start((my $frame = new Gtk2::Frame), 0, 1, 0);
244
245 # RIGHT PANE 246 # RIGHT PANE
246 247
247 $hpane->pack2 ((my $vbox = new Gtk2::VBox), 1, 1); 248 $hpane->pack2 ((my $vbox = new Gtk2::VBox), 1, 1);
248 $hpane->set (position_set => 1); 249 $hpane->set (position_set => 1);
249 250
250 $vbox->pack_start ((my $frame = new Gtk2::Frame), 0, 1, 0); 251 $vbox->pack_start ((my $frame = new Gtk2::Frame), 0, 1, 0);
251 252
252 { 253 {
253 $frame->add (my $vbox = new Gtk2::VBox); 254 $frame->add (my $vbox = new Gtk2::VBox);
254 $vbox->add ($self->{title} = new Gtk2::Label $title); 255 $vbox->add ($self->{title} = new Gtk2::Label "-");
255 256
256 $vbox->add (my $hbox = new Gtk2::HBox); 257 $vbox->add (my $hbox = new Gtk2::HBox);
257 258
258 $hbox->pack_start (($self->{board_label} = new Gtk2::Label), 0, 1, 0); 259 $hbox->pack_start (($self->{board_label} = new Gtk2::Label), 0, 0, 0);
259 260
260 $self->{moveadj} = new Gtk2::Adjustment 1, 1, 1, 1, 5, 0; 261 $self->{moveadj} = new Gtk2::Adjustment 1, 1, 1, 1, 5, 0;
261 262
262 $hbox->pack_start ((my $scale = new Gtk2::HScale $self->{moveadj}), 1, 1, 0); 263 $hbox->pack_start ((my $scale = new Gtk2::HScale $self->{moveadj}), 1, 1, 0);
263 $scale->set_draw_value (0); 264 $scale->set_draw_value (0);
275 for COLOUR_WHITE, COLOUR_BLACK; 276 for COLOUR_WHITE, COLOUR_BLACK;
276 277
277 $vbox->pack_start ((my $buttonbox = new Gtk2::HButtonBox), 0, 1, 0); 278 $vbox->pack_start ((my $buttonbox = new Gtk2::HButtonBox), 0, 1, 0);
278 279
279 $buttonbox->add ($self->{button_pass} = 280 $buttonbox->add ($self->{button_pass} =
280 Gtk2::Button->Glib::Object::new (label => "Pass", no_show_all => 1, visible => 0)); 281 Gtk2::Button->Glib::Object::new (label => "Pass", visible => 0));
281 $self->{button_pass}->signal_connect (clicked => sub { 282 $self->{button_pass}->signal_connect (clicked => sub {
282 $self->{board_click}->(255, 255) if $self->{board_click}; 283 $self->{board_click}->(255, 255) if $self->{board_click};
283 }); 284 });
285 eval { $self->{button_pass}->set (no_show_all => 1) }; # workaround for gtk+-2.2
284 $buttonbox->add ($self->{button_undo} = 286 $buttonbox->add ($self->{button_undo} =
285 Gtk2::Button->Glib::Object::new (label => "Undo", no_show_all => 1, visible => 0)); 287 Gtk2::Button->Glib::Object::new (label => "Undo", visible => 0));
286 $self->{button_undo}->signal_connect (clicked => sub { 288 $self->{button_undo}->signal_connect (clicked => sub {
287 $self->send (req_undo => channel => $self->{channel}); 289 $self->send (req_undo => channel => $self->{channel});
288 }); 290 });
291 eval { $self->{button_undo}->set (no_show_all => 1) }; # workaround for gtk+-2.2
289 $buttonbox->add ($self->{button_resign} = 292 $buttonbox->add ($self->{button_resign} =
290 Gtk2::Button->Glib::Object::new (label => "Resign", no_show_all => 1, visible => 0)); 293 Gtk2::Button->Glib::Object::new (label => "Resign", visible => 0));
291 $self->{button_resign}->signal_connect (clicked => sub { 294 $self->{button_resign}->signal_connect (clicked => sub {
292 $self->send (resign_game => channel => $self->{channel}, player => $self->{colour}); 295 $self->send (resign_game => channel => $self->{channel}, player => $self->{colour});
293 }); 296 });
297 eval { $self->{button_resign}->set (no_show_all => 1) }; # workaround for gtk+-2.2
294 298
295 $vbox->pack_start (($self->{chat} = new superchat), 1, 1, 0); 299 $vbox->pack_start (($self->{chat} = new chat), 1, 1, 0);
296 300
297 $self->set_channel ($self->{channel}); 301 $self->set_channel ($self->{channel});
298 302
299 $self->show_all; 303 $self->show_all;
300 304
458 462
459 return unless $self->{joined}; 463 return unless $self->{joined};
460 464
461 $self->{colour} = $self->player_colour ($self->{conn}{name}); 465 $self->{colour} = $self->player_colour ($self->{conn}{name});
462 466
463 my $title = defined $self->{channel}
464 ? $self->owner->as_string . " " . $self->opponent_string
465 : "Game Window";
466 $self->set_title ("KGS Game $title");
467 $self->{title}->set_text ($title);
468
469 $self->{user}[COLOUR_BLACK] = $self->{black}; 467 $self->{user}[COLOUR_BLACK] = $self->{black};
470 $self->{user}[COLOUR_WHITE] = $self->{white}; 468 $self->{user}[COLOUR_WHITE] = $self->{white};
471 469
472 # show board 470 # show board
473 if ($self->is_inprogress) { 471 if ($self->is_inprogress) {
474 if (!$self->{boardbox}->parent) { 472 if (!$self->{board}) {
475 $self->{boardbox}->add ($self->{board} = new Gtk2::GoBoard size => $self->{size}); 473 $self->{left}->add ($self->{board} = new Gtk2::GoBoard size => $self->{size});
476 $self->{left}->add ($self->{boardbox});
477 $self->{board}->signal_connect (button_release => sub { 474 $self->{board}->signal_connect (button_release => sub {
475 return unless $self->{cur_board};
478 if ($_[1] == 1) { 476 if ($_[1] == 1) {
479 $self->{board_click}->($_[2], $_[3]) if $self->{board_click}; 477 $self->{board_click}->($_[2], $_[3]) if $self->{board_click};
480 } 478 }
481 }); 479 });
480 $self->{board}->show_all;
482 } 481 }
483 if (my $ch = delete $self->{challenge}) { 482 if (my $ch = delete $self->{challenge}) {
484 $_->{inlay}->destroy for values %$ch; 483 $_->{inlay}->destroy for values %$ch;
485 } 484 }
486 $self->update_cursor; 485 $self->update_cursor;
487 } 486 }
488 487
489 $self->{left}->show_all; 488 my $title = defined $self->{channel}
489 ? $self->owner->as_string . " " . $self->opponent_string
490 : "Game Window";
491 $self->set_title ("KGS Game $title");
492 $self->{title}->set_text ($title); # title gets redrawn wrongly
490 493
491 $self->{rules_inlay}->refresh; 494 $self->{rules_inlay}->refresh;
495
496 if (exists $self->{teacher}) {
497 $self->{teacher_inlay} ||= $self->{chat}->new_inlay;
498 $self->{teacher_inlay}->clear;
499 $self->{teacher_inlay}->append_text ("\n<header>Teacher:</header> <user>"
500 . (util::toxml $self->{teacher}) . "</user>");
501 } elsif ($self->{teacher_inlay}) {
502 (delete $self->{teacher_inlay})->clear;
492 503 }
504
505 $self->update_cursor;
493} 506}
494 507
495sub event_update_rules { 508sub event_update_rules {
496 my ($self, $rules) = @_; 509 my ($self, $rules) = @_;
497 510
498 $self->{rules} = $rules; 511 $self->{rules} = $rules;
499 512
500 if ($self->{user}) { 513 if ($self->{user}) {
514 # todo. gets drawn wrongly
515
501 $self->{userpanel}[$_]->configure ($self->{app}, $self->{user}[$_], $rules) 516 $self->{userpanel}[$_]->configure ($self->{app}, $self->{user}[$_], $rules)
502 for COLOUR_BLACK, COLOUR_WHITE; 517 for COLOUR_BLACK, COLOUR_WHITE;
503 } 518 }
504 519
505 sound::play 3, "gamestart"; 520 sound::play 3, "gamestart";
518 $self->{userpanel}[$colour]->set_timer ( 533 $self->{userpanel}[$colour]->set_timer (
519 $running && $colour == $self->{whosemove} && $t->[0], 534 $running && $colour == $self->{whosemove} && $t->[0],
520 $t->[1] || $self->{rules}{time} 535 $t->[1] || $self->{rules}{time}
521 + ($self->{rules}{timesys} == TIMESYS_BYO_YOMI 536 + ($self->{rules}{timesys} == TIMESYS_BYO_YOMI
522 && $self->{rules}{interval} * $self->{rules}{count}), 537 && $self->{rules}{interval} * $self->{rules}{count}),
523 $t->[2] || $self->{rules}{count}); 538 $t->[2]);
524 } 539 }
525} 540}
526 541
527sub inject_set_gametime { 542sub inject_set_gametime {
528 my ($self, $msg) = @_; 543 my ($self, $msg) = @_;
536 if $self->{showmove} == @{$self->{path}}; 551 if $self->{showmove} == @{$self->{path}};
537} 552}
538 553
539sub update_cursor { 554sub update_cursor {
540 my ($self) = @_; 555 my ($self) = @_;
556
557 return unless $self->{cur_board};
541 558
542 my $running = $self->{showmove} == @{$self->{path}} && $self->is_active; 559 my $running = $self->{showmove} == @{$self->{path}} && $self->is_active;
543 560
544 delete $self->{board_click}; 561 delete $self->{board_click};
545 562
579 596
580 } elsif ($self->{colour} == $self->{whosemove}) { 597 } elsif ($self->{colour} == $self->{whosemove}) {
581 # normal move 598 # normal move
582 $self->{button_pass}->set (label => "Pass", visible => 1, sensitive => 1); 599 $self->{button_pass}->set (label => "Pass", visible => 1, sensitive => 1);
583 $self->{board}->set (cursor => sub { 600 $self->{board}->set (cursor => sub {
584 # if is_valid_move oder so#TODO# 601 $self->{cur_board}
585 $_[0] & (MARK_B | MARK_W) 602 && $self->{cur_board}->is_valid_move ($self->{colour}, $_[1], $_[2],
586 ? $_[0] 603 $self->{rules}{ruleset} == RULESET_NEW_ZEALAND)
587 : $_[0] | MARK_GRAYED | ($self->{colour} == COLOUR_WHITE ? MARK_W : MARK_B); 604 ? $_[0] | MARK_GRAYED | ($self->{colour} == COLOUR_WHITE ? MARK_W : MARK_B)
605 : $_[0];
588 }); 606 });
589 $self->{board_click} = sub { 607 $self->{board_click} = sub {
608 return unless
609 $self->{cur_board}->is_valid_move ($self->{colour}, $_[1], $_[2],
610 $self->{rules}{ruleset} == RULESET_NEW_ZEALAND);
590 $self->send (game_move => channel => $self->{channel}, x => $_[0], y => $_[1]); 611 $self->send (game_move => channel => $self->{channel}, x => $_[0], y => $_[1]);
591 $self->{board}->set (cursor => undef); 612 $self->{board}->set (cursor => undef);
592 delete $self->{board_click}; 613 delete $self->{board_click};
593 $self->{button_pass}->sensitive (0); 614 $self->{button_pass}->sensitive (0);
594 }; 615 };
605 } 626 }
606} 627}
607 628
608sub update_board { 629sub update_board {
609 my ($self) = @_; 630 my ($self) = @_;
631
610 return unless $self->{path}; 632 return unless $self->{path};
611 633
612 $self->{board_label}->set_text ("Move " . ($self->{showmove} - 1)); 634 $self->{board_label}->set_text ("Move " . ($self->{showmove} - 1));
613 635
614 $self->{cur_board} = new KGS::Game::Board $self->{size}; 636 $self->{cur_board} = new KGS::Game::Board $self->{size};
615 $self->{cur_board}->interpret_path ([@{$self->{path}}[0 .. $self->{showmove} - 1]]); 637 $self->{cur_board}->interpret_path ([@{$self->{path}}[0 .. $self->{showmove} - 1]]);
616
617 $self->{userpanel}[$_]->set_captures ($self->{cur_board}{captures}[$_])
618 for COLOUR_WHITE, COLOUR_BLACK;
619 638
620 if ($self->{rules}{ruleset} == RULESET_JAPANESE) { 639 if ($self->{rules}{ruleset} == RULESET_JAPANESE) {
621 if ($self->{curnode}{move} == 0) { 640 if ($self->{curnode}{move} == 0) {
622 $self->{whosemove} = $self->{handicap} ? COLOUR_WHITE : COLOUR_BLACK; 641 $self->{whosemove} = $self->{handicap} ? COLOUR_WHITE : COLOUR_BLACK;
623 } else { 642 } else {
632 } else { 651 } else {
633 $self->{whosemove} = 1 - $self->{cur_board}{last}; 652 $self->{whosemove} = 1 - $self->{cur_board}{last};
634 } 653 }
635 } 654 }
636 655
656 $self->{userpanel}[$_]->set_captures ($self->{cur_board}{captures}[$_])
657 for COLOUR_WHITE, COLOUR_BLACK;
658
637 my $start_time = $self->{rules}{time}; 659 my $start_time = $self->{rules}{time};
638 660
639 if ($self->{showmove} == @{$self->{path}}) { 661 if ($self->{showmove} == @{$self->{path}}) {
640 $self->{timers} = [ 662 $self->{timers} = [
641 [$self->{lastmove_time}, @{$self->{cur_board}{timer}[0]}], 663 [$self->{lastmove_time}, @{$self->{cur_board}{timer}[0]}],
662 } elsif ($self->{score_inlay}) { 684 } elsif ($self->{score_inlay}) {
663 (delete $self->{score_inlay})->clear; 685 (delete $self->{score_inlay})->clear;
664 } 686 }
665 687
666 $self->update_cursor; 688 $self->update_cursor;
689
667} 690}
668 691
669sub event_update_tree { 692sub event_update_tree {
670 my ($self) = @_; 693 my ($self) = @_;
671 694
739 762
740 sound::play 3, "resign"; 763 sound::play 3, "resign";
741 $self->{chat}->append_text ("\n<infoblock><header>Resign</header>" 764 $self->{chat}->append_text ("\n<infoblock><header>Resign</header>"
742 . "\n<user>" 765 . "\n<user>"
743 . (util::toxml $self->{user}[$msg->{player}]->as_string) 766 . (util::toxml $self->{user}[$msg->{player}]->as_string)
744 . "</user> resigned.</infoblock>"); 767 . "</user> resigned."
768 . "\n<user>"
769 . (util::toxml $self->{user}[1 - $msg->{player}]->as_string)
770 . "</user> wins the game."
771 . "</infoblock>");
745} 772}
746 773
747sub event_out_of_time { 774sub event_time_win {
748 my ($self, $player) = @_; 775 my ($self, $player) = @_;
749 776
750 sound::play 3, "timewin"; 777 sound::play 3, "timewin";
751 $self->{chat}->append_text ("\n<infoblock><header>Out of Time</header>" 778 $self->{chat}->append_text ("\n<infoblock><header>Out of Time</header>"
752 . "\n<user>" 779 . "\n<user>"
780 . (util::toxml $self->{user}[1 - $msg->{player}]->as_string)
781 . "</user> ran out of time and lost."
782 . "\n<user>"
753 . (util::toxml $self->{user}[$msg->{player}]->as_string) 783 . (util::toxml $self->{user}[$msg->{player}]->as_string)
784 . "</user> wins the game."
785 . "</infoblock>");
786}
787
788sub event_owner_left {
789 my ($self) = @_;
790
791 $self->{chat}->append_text ("\n<infoblock><header>Owner left</header>"
754 . "</user> ran out of time and lost.</infoblock>"); 792 . "\nThe owner of this game left.</infoblock>");
793}
794
795sub event_teacher_left {
796 my ($self) = @_;
797
798 $self->{chat}->append_text ("\n<infoblock><header>Teacher left</header>"
799 . "\nThe teacher left the game.</infoblock>");
755} 800}
756 801
757sub event_done { 802sub event_done {
758 my ($self) = @_; 803 my ($self) = @_;
759 804

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines