File Coverage

lib/BalanceOfPower/Role/Historian.pm
Criterion Covered Total %
statement 73 321 22.7
branch 12 58 20.6
condition 4 29 13.7
subroutine 13 29 44.8
pod 0 20 0.0
total 102 457 22.3


line stmt bran cond sub pod time code
1             package BalanceOfPower::Role::Historian;
2             $BalanceOfPower::Role::Historian::VERSION = '0.400115';
3 13     13   6027 use v5.10;
  13         37  
4 13     13   58 use strict;
  13         20  
  13         252  
5 13     13   47 use Moo::Role;
  13         19  
  13         80  
6 13     13   3018 use Term::ANSIColor;
  13         24  
  13         768  
7 13     13   53 use List::Util qw( min max );
  13         20  
  13         681  
8 13     13   54 use BalanceOfPower::Printer;
  13         36  
  13         246  
9 13     13   44 use Data::Dumper;
  13         28  
  13         613  
10              
11 13     13   61 use BalanceOfPower::Utils qw( get_year_turns as_title from_to_turns );
  13         15  
  13         619  
12 13     13   51 use BalanceOfPower::Constants ':all';
  13         18  
  13         41861  
13              
14             with 'BalanceOfPower::Role::Reporter';
15              
16             has statistics => (
17             is => 'rw',
18             default => sub { { "PLAYERS" => {} } }
19             );
20              
21             requires 'get_nation';
22             requires 'by_tags';
23              
24             sub get_statistics_value
25             {
26 2941     2941 0 2624 my $self = shift;
27 2941         2596 my $turn = shift;
28 2941         2565 my $object = shift;
29 2941         2413 my $value = shift;
30 2941   50     8254 my $type = shift || 'nation';
31 2941         2419 my $stats;
32 2941 50       3847 if($type eq 'nation')
    0          
33             {
34 2941         3907 $stats = $self->statistics;
35             }
36             elsif($type eq 'player')
37             {
38 0         0 $stats = $self->statistics->{'PLAYERS'}
39             }
40 2941 100 33     7008 if($turn && exists $stats->{$turn})
41             {
42 2736 50       3276 if($object)
43             {
44 2736         7218 return $stats->{$turn}->{$object}->{$value};
45             }
46             else
47             {
48 0         0 return $stats->{$turn}->{$value};
49             }
50             }
51             else
52             {
53 205         401 return undef;
54             }
55             }
56             sub set_statistics_value
57             {
58 2750     2750 0 2670 my $self = shift;
59 2750         2241 my $object = shift;
60 2750         2520 my $value_name = shift;
61 2750         2391 my $value = shift;
62 2750   100     8270 my $type = shift || 'nation';
63 2750 100       4237 if($type eq 'nation')
    50          
64             {
65 2720 100       3571 if($object)
66             {
67 2630         11675 $self->statistics->{$object->current_year}->{$object->name}->{$value_name} = $value;
68             }
69             else
70             {
71 90         388 $self->statistics->{$self->current_year}->{$value_name} = $value;
72             }
73             }
74             elsif($type eq 'player')
75             {
76 30 50       47 if($object)
77             {
78 30         214 $self->statistics->{'PLAYERS'}->{$object->current_year}->{$object->name}->{$value_name} = $value;
79             }
80             else
81             {
82 0         0 $self->statistics->{$self->current_year}->{$value_name} = $value;
83             }
84             }
85            
86             }
87              
88             sub print_nation_statistics
89             {
90 0     0 0 0 my $self = shift;
91 0         0 my $nation = shift;
92 0         0 my $first_turn = shift;
93 0         0 my $last_turn = shift;
94 0   0     0 my $mode = shift || 'print';
95 0         0 my $attributes_names = ["Size", "Prod.", "Wealth", "W/D", "Growth", "Disor.", "Army", "Prog.", "Pstg."];
96 0         0 my $attributes = ["production", "wealth", "w/d", "growth", "internal disorder", "army", "progress", "prestige"];
97 0         0 my %data = ();
98              
99 0         0 foreach my $t (from_to_turns($first_turn, $last_turn))
100             {
101 0         0 my @ndata = $self->get_nation_statistics_line($nation, $t, $attributes);
102 0         0 $data{$t} = \@ndata;
103             }
104 0         0 return BalanceOfPower::Printer::print($mode, $self, 'print_nation_statistics',
105             { nation => $nation,
106             attributes => $attributes_names,
107             statistics => \%data,
108             } );
109             }
110              
111             sub print_nation_graphs
112             {
113 0     0 0 0 my $self = shift;
114 0         0 my $nation = shift;
115 0         0 my $start_turn = shift;
116 0         0 my $depth = shift;
117 0   0     0 my $mode = shift || 'html';
118              
119 0         0 my @entities = ( "production", "w/d", "internal disorder", "army" );
120 0         0 my %data;
121 0         0 foreach my $e ( @entities )
122             {
123 0         0 my $out = "";
124 0         0 my $min = 10000;
125 0         0 my $turn = $start_turn;
126 0         0 for(my $step = 0; $step < $depth; $step++)
127             {
128 0         0 my $value = $self->get_statistics_value($turn, $nation, $e);
129 0 0       0 last if ! $value;
130 0         0 $out = ", ['$turn', $value]" . $out;
131 0         0 $turn = prev_turn($turn);
132 0 0       0 if($value < $min)
133             {
134 0         0 $min = $value;
135             }
136             }
137 0         0 $out = "['Turn', '$e']" . $out;
138 0         0 $data{$e} = $out;
139 0         0 $data{min}->{$e} = $min;
140             }
141 0         0 $data{'object'} = $nation;
142 0         0 $data{'entities'} = \@entities;
143 0         0 $data{'colors'} = { 'w/d' => '#00c87c',
144             'production' => '#0081c9',
145             'internal disorder' => '#d90d11',
146             'army' => '#736f6e' };
147            
148 0         0 return BalanceOfPower::Printer::print($mode, $self, 'print_graphs',
149             \%data );
150            
151             }
152             sub print_player_graphs
153             {
154 0     0 0 0 my $self = shift;
155 0         0 my $player = shift;
156 0         0 my $start_turn = shift;
157 0         0 my $depth = shift;
158 0   0     0 my $mode = shift || 'html';
159              
160 0         0 my @entities = ( "stock value", "money", "total value" );
161 0         0 my %data;
162 0         0 foreach my $e ( @entities )
163             {
164 0         0 my $out = "";
165 0         0 my $min = 10000;
166 0         0 my $turn = $start_turn;
167 0         0 for(my $step = 0; $step < $depth; $step++)
168             {
169 0         0 my $value = $self->get_statistics_value($turn, $player, $e, 'player');
170 0 0       0 last if ! $value;
171 0         0 $out = ", ['$turn', $value]" . $out;
172 0         0 $turn = prev_turn($turn);
173 0 0       0 if($value < $min)
174             {
175 0         0 $min = $value;
176             }
177             }
178 0         0 $out = "['Turn', '$e']" . $out;
179 0         0 $data{$e} = $out;
180 0         0 $data{min}->{$e} = $min;
181             }
182 0         0 $data{'object'} = $player;
183 0         0 $data{'entities'} = \@entities;
184 0         0 $data{'colors'} = { 'stock value' => '#00c87c',
185             'money' => '#0081c9',
186             'total value' => '#d90d11',
187             };
188            
189 0         0 return BalanceOfPower::Printer::print($mode, $self, 'print_graphs',
190             \%data );
191            
192             }
193              
194              
195              
196             sub print_nation_factor
197             {
198 0     0 0 0 my $self = shift;
199 0         0 my $nation = shift;
200 0         0 my $factor = shift;
201 0         0 my $first_turn = shift;
202 0         0 my $last_turn = shift;
203 0         0 my $out = as_title($nation . " - " . $factor . " - column of values" . "\n===\n");
204 0         0 foreach my $t (from_to_turns($first_turn, $last_turn))
205             {
206 0 0       0 if(defined $self->get_statistics_value($t, $nation, $factor))
207             {
208 0         0 $out .= $self->get_statistics_value($t, $nation, $factor) . "\n";
209             }
210             else
211             {
212 0         0 $out .= "*** UNAVAILABLE ***" . "\n";
213             }
214             }
215 0         0 return $out;
216             }
217              
218             sub plot_nation_factor
219             {
220 0     0 0 0 my $self = shift;
221 0         0 my $nation = shift;
222 0         0 my $factor = shift;
223 0         0 my $first_turn = shift;
224 0         0 my $last_turn = shift;
225            
226 0         0 my $graph_height = 12;
227              
228 0         0 my @data = ();
229 0         0 my $valid = 0;
230 0         0 foreach my $t (from_to_turns($first_turn, $last_turn))
231             {
232 0 0       0 if(defined $self->get_statistics_value($t, $nation, $factor))
233             {
234 0         0 push @data, $self->get_statistics_value($t, $nation, $factor);
235 0         0 $valid = 1;
236             }
237             else
238             {
239 0         0 push @data, undef;
240             }
241             }
242 0 0       0 return "" if(! $valid);
243 0         0 my $min = min @data;
244 0         0 my $max = max @data;
245 0         0 my $step = ($max - $min) / $graph_height;
246 0         0 my @lines = ();
247 0         0 my $out = as_title($nation . " - " . $factor . " - graph " . "\n===\n");
248 0         0 $out .= "Min. value: $min Max. value: $max\n\n";
249 0         0 for(my $i = 0; $i <= $graph_height; $i++)
250             {
251 0         0 $lines[$i] = "";
252 0         0 my $level = $step * ( $graph_height - $i);
253 0         0 for(@data)
254             {
255 0         0 my $v = $_;
256 0 0       0 if(! $v)
257             {
258 0         0 $lines[$i] .= " ";
259             }
260             else
261             {
262             #if(($v - $min) < $step * ( $graph_height - ($i-1)) &&
263 0 0       0 if(($v - $min) >= $level)
264             {
265 0         0 $lines[$i] .= "o";
266             }
267             else
268             {
269 0         0 $lines[$i] .= " ";
270             }
271             }
272             }
273 0         0 my $level_label = int($level * 100) / 100 + $min;
274 0         0 $out .= $lines[$i] . "...$level_label" ."\n";
275             }
276 0         0 return $out . "\n";
277             }
278              
279              
280             sub print_nation_statistics_header
281             {
282 0     0 0 0 if(DEBT_ALLOWED)
283             {
284             return "Size\tProd.\tWealth\tW/D\tGrowth\tDebt\tDisor.\tArmy\tProg.\tPstg.";
285             }
286             else
287             {
288 0         0 return "Size\tProd.\tWealth\tW/D\tGrowth\tDisor.\tArmy\tProg.\tPstg.";
289             }
290             }
291             sub get_nation_statistics_line
292             {
293 1     1 0 2 my $self = shift;
294 1         1 my $nation = shift;
295 1         2 my $y = shift;
296 1         2 my $characteristics = shift;
297 1         2 my @out = ();
298 1         3 push @out, $self->get_nation($nation)->size;
299 1         1 for(@{$characteristics})
  1         3  
300             {
301 8         12 push @out, $self->get_statistics_value($y, $nation, $_);
302             }
303 1         5 return @out;
304             }
305             sub print_nation_statistics_line
306             {
307 0     0 0 0 my $self = shift;
308 0         0 my $nation = shift;
309 0         0 my $y = shift;
310 0         0 my $out = "";
311 0         0 $out .= $self->get_nation($nation)->size . "\t";
312 0 0       0 if(! defined $self->get_statistics_value($y, $nation, 'production'))
313             {
314 0         0 $out .= "### no statistics available ###";
315 0         0 return $out;
316             }
317 0         0 $out .= $self->get_statistics_value($y, $nation, 'production') . "\t";
318 0         0 $out .= $self->get_statistics_value($y, $nation, 'wealth') . "\t";
319 0         0 $out .= $self->get_statistics_value($y, $nation, 'w/d') . "\t";
320 0         0 $out .= $self->get_statistics_value($y, $nation, 'growth') . "\t";
321 0         0 if(DEBT_ALLOWED)
322             {
323             $out .= $self->get_statistics_value($y, $nation, 'debt') . "\t";
324             }
325 0         0 $out .= $self->get_statistics_value($y, $nation, 'internal disorder') . "\t";
326 0         0 $out .= $self->get_statistics_value($y, $nation, 'army') . "\t";
327 0         0 $out .= $self->get_statistics_value($y, $nation, 'progress') . "\t";
328 0         0 $out .= $self->get_statistics_value($y, $nation, 'prestige') . "\t";
329 0         0 return $out;
330             }
331              
332              
333              
334             sub print_formatted_turn_events
335             {
336 0     0 0 0 my $self = shift;
337 0         0 my $y = shift;
338 0         0 my $title = shift;
339 0   0     0 my $mode = shift || 'print';
340 0         0 my $out = "";
341 0         0 $out .= $self->print_turn_events($y, $title, 0, $mode);
342 0         0 return $out;
343             }
344              
345             sub print_nation_events
346             {
347 0     0 0 0 my $self = shift;
348 0         0 my $nation_name = shift;
349 0         0 my $y = shift;
350 0         0 my $title = shift;
351 0   0     0 my $mode = shift || 'print';
352 0         0 my $nation = $self->get_nation($nation_name);
353 0         0 return $nation->print_turn_events($y, $title, 3, $mode);
354             }
355              
356             sub print_turn_statistics
357             {
358 0     0 0 0 my $self = shift;
359 0         0 my $y = shift;
360 0         0 my $order = shift;
361 0   0     0 my $mode = shift || 'print';
362 0         0 my @nations = @{$self->nation_names};
  0         0  
363 0         0 my $attributes_names = ["Size", "Prod.", "Wealth", "W/D", "Disor.", "Army", "Prog.", "Pstg."];
364 0         0 my $attributes = ["production", "wealth", "w/d", "internal disorder", "army", "progress", "prestige"];
365 0         0 my %data = ();
366 0         0 my @names;
367 0 0       0 if($order)
368             {
369 0         0 my @ordered = $self->order_statistics($y, lc $order);
370 0         0 for(@ordered)
371             {
372 0         0 push @names, $_->{nation};
373             }
374             }
375             else
376             {
377 0         0 @names = @nations;
378             }
379 0         0 for(@names)
380             {
381 0         0 my @ndata = $self->get_nation_statistics_line($_, $y, $attributes);
382 0         0 $data{$_} = \@ndata;
383             }
384 0         0 return BalanceOfPower::Printer::print($mode, $self, 'print_turn_statistics',
385             { year => $y,
386             order => $order,
387             attributes => $attributes_names,
388             statistics => \%data,
389             names => \@names, });
390             }
391              
392             sub print_overall_statistics
393             {
394 0     0 0 0 my $self =shift;
395 0         0 my $first_year = shift;
396 0         0 my $last_year = shift;
397 0         0 my @nations = @{$self->nation_names};
  0         0  
398 0         0 my $out = "Overall medium values\n";
399 0         0 $out .= "Year\tProd.\tWealth\tInt.Dis\n";
400 0         0 foreach my $y ($first_year..$last_year)
401             {
402 0         0 foreach my $t (get_year_turns($y))
403             {
404 0         0 my ($prod, $wealth, $disorder) = $self->medium_statistics($t, @nations);
405 0         0 $out .= "$y\t$prod\t$wealth\t$disorder\n";
406             }
407             }
408 0         0 return $out;
409             }
410             sub medium_statistics
411             {
412 0     0 0 0 my $self = shift;
413 0         0 my $year = shift;
414 0         0 my @nations = @{$self->nation_names};
  0         0  
415 0         0 my $total_production = 0;
416 0         0 my $total_wealth = 0;
417 0         0 my $total_disorder = 0;
418 0         0 foreach my $t (get_year_turns($year))
419             {
420 0         0 foreach my $n (@nations)
421             {
422 0         0 $total_production += $self->get_statistics_value($t, $n, 'production');
423 0         0 $total_wealth += $self->get_statistics_value($t, $n, 'wealth');
424 0         0 $total_disorder += $self->get_statistics_value($t, $n, 'internal disorder');
425             }
426             }
427 0         0 my $medium_production = int(($total_production / @nations)*100)/100;
428 0         0 my $medium_wealth = int(($total_wealth / @nations)*100)/100;
429 0         0 my $medium_disorder = int(($total_disorder / @nations)*100)/100;
430 0         0 return ($medium_production, $medium_wealth, $medium_disorder);
431             }
432              
433             sub order_statistics
434             {
435 535     535 0 596 my $self = shift;
436 535         568 my $turn = shift;
437 535         501 my $value = shift;
438 535         508 my @nations = @{$self->nation_names};
  535         1747  
439 535         557 my @ordered;
440 535         749 foreach my $n (@nations)
441             {
442 2008         3074 my $val = $self->get_statistics_value($turn, $n, $value);
443 2008 100       3454 if(! defined $val)
444             {
445 149         423 return ();
446             }
447 1859         4362 push @ordered, { nation => $n, value => $val };
448             }
449 386         1114 @ordered = sort { $b->{value} <=> $a->{value} } @ordered;
  2944         3314  
450 386         1367 return @ordered;
451             }
452              
453             sub print_defcon_statistics
454             {
455 0     0 0   my $self = shift;
456 0           my $first_year = shift;
457 0           my $last_year = shift;
458 0           my $out = "Year\tCrises\tWars\n";
459 0           foreach my $y ($first_year..$last_year)
460             {
461 0           foreach my $t (get_year_turns($y))
462             {
463 0           my $crises = $self->get_statistics_value($t, undef, 'crises');
464 0           my $wars = $self->get_statistics_value($t, undef, 'wars');
465 0           $out .= "$t\t$crises\t$wars\n";
466             }
467             }
468 0           return $out;
469             }
470              
471             sub print_newspaper
472             {
473 0     0 0   my $self = shift;
474 0           my $y = shift;
475 0           my $title = shift;
476 0   0       my $mode = shift || 'print';
477 0 0         return "" if(! exists $self->events->{$y});
478 0           my @ignored = ('traderefused', 'tradelack', 'wargoon', 'pressure', 'crisisstart', 'crisisup', 'crisisdown', 'crisisend', 'supfailed', 'rebsupfailed', 'progress', 'hatetreaty', 'limittreaty', 'uselesstreaty', 'lowerdisorder', 'disorderchange', 'acquireprogress', 'occupy', 'domintate', 'control', 'crisisescalate', 'nopartecipatewar',
479             );
480 0           my @managed = ('bestprogress', 'bestwealth', 'tradedeleted', 'tradeadded', 'relchange', 'militaryaid', 'insurgentsaid', 'economicaid', 'supincreased', 'supstarted', 'supstopped', 'supdestroyed', 'suprefused', 'rebsupincreased', 'rebsupstarted','rebsupstopped', 'comtreatynew', 'nagtreatynew', 'alliancetreatynew', 'comtreatybroken', 'nagtreatybroken', 'alltreatybroken', 'govwincivil', 'rebwincivil', 'civiloutbreak' );
481 0           my @war_events = ('warstart', 'warlinkedstart', 'warend');
482 0           my @generic = ();
483 0           my %events = $self->by_tags(@{$self->events->{$y}});
  0            
484 0           my %wars = ();
485 0           foreach my $key (keys %events)
486             {
487 0 0         if(grep { $_ eq $key } @ignored)
  0 0          
    0          
488             {
489 0           delete $events{$key};
490             }
491 0           elsif(grep { $_ eq $key } @managed)
492             {
493             #No action needed
494             }
495 0           elsif(grep { $_ eq $key } @war_events)
496             {
497 0           foreach my $e (@{$events{$key}})
  0            
498             {
499 0           my $war_id = $e->{values}->[0];
500 0 0         if($key eq 'warstart')
    0          
    0          
501             {
502 0           $wars{$war_id}->{'warstart'} = $e;
503             }
504             elsif($key eq 'warlinkedstart')
505             {
506 0 0 0       if(exists $wars{$war_id} && exists $wars{$war_id}->{'warlinkedstart'})
507             {
508 0           push @{ $wars{$war_id}->{'warlinkedstart'} }, $e;
  0            
509             }
510             else
511             {
512 0           $wars{$war_id}->{'warlinkedstart'} = [ $e ];
513             }
514             }
515             elsif($key eq 'warend')
516             {
517 0 0 0       if(exists $wars{$war_id} && exists $wars{$war_id}->{'warend'})
518             {
519 0           push @{ $wars{$war_id}->{'warend'} }, $e;
  0            
520             }
521             else
522             {
523 0           $wars{$war_id}->{'warend'} = [ $e ];
524             }
525            
526             }
527             }
528            
529             }
530             else
531             {
532 0           @generic = (@generic, @{$events{$key}});
  0            
533             }
534             }
535 0           $events{'others'} = \@generic;
536 0           $events{'wars'} = \%wars;
537 0           return BalanceOfPower::Printer::print($mode, $self, 'print_newspaper',
538             { title => $title,
539             turn => $y,
540             events => \%events });
541             }
542              
543             sub dump_statistics
544             {
545 0     0 0   my $self = shift;
546 0           my $io = shift;
547 0   0       my $indent = shift || "";
548 0           my $dump = Data::Dumper->new([$self->statistics]);
549 0           $dump->Indent(0);
550 0           print {$io} $indent . $dump->Dump . "\n";
  0            
551             }
552             sub load_statistics
553             {
554 0     0 0   my $self = shift;
555 0           my $data = shift;
556 0           my $VAR1;
557 0           eval ( $data );
558 0           $self->statistics($VAR1);
559             }
560              
561              
562             1;
563              
564              
565              
566