File: | blib/lib/Language/Homespring/Salmon.pm |
Coverage: | 94.7% |
line | stmt | bran | cond | sub | time | code |
---|---|---|---|---|---|---|
1 | package Language::Homespring::Salmon; | |||||
2 | ||||||
3 | $VERSION = 0.02; | |||||
4 | ||||||
5 | 4 4 4 | 17 10 18 | use warnings; | |||
6 | 4 4 4 | 25 7 17 | use strict; | |||
7 | ||||||
8 | my $salmon_count = 0; | |||||
9 | ||||||
10 | sub new { | |||||
11 | 187 | 432 | my $class = shift; | |||
12 | 187 | 593 | my $self = bless {}, $class; | |||
13 | ||||||
14 | 187 | 415 | my $options = shift; | |||
15 | 187 | 615 | $self->{interp} = $options->{interp}; | |||
16 | 187 | 1092 | $self->{value} = $options->{value} || 'homeless'; | |||
17 | 187 | 1002 | $self->{upstream} = $options->{upstream} || 0; | |||
18 | 187 | 957 | $self->{mature} = $options->{mature} || 0; | |||
19 | 187 | 579 | $self->{location} = $options->{location}; | |||
20 | 187 | 462 | $self->{time_in_river} = 0; | |||
21 | 187 | 489 | $self->{uid} = ++$salmon_count; | |||
22 | ||||||
23 | #print "Creating salmon : ".$self->debug()."\n"; | |||||
24 | ||||||
25 | 187 | 522 | return $self; | |||
26 | } | |||||
27 | ||||||
28 | sub move { | |||||
29 | 338 | 828 | my ($self) = @_; | |||
30 | 338 | 657 | my ($node_to_pass, $river_target); | |||
31 | ||||||
32 | 338 | 996 | if ($self->{upstream}){ | |||
33 | 90 | 276 | $node_to_pass = $self->{location}->{up_node}; | |||
34 | 90 | 166 | $river_target = undef; | |||
35 | 90 | 245 | if ($node_to_pass){ | |||
36 | 90 90 | 141 271 | my $count = scalar(@{$node_to_pass->{rivers_up}}); | |||
37 | 90 | 264 | if ($count){ | |||
38 | 11 11 | 21 40 | $river_target = @{$node_to_pass->{rivers_up}}[0]; | |||
39 | } | |||||
40 | } | |||||
41 | }else{ | |||||
42 | 248 | 772 | $node_to_pass = $self->{location}->{down_node}; | |||
43 | 248 | 632 | $river_target = $node_to_pass->{river_down}; | |||
44 | } | |||||
45 | ||||||
46 | 338 | 764 | $self->{time_in_river}++; | |||
47 | ||||||
48 | ## | |||||
49 | ## see if we can pass the next node | |||||
50 | ## | |||||
51 | ||||||
52 | 338 | 818 | my $node_name = $node_to_pass->{node_name}; | |||
53 | ||||||
54 | 338 | 1907 | return if (($node_to_pass->{node_name} eq 'shallows') && ($self->{mature}) && ($self->{time_in_river} == 1)); | |||
55 | 335 | 1839 | return if (($node_to_pass->{node_name} eq 'rapids') && (!$self->{mature}) && ($self->{time_in_river} == 1)); | |||
56 | ||||||
57 | 332 | 1508 | return if (($node_to_pass->{node_name} eq 'net') && ($self->{mature})); | |||
58 | 326 | 1461 | return if (($node_to_pass->{node_name} eq 'current') && (!$self->{mature})); | |||
59 | ||||||
60 | 323 | 1538 | if (($node_to_pass->{node_name} eq 'bear') && ($self->{mature})){ | |||
61 | 19 | 54 | $self->kill(); | |||
62 | 19 | 83 | return; | |||
63 | } | |||||
64 | ||||||
65 | 304 | 1354 | if (($node_to_pass->{node_name} eq 'young bear') && ($self->{mature})){ | |||
66 | 4 | 15 | if ($node_to_pass->every_other()){ | |||
67 | 2 | 6 | $self->kill(); | |||
68 | 2 | 9 | return; | |||
69 | } | |||||
70 | } | |||||
71 | ||||||
72 | 302 | 1358 | if (($node_to_pass->{node_name} eq 'bird') && (!$self->{mature})){ | |||
73 | 2 | 5 | $self->kill(); | |||
74 | 2 | 7 | return; | |||
75 | } | |||||
76 | ||||||
77 | 300 | 1413 | if (($node_to_pass->{node_name} eq 'force field') && ($node_to_pass->{power})){ | |||
78 | 15 | 45 | if ($self->{upstream}){ | |||
79 | 5 | 15 | $self->spawn($node_to_pass); | |||
80 | }else{ | |||||
81 | 10 | 38 | return; | |||
82 | } | |||||
83 | } | |||||
84 | ||||||
85 | ## | |||||
86 | ## do we have a new river to swim into? | |||||
87 | ## | |||||
88 | ||||||
89 | 290 | 730 | if (defined($river_target)){ | |||
90 | ||||||
91 | 147 | 358 | $self->{location} = $river_target; | |||
92 | 147 | 720 | $self->{time_in_river} = 0; | |||
93 | ||||||
94 | }else{ | |||||
95 | ||||||
96 | # if there's nowhere to go, | |||||
97 | # either spawn or print | |||||
98 | ||||||
99 | 143 | 431 | if ($self->{upstream}){ | |||
100 | 79 | 233 | $self->spawn($node_to_pass); | |||
101 | }else{ | |||||
102 | 64 | 177 | $self->output(); | |||
103 | } | |||||
104 | } | |||||
105 | ||||||
106 | } | |||||
107 | ||||||
108 | sub spawn { | |||||
109 | 84 | 220 | my ($self, $spring) = @_; | |||
110 | ||||||
111 | #print "spawning in river ".$self->{location}->{uid}." from node ".$spring->debug()."\n"; | |||||
112 | ||||||
113 | 84 | 332 | my $value = ($spring->{spring})?$spring->{node_name}:'nameless'; | |||
114 | 84 | 655 | my $new_salmon = new Language::Homespring::Salmon({ | |||
115 | 'interp' => $self->{interp}, | |||||
116 | 'value' => $value, | |||||
117 | 'upstream' => 0, | |||||
118 | 'mature' => 0, | |||||
119 | 'location' => $self->{location}, | |||||
120 | }); | |||||
121 | 84 84 | 207 332 | push @{$self->{interp}->{new_salmon}}, $new_salmon; | |||
122 | 84 | 214 | $self->{upstream} = 0; | |||
123 | 84 | 428 | $self->{mature} = 1; | |||
124 | } | |||||
125 | ||||||
126 | sub output { | |||||
127 | 64 | 159 | my ($self) = @_; | |||
128 | 64 | 243 | $self->{interp}->{output} .= $self->{value}; | |||
129 | 64 | 169 | $self->kill(); | |||
130 | } | |||||
131 | ||||||
132 | sub kill { | |||||
133 | 87 | 203 | my ($self) = @_; | |||
134 | 87 | 217 | $self->{value} = 'DEAD'; | |||
135 | 87 87 | 140 546 | push @{$self->{interp}->{dead_salmon}}, $_; | |||
136 | } | |||||
137 | ||||||
138 | sub debug { | |||||
139 | 0 | my ($self) = @_; | ||||
140 | ||||||
141 | 0 | return "salmon $self->{uid} in river ".$self->{location}->{uid}." (" | ||||
142 | .(($self->{mature})?'mature':'young') | |||||
143 | .") swimming " | |||||
144 | .(($self->{upstream})?'upsteam':'downstream') | |||||
145 | ."\n"; | |||||
146 | ||||||
147 | } | |||||
148 | ||||||
149 | 1; | |||||
150 |