Game-TextMapper

 view release on metacpan or  search on metacpan

META.json  view on Meta::CPAN

         "requires" : {
            "ExtUtils::MakeMaker" : "6.52",
            "File::ShareDir::Install" : "0"
         }
      },
      "runtime" : {
         "requires" : {
            "File::ShareDir" : "0",
            "File::Slurper" : "0",
            "List::MoreUtils" : "0",
            "Modern::Perl" : "1.20180701",
            "Mojolicious" : "0",
            "Role::Tiny" : "0",
            "perl" : "5.026000",
            "strict" : "0",
            "warnings" : "0"
         }
      }
   },
   "release_status" : "stable",
   "resources" : {

META.yml  view on Meta::CPAN

  version: '1.4'
name: Game-TextMapper
no_index:
  directory:
    - t
    - inc
requires:
  File::ShareDir: '0'
  File::Slurper: '0'
  List::MoreUtils: '0'
  Modern::Perl: '1.20180701'
  Mojolicious: '0'
  Role::Tiny: '0'
  perl: '5.026000'
  strict: '0'
  warnings: '0'
resources:
  repository: https://alexschroeder.ch/cgit/text-mapper
version: 1.08
x_serialization_backend: 'CPAN::Meta::YAML version 0.018'

Makefile.PL  view on Meta::CPAN

use File::ShareDir::Install;

install_share 'share';

WriteMakefile(
  NAME             => 'Game::TextMapper',
  VERSION_FROM     => 'lib/Game/TextMapper.pm',
  ABSTRACT_FROM    => 'lib/Game/TextMapper.pm',
  AUTHOR           => 'Alex Schroeder',
  LICENSE          => 'agpl_3',
  MIN_PERL_VERSION => '5.26.0', # Modern::Perl '2018'
  EXE_FILES        => [
    'script/text-mapper',
  ],
  PREREQ_PM => {
    'strict' => 0,
    'warnings' => 0,
    'Modern::Perl' => 1.20180701, # for '2018'
    'Mojolicious' => 0, # for Mojo::Template and Mojo::UserAgent
    'File::Slurper' => 0,
    'Role::Tiny' => 0,
    'List::MoreUtils' => 0,
    'File::ShareDir' => 0,
  },
  CONFIGURE_REQUIRES => {
    'ExtUtils::MakeMaker' => '6.52',
    'File::ShareDir::Install' => 0,
  },

README.md  view on Meta::CPAN

[Help](https://campaignwiki.org/text-mapper/help) link.

## Dependencies

Perl Modules (or Debian modules):

* File::ShareDir::Install or libfile-sharedir-install-perl
* IO::Socket::SSL or libio-socket-ssl-perl
* LWP::UserAgent or liblwp-useragent-perl
* List::MoreUtils or liblist-moreutils-perl
* Modern::Perl or libmodern-perl-perl
* Mojolicious or libmojolicious-perl
* Role::Tiny::With or librole-tiny-perl

If you are going to build IO::Socket::SSL, then you’ll need OpenSSL
development libraries installed: openssl-devel or equivalent,
depending on your package manager.

To install from the working directory (which will also install all the
dependencies from CPAN unless you installed them beforehand using your
system’s package manager) use cpan or cpanm.

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

use Game::TextMapper::Smale;
use Game::TextMapper::Apocalypse;
use Game::TextMapper::Gridmapper;
use Game::TextMapper::Schroeder::Alpine;
use Game::TextMapper::Schroeder::Archipelago;
use Game::TextMapper::Schroeder::Island;
use Game::TextMapper::Traveller;
use Game::TextMapper::Folkesten;
use Game::TextMapper::Solo;

use Modern::Perl '2018';
use Mojolicious::Lite;
use Mojo::DOM;
use Mojo::Util qw(url_escape xml_escape);
use File::ShareDir 'dist_dir';
use Pod::Simple::HTML;
use Pod::Simple::Text;
use List::Util qw(none);
use Cwd;

# Commands for the command line!

lib/Game/TextMapper/Apocalypse.pm  view on Meta::CPAN

# with this program. If not, see <http://www.gnu.org/licenses/>.

=encoding utf8

=head1 NAME

Game::TextMapper::Apocalypse - generate postapocalyptic landscape

=head1 SYNOPSIS

    use Modern::Perl;
    use Game::TextMapper::Apocalypse;
    my $map = Game::TextMapper::Apocalypse->new->generate_map();
    print $map;

=head1 DESCRIPTION

This fills the map with random seed regions which then grow to fill the map.

Settlements are placed at random.

Every mountain region is the source of a river. Rivers flow through regions that
are not themselves mountains or a deserts. Rivers end in swamps.

=cut

package Game::TextMapper::Apocalypse;
use Game::TextMapper::Log;
use Modern::Perl '2018';
use List::Util qw(shuffle any none);
use Mojo::Base -base;

my $log = Game::TextMapper::Log->get;

=head1 ATTRIBUTES

=head2 rows

The height of the map, defaults to 10.

    use Modern::Perl;
    use Game::TextMapper::Apocalypse;
    my $map = Game::TextMapper::Apocalypse->new(rows => 20)
        ->generate_map;
    print $map;

=head2 cols

The width of the map, defaults to 20.

    use Modern::Perl;
    use Game::TextMapper::Apocalypse;
    my $map = Game::TextMapper::Apocalypse->new(cols => 30)
        ->generate_map;
    print $map;

=head2 region_size

The size of regions sharing the same terrain type, on average, defaults to 5
hexes. The algorithm computes the number of hexes, divides it by the region size,
and that's the number of seeds it starts with (C<rows> × C<cols> ÷
C<region_size>).

    use Modern::Perl;
    use Game::TextMapper::Apocalypse;
    my $map = Game::TextMapper::Apocalypse->new(region_size => 3)
        ->generate_map;
    print $map;

=head2 settlement_chance

The chance of a hex containing a settlement, from 0 to 1, defaults to 0.1 (10%).

    use Modern::Perl;
    use Game::TextMapper::Apocalypse;
    my $map = Game::TextMapper::Apocalypse->new(settlement_chance => 0.2)
        ->generate_map;
    print $map;

=head2 loglevel

By default, the log level is set by L<Game::TextMapper> from the config file. If
you use the generator on its own, however, the log defaults to log level
"debug". You might want to change that. The options are "error", "warn", "info"
and "debug".

    use Modern::Perl;
    use Game::TextMapper::Apocalypse;
    my $map = Game::TextMapper::Apocalypse->new(loglevel => 'error')
        ->generate_map;
    print $map;

=cut

has 'rows' => 10;
has 'cols' => 20;
has 'region_size' => 5;

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

=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;

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

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 };

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


Square map:

    text-mapper random Game::TextMapper::Schroeder::Alpine \
        --role Game::TextMapper::Schroeder::Square \
    | text-mapper render --square > map.svg

=cut

package Game::TextMapper::Command::render;
use Modern::Perl '2018';
use Mojo::Base 'Mojolicious::Command';
use File::ShareDir 'dist_dir';
use Pod::Simple::Text;
use Getopt::Long qw(GetOptionsFromArray);
use Encode;

has description => 'Render map from STDIN to STDOUT, as SVG (all UTF-8)';

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

lib/Game/TextMapper/Folkesten.pm  view on Meta::CPAN


Note that this module acts as a class with the C<generate_map> method, but none
of the other subroutines defined are actual methods. They don't take a C<$self>
argument.

=cut

package Game::TextMapper::Folkesten;
use Game::TextMapper::Log;
use Game::TextMapper::Point;
use Modern::Perl '2018';
use Mojo::Base -base;
use List::Util qw(shuffle any first);

has 'world' => sub { {} };
has 'dry' => sub { {} };
has 'wet' => sub { {} };
has 'width' => 10;
has 'height' => 10;
has 'rivers' => sub { [] };
has 'canyons' => sub { [] };

lib/Game/TextMapper/Gridmapper.pm  view on Meta::CPAN

number of layouts containing 5 or 7 rooms to get to that number, and then simply
drops the extra rooms.

=head1 METHODS

=cut

package Game::TextMapper::Gridmapper;
use Game::TextMapper::Log;
use Game::TextMapper::Constants qw($dx $dy);
use Modern::Perl '2018';
use List::Util qw'shuffle none any min max all';
use List::MoreUtils qw'pairwise';
use Mojo::Util qw(url_escape);
use Mojo::Base -base;

my $log = Game::TextMapper::Log->get;

# This is the meta grid for the geomorphs. Normally this is (3,3) for simple
# dungeons. We need to recompute these when smashing geomorphs together.
has 'dungeon_dimensions';

lib/Game/TextMapper/Line.pm  view on Meta::CPAN

# with this program. If not, see <http://www.gnu.org/licenses/>.

=encoding utf8

=head1 NAME

Game::TextMapper::Line - a line between two points

=head1 SYNOPSIS

    use Modern::Perl;
    use Game::TextMapper::Line::Hex;
    use Game::TextMapper::Point::Hex;
    my $line = Game::TextMapper::Line::Hex->new();
    my $from = Game::TextMapper::Point::Hex->new(x => 1, y => 1, z => 0);
    my $to   = Game::TextMapper::Point::Hex->new(x => 5, y => 3, z => 0);
    $line->points([$from, $to]);
    my @line = $line->compute_missing_points;
    say join(" ", map { $_->str } @line);
    # (1,1,0) (2,1,0) (3,2,0) (4,2,0) (5,3,0)

lib/Game/TextMapper/Line.pm  view on Meta::CPAN

to output SVG.

In order to do this, the class needs to know how to work with the regions on the
map. This is different for hexes and squares. Therefore you should always be
using the appropriate Hex or Square class instead.

=cut

package Game::TextMapper::Line;

use Modern::Perl '2018';
use Mojo::Util qw(url_escape);
use Mojo::Base -base;

our $debug;

=head1 ATTRIBUTES

=head2 points

An array reference of points using a class derived from

lib/Game/TextMapper/Line/Hex.pm  view on Meta::CPAN

L<Game::TextMapper::Line::Line>
L<Game::TextMapper::Line::Square>

=cut

package Game::TextMapper::Line::Hex;

use Game::TextMapper::Constants qw($dx $dy);
use Game::TextMapper::Point;

use Modern::Perl '2018';
use Mojo::Base 'Game::TextMapper::Line';

sub pixels {
  my ($self, $point) = @_;
  my ($x, $y) = ($point->x * $dx * 3/2, ($point->y + $self->offset->[$point->z]) * $dy - $point->x % 2 * $dy/2);
  return ($x, $y) if wantarray;
  return sprintf("%.1f,%.1f", $x, $y);
}

# Brute forcing the "next" step by trying all the neighbors. The

lib/Game/TextMapper/Line/Square.pm  view on Meta::CPAN

L<Game::TextMapper::Line::Line>
L<Game::TextMapper::Line::Hex>

=cut

package Game::TextMapper::Line::Square;

use Game::TextMapper::Constants qw($dx $dy);
use Game::TextMapper::Point;

use Modern::Perl '2018';
use Mojo::Base 'Game::TextMapper::Line';

sub pixels {
  my ($self, $point) = @_;
  my ($x, $y) = ($point->x * $dy, ($point->y + $self->offset->[$point->z]) * $dy);
  return ($x, $y) if wantarray;
  return sprintf("%d,%d", $x, $y);
}

sub one_step {

lib/Game/TextMapper/Mapper.pm  view on Meta::CPAN

# with this program. If not, see <http://www.gnu.org/licenses/>.

=encoding utf8

=head1 NAME

Game::TextMapper::Mapper - a text map parser and builder

=head1 SYNOPSIS

    use Modern::Perl;
    use Game::TextMapper::Mapper::Hex;
    my $map = <<EOT;
    0101 forest
    include default.txt
    EOT
    my $svg = Game::TextMapper::Mapper::Hex->new(dist_dir => 'share')
      ->initialize($map)
      ->svg();
    print $svg;

lib/Game/TextMapper/Mapper.pm  view on Meta::CPAN

generate the SVG for the entire map.

The details depend on whether the map is a hex map or a square map. You should
use the appropriate class instead of this one: L<Game::TextMapper::Mapper::Hex>
or L<Game::TextMapper::Mapper::Square>.

=cut

package Game::TextMapper::Mapper;
use Game::TextMapper::Log;
use Modern::Perl '2018';
use Mojo::UserAgent;
use Mojo::Base -base;
use File::Slurper qw(read_text);
use Encode qw(encode_utf8 decode_utf8);
use Mojo::Util qw(url_escape);
use File::ShareDir 'dist_dir';
use Scalar::Util 'weaken';

=head1 ATTRIBUTES

lib/Game/TextMapper/Mapper/Hex.pm  view on Meta::CPAN

L<Game::TextMapper::Mapper::Square> is a similar class for square maps.

=cut

package Game::TextMapper::Mapper::Hex;

use Game::TextMapper::Constants qw($dx $dy);
use Game::TextMapper::Point::Hex;
use Game::TextMapper::Line::Hex;

use Modern::Perl '2018';
use Mojo::Base 'Game::TextMapper::Mapper';

sub make_region {
  my $self = shift;
  return Game::TextMapper::Point::Hex->new(@_);
}

sub make_line {
  my $self = shift;
  return Game::TextMapper::Line::Hex->new(@_);

lib/Game/TextMapper/Mapper/Square.pm  view on Meta::CPAN

L<Game::TextMapper::Mapper::Hex> is a similar class for hex maps.

=cut

package Game::TextMapper::Mapper::Square;

use Game::TextMapper::Constants qw($dy);
use Game::TextMapper::Point::Square;
use Game::TextMapper::Line::Square;

use Modern::Perl '2018';
use Mojo::Base 'Game::TextMapper::Mapper';

sub make_region {
  my $self = shift;
  return Game::TextMapper::Point::Square->new(@_);
}

sub make_line {
  my $self = shift;
  return Game::TextMapper::Line::Square->new(@_);

lib/Game/TextMapper/Point.pm  view on Meta::CPAN

Game::TextMapper::Point - a point on the map

=head1 DESCRIPTION

This is a simple class to hold points. Points have coordinates and know how to
print them.

=cut

package Game::TextMapper::Point;
use Modern::Perl '2018';
use Mojo::Base -base;

=head2 Attributes

C<x>, C<y>, C<z> are coordinates.

C<type>, C<label>, C<size> are used to draw the SVG. These are used by the
actual implementations, L<Game::TextMapper::Point::Hex> and
L<Game::TextMapper::Point::Square>.

lib/Game/TextMapper/Point/Hex.pm  view on Meta::CPAN

# with this program. If not, see <http://www.gnu.org/licenses/>.

=encoding utf8

=head1 NAME

Game::TextMapper::Point::Hex - a hex on a map

=head1 SYNOPSIS

    use Modern::Perl;
    use Game::TextMapper::Point::Hex;
    my $hex = Game::TextMapper::Point::Hex->new(x => 1, y => 1, z => 0);
    say $hex->svg_region('', [0]);
    # <polygon id="hex110"  points="50.0,86.6 100.0,173.2 200.0,173.2 250.0,86.6 200.0,0.0 100.0,0.0" />

=head1 DESCRIPTION

This class holds information about a hex region: coordinates, a label, and
types. Types are the kinds of symbols that can be found in the region: a keep, a
tree, a mountain. They correspond to SVG definitions. The class knows how to

lib/Game/TextMapper/Point/Hex.pm  view on Meta::CPAN

For attributes and methods, see L<Game::TextMapper::Point>.

=head2 Additional Methods

=cut

package Game::TextMapper::Point::Hex;

use Game::TextMapper::Constants qw($dx $dy);

use Modern::Perl '2018';
use Mojo::Util qw(url_escape);
use Encode qw(encode_utf8);
use Mojo::Base 'Game::TextMapper::Point';

=head3 corners

Return the relative SVG coordinates of the points making up the shape, i.e. six
for L<Game::TextMapper::Point::Hex> and four for
L<Game::TextMapper::Point::Square>.

lib/Game/TextMapper/Point/Square.pm  view on Meta::CPAN

# with this program. If not, see <http://www.gnu.org/licenses/>.

=encoding utf8

=head1 NAME

Game::TextMapper::Point::Square - a square on a map

=head1 SYNOPSIS

    use Modern::Perl;
    use Game::TextMapper::Point::Square;
    my $square = Game::TextMapper::Point::Square->new(x => 1, y => 1, z => 0);
    say $square->svg_region('', [0]);
    # <rect id="square110"  x="86.6" y="86.6" width="173.2" height="173.2" />

=head1 DESCRIPTION

This class holds information about a square region: coordinates, a label, and
types. Types are the kinds of symbols that can be found in the region: a keep, a
tree, a mountain. They correspond to SVG definitions. The class knows how to

lib/Game/TextMapper/Point/Square.pm  view on Meta::CPAN


The SVG size is determined by C<$dy> from L<Game::TextMapper::Constants>.

=cut

package Game::TextMapper::Point::Square;

use Game::TextMapper::Constants qw($dy);

use Game::TextMapper::Point;
use Modern::Perl '2018';
use Mojo::Util qw(url_escape);
use Mojo::Base 'Game::TextMapper::Point';
use Encode;

sub pixels {
  my ($self, $offset, $add_x, $add_y) = @_;
  my $x = $self->x;
  my $y = $self->y;
  my $z = $self->z;
  $y += $offset->[$z] if defined $offset->[$z];

lib/Game/TextMapper/Schroeder/Alpine.pm  view on Meta::CPAN

=head1 SEE ALSO

L<Game::TextMapper::Schroeder::Base>
L<Game::TextMapper::Schroeder::Hex>
L<Game::TextMapper::Schroeder::Square>

=cut

package Game::TextMapper::Schroeder::Alpine;
use Game::TextMapper::Log;
use Modern::Perl '2018';
use Mojo::Base -base;
use Role::Tiny::With;
with 'Game::TextMapper::Schroeder::Base';
use List::Util 'shuffle';

my $log = Game::TextMapper::Log->get;

has 'steepness';
has 'peaks';
has 'peak';

lib/Game/TextMapper/Schroeder/Archipelago.pm  view on Meta::CPAN

Game::TextMapper::Archipelago - work in progress

=head1 DESCRIPTION

This is an unfinished idea.

=cut

package Game::TextMapper::Schroeder::Archipelago;
use Game::TextMapper::Log;
use Modern::Perl '2018';
use Mojo::Base -base;
use Role::Tiny::With;
with 'Game::TextMapper::Schroeder::Base';
use List::Util qw'shuffle min max';

my $log = Game::TextMapper::Log->get;

has 'bottom' => 0;
has 'top' => 10;
has 'radius' => 5;

lib/Game/TextMapper/Schroeder/Base.pm  view on Meta::CPAN

=encoding utf8

=head1 NAME

Game::TextMapper::Schroeder::Base - a base role for map generators

=head1 SYNOPSIS

    # create a map
    package World;
    use Modern::Perl;
    use Game::TextMapper::Schroeder::Base;
    use Mojo::Base -base;
    use Role::Tiny::With;
    with 'Game::TextMapper::Schroeder::Base';
    # use it
    package main;
    my $map = World->new(height => 10, width => 10);

=head1 DESCRIPTION

Map generators that work for both hex maps and square maps use this role and
either the Hex or Square role to provide basic functionality for their regions,
such as the number of neighbours they have (six or four).

=cut

package Game::TextMapper::Schroeder::Base;
use Game::TextMapper::Point;
use Modern::Perl '2018';
use Mojo::Base -role;

# We're assuming that $width and $height have two digits (10 <= n <= 99).

has width => 30;
has height => 10;

sub coordinates {
  my ($x, $y) = @_;
  return Game::TextMapper::Point::coord($x, $y);

lib/Game/TextMapper/Schroeder/Hex.pm  view on Meta::CPAN

=encoding utf8

=head1 NAME

Game::TextMapper::Schroeder::Hex - a role for hex map generators

=head1 SYNOPSIS

    # create a map
    package World;
    use Modern::Perl;
    use Mojo::Base -base;
    use Role::Tiny::With;
    with 'Game::TextMapper::Schroeder::Base';
    with 'Game::TextMapper::Schroeder::Hex';
    # use it
    package main;
    my $map = World->new(height => 10, width => 10);

=head1 DESCRIPTION

lib/Game/TextMapper/Schroeder/Hex.pm  view on Meta::CPAN

number of neighbours within one or two regions distance, how to pick a random
neighbour direction, how to compute the coordinates of these neighbours, how to
draw arrows towards these neighbours.

This inherits attributes and methods from L<Game::TextMapper::Schroeder::Base>,
such as C<width> and C<height>.

=cut

package Game::TextMapper::Schroeder::Hex;
use Modern::Perl '2018';
use Mojo::Base -role;
use POSIX qw(ceil);

=head1 METHODS

=head2 reverse

Reverses a direction.

=cut

lib/Game/TextMapper/Schroeder/Island.pm  view on Meta::CPAN


L<Game::TextMapper::Schroeder::Alpine>
L<Game::TextMapper::Schroeder::Base>
L<Game::TextMapper::Schroeder::Hex>
L<Game::TextMapper::Schroeder::Square>

=cut

package Game::TextMapper::Schroeder::Island;
use Game::TextMapper::Log;
use Modern::Perl '2018';
use Mojo::Base 'Game::TextMapper::Schroeder::Alpine';
use Role::Tiny::With;
with 'Game::TextMapper::Schroeder::Base';
use List::Util qw'shuffle min max';

my $log = Game::TextMapper::Log->get;

has 'bottom' => 0;
has 'top' => 10;
has 'radius' => 5;

lib/Game/TextMapper/Schroeder/Square.pm  view on Meta::CPAN

=encoding utf8

=head1 NAME

Game::TextMapper::Schroeder::Square - a role for square map generators

=head1 SYNOPSIS

    # create a map
    package World;
    use Modern::Perl;
    use Mojo::Base -base;
    use Role::Tiny::With;
    with 'Game::TextMapper::Schroeder::Base';
    with 'Game::TextMapper::Schroeder::Square';
    # use it
    package main;
    my $map = World->new(height => 10, width => 10);

=head1 DESCRIPTION

lib/Game/TextMapper/Schroeder/Square.pm  view on Meta::CPAN

number of neighbours within one or two regions distance, how to pick a random
neighbour direction, how to compute the coordinates of these neighbours, how to
draw arrows towards these neighbours.

This inherits attributes and methods from L<Game::TextMapper::Schroeder::Base>,
such as C<width> and C<height>.

=cut

package Game::TextMapper::Schroeder::Square;
use Modern::Perl '2018';
use Mojo::Base -role;

=head1 METHODS

=head2 reverse

Reverses a direction.

=cut

lib/Game/TextMapper/Smale.pm  view on Meta::CPAN


Note that this module acts as a class with the C<generate_map> method, but none
of the other subroutines defined are actual methods. They don't take a C<$self>
argument.

=cut

package Game::TextMapper::Smale;
use Game::TextMapper::Log;
use Game::TextMapper::Point;
use Modern::Perl '2018';
use Mojo::Base -base;

my $log = Game::TextMapper::Log->get;

my %world = ();

#         ATLAS HEX PRIMARY TERRAIN TYPE
#         Water   Swamp   Desert  Plains  Forest  Hills   Mountains
# Water   P       W       W       W       W       W       -
# Swamp   W       P       -       W       W       -       -

lib/Game/TextMapper/Solo.pm  view on Meta::CPAN

# with this program. If not, see <http://www.gnu.org/licenses/>.

=encoding utf8

=head1 NAME

Game::TextMapper::Solo - generate a map generated step by step

=head1 SYNOPSIS

    use Modern::Perl;
    use Game::TextMapper::Solo;
    my $map = Game::TextMapper::Solo->new->generate_map();
    print $map;

=head1 DESCRIPTION

This starts the map and generates all the details directly, for each step,
without knowledge of the rest of the map. The tricky part is to generate
features such that no terrible geographical problems arise.

=cut

package Game::TextMapper::Solo;
use Game::TextMapper::Log;
use Modern::Perl '2018';
use List::Util qw(shuffle all any none);
use Mojo::Base -base;

my $log = Game::TextMapper::Log->get;

=head1 ATTRIBUTES

=head2 rows

The height of the map, defaults to 15.

    use Modern::Perl;
    use Game::TextMapper::Solo;
    my $map = Game::TextMapper::Solo->new(rows => 20)
        ->generate_map;
    print $map;

=head2 cols

The width of the map, defaults to 30.

    use Modern::Perl;
    use Game::TextMapper::Solo;
    my $map = Game::TextMapper::Solo->new(cols => 40)
        ->generate_map;
    print $map;

=cut

has 'rows' => 15;
has 'cols' => 30;
has 'altitudes' => sub{[]}; # these are the altitudes of each hex, a number between 0 (deep ocean) and 10 (ice)

lib/Game/TextMapper/Traveller.pm  view on Meta::CPAN

editions. Trade and communication routes are based on starports, bases, and
trade codes and jump distance; the potential connections are then winnowed down
using a minimal spanning tree.

=head1 METHODS

=cut

package Game::TextMapper::Traveller;
use Game::TextMapper::Log;
use Modern::Perl '2018';
use List::Util qw(shuffle max any);
use Mojo::Base -base;
use Role::Tiny::With;
use Game::TextMapper::Constants qw($dx $dy);
with 'Game::TextMapper::Schroeder::Hex';

my $log = Game::TextMapper::Log->get;

has 'rows' => 10;
has 'cols' => 8;

t/basic.t  view on Meta::CPAN

# later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <https://www.gnu.org/licenses/>.

use Modern::Perl;
use Test::More;
use Test::Mojo;
use utf8;

my $t = Test::Mojo->new('Game::TextMapper');

my $stash;
$t->app->hook(after_dispatch => sub { my $c = shift; $stash = $c->stash });

$t->get_ok('/')

t/commands.t  view on Meta::CPAN

# later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <https://www.gnu.org/licenses/>.

use Modern::Perl;
use Test::More;
use IPC::Open2;
use Mojo::DOM;
use Test::Mojo;
use Mojo::File;

my $script = Mojo::File->new('script', 'text-mapper');

# random



( run in 0.690 second using v1.01-cache-2.11-cpan-a5abf4f5562 )