Settlers of Catan via Email | Back to Games
The Settlers of Catan
Play By E-Mail (PBEM) Guidelines
First written on 1/15/97 finally uploaded to the net on 2/11/01!

written by Mark Johnson, johnson@ccnet.com MarkJohnson@gtcinternet.com

0. Introduction
The following is a set of guidelines for playing Mayfair Games' The Settlers of Catan (or the original German edition Die Siedler von Catan, by Frankh/Kosmos) via email. This clever game won Germany's Game of the Year in 1995, and was already popular in the US as an import before Mayfair Games' published their less expensive english edition. To find out more, check out the following on the world wide web:

THE site for the whole Settlers franchise (unfortunately for some of us, it's only in German)
Mayfair Games' website
A review of the game at The Game Cabinet
Another review of the game at The Game Report
Mark Jackson's excellent Game Central Station, with its page devoted to Settlers

A quick note about copyrights. The game publishers obviously own the copyrights to the game, and these PBEM guidelines are in no way intended to divert customers from purchasing the real game. Consequently, the rules of the game itself will not be listed her. Instead, this just gives people another chance to play. I own the game, and when I set up a PBEM game, it is the electronic equivalent of inviting those email correspondents over to my home to play. Maybe some of them own the game, and maybe some will be convinced to buy it after playing it electronically. Certainly both the German and American editions look a lot nicer than the plain ASCII map used for PBEM!

These guidelines are presented assuming the game is played using the honor system. All that means is that the players don't cheat. Doing so in a PBEM game is meaningless beyond belief, and it's not worth everyone else's time to devise foolproof PBEM mechanics or involve a nonplayer referee. Enough said about that.


1. The Map
The central feature of most boardgames is the board itself, or the map. Settlers is no exception, with its randomized layout of hex tiles. For PBEM play, this map is rendered into an ASCII image, using plain text only. About the most complex characters are the slashes /, \, and the optional tilde for water waves ~. The resource produced by each hex tile is simply listed inside it, as is the frequency number. Ports have 3:1 or 2:1-resource designation, and asterisks to denote the corners that may be settled.

Player pieces--roads, settlements, and cities--are noted on the map as they are placed using letters according to the color being played. Lower case letters are roads, capital letters are settlements, and double-capitals are cities. Since the standard colors are red, blue, green, and yellow, the wooden pieces are simulated by rrr, R, RR, bbb, B, BB, ggg, G, GG, yyy, Y, YY. (Road segments are only two lower case letters long on the diagonals, see below.)

So here's a sample of a map before any player pieces have been put on it:


                                  >-----<
                                 /~~~~~~~\
                                /~~~~~~~~~\
                         >-----<~~~~3:1~~~~>-----<
                        /~~~~~~~\~~~~~~~~~/~~~~~~~\
                       /~~~~~~~~~\*~~~~~*/~~~~~~~~~\
                >-----<~~~~~~~~~~~>-----<~~~~~~~~~~~>-----<
               /~~~~~~~\~~~~~~~~~/       \~~~~~~~~~/~~~~~~~\
              /~~~2:1~~~\~~~~~~~/    8    \~~~~~~~/~~~2:1~~~\
       >-----<~~~wood~~~*>-----<   wood    >-----<*~~sheep~~~>-----<
      /~~~~~~~\~~~~~~~~~/       \         /       \~~~~~~~~~/~~~~~~~\
     /~~~~~~~~~\~~~~~~*/   11    \       /    4    \*~~~~~~/~~~~~~~~~\
    <~~~~~~~~~~~>-----<   brick   >-----<   brick   >-----<~~~~~~~~~~~>
     \~~~~~~~~~/       \         /       \         /       \~~~~~~~~~/
      \~~~~~~~/    3    \       /    9    \       /    9    \~~~~~~~/
       >-----<   grain   >-----<   wood    >-----<   stone   >-----<
      /~~~~~~~\         /       \         /       \         /~~~~~~~\
     /~~~2:1~~~\       /    8    \       /         \       /~~~2:1~~~\
    <~~~brick~~*>-----<   sheep   >-----<   desert  >-----<*~~~ore~~~~>
     \~~~~~~~~~/       \         /       \  ROBBER /       \~~~~~~~~~/
      \~~~~~~*/   10    \       /    6    \       /   10    \*~~~~~~/
       >-----<   wood    >-----<   brick   >-----<   sheep   >-----<
      /~~~~~~~\         /       \         /       \         /~~~~~~~\
     /~~~~~~~~~\       /   12    \       /    2    \       /~~~~~~~~~\
    <~~~~~~~~~~~>-----<   grain   >-----<   stone   >-----<~~~~~~~~~~~>  
     \~~~~~~~~~/       \         /       \         /       \~~~~~~~~~/
      \~~~~~~~/    6    \       /    4    \       /   12    \~~~~~~~/
       >-----<   grain   >-----<   sheep   >-----<   brick   >-----<
      /~~~~~~*\         /       \         /       \         /*~~~~~~\
     /~~~~~~~~~\       /   11    \       /    5    \       /~~~~~~~~~\
    <~~~~3:1~~~*>-----<   wood    >-----<   grain   >-----<*~~~3:1~~~~>
     \~~~~~~~~~/~~~~~~~\         /       \         /~~~~~~~\~~~~~~~~~/
      \~~~~~~~/~~~~~~~~~\       /    5    \       /~~~~~~~~~\~~~~~~~/
       >-----< ~~~~~~~~~~>-----<   sheep   >-----<~~~~~~~~~~~>-----<
              \~~~~~~~~~/*~~~~~*\         /*~~~~~*\~~~~~~~~~/
               \~~~~~~~/~~~~~~~~~\       /~~~2:1~~~\~~~~~~~/
                >-----<~~~~3:1~~~~>-----<~~~grain~~~>-----<
                       \~~~~~~~~~/~~~~~~~\~~~~~~~~~/
                        \~~~~~~~/~~~~~~~~~\~~~~~~~/
                         >-----<~~~~~~~~~~~>-----<
                                \~~~~~~~~~/
                                 \~~~~~~~/
                                  >-----<

Note the watery border, the ports and their "build corners", the land tiles and their resources (including the desert), and the location of the ROBBER.

During the game the map is repeatedly emailed to all of the other players. Individual players alter it when they place their roads, etc., then emailing the new configuration. After the initial settlement rounds, it might look something like this



                                  >-----<
                                 /~~~~~~~\
                                /~~~~~~~~~\
                         >-----<~~~~3:1~~~~>-----<
                        /~~~~~~~\~~~~~~~~~/~~~~~~~\
                       /~~~~~~~~~\*~~~~~*/~~~~~~~~~\
                >-----<~~~~~~~~~~~>-----<~~~~~~~~~~~>-----<
               /~~~~~~~\~~~~~~~~~/       \~~~~~~~~~/~~~~~~~\
              /~~~2:1~~~\~~~~~~~/    8    \~~~~~~~/~~~2:1~~~\
       >-----<~~~wood~~~*>-----<   wood    >-----<*~~sheep~~~>-----<
      /~~~~~~~\~~~~~~~~~/       \         /       \~~~~~~~~~/~~~~~~~\
     /~~~~~~~~~\~~~~~~*/    11   \       /    4    \*~~~~~~/~~~~~~~~~\
    <~~~~~~~~~~~>-----G   brick   >-ggg-G   brick   R-----<~~~~~~~~~~~>
     \~~~~~~~~~/       g         /       \         r       \~~~~~~~~~/
      \~~~~~~~/    3    g       /    9    \       r    9    \~~~~~~~/
       >-----<   grain   >-----<   wood    >-----<   stone   >-----<
      /~~~~~~*\         /       \         /       \         /~~~~~~~\
     /~~~2:1~~~\       /    8    \       /         \       /~~~2:1~~~\
    <~~~brick~~*>-----<   sheep   R-----<   desert  >-bbb-B*~~~ore~~~~>
     \~~~~~~~~~/       \         r       \  ROBBER /       \~~~~~~~~~/
      \~~~~~~~/   10    \       r    6    \       /   10    \*~~~~~~/
       >-----<   wood    >-----<   brick   >-----<   sheep   >-----<
      /~~~~~~~\         /       \         /       \         /~~~~~~~\
     /~~~~~~~~~\       /   12    \       /    2    \       /~~~~~~~~~\
    <~~~~~~~~~~~>-yyy-Y   grain   >-----<   stone   >-----<~~~~~~~~~~~>  
     \~~~~~~~~~/       \         /       \         /       \~~~~~~~~~/
      \~~~~~~~/    6    \       /    4    \       /   12    \~~~~~~~/
       >-----<   grain   >-----<   sheep   >-----<   brick   >-----<
      /~~~~~~*y         /       \         /       \         /*~~~~~~\
     /~~~~~~~~~y       /   11    \       /    5    \       /~~~~~~~~~\
    <~~~~3:1~~~*Y-----<   wood    >-----<   grain   >-----<*~~~3:1~~~~>
     \~~~~~~~~~/~~~~~~~\         /       b         /~~~~~~~\~~~~~~~~~/
      \~~~~~~~/~~~~~~~~~\       /    5    b       /~~~~~~~~~\~~~~~~~/
       >-----< ~~~~~~~~~~>-----<   sheep   B-----<~~~~~~~~~~~>-----<
              \~~~~~~~~~/*~~~~~*\         /*~~~~~*\~~~~~~~~~/
               \~~~~~~~/~~~~~~~~~\       /~~~2:1~~~\~~~~~~~/
                >-----<~~~~3:1~~~~>-----<~~~grain~~~>-----<
                       \~~~~~~~~~/~~~~~~~\~~~~~~~~~/
                        \~~~~~~~/~~~~~~~~~\~~~~~~~/
                         >-----<~~~~~~~~~~~>-----<
                                \~~~~~~~~~/
                                 \~~~~~~~/
                                  >-----<

Red has built an interior settlement at the intersection of an 8-sheep, 9-wood, and 6-brick tiles, with a road extending to the southwest (bottom-left). Red's second settlement was placed on the coast at the intersection of a 4-brick and 9-stone, which is also a 2:1-sheep port. You can also see how the other four colors started their game.

Later in the game, after more roads and settlements have been built, and after some were upgraded to cities, the same map might look like this

                                  >-----<
                                 /~~~~~~~\
                                /~~~~~~~~~\
                         >-----<~~~~3:1~~~~>-----<
                        /~~~~~~~\~~~~~~~~~/~~~~~~~\
                       /~~~~~~~~~\*~~~~~*/~~~~~~~~~\
                >-----<~~~~~~~~~~~>-----G~~~~~~~~~~~>-----<
               /~~~~~~~\~~~~~~~~~/       g~~~~~~~~~/~~~~~~~\
              /~~~2:1~~~\~~~~~~~/    8    g~~~~~~~/~~~2:1~~~\
       >-----<~~~wood~~~*>-ggg-G   wood    >-----<*~~sheep~~~>-----<
      /~~~~~~~\~~~~~~~~~g       \         g       \~~~~~~~~~/~~~~~~~\
     /~~~~~~~~~\~~~~~~*g    11   \       g    4    \*~~~~~~/~~~~~~~~~\
    <~~~~~~~~~~~>-----G   brick   >-gggGG   brick   R-----<~~~~~~~~~~~>
     \~~~~~~~~~/       g         /       \         r       \~~~~~~~~~/
      \~~~~~~~/    3    g       /    9    \       r    9    \~~~~~~~/
       >-----<   grain   >-----<   wood    >-rrr-<   stone   >-----<
      /~~~~~~~\         /       \ ROBBER  r       \         /~~~~~~~\
     /~~~2:1~~~\       /    8    \       r         \       /~~~2:1~~~\
    <~~~brick~~*>-----R   sheep  RR-rrrr<   desert  >-bbbBB*~~~ore~~~~>
     \~~~~~~~~~/       r         r       \         b       \~~~~~~~~~/
      \~~~~~~*/   10    r       r    6    \       b   10    \*~~~~~~/
       >-----<   wood    >-rrr-<   brick   B-bbb-<   sheep   >-----<
      /~~~~~~~\         /       \         /       \         /~~~~~~~\
     /~~~~~~~~~\       /   12    \       /    2    \       /~~~~~~~~~\
    <~~~~~~~~~~~>-yyyYY   grain   >-----<   stone   >-----<~~~~~~~~~~~>  
     \~~~~~~~~~y       y         /       \         /       \~~~~~~~~~/
      \~~~~~~~y    6    y       /    4    \       /   12    \~~~~~~~/
       >-----<   grain   >-yyyYY   sheep   B-----<   brick   >-----<
      /~~~~~~*y         /       \         b       \         /*~~~~~~\
     /~~~~~~~~~y       /   11    \       b    5    \       /~~~~~~~~~\
    <~~~~3:1~~~*Y-yyy-<   wood    >-----<   grain   >-----<*~~~3:1~~~~>
     \~~~~~~~~~/~~~~~~~y         /       b         /~~~~~~~\~~~~~~~~~/
      \~~~~~~~/~~~~~~~~~y       /    5    b       /~~~~~~~~~\~~~~~~~/
       >-----< ~~~~~~~~~~>-----<   sheep   BB----<~~~~~~~~~~~>-----<
              \~~~~~~~~~/*~~~~~*\         /*~~~~~*\~~~~~~~~~/
               \~~~~~~~/~~~~~~~~~\       /~~~2:1~~~\~~~~~~~/
                >-----<~~~~3:1~~~~>-----<~~~grain~~~>-----<
                       \~~~~~~~~~/~~~~~~~\~~~~~~~~~/
                        \~~~~~~~/~~~~~~~~~\~~~~~~~/
                         >-----<~~~~~~~~~~~>-----<
                                \~~~~~~~~~/
                                 \~~~~~~~/
                                  >-----<

Now notice that red has built an additional settlement (3-grain,8-sheep,10-wood) and upgraded its first settlement to a city (double letter). (The extra letter on a city always is on the nearby horizontal hex border, rather than intruding into the hex itself, which messes up ports.) Red may also have the Longest Road award, unless yellow built it's seventh road section first. Oh, and do you see the robber? It's on the 9-wood, possibly placed there by yellow to slow red's road production!

WARNING #1: Do not quote the map from one email message to the next, accumulating > or other typical quote characters on the left margin. Before long the map will be pushed far enough that other emailers will wrap the lines greater than 80 characters (or less), at which point it will take some text editing surgery to piece it back together. If your emailer has a Send Again, Forward, or other option that doesn't indent the previous message, use that. Otherwise, copy and paste the existing map into the new message.

WARNING #2: The map white space is entirely spaces, not tabs. Do not use tabs, as different platforms interpret them differently, probably causing the map to be greatly distorted.


2. The Cards
Resource cards come from unshuffled decks, and it is known to everyone at the "table" what resource is drawn by whom. That's easy for PBEM. If a 6 is rolled in the later game map above, red collects two brick (or clay) resource card, blue gets one brick card, and yellow scores big with three grain. Everyone knows this. Though the rules of the game are written with each player's hand of resource cards being hidden, it is easy enough with email records to keep track of everyone's holdings. I and others have played the game with open, face-up holdings of resource cards, and it doesn't seem to affect the game play hardly at all. Since this will facilitate PBEM play, this is recommended. To that end, each turn record (see section 3), will include four lines listing the resource holdings of each color, updated that turn by whoever rolled the dice. (Basically, whoever rolled the dice is responsible for updating the state of the game on the map and turn record.)

When the robber is placed, allowing a player to steal a resource card, it's too powerful to let the open hand be picked for a particular resource. Instead, the player who placed the robber simply chooses who to steal from, then rolls dice or uses some other method to *randomly* pick one from the other player. The honor system comes into play here, of course. It is suggested that the roll of a single die ought to work for most situations, since players don't often have more than six cards, especially if a seven was just rolled. (Though here's an instance where inactive players, the one(s) who must discard, must update the turn record.)

The special cards are a little different, since they come from a shuffled deck, and often need to be kept secret from the other players. Though there may be ways to handle a shuffled deck in PBEM, for this game a simpler approach is to use a 2d6 roll, a probability table, and the honor system. In other words, when someone turns in stone/grain/sheep to draw a special card, that person secretly rolls 2d6 and consults the following table.

     Die roll        Card drawn
     --------        ----------
       2,3           Monopoly
        4            Discovery
       5-8           Knight
       9,10          Victory Point
      11,12          Road Building

Everyone else will know that a special card was drawn, but not which one, since the die roll is secret (that's where the honor system comes in). The fact that a player has one or more hidden/face-down special cards is known, and noted in the turn record. That player will have to keep their own private record of what they're holding, for instance a local text file, or maybe just a sticky-note attached to the computer screen! When the special is played, then its identity is revealed. Knights and Victory Points stick around for the rest of the game, listed in the turn record, while the others don't need any notation after they're used.

[As a curious aside, the card distribution worked out perfectly so that the correct quantities turn up on a nominal 2d6 bell curve. With 36 cards, there are 20 Knights, 7 VPs, and 3 each of Monopoly, Discovery, and Road Building. Of course the dice will stray from that a bit, causing more or less knights than in a real, shuffled special deck. But that's hardly a problem. Also, I've heard that the distribution of cards in the German editions is almost, but not quite the same.]

The Longest Road and Largest Army special award cards are also noted in the turn record.

The easiest way to use dice is certainly to keep a couple near where you read your email (work, school, home, etc.), rolling them discreetly, and trusting everyone with the honor system. (Frankly, I don't see the point of PBEM gaming without the honor system.) Alternatively, use the web-based dice-roller at Irony Games, or the email one at Shadow Island Games. The real geeks among us may want to write our own little programs. Bonus points for using a 1980s programmable calculator! :)


3. The Turn Record (and trading)
Every turn the active player will roll the dice, apply the result for everyone, and record the new gamne-state in a standardized email message, the turn record. An example is shown here. It's red's turn, and that player rolls a 10. The resource collection is noted for each color, and the current holdings are updated (for instance, red had wood x2 before this turn). It is suggested that the building and special card die roll tables be attached to the bottom of the map. The listing of colors at the top should be in player order, and will not vary from turn to turn (though the holdings will).

The players comments go up here!
===========================================================================
PBEM Settlers of Catan, original game published by Mayfair Games.


This turn: Red (turn #15)
Next turn: Blue (turn #16)

Die roll=10 (Red: wood, Blue: sheep x2, Green: nothing, Yellow: wood x2)

Red (Moe)    : brick x2, wood x3, stone -- Longest Road, VP, special
Blue (Larry) : sheep x7, brick
Green (Curly): wood, brick
Yellow (Shep): grain, wood x2 -- Biggest Army, Knightx3

Trade offer(s): MY (wood) for YOUR (any two cards)

                                  >-----<
                                 /~~~~~~~\
                                /~~~~~~~~~\
                         >-----<~~~~3:1~~~~>-----<
                        /~~~~~~~\~~~~~~~~~/~~~~~~~\
                       /~~~~~~~~~\*~~~~~*/~~~~~~~~~\
                >-----<~~~~~~~~~~~>-----G~~~~~~~~~~~>-----<
               /~~~~~~~\~~~~~~~~~/       g~~~~~~~~~/~~~~~~~\
              /~~~2:1~~~\~~~~~~~/    8    g~~~~~~~/~~~2:1~~~\
       >-----<~~~wood~~~*>-ggg-G   wood    >-----<*~~sheep~~~>-----<
      /~~~~~~~\~~~~~~~~~g       \         g       \~~~~~~~~~/~~~~~~~\
     /~~~~~~~~~\~~~~~~*g    11   \       g    4    \*~~~~~~/~~~~~~~~~\
    <~~~~~~~~~~~>-----G   brick   >-gggGG   brick   R-----<~~~~~~~~~~~>
     \~~~~~~~~~/       g         /       \         r       \~~~~~~~~~/
      \~~~~~~~/    3    g       /    9    \       r    9    \~~~~~~~/
       >-----<   grain   >-----<   wood    >-rrr-<   stone   >-----<
      /~~~~~~~\         /       \ ROBBER  r       \         /~~~~~~~\
     /~~~2:1~~~\       /    8    \       r         \       /~~~2:1~~~\
    <~~~brick~~*>-----R   sheep  RR-rrrr<   desert  >-bbbBB*~~~ore~~~~>
     \~~~~~~~~~/       r         r       \         b       \~~~~~~~~~/
      \~~~~~~*/   10    r       r    6    \       b   10    \*~~~~~~/
       >-----<   wood    >-rrr-<   brick   B-bbb-<   sheep   >-----<
      /~~~~~~~\         /       \         /       \         /~~~~~~~\
     /~~~~~~~~~\       /   12    \       /    2    \       /~~~~~~~~~\
    <~~~~~~~~~~~>-yyyYY   grain   >-----<   stone   >-----<~~~~~~~~~~~>  
     \~~~~~~~~~y       y         /       \         /       \~~~~~~~~~/
      \~~~~~~~y    6    y       /    4    \       /   12    \~~~~~~~/
       >-----<   grain   >-yyyYY   sheep   B-----<   brick   >-----<
      /~~~~~~*y         /       \         b       \         /*~~~~~~\
     /~~~~~~~~~y       /   11    \       b    5    \       /~~~~~~~~~\
    <~~~~3:1~~~*Y-yyy-<   wood    >-----<   grain   >-----<*~~~3:1~~~~>
     \~~~~~~~~~/~~~~~~~y         /       b         /~~~~~~~\~~~~~~~~~/
      \~~~~~~~/~~~~~~~~~y       /    5    b       /~~~~~~~~~\~~~~~~~/
       >-----< ~~~~~~~~~~>-----<   sheep   BB----<~~~~~~~~~~~>-----<
              \~~~~~~~~~/*~~~~~*\         /*~~~~~*\~~~~~~~~~/
               \~~~~~~~/~~~~~~~~~\       /~~~2:1~~~\~~~~~~~/
                >-----<~~~~3:1~~~~>-----<~~~grain~~~>-----<
                       \~~~~~~~~~/~~~~~~~\~~~~~~~~~/
                        \~~~~~~~/~~~~~~~~~\~~~~~~~/
                         >-----<~~~~~~~~~~~>-----<
                                \~~~~~~~~~/
                                 \~~~~~~~/
                                  >-----<


SPECIAL CARDS                          BUILDING

Die roll        Card drawn             To build       Turn in
--------        ----------             --------       -------
  2,3           Monopoly               Road           wood, brick
   4            Discovery              Settlement     wood, brick, sheep, grain
  5-8           Knight                 City           grain x2, ore x3
  9,10          Victory Point          Special card   ore, grain, sheep
 11,12          Road Building


Players:
Red:    Moe, moe@stooge.com
Blue:   Larry, larry@u.hello.edu
Green:  Curly, curly@nyuk-nyuk-nyuk.net
Yellow: Shep, shep@slap.gov
===========================================================================


Trading could make a game really bog down waiting for email to go back and forth while haggling. To prevent that from happening, trades are to be done with formal offers in the trade record, responded to with public email (i.e., at least cc'd to all of the players), and resolved within a day. I suppose there's nothing wrong with a little haggling, but I hope that by making a clear offer up front in the turn record (and knowing everyone's resource holdings via the open hands), it should go smoothly. Note the emphasis on MY and YOUR in the trade offer. That helps avoid miscommunications.

4. Generating the Map
The first couple times I made a map, it was by actually laying out a random Settlers map with the real components, then typing its representation into an email message. One of my original players, Muffy Barkocy, devised a much better method, writing a perl script that does it all automatically. Here it is. (If you're not sure what to do with a perl script, find the nearest Unix junkie or dive in yourself.)

#!/usr/local/bin/perl

$ROWS = 14;
$COLS = 7;

#
# board is a set of hexes
#
# hexes have:
#
# type = water, port, empty, wood, brick, sheep, grain, ore, desert
# slice = top, bottom
# roll = die roll
# port = type of port (three, wood, brick, sheep, grain, ore)
#
@board = (
# row 0
[{type => 'empty', slice => 'bottom'},
 {type => 'empty', slice => 'top'},
 {type => 'empty', slice => 'bottom'},
 {type => 'port', slice => 'top'},
 {type => 'empty', slice => 'bottom'},
 {type => 'empty', slice => 'top'},
 {type => 'empty', slice => 'bottom'}],
#row 1
[{type => 'empty', slice => 'top'},
 {type => 'empty', slice => 'bottom'},
 {type => 'water', slice => 'top'},
 {type => 'port', slice => 'bottom'},
 {type => 'water', slice => 'top'},
 {type => 'empty', slice => 'bottom'},
 {type => 'empty', slice => 'top'}],
#row 2
[{type => 'empty', slice => 'bottom'},
 {type => 'port', slice => 'top'},
 {type => 'water', slice => 'bottom'},
 {type => 'resource', slice => 'top'},
 {type => 'water', slice => 'bottom'},
 {type => 'port', slice => 'top'},
 {type => 'empty', slice => 'bottom'}],
#row 3
[{type => 'water', slice => 'top'},
 {type => 'port', slice => 'bottom'},
 {type => 'resource', slice => 'top'},
 {type => 'resource', slice => 'bottom'},
 {type => 'resource', slice => 'top'},
 {type => 'port', slice => 'bottom'},
 {type => 'water', slice => 'top'}],
#row 4
[{type => 'water', slice => 'bottom'},
 {type => 'resource', slice => 'top', roll => 1},
 {type => 'resource', slice => 'bottom'},
 {type => 'resource', slice => 'top'},
 {type => 'resource', slice => 'bottom'},
 {type => 'resource', slice => 'top'},
 {type => 'water', slice => 'bottom'}],
#row 5
[{type => 'port', slice => 'top'},
 {type => 'resource', slice => 'bottom'},
 {type => 'resource', slice => 'top'},
 {type => 'resource', slice => 'bottom'},
 {type => 'resource', slice => 'top'},
 {type => 'resource', slice => 'bottom'},
 {type => 'port', slice => 'top'}],
#row 6
[{type => 'port', slice => 'bottom'},
 {type => 'resource', slice => 'top'},
 {type => 'resource', slice => 'bottom'},
 {type => 'resource', slice => 'top'},
 {type => 'resource', slice => 'bottom'},
 {type => 'resource', slice => 'top'},
 {type => 'port', slice => 'bottom'}],
#row 7
[{type => 'water', slice => 'top'},
 {type => 'resource', slice => 'bottom'},
 {type => 'resource', slice => 'top'},
 {type => 'resource', slice => 'bottom'},
 {type => 'resource', slice => 'top'},
 {type => 'resource', slice => 'bottom'},
 {type => 'water', slice => 'top'}],
#row 8
[{type => 'water', slice => 'bottom'},
 {type => 'resource', slice => 'top'},
 {type => 'resource', slice => 'bottom'},
 {type => 'resource', slice => 'top'},
 {type => 'resource', slice => 'bottom'},
 {type => 'resource', slice => 'top'},
 {type => 'water', slice => 'bottom'}],
#row 9
[{type => 'port', slice => 'top'},
 {type => 'resource', slice => 'bottom'},
 {type => 'resource', slice => 'top'},
 {type => 'resource', slice => 'bottom'},
 {type => 'resource', slice => 'top'},
 {type => 'resource', slice => 'bottom'},
 {type => 'port', slice => 'top'}],
#row 10
[{type => 'port', slice => 'bottom'},
 {type => 'water', slice => 'top'},
 {type => 'resource', slice => 'bottom'},
 {type => 'resource', slice => 'top'},
 {type => 'resource', slice => 'bottom'},
 {type => 'water', slice => 'top'},
 {type => 'port', slice => 'bottom'}],
#row 11
[{type => 'empty', slice => 'top'},
 {type => 'water', slice => 'bottom'},
 {type => 'port', slice => 'top'},
 {type => 'resource', slice => 'bottom'},
 {type => 'port', slice => 'top'},
 {type => 'water', slice => 'bottom'},
 {type => 'empty', slice => 'top'}],
#row 12
[{type => 'empty', slice => 'bottom'},
 {type => 'empty', slice => 'top'},
 {type => 'port', slice => 'bottom'},
 {type => 'water', slice => 'top'},
 {type => 'port', slice => 'bottom'},
 {type => 'empty', slice => 'top'},
 {type => 'empty', slice => 'bottom'}],
#row 13
[{type => 'empty', slice => 'top'},
 {type => 'empty', slice => 'bottom'},
 {type => 'empty', slice => 'top'},
 {type => 'water', slice => 'bottom'},
 {type => 'empty', slice => 'top'},
 {type => 'empty', slice => 'bottom'},
 {type => 'empty', slice => 'top'}],
);

@rolls = (11, 3, 6, 5, 4, 9, 10, 8, 4, 11, 12, 9, 10, 8, 3, 6, 2, 5);

&set_resources();
&set_rolls();


print<<EOF;
===========================================================================

PBEM Settlers of Catan, original game published by Mayfair Games.
Game #
===========================================================================

This turn:
Next turn:

-----------------------------------------------------------------------
| Resource collection and die roll histogram                          |
|---------------------------------------------------------------------|
|  Roll   |  Blue   |  Green  |   Red   | Yellow  |     Histogram     |
|---------|---------|---------|---------|---------|-------------------|
|        2|         |         |         |         |                   |
|        3|         |         |         |         |                   |
|        4|         |         |         |         |                   |
|        5|         |         |         |         |                   |
|        6|         |         |         |         |                   |
|        7|---------|---------|---------|---------|                   |
|        8|         |         |         |         |                   |
|        9|         |         |         |         |                   |
|       10|         |         |         |         |                   |
|       11|         |         |         |         |                   |
| ***** 12|         |         |         |         |                   |
|----------------------------------------------------------------------
| Resource|         |         |         |         |
| Holdings|         |         |         |         |
|-------------------------------------------------|
|  Wood   |         |         |         |         |
|  Brick  |         |         |         |         |
|  Sheep  |         |         |         |         |
|  Grain  |         |         |         |         |
|   Ore   |         |         |         |         |
|         |---------|---------|---------|---------|
|  Cards  |         |         |         |         |
| Knights |         |         |         |         |
| L-Army  |         |         |         |         |
| L-Road  |         |         |         |         |
|  VPs    |         |         |         |         |
---------------------------------------------------

Trade offer(s):

Actions:

Build:

EOF

&print_board();
print<<EOF;

SPECIAL CARDS                     BUILDING

Die roll        Card drawn        To build       Turn in
--------        ----------        --------       -------
  2,3           Monopoly          Road           wood, brick
   4            Discovery         Settlement     wood, brick, sheep, grain
  5-8           Knight            City           grain x2, ore x3
  9,10          Victory Point     Special card   ore, grain, sheep
 11,12          Road Building

Players:
Blue:   
Green:  
Red:    
Yellow:
===========================================================================
EOF

#
# subroutines
#
sub print_board {
  my ($row, $col, $line);

  for $row (0..$ROWS - 1) {
      for $line (0..2) {
       print "  ";
       for $col (0..$COLS - 1) {
           my $type = $board[$row][$col]{'type'};
           my $slice = $board[$row][$col]{'slice'};
           my $roll = $board[$row][$col]{'roll'};
           my ($first_char, $char, $last_char);
           if (($type eq 'water') || &is_port($type)) {
            $char = '~';
           } else {
            $char = ' ';
           }
           if ($slice eq 'top') {
            $chars = 5 + ($line * 2);
            if ($col == 0) {
                &print_char(' ', 3 - $line);
            }
            if ($type eq 'empty') {
                $first_char = ' ';
                $last_char = ' ';
            } else {
                if ($line == 0) {
                 $first_char = '>';
                 $last_char = '<';
                 $char = '-';
                } else {
                 $first_char = '/';
                 $last_char = '\\';
                }
            }
            if ((&is_port($type)) && ($type ne 'three') &&
                ($line == 2)) {
                print "/~~~2:1~~~\\";
                $first_char = $last_char = $char = '';
            }
            if (($line == 2) && $roll) {
                print "/";
                print "    ${roll}   ";
                if ($roll < 10) {
                 print " ";
                }
                print "\\";
                $first_char = $last_char = $char = '';
            }
            if (((($row - $col) == 11) ||
                 (($row - (6 - $col)) == 11) ||
                 ($row == 14)) && ($line == 0)) {
                $first_char = '>';
                $char = '-';
                $last_char = '<';
            }
            if ((($row - $col) == 11) && $line) {
                $last_char = '\\';
            }
            if ((($row - (6 - $col)) == 11) && $line) {
                $first_char = '/';
            }
            if (&is_port($type) && ($row == 11) && ($line == 1)) {
                $first_char .= '*';
                $last_char = '*' . $last_char;
                $chars -= 2;
            }
            if (&is_port($type) && ($row == 9) && ($line == 1)) {
                if ($col == 0) {
                 $last_char = '*' . $last_char;
                } else {
                 $first_char .= '*';
                }
                $chars--;
            }
           } else {
            $first_char = '';
            if (($type ne 'empty') && ($col == 6)) {
                if ($line) {
                 $last_char = '/';
                } else {
                 $last_char = '>';
                }
            } else {
                $last_char = '';
            }
            $chars = 5 + ((3 - $line) * 2);
            if ($col == 0) {
                if ($type eq 'empty') {
                 &print_char(' ', $line + 1);
                } else {
                 &print_char(' ', $line);
                 ($line) ? print '\\' : print '<';
                }
            }
            if (($type eq 'desert') && ($line == 1)) {
                print '  ROBBER ';
                $first_char = $last_char = $char = '';
            }
            if (&is_resource($type) && ($line == 0)) {
                print '  ';
                if ($type eq 'ore') {
                 print '  ore  ';
                } elsif ($type eq 'wood') {
                 print ' wood  ';
                } elsif ($type eq 'desert') {
                 print ' desert';
                } else {
                 print " $type ";
                }
                print '  ';
                $first_char = $last_char = $char = '';
            }
            if (&is_port($type) && ($line == 0)) {
                if ($col > 4) {
                 print '*~';
                } else {
                 print '~~';
                }
                if ($type eq 'orep') {
                 print '~~ore~~';
                } elsif ($type eq 'woodp') {
                 print '~wood~~';
                } elsif ($type eq 'three') {
                 print '~~3:1~~';
                } else {
                 chop($type);
                 print "~$type~";
                }
                if ($col < 2) {
                 print '~*';
                } else {
                 print '~~';
                }
                $first_char = $last_char = $char = '';
                if ($col == 6) {
                 $last_char = '>';
                }
            }
            if (&is_port($type) && ($row == 6) && ($line == 2)) {
                if ($col == 0) {
                 $last_char = '*' . $last_char;
                } else {
                 $first_char .= '*';
                }
                $chars--;
            }
            if (&is_port($type) && ($row == 3) && ($line == 2)) {
                if ($col == 1) {
                 $last_char = '*' . $last_char;
                } else {
                 $first_char .= '*';
                }
                $chars--;
            }
            if (&is_port($type) && ($row == 1) && ($line == 2)) {
                $first_char .= '*';
                $last_char = '*' . $last_char;
                $chars -= 2;
            }
           }
           print $first_char;
           print_char($char, $chars);
           print $last_char;
       }
       print "\n";
      }
  }
  print "                                >-----<\n";
}

sub is_port {
    my ($type) = @_;
    return (($type eq 'woodp') ||
         ($type eq 'brickp') ||
         ($type eq 'sheepp') ||
         ($type eq 'grainp') ||
         ($type eq 'orep') ||
         ($type eq 'three'))    
}

sub is_resource {
    my ($type) = @_;
    return (($type eq 'wood') ||
         ($type eq 'brick') ||
         ($type eq 'sheep') ||
         ($type eq 'grain') ||
         ($type eq 'ore') ||
         ($type eq 'desert'));
}

sub print_char {
    my ($char, $times) = @_;
    my $i;
    if ($times) {
     for $i (1..$times) {
         print $char;
     }
    }
}

sub set_resources {
    my @resources = ('desert',
               'wood', 'wood', 'wood', 'wood',
               'brick', 'brick', 'brick',
               'sheep', 'sheep', 'sheep', 'sheep',
               'grain', 'grain', 'grain', 'grain',
               'ore', 'ore', 'ore');
    my @ports = ('three', 'three', 'three', 'three',
           'woodp', 'brickp', 'sheepp', 'grainp', 'orep');

    srand;
    my ($row, $col, $num);

    for $row (0..$ROWS) {
     for $col (0..$COLS) {
         my $type = $board[$row][$col]->{'type'};
         if ($type eq 'resource') {
          $num = int(rand(19));
          while (!$resources[$num]) {
              $num = int(rand(19));
          }
          my $res = $resources[$num];
          $board[$row][$col]->{'type'} = $res;
          $board[$row + 1][$col]->{'type'} = $res;
          $resources[$num] = '';
         } elsif ($type eq 'port') {
          $num = int(rand(10));
          while (!$ports[$num]) {
              $num = int(rand(10));
          }
          my $port = $ports[$num];
          $board[$row][$col]->{'type'} = $port;
          $board[$row + 1][$col]->{'type'} = $port;
          $ports[$num] = '';
         }
     }
    }
}

sub set_rolls {
    set_roll(4, 1);
    set_roll(3, 2);
    set_roll(2, 3);
    set_roll(3, 4);
    set_roll(4, 5);
    set_roll(6, 5);
    set_roll(8, 5);
    set_roll(9, 4);
    set_roll(10, 3);
    set_roll(9, 2);
    set_roll(8, 1);
    set_roll(6, 1);
    set_roll(5, 2);
    set_roll(4, 3);
    set_roll(5, 4);
    set_roll(7, 4);
    set_roll(8, 3);
    set_roll(7, 2);
    set_roll(6, 3);
}

sub set_roll {
    my ($r, $c) = @_;
    if ($board[$r][$c]{'type'} ne 'desert') {
     my $roll = pop(@rolls);
     $board[$r][$c]->{'roll'} = $roll;
    }
}