Game-TextMapper

 view release on metacpan or  search on metacpan

lib/Game/TextMapper/Command/random.pm  view on Meta::CPAN

=head1 OPTIONS

C<help> prints the man page.

The algorithm can be any module that Perl can load using C<require>. By default,
these are the ones:

=over

=item * L<Game::TextMapper::Apocalypse>

=item * L<Game::TextMapper::Gridmapper>

=item * L<Game::TextMapper::Schroeder::Alpine> (needs role)

=item * L<Game::TextMapper::Schroeder::Island> (needs role)

=item * L<Game::TextMapper::Smale>

=item * L<Game::TextMapper::Solo>

=item * L<Game::TextMapper::Traveller>

=back

The default algorithm is L<Game::TextMapper::Smale>.

Valid options depend on the algorithm. If an algorithm needs a role, you can
provide it using the C<--role> option.

    text-mapper random Game::TextMapper::Schroeder::Alpine \
        --role Game::TextMapper::Schroeder::Hex

If you don't do this, you'll get errors such as:

    Can't locate object method "random_neighbor" via package ...

That's because C<random_neighbor> must differ depending on whether we are
looking at a hex map (6) or a square map (4).

The two roles currently used:

=over

=item * L<Game::TextMapper::Schroeder::Hex>

=item * L<Game::TextMapper::Schroeder::Square>

=back

=head1 DEVELOPING YOUR OWN

The algorithm modules must be classes one instantiates using C<new> and they
must provide a method called C<generate_map> that returns a string.

Assume you write your own, and put it in the F<./lib> directory, called
F<Arrakis.pm>. Here is a sample implementation. It uses L<Mojo::Base> to make it
a class.

    package Arrakis;
    use Modern::Perl;
    use Mojo::Base -base;
    sub generate_map {
      for my $x (0 .. 10) {
	for my $y (0 .. 10) {
	  printf("%02d%02d dust desert\n", $x, $y);
	}
      }
      say "include gnomeyland.txt";
    }
    1;

Since the lib directory is in @INC when called via F<text-mapper>, you run it
like this:

    text-mapper random Arrakis | text-mapper render > map.svg

Any extra arguments are passed along to the call to C<generate_map>.

=cut

package Game::TextMapper::Command::random;

use Modern::Perl '2018';
use Mojo::Base 'Mojolicious::Command';
use Pod::Simple::Text;
use Getopt::Long qw(GetOptionsFromArray);
use Role::Tiny;
binmode(STDOUT, ':utf8');

has description => 'Print a random map to STDOUT';

has usage => sub { my $self = shift; $self->extract_usage };

sub run {
  my ($self, $module, @args) = @_;
  $module ||= 'Game::TextMapper::Smale';
  if ($module eq 'help') {
    seek(DATA, 0, 0); # read from this file
    my $parser = Pod::Simple::Text->new();
    $parser->output_fh(*STDOUT);
    $parser->parse_lines(<DATA>);
    return 1;
  }
  my $res = eval "require $module"; # require needs bareword!
  die "random: compilation of module '$module' failed: $!\n" unless defined $res;
  die "$module did not return a true value\n" unless $res;
  my $obj = eval "${module}->new";
  die "random: module '$module->new' failed: $@" unless defined $obj;
  die "random: module '$module->new' did not return a value\n" unless $obj;
  my @roles;
  GetOptionsFromArray (\@args, "role=s" => \@roles);
  Role::Tiny->apply_roles_to_object($obj, @roles) if @roles;
  print $obj->generate_map(@args);
}

1;

__DATA__



( run in 1.241 second using v1.01-cache-2.11-cpan-75ffa21a3d4 )