Jeffro's Space Gaming Blog

Microgames, Monster Games, and Role Playing Games

The Toy Universe: A Computerized Hex Map

Introduction:

Space gaming inevitably leads to computer programming. This ranges from character generation applications, to souped up spreadsheets for star system generation, and on to large databases of worlds for elaborate statistical analysis. Being a a dedicated tabletop guy, I generally see this sort of thing as a distracting intrusion upon my hobby. I mean, if your first reaction to a new game is to sit down and start programming, then something is a little off. And much of the preparation time involved in using these sorts of systems seems to contribute very little to actual game sessions. Consider, for instance, how much real gaming can be done just with Classic Traveller’s books 1-3. Does all the additional crunch and cruft added to the game after that point really improve the overall experience at the table?

If it was up to me, I’d probably try to do without the computer altogether as a gaming aid– with maybe one exception for posting session reports to the web. I mean, I look at the things all day long at work. If I’m gaming, it sure is nice to get away from the screen for a while. After mulling it over, though, I begin to see that perhaps best use of computers in this context would be as a tool to explore game design ideas. I mean… I don’t even feel like playtesting my own space combat game as it is, but I really need to see how things play out in order to see how best to balance and develop the design. So that leads to this. A series of posts on using exploratory programming to do exploratory game design. The programming here is not really an end unto itself. As such, the coding will be spartan, utilitarian, and minimalistic. While it may not do anything that hard core geeks can’t do for themselves, it may be useful to novice programmers by being more accessible to their tinkering. Perhaps along the way we’ll discover some things that can be more easily described and interacted with via small programs than with anything else. Let’s see where this leads!

Too kick things off, here is a small program that creates a hex map that the user can navigate from a command line. Note that the default map is the same size as a Traveller subsector map. If you’d rather switch to a map the size of a Star Fleet Battles map, enter the command “l 42 30”.

Sample run:

Welcome to the toy universe!
You are now at 0406.

> m 3
You are now at 0507.

> m 2
You are now at 0508.

> m 7 7 7 7
You are now at 0106.

> s
Hexes: 0101 0102 0103 0104 0105 0106 0107 0108 0109 0110 0201 0202 0203 0204 0205 0206 0207 0208 0209 0210 0301 0302 0303 0304 0305 0306 0307 0308 0309 0310 0401 0402 0403 0404 0405 0406 0407 0408 0409 0410 0501 0502 0503 0504 0505 0506 0507 0508 0509 0510 0601 0602 0603 0604 0605 0606 0607 0608 0609 0610 0701 0702 0703 0704 0705 0706 0707 0708 0709 0710 0801 0802 0803 0804 0805 0806 0807 0808 0809 0810
> j 0807
You are now at 0807.

> x

The code:

#!/usr/bin/perl
use Modern::Perl;

my %map;
my %state;

my %commands = (
    "x" => sub { exit(); },
    "l" => \&load_map,
    "s" => \&show_map,
    "j" => \&jump,
    "m" => \&move,
    );

sub load_map {
    my ($x, $y) = @_;
    die "Map size ($x,$y) is too big!" if $x > 99 || $y > 99;
    undef(%map);
    for (1..$x) {
	my $a = $_;
	for (1..$y) {
	    my $b = $_;
	    $map{get_coords($a,$b)} = "";
	}
    }
}

sub get_coords {
    my ($x, $y) = @_;
    $x = "0$x" if $x < 10;
    $y = "0$y" if $y < 10;
    return "$x$y";

}
sub show_map {
    print "Hexes: ";
    map {
	print " $_";
    } sort keys %map;
    print "\n\n";
}

sub jump {
    my ($to) = @_;
    if (exists ($map{$to})) {
	$state{cur} = $to;
	say "You are now at $to.";
    } else {
	say "There is no location at hex $to.";
    }
}

sub move {
    my $dir = shift(@_);
    my ($x, $y);

    ($x, $y) = ($1, $2) if $state{cur} =~ /(\d{2})(\d{2})/;
    $x =~ s/^0+//;
    $y =~ s/^0+//;

    if ($dir == 8) {
	$y -= 1; #North
    } elsif ($dir == 2) {
	$y += 1; #South
    } elsif ($dir == 7) {
	$x -= 1; #Northwest
	$y -= 1 unless ($x % 2);
    } elsif ($dir == 9) {
	$x += 1; #Northeast
	$y -= 1 unless ($x % 2);
    } elsif ($dir == 1) {
	$x -= 1; #Southwest
	$y += 1 if ($x % 2);
    } elsif ($dir == 3) {
	$x += 1; #Southeast
	$y += 1 if ($x % 2);
    }

    my $c = get_coords($x,$y);
    if (exists $map{$c}) {
	$state{cur} = $c;
	if (scalar @_) {
	    move(@_);
	} else {
	    say "You are now at $c.";
	}
    } else {
	say "That is off the map!";
    }
}

load_map(8,10);
say "Welcome to the toy universe!";
jump("0406");

while (1) {
    print "\n> ";
    my $x = <STDIN>;
    chomp($x);
    my @args = split(/\s+/, $x);
    my $c = shift(@args);

    if ($commands{$c}) {
	$commands{$c}->(@args);
    }
}

Exercises for the novice programmer:

  1. Add a command that will list all of the hexes that are 1 hex away.
  2. Restrict the jump command so that the user can only jump to locations that are no more than two hexes away.
  3. The layout of the hex map does not allow for east-west movement because there is no hex immediately in that direction. However… two moves to the “east” (or west) will take you to a hex. Alter the move command to allow this so that the 4 and 6 numbers translate to a direction as well, but only if a pair of those numbers are entered in together.
  4. The program currently has a little validation code to prevent the user from going off the map edge when the move command is used. Add an option that will instead cause the map to wrap around upon itself like a torus so that the user can never go off the edge.
Advertisements

7 responses to “The Toy Universe: A Computerized Hex Map

  1. MishaBurnett July 12, 2013 at 6:26 am

    Heh. I actually wrote my very first computer program to roll up D&D characters, back when Basic was cutting edge and programs were loaded on tape. As I recall it went something like:

    0010 Let X(STR)=INT(RND*6)+INT(RND*6)+INT(RND*6)
    0020 Let X(INT)=INT(RND*6)+INT(RND*6)+INT(RND*6)

    and so on.

  2. Chris Mata July 12, 2013 at 6:58 am

    I feel like I am reading Dragon #76 here. Very nice!!! I spent hours typing in one when I was little only to have it not work. Found out 15 years later the article had the code wrong. :)

  3. Robert Eaglestone July 13, 2013 at 10:29 pm

    If you think finding all locations a distance of 2 from a hex is a novice task, you might be surprised.

  4. Pingback: The Toy Universe: Von Neumann’s Middle-Square Method | Jeffro's Space Gaming Blog

  5. Pingback: The Toy Universe: Exploring Iterative Functions | Jeffro's Space Gaming Blog

  6. Pingback: The Toy Universe: Exploring Dot Maps | Jeffro's Space Gaming Blog

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: