File Coverage

lib/Game/TextMapper/Command/random.pm
Criterion Covered Total %
statement 28 33 84.8
branch 7 12 58.3
condition 2 2 100.0
subroutine 6 6 100.0
pod 1 1 100.0
total 44 54 81.4


line stmt bran cond sub pod time code
1             # Copyright (C) 2009-2021 Alex Schroeder
2             #
3             # This program is free software: you can redistribute it and/or modify it under
4             # the terms of the GNU Affero General Public License as published by the Free
5             # Software Foundation, either version 3 of the License, or (at your option) any
6             # later version.
7             #
8             # This program is distributed in the hope that it will be useful, but WITHOUT
9             # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
10             # FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
11             # details.
12             #
13             # You should have received a copy of the GNU Affero General Public License along
14             # with this program. If not, see .
15              
16             =head1 NAME
17              
18             Game::TextMapper::Command::random
19              
20             =head1 SYNOPSIS
21              
22             text-mapper random [algorithm] [options]
23             text-mapper random help
24              
25             =head1 DESCRIPTION
26              
27             This prints a random map description to STDOUT.
28              
29             text-mapper random | text-mapper render > map.svg
30              
31             =head1 OPTIONS
32              
33             C prints the man page.
34              
35             The algorithm can be any module that Perl can load using C. By default,
36             these are the ones:
37              
38             =over
39              
40             =item * L
41              
42             =item * L
43              
44             =item * L (needs role)
45              
46             =item * L (needs role)
47              
48             =item * L
49              
50             =item * L
51              
52             =item * L
53              
54             =back
55              
56             The default algorithm is L.
57              
58             Valid options depend on the algorithm. If an algorithm needs a role, you can
59             provide it using the C<--role> option.
60              
61             text-mapper random Game::TextMapper::Schroeder::Alpine \
62             --role Game::TextMapper::Schroeder::Hex
63              
64             If you don't do this, you'll get errors such as:
65              
66             Can't locate object method "random_neighbor" via package ...
67              
68             That's because C must differ depending on whether we are
69             looking at a hex map (6) or a square map (4).
70              
71             The two roles currently used:
72              
73             =over
74              
75             =item * L
76              
77             =item * L
78              
79             =back
80              
81             =head1 DEVELOPING YOUR OWN
82              
83             The algorithm modules must be classes one instantiates using C and they
84             must provide a method called C that returns a string.
85              
86             Assume you write your own, and put it in the F<./lib> directory, called
87             F. Here is a sample implementation. It uses L to make it
88             a class.
89              
90             package Arrakis;
91             use Modern::Perl;
92             use Mojo::Base -base;
93             sub generate_map {
94             for my $x (0 .. 10) {
95             for my $y (0 .. 10) {
96             printf("%02d%02d dust desert\n", $x, $y);
97             }
98             }
99             say "include gnomeyland.txt";
100             }
101             1;
102              
103             Since the lib directory is in @INC when called via F, you run it
104             like this:
105              
106             text-mapper random Arrakis | text-mapper render > map.svg
107              
108             Any extra arguments are passed along to the call to C.
109              
110             =cut
111              
112             package Game::TextMapper::Command::random;
113              
114 9     9   68148 use Modern::Perl '2018';
  9         27  
  9         104  
115 9     9   3913 use Mojo::Base 'Mojolicious::Command';
  9         56  
  9         119  
116 9     9   3102 use Pod::Simple::Text;
  9         28  
  9         425  
117 9     9   56 use Getopt::Long qw(GetOptionsFromArray);
  9         20  
  9         85  
118 9     9   1646 use Role::Tiny;
  9         23  
  9         90  
119             binmode(STDOUT, ':utf8');
120              
121             has description => 'Print a random map to STDOUT';
122              
123             has usage => sub { my $self = shift; $self->extract_usage };
124              
125             sub run {
126 9     9 1 1285 my ($self, $module, @args) = @_;
127 9   100     49 $module ||= 'Game::TextMapper::Smale';
128 9 50       37 if ($module eq 'help') {
129 0         0 seek(DATA, 0, 0); # read from this file
130 0         0 my $parser = Pod::Simple::Text->new();
131 0         0 $parser->output_fh(*STDOUT);
132 0         0 $parser->parse_lines();
133 0         0 return 1;
134             }
135 9         978 my $res = eval "require $module"; # require needs bareword!
136 9 50       94 die "random: compilation of module '$module' failed: $!\n" unless defined $res;
137 9 50       37 die "$module did not return a true value\n" unless $res;
138 9         1670 my $obj = eval "${module}->new";
139 9 50       195 die "random: module '$module->new' failed: $@" unless defined $obj;
140 9 50       75 die "random: module '$module->new' did not return a value\n" unless $obj;
141 9         25 my @roles;
142 9         57 GetOptionsFromArray (\@args, "role=s" => \@roles);
143 9 100       6702 Role::Tiny->apply_roles_to_object($obj, @roles) if @roles;
144 9         2402 print $obj->generate_map(@args);
145             }
146              
147             1;
148              
149             __DATA__