line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Games::Worms::Beeler; |
2
|
1
|
|
|
1
|
|
18077
|
use strict; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
68
|
|
3
|
1
|
|
|
1
|
|
6
|
use vars qw($Debug $VERSION @ISA); |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
83
|
|
4
|
1
|
|
|
1
|
|
8
|
use Games::Worms::Base 0.6; |
|
1
|
|
|
|
|
35
|
|
|
1
|
|
|
|
|
1084
|
|
5
|
|
|
|
|
|
|
@ISA = ('Games::Worms::Base'); |
6
|
|
|
|
|
|
|
$Debug = 0; |
7
|
|
|
|
|
|
|
$VERSION = "0.60"; |
8
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
my %let2num = qw(A 1 B 2 C 3 D 4); |
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
=head1 NAME |
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
Games::Worms::Beeler -- class for Conway/Patterson/Beeler worms |
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
=head1 SYNOPSIS |
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
perl -MGames::Worms -e worms -- -tTk Games::Worms::Beeler/1a2d3cbaa4b |
18
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
=head1 DESCRIPTION |
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
This class implements Conway/Patterson/Beeler worms -- "Beeler worms" |
22
|
|
|
|
|
|
|
for short. |
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
See the I reference in L. |
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
Note that my notation for rule-strings is directly taken from that |
27
|
|
|
|
|
|
|
article. |
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
=cut |
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
#-------------------------------------------------------------------------- |
32
|
|
|
|
|
|
|
# init rules. |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
sub init { |
35
|
0
|
|
|
0
|
0
|
|
my $worm = $_[0]; |
36
|
|
|
|
|
|
|
|
37
|
0
|
|
|
|
|
|
$worm->{'memory'} = {}; # for memoization |
38
|
|
|
|
|
|
|
|
39
|
0
|
|
0
|
|
|
|
$worm->{'rules'} ||= # default to a random rule |
40
|
|
|
|
|
|
|
join('', |
41
|
|
|
|
|
|
|
'1', (qw(A B))[rand 2], |
42
|
|
|
|
|
|
|
'2', (qw(A B C D))[rand 4], |
43
|
|
|
|
|
|
|
'3', (qw(A B C))[rand 3], (qw(A B C))[rand 3], |
44
|
|
|
|
|
|
|
(qw(A B C))[rand 3], (qw(A B C))[rand 3], |
45
|
|
|
|
|
|
|
'4', (qw(A B))[rand 2], |
46
|
|
|
|
|
|
|
); |
47
|
|
|
|
|
|
|
|
48
|
0
|
0
|
|
|
|
|
die "Rule string $worm->{'rules'} is malformed" |
49
|
|
|
|
|
|
|
unless uc($worm->{'rules'}) =~ |
50
|
|
|
|
|
|
|
/^1([AB]) |
51
|
|
|
|
|
|
|
2([ABCD]) |
52
|
|
|
|
|
|
|
3([ABC])([ABC])([ABC])([ABC]) |
53
|
|
|
|
|
|
|
4([AB]) |
54
|
|
|
|
|
|
|
$ |
55
|
|
|
|
|
|
|
/xs; |
56
|
0
|
|
|
|
|
|
@{$worm}{ |
57
|
0
|
|
|
|
|
|
qw(beeler_1 |
58
|
|
|
|
|
|
|
beeler_2 |
59
|
|
|
|
|
|
|
beeler_3a beeler_3b beeler_3c beeler_3d |
60
|
|
|
|
|
|
|
beeler_4 |
61
|
|
|
|
|
|
|
) |
62
|
|
|
|
|
|
|
} = map($let2num{$_}, $1, $2, $3, $4, $5, $6, $7); |
63
|
|
|
|
|
|
|
|
64
|
0
|
|
|
|
|
|
$worm->{'name'} .= '/' . $worm->{'rules'}; |
65
|
|
|
|
|
|
|
|
66
|
0
|
|
|
|
|
|
$worm->SUPER::init; |
67
|
0
|
|
|
|
|
|
return; |
68
|
|
|
|
|
|
|
} |
69
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
#-------------------------------------------------------------------------- |
71
|
|
|
|
|
|
|
# a necessary data table |
72
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
my %group3rules = ( # A B C |
74
|
|
|
|
|
|
|
'00111' => ['beeler_3a', [0,1,2]], |
75
|
|
|
|
|
|
|
'01011' => ['beeler_3a', [2,0,1]], |
76
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
'10011' => ['beeler_3b', [0,1,2]], |
78
|
|
|
|
|
|
|
'01110' => ['beeler_3b', [1,0,2]], |
79
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
'11001' => ['beeler_3c', [0,1,2]], |
81
|
|
|
|
|
|
|
'10101' => ['beeler_3c', [1,0,2]], |
82
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
'11100' => ['beeler_3d', [0,1,2]], |
84
|
|
|
|
|
|
|
'11010' => ['beeler_3d', [0,1,2]], |
85
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
# the two 'unnatural' cases: |
87
|
|
|
|
|
|
|
'01101' => ['beeler_3d', [0,1,2]], |
88
|
|
|
|
|
|
|
'10110' => ['beeler_3d', [0,1,2]], |
89
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
); |
92
|
|
|
|
|
|
|
|
93
|
|
|
|
|
|
|
#-------------------------------------------------------------------------- |
94
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
sub which_way { # figure out which direction to go in |
96
|
0
|
|
|
0
|
0
|
|
my($worm, $hash_r, $list_r, $context) = @_; |
97
|
|
|
|
|
|
|
|
98
|
0
|
|
|
|
|
|
my $situation = substr($context,1); |
99
|
|
|
|
|
|
|
|
100
|
0
|
0
|
|
|
|
|
return($worm->{'memory'}{$situation}) # memoization |
101
|
|
|
|
|
|
|
if exists $worm->{'memory'}{$situation}; |
102
|
|
|
|
|
|
|
|
103
|
0
|
|
|
|
|
|
my $rules = $worm->{'rules'}; |
104
|
0
|
0
|
|
|
|
|
die "No rules for worm $worm?\n" unless $rules; |
105
|
|
|
|
|
|
|
|
106
|
0
|
|
|
|
|
|
my $free_count = grep($_, @$list_r); |
107
|
0
|
|
|
|
|
|
my @avail = grep($list_r->[$_], (1,2,3,4,5)); |
108
|
0
|
0
|
|
|
|
|
print "% $free_count nodes free: $situation (@avail) | " if $Debug; |
109
|
|
|
|
|
|
|
|
110
|
0
|
|
|
|
|
|
my($rule, $dir); |
111
|
|
|
|
|
|
|
|
112
|
0
|
0
|
|
|
|
|
if($free_count >= 5) { $rule = 'beeler_1'; |
|
0
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
113
|
0
|
|
|
|
|
|
splice(@avail,0,3); # leaving just the last 2 |
114
|
0
|
|
|
|
|
|
} elsif($free_count == 2) { $rule = 'beeler_4'; |
115
|
0
|
|
|
|
|
|
} elsif($free_count == 4) { $rule = 'beeler_2'; |
116
|
|
|
|
|
|
|
} elsif($free_count == 3) { # Rule 3... |
117
|
0
|
|
0
|
|
|
|
my $sit_entry = $group3rules{$situation} |
118
|
|
|
|
|
|
|
|| die "Tilt! Unknown situation $situation\n"; |
119
|
0
|
|
|
|
|
|
$rule = $sit_entry->[0]; |
120
|
0
|
|
|
|
|
|
$dir = $avail[ |
121
|
|
|
|
|
|
|
$sit_entry->[1]->[ $worm->{$rule} - 1 ] |
122
|
|
|
|
|
|
|
]; |
123
|
|
|
|
|
|
|
} |
124
|
|
|
|
|
|
|
|
125
|
0
|
0
|
|
|
|
|
die "No deciding rule?" unless $rule; |
126
|
|
|
|
|
|
|
|
127
|
0
|
0
|
|
|
|
|
$dir = $avail[ $worm->{$rule} - 1] unless defined($dir); |
128
|
0
|
0
|
|
|
|
|
print " out of ", join('', @avail), |
129
|
|
|
|
|
|
|
", going R$dir via rule $rule (=", $worm->{$rule}, ")\n" |
130
|
|
|
|
|
|
|
if $Debug; |
131
|
|
|
|
|
|
|
|
132
|
0
|
|
|
|
|
|
return( $worm->{'memory'}{$situation} = $dir ); |
133
|
|
|
|
|
|
|
} |
134
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
#-------------------------------------------------------------------------- |
136
|
|
|
|
|
|
|
1; |
137
|
|
|
|
|
|
|
|
138
|
|
|
|
|
|
|
__END__ |