KGS

 view release on metacpan or  search on metacpan

kgsueme/game.pl  view on Meta::CPAN

   $self->{user}[COLOUR_BLACK] = $self->{black};
   $self->{user}[COLOUR_WHITE] = $self->{white};

   # show board
   if ($self->is_inprogress) {
      if (!$self->{board}) {
         $self->{left}->add ($self->{board} = new Gtk2::GoBoard size => $self->{size});
         $self->{board}->signal_connect (button_release => sub {
            return unless $self->{cur_board};
            if ($_[1] == 1) {
               $self->{board_click}->($_[2], $_[3]) if $self->{board_click};
            }
         });
         $self->{board}->show_all;
      }
      if (my $ch = delete $self->{challenge}) {
         $_->{inlay}->destroy for values %$ch;
      }
      $self->update_cursor;
   }

   my $title = defined $self->{channel}
                  ? $self->owner->as_string . " " . $self->opponent_string
                  : "Game Window";
   $self->set_title ("KGS Game $title");
   $self->{title}->set_text ($title); # title gets redrawn wrongly
   $self->{title}->show; # workaround for refresh-bug

   $self->{rules_inlay}->refresh;

   if (exists $self->{teacher}) {
      $self->{teacher_inlay} ||= $self->{chat}->new_inlay;
      $self->{teacher_inlay}->clear;
      $self->{teacher_inlay}->append_text ("\n<header>Teacher:</header> <user>"
                                           . (util::toxml $self->{teacher}) . "</user>");
   } elsif ($self->{teacher_inlay}) {
      (delete $self->{teacher_inlay})->clear;
   }

   $self->update_cursor;
}

sub event_update_rules {
   my ($self, $rules) = @_;

   $self->{rules} = $rules;

   if ($self->{user}) {
      # todo. gets drawn wrongly

      $self->{userpanel}[$_]->configure ($self->{app}, $self->{user}[$_], $rules)
         for COLOUR_BLACK, COLOUR_WHITE;
   }

   sound::play 3, "gamestart";
   $self->{rules_inlay}->refresh;
}

### BOARD DISPLAY ###########################################################

sub update_timers {
   my ($self, $timers) = @_;

   my $running = $self->{showmove} == @{$self->{path}} && !$self->{teacher};

   for my $colour (COLOUR_BLACK, COLOUR_WHITE) {
      my $t = $timers->[$colour];
      $self->{userpanel}[$colour]->set_timer (
            $running && $colour == $self->{whosemove} && $t->[0],
            $t->[1] || $self->{rules}{time}
                       + ($self->{rules}{timesys} == TIMESYS_BYO_YOMI
                         && $self->{rules}{interval} * $self->{rules}{count}),
            $t->[2]);
   }
}

sub inject_set_gametime {
   my ($self, $msg) = @_;

   $self->{timers} = [
      [$msg->{NOW}, $msg->{black_time}, $msg->{black_moves}],
      [$msg->{NOW}, $msg->{white_time}, $msg->{white_moves}],
   ];

   $self->update_timers ($self->{timers})
      if $self->{showmove} == @{$self->{path}};
}

sub update_cursor {
   my ($self) = @_;

   return unless $self->{cur_board};

   if ($self->{rules}{ruleset} == RULESET_JAPANESE) {
      if ($self->{curnode}{move} == 0) {
         $self->{whosemove} = $self->{handicap} ? COLOUR_WHITE : COLOUR_BLACK;
      } else {
         $self->{whosemove} = 1 - $self->{cur_board}{last};
      }
   } else {
      # Chinese, Aga, NZ all have manual placement
      if ($self->{curnode}{move} < $self->{handicap}) {
         $self->{whosemove} = COLOUR_BLACK;
      } elsif ($self->{curnode}{move} == $self->{handicap}) {
         $self->{whosemove} = $self->{handicap} ? COLOUR_WHITE : COLOUR_BLACK;
      } else {
         $self->{whosemove} = 1 - $self->{cur_board}{last};
      }
   }

   my $running = $self->{showmove} == @{$self->{path}} && $self->is_active;

   delete $self->{board_click};

   if ($self->{teacher} eq $self->{app}{conn}) {
      #TODO# # teaching mode not implemented
      $self->{button_pass}->set (label => "Pass", sensitive => 1);
      $self->{button_pass}->show;
      $self->{button_undo}->hide;
      $self->{button_resign}->hide;
      $self->{board}->set (cursor => undef);

   } elsif ($running && $self->{colour} != COLOUR_NONE) {
      # during game
      $self->{button_undo}->show;
      $self->{button_resign}->show;

      if ($self->{cur_board}{score}) {
         # during scoring
         $self->{button_pass}->set (label => "Done", sensitive => 1);
         $self->{button_pass}->show;
         $self->{board}->set (cursor => sub {
            $_[0] & (MARK_B | MARK_W)
               ? $_[0] ^ MARK_GRAYED
               : $_[0];
         });
         $self->{board_click} = sub {
            if ($_[0] == 255) {
               $self->{button_pass}->sensitive (0);
               $self->done;
            } else {
               $self->send (mark_dead =>
                  channel => $self->{channel},
                  x       => $_[0],
                  y       => $_[1],
                  dead    => !($self->{cur_board}{board}[$_[0]][$_[1]] & MARK_GRAYED),
               );
            }
         };

      } elsif ($self->{colour} == $self->{whosemove}) {
         # normal move
         $self->{button_pass}->set (label => "Pass", sensitive => 1);
         $self->{button_pass}->show;
         $self->{board}->set (cursor => sub {
            $self->{cur_board}
               && $self->{cur_board}->is_valid_move ($self->{colour}, $_[1], $_[2],
                                         $self->{rules}{ruleset} == RULESET_NEW_ZEALAND)
               ? $_[0] | MARK_GRAYED | ($self->{colour} == COLOUR_WHITE ? MARK_W : MARK_B)
               : $_[0];
         });
         $self->{board_click} = sub {
            return unless
               $self->{cur_board}->is_valid_move ($self->{colour}, $_[0], $_[1],
                                      $self->{rules}{ruleset} == RULESET_NEW_ZEALAND);
            $self->send (game_move => channel => $self->{channel}, x => $_[0], y => $_[1]);
            $self->{board}->set (cursor => undef);
            delete $self->{board_click};
            $self->{button_pass}->sensitive (0);
         };
      } else {
         $self->{button_pass}->set (label => "Pass", sensitive => 0);
         $self->{button_pass}->show;
         $self->{board}->set (cursor => undef);
      }
   } else {
      $self->{button_undo}->hide;
      $self->{button_resign}->hide;
      $self->{button_pass}->hide;
      $self->{board}->set (cursor => undef);
      #TODO# # implement coordinate-grabbing
   }
}

sub update_board {
   my ($self) = @_;

   return unless $self->{path};

   $self->{board_label}->set_text ("Move " . ($self->{showmove} - 1));

   $self->{cur_board} = new KGS::Game::Board $self->{size};
   $self->{cur_board}->interpret_path ([@{$self->{path}}[0 .. $self->{showmove} - 1]]);

   $self->{userpanel}[$_]->set_captures ($self->{cur_board}{captures}[$_])
      for COLOUR_WHITE, COLOUR_BLACK;

   $self->{board}->set_board ($self->{cur_board});

   if ($self->{cur_board}{score}) {
      $self->{score_inlay} ||= $self->{chat}->new_inlay;
      $self->{score_inlay}->clear;
      $self->{score_inlay}->append_text ("\n<header>Scoring</header>"
                                         . "\n<score>"
                                         . "White: $self->{cur_board}{score}[COLOUR_WHITE], "
                                         . "Black: $self->{cur_board}{score}[COLOUR_BLACK]"
                                         . "</score>");
   } elsif ($self->{score_inlay}) {
      (delete $self->{score_inlay})->clear;
   }

   $self->update_cursor;

   if ($self->{showmove} == @{$self->{path}}) {
      $self->{timers} = [
         [$self->{lastmove_time}, @{$self->{cur_board}{timer}[0]}],
         [$self->{lastmove_time}, @{$self->{cur_board}{timer}[1]}],
      ];
      $self->update_timers ($self->{timers});
   } else {
      $self->update_timers ([
         [0, @{$self->{cur_board}{timer}[0]}],
         [0, @{$self->{cur_board}{timer}[1]}],
      ]);
   }

}

sub event_update_tree {
   my ($self) = @_;

   (delete $self->{undo_inlay})->clear
      if $self->{undo_inlay};

   $self->{path} = $self->get_path;

   if ($self->{moveadj}) {
      my $upper = $self->{moveadj}->upper;
      my $pos = $self->{moveadj}->get_value;
      my $move = scalar @{$self->{path}};

      $self->{moveadj}->upper ($move);
      
      $self->{moveadj}->changed;
      if ($pos == $upper) {



( run in 0.506 second using v1.01-cache-2.11-cpan-13bb782fe5a )