line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
#!/usr/bin/perl |
2
|
|
|
|
|
|
|
# Copyright (C) 2009-2021 Alex Schroeder |
3
|
|
|
|
|
|
|
# Copyright (C) 2020 Christian Carey |
4
|
|
|
|
|
|
|
# |
5
|
|
|
|
|
|
|
# This program is free software: you can redistribute it and/or modify it under |
6
|
|
|
|
|
|
|
# the terms of the GNU General Public License as published by the Free Software |
7
|
|
|
|
|
|
|
# Foundation, either version 3 of the License, or (at your option) any later |
8
|
|
|
|
|
|
|
# version. |
9
|
|
|
|
|
|
|
# |
10
|
|
|
|
|
|
|
# This program is distributed in the hope that it will be useful, but WITHOUT |
11
|
|
|
|
|
|
|
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
12
|
|
|
|
|
|
|
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. |
13
|
|
|
|
|
|
|
# |
14
|
|
|
|
|
|
|
# You should have received a copy of the GNU General Public License along with |
15
|
|
|
|
|
|
|
# this program. If not, see . |
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
package Traveller::Subsector; |
18
|
2
|
|
|
2
|
|
12
|
use List::Util qw(shuffle); |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
144
|
|
19
|
2
|
|
|
2
|
|
375
|
use Traveller::Util qw(nearby in); |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
92
|
|
20
|
2
|
|
|
2
|
|
779
|
use Traveller::System::Classic::MPTS; |
|
2
|
|
|
|
|
5
|
|
|
2
|
|
|
|
|
19
|
|
21
|
2
|
|
|
2
|
|
66
|
use Traveller::System::Classic; |
|
2
|
|
|
|
|
3
|
|
|
2
|
|
|
|
|
10
|
|
22
|
2
|
|
|
2
|
|
44
|
use Traveller::System; |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
8
|
|
23
|
2
|
|
|
2
|
|
51
|
use Mojo::Base -base; |
|
2
|
|
|
|
|
3
|
|
|
2
|
|
|
|
|
6
|
|
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
has 'systems' => sub { [] }; |
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
sub one { |
28
|
2538
|
|
|
2538
|
0
|
3550
|
my $i = int(rand(scalar @_)); |
29
|
2538
|
|
|
|
|
4392
|
return $_[$i]; |
30
|
|
|
|
|
|
|
} |
31
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
sub compute_digraphs { |
33
|
64
|
|
|
64
|
0
|
645
|
my @first = qw(b c d f g h j k l m n p q r s t v w x y z . |
34
|
|
|
|
|
|
|
sc ng ch gh ph rh sh th wh zh wr qu |
35
|
|
|
|
|
|
|
st sp tr tw fl dr pr dr); |
36
|
|
|
|
|
|
|
# make missing vowel rare |
37
|
64
|
|
|
|
|
360
|
my @second = qw(a e i o u a e i o u a e i o u .); |
38
|
64
|
|
|
|
|
131
|
my @d; |
39
|
64
|
|
|
|
|
237
|
for (1 .. 10+rand(20)) { |
40
|
1269
|
|
|
|
|
2152
|
push(@d, one(@first)); |
41
|
1269
|
|
|
|
|
1898
|
push(@d, one(@second)); |
42
|
|
|
|
|
|
|
} |
43
|
64
|
|
|
|
|
408
|
return \@d; |
44
|
|
|
|
|
|
|
} |
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
sub add { |
47
|
1283
|
|
|
1283
|
0
|
2219
|
my ($self, $system) = @_; |
48
|
1283
|
|
|
|
|
1607
|
push(@{$self->systems}, $system); |
|
1283
|
|
|
|
|
2275
|
|
49
|
|
|
|
|
|
|
} |
50
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
sub init { |
52
|
2
|
|
|
2
|
0
|
2053
|
my ($self, $width, $height, $rules, $density) = @_; |
53
|
2
|
|
50
|
|
|
9
|
$density ||= 0.5; |
54
|
2
|
|
|
|
|
11
|
my $digraphs = $self->compute_digraphs; |
55
|
2
|
|
50
|
|
|
17
|
$width //= 8; |
56
|
2
|
|
50
|
|
|
9
|
$height //= 10; |
57
|
2
|
|
|
|
|
7
|
for my $x (1..$width) { |
58
|
64
|
|
|
|
|
241
|
for my $y (1..$height) { |
59
|
2560
|
100
|
|
|
|
9530
|
if (rand() < $density) { |
60
|
1283
|
|
|
|
|
1616
|
my $system; |
61
|
1283
|
50
|
|
|
|
2705
|
if ($rules eq 'mpts') { |
|
|
50
|
|
|
|
|
|
62
|
0
|
|
|
|
|
0
|
$system = Traveller::System::Classic::MPTS->new(); |
63
|
|
|
|
|
|
|
} elsif ($rules eq 'ct') { |
64
|
0
|
|
|
|
|
0
|
$system = Traveller::System::Classic->new(); |
65
|
|
|
|
|
|
|
} else { |
66
|
1283
|
|
|
|
|
3100
|
$system = Traveller::System->new(); |
67
|
|
|
|
|
|
|
} |
68
|
1283
|
|
|
|
|
7903
|
$self->add($system->init($x, $y, $digraphs)); |
69
|
|
|
|
|
|
|
} |
70
|
|
|
|
|
|
|
} |
71
|
|
|
|
|
|
|
} |
72
|
|
|
|
|
|
|
# Rename some systems: assume a jump-2 and a jump-1 culture per every |
73
|
|
|
|
|
|
|
# subsector of 8×10×½ systems. Go through the list in random order. |
74
|
2
|
|
|
|
|
10
|
for my $system (shuffle(grep { rand(20) < 1 } @{$self->systems})) { |
|
1283
|
|
|
|
|
1973
|
|
|
2
|
|
|
|
|
9
|
|
75
|
62
|
|
|
|
|
873
|
$self->spread( |
76
|
|
|
|
|
|
|
$system, |
77
|
|
|
|
|
|
|
$self->compute_digraphs, |
78
|
|
|
|
|
|
|
1 + int(rand(2)), # jump distance |
79
|
|
|
|
|
|
|
1 + int(rand(3))); # jump number |
80
|
|
|
|
|
|
|
} |
81
|
2
|
|
|
|
|
44
|
return $self; |
82
|
|
|
|
|
|
|
} |
83
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
sub spread { |
85
|
62
|
|
|
62
|
0
|
189
|
my ($self, $system, $digraphs, $jump_distance, $jump_number) = @_; |
86
|
62
|
|
|
|
|
249
|
my $culture = $system->compute_name($digraphs); |
87
|
|
|
|
|
|
|
# warn sprintf("%02d%02d %s %d %d\n", $system->x, $system->y, $culture, $jump_distance, $jump_number); |
88
|
62
|
|
|
|
|
192
|
my $network = [$system]; |
89
|
62
|
|
|
|
|
254
|
$self->grow($system, $jump_distance, $jump_number, $network); |
90
|
62
|
|
|
|
|
228
|
for my $other (@$network) { |
91
|
1437
|
|
|
|
|
9164
|
$other->culture($culture); |
92
|
1437
|
|
|
|
|
8413
|
$other->name($other->compute_name($digraphs)); |
93
|
|
|
|
|
|
|
} |
94
|
|
|
|
|
|
|
} |
95
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
sub grow { |
97
|
715
|
|
|
715
|
0
|
1962
|
my ($self, $system, $jump_distance, $jump_number, $network) = @_; |
98
|
|
|
|
|
|
|
my @new_neighbours = |
99
|
1830
|
100
|
|
|
|
10065
|
grep { not $_->culture or int(rand(2)) } |
100
|
715
|
|
|
|
|
2293
|
grep { not Traveller::Util::in($_, @$network) } |
|
5485
|
|
|
|
|
12290
|
|
101
|
|
|
|
|
|
|
$self->neighbours($system, $jump_distance, $jump_number); |
102
|
|
|
|
|
|
|
# for my $neighbour (@new_neighbours) { |
103
|
|
|
|
|
|
|
# warn sprintf(" added %02d%02d %d %d\n", $neighbour->x, $neighbour->y, $jump_distance, $jump_number); |
104
|
|
|
|
|
|
|
# } |
105
|
715
|
|
|
|
|
5066
|
push(@$network, @new_neighbours); |
106
|
715
|
100
|
|
|
|
2650
|
if ($jump_number > 0) { |
107
|
363
|
|
|
|
|
876
|
for my $neighbour (@new_neighbours) { |
108
|
653
|
|
|
|
|
2432
|
$self->grow($neighbour, $jump_distance, $jump_number - 1, $network); |
109
|
|
|
|
|
|
|
} |
110
|
|
|
|
|
|
|
} |
111
|
|
|
|
|
|
|
} |
112
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
sub neighbours { |
114
|
715
|
|
|
715
|
0
|
1643
|
my ($self, $system, $jump_distance, $jump_number) = @_; |
115
|
715
|
|
|
|
|
2501
|
my @neighbours = nearby($system, $jump_distance, $self->systems); |
116
|
715
|
|
|
|
|
3071
|
return @neighbours; |
117
|
|
|
|
|
|
|
} |
118
|
|
|
|
|
|
|
|
119
|
|
|
|
|
|
|
sub str { |
120
|
2
|
|
|
2
|
0
|
10
|
my $self = shift; |
121
|
2
|
|
|
|
|
6
|
my $subsector; |
122
|
2
|
|
|
|
|
4
|
foreach my $system (@{$self->systems}) { |
|
2
|
|
|
|
|
11
|
|
123
|
1283
|
|
|
|
|
2625
|
$subsector .= $system->str . "\n"; |
124
|
|
|
|
|
|
|
} |
125
|
2
|
|
|
|
|
158
|
return $subsector; |
126
|
|
|
|
|
|
|
} |
127
|
|
|
|
|
|
|
|
128
|
|
|
|
|
|
|
1; |