ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Games-Go-SimpleBoard/SimpleBoard.pm
(Generate patch)

Comparing Games-Go-SimpleBoard/SimpleBoard.pm (file contents):
Revision 1.9 by root, Wed Jun 25 20:11:33 2008 UTC vs.
Revision 1.15 by elmex, Thu Jul 24 09:14:12 2008 UTC

100 100
101sub new { 101sub new {
102 my $class = shift; 102 my $class = shift;
103 my $size = shift; 103 my $size = shift;
104 104
105 unless ($size > 0) {
106 Carp::croak ("no board size given!");
107 }
108
105 bless { 109 bless {
106 max => $size - 1, 110 max => $size - 1,
107 size => $size, 111 size => $size,
108 board => [map [(0) x $size], 1 .. $size], 112 board => [map [(0) x $size], 1 .. $size],
109 captures => [0, 0], # captures 113 captures => [0, 0], # captures
110 #timer => [], 114 #timer => [],
111 #score => [], 115 #score => [],
112 @_, 116 @_,
113 unmark => [],
114 }, $class 117 }, $class
115} 118}
116 119
117# inefficient and primitive, I hear you say? 120# inefficient and primitive, I hear you say?
118# well... you are right :) 121# well... you are right :)
127 130
128 my $max = $self->{max}; 131 my $max = $self->{max};
129 132
130 while (@nodes) { 133 while (@nodes) {
131 my ($x, $y) = @{pop @nodes}; 134 my ($x, $y) = @{pop @nodes};
135
132 unless ($seen{$x,$y}++) { 136 unless ($seen{$x,$y}++) {
133 if ($board->[$x][$y] & $mark) { 137 if ($board->[$x][$y] & $mark) {
134 push @found, [$x, $y]; 138 push @found, [$x, $y];
135 139
136 push @nodes, [$x-1, $y] unless $seen{$x-1, $y} || $x <= 0; 140 push @nodes, [$x-1, $y] unless $seen{$x-1, $y} || $x <= 0;
220 224
221 for (@$path) { 225 for (@$path) {
222 my ($x, $y, $clr, $set, $label) = @$_; 226 my ($x, $y, $clr, $set, $label) = @$_;
223 227
224 if (!defined $x) { 228 if (!defined $x) {
229 $$_ &= ~$mark_symbols for @{ delete $self->{unmark} || [] };
225 # pass 230 # pass
226 231
227 } elsif ($x == MOVE_HANDICAP) { 232 } elsif ($x == MOVE_HANDICAP) {
233 $$_ &= ~$mark_symbols for @{ delete $self->{unmark} || [] };
234
228 # $y = #handicap stones 235 # $y = #handicap stones
229 my $c = $HANDICAP_COORD{$self->{size}} 236 my $c = $HANDICAP_COORD{$self->{size}}
230 or Carp::croak "$self->{size}: illegal board size for handicap"; 237 or Carp::croak "$self->{size}: illegal board size for handicap";
231 my $h = $HANDICAP_XY{$y} 238 my $h = $HANDICAP_XY{$y}
232 or Carp::croak "$y: illegal number of handicap stones"; 239 or Carp::croak "$y: illegal number of handicap stones";
242 $$space = $$space & ~$clr | $set; 249 $$space = $$space & ~$clr | $set;
243 250
244 $self->{label}[$x][$y] = $label if $set & MARK_LABEL; 251 $self->{label}[$x][$y] = $label if $set & MARK_LABEL;
245 252
246 if ($set & MARK_MOVE) { 253 if ($set & MARK_MOVE) {
247 $$_ &= ~$mark_symbols for @{ $self->{unmark} }; 254 $$_ &= ~$mark_symbols for @{ $self->{unmark} || [] };
248 @{ $self->{unmark} } = $space; 255 @{ $self->{unmark} } = $space;
256
257 # remark the space, in case the move was on the same spot as the
258 # old mark
259 $$space |= $set;
249 260
250 unless (${ $_->[5] ||= \my $hint }) { 261 unless (${ $_->[5] ||= \my $hint }) {
251 my ($own, $opp) = 262 my ($own, $opp) =
252 $set & MARK_B 263 $set & MARK_B
253 ? (MARK_B, MARK_W) 264 ? (MARK_B, MARK_W)
254 : (MARK_W, MARK_B); 265 : (MARK_W, MARK_B);
255 266
256 my (@capture, $suicide); 267 my (@capture, @suicide);
257 268
258 push @capture, $self->capture ($opp, $x-1, $y) if $x > 0 && $board->[$x-1][$y] & $opp; 269 push @capture, $self->capture ($opp, $x-1, $y) if $x > 0 && $board->[$x-1][$y] & $opp;
259 push @capture, $self->capture ($opp, $x+1, $y) if $x < $self->{max} && $board->[$x+1][$y] & $opp; 270 push @capture, $self->capture ($opp, $x+1, $y) if $x < $self->{max} && $board->[$x+1][$y] & $opp;
260 push @capture, $self->capture ($opp, $x, $y-1) if $y > 0 && $board->[$x][$y-1] & $opp; 271 push @capture, $self->capture ($opp, $x, $y-1) if $y > 0 && $board->[$x][$y-1] & $opp;
261 push @capture, $self->capture ($opp, $x, $y+1) if $y < $self->{max} && $board->[$x][$y+1] & $opp; 272 push @capture, $self->capture ($opp, $x, $y+1) if $y < $self->{max} && $board->[$x][$y+1] & $opp;
266 # remove captured stones 277 # remove captured stones
267 $self->{captures}[$own == MARK_B ? COLOUR_BLACK : COLOUR_WHITE] += @capture; 278 $self->{captures}[$own == MARK_B ? COLOUR_BLACK : COLOUR_WHITE] += @capture;
268 $self->{board}[$_->[0]][$_->[1]] = 0 279 $self->{board}[$_->[0]][$_->[1]] = 0
269 for @capture; 280 for @capture;
270 281
271 $suicide += $self->capture ($own, $x, $y); 282 push @suicide, $self->capture ($own, $x, $y);
272 283
273 ${ $_->[5] } ||= !(@capture || $suicide); 284 ${ $_->[5] } ||= !(@capture || @suicide);
274 285
286 if (@suicide) {
287 $self->{board}[$_->[0]][$_->[1]] = 0
288 for @suicide;
289 # count suicides as other sides stones
290 $self->{captures}[$opp == MARK_B ? COLOUR_BLACK : COLOUR_WHITE] += @suicide;
291
275 if (!$suicide && @capture == 1) { 292 } elsif (!@suicide && @capture == 1) {
276 # possible ko. now check liberties on placed stone 293 # possible ko. now check liberties on placed stone
277 294
278 my $libs; 295 my $libs;
279 296
280 $libs++ if $x > 0 && !($board->[$x-1][$y] & $opp); 297 $libs++ if $x > 0 && !($board->[$x-1][$y] & $opp);
309sub is_valid_move { 326sub is_valid_move {
310 my ($self, $colour, $x, $y, $may_suicide) = @_; 327 my ($self, $colour, $x, $y, $may_suicide) = @_;
311 328
312 my $board = $self->{board}; 329 my $board = $self->{board};
313 330
314 return if $board->[$x][$y] & (MARK_B | MARK_W | MARK_KO); 331 return if $board->[$x][$y] & (MARK_B | MARK_W | MARK_KO)
332 && !($board->[$x][$y] & MARK_GRAYED);
315 333
316 if ($may_suicide) { 334 if ($may_suicide) {
317 return 1; 335 return 1;
318 } else { 336 } else {
319 my ($own, $opp) = $colour == COLOUR_BLACK 337 my ($own, $opp) = $colour == COLOUR_BLACK

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines