Generating random demand decks

None of the information on this page is necessary for printing and using our generated decks. But if you're curious as to how we come up with the payoffs, what demands can appear together on a card, and so forth, here are the gory details.

There are several steps involved in creating a random demand deck. First, we have to be able to decide what the payoff should be for a given commodity at a given destination. Second, we have to decide which demands to include in the deck. Third, we have to combine the demands into sets of three to form the cards. Finally, we have to shuffle the cards, and determine where in the deck the Taxes event should arise (possibly more than once).

Determining payoffs

Payoffs are mostly a function of distance, but the distance used is the length of the cheapest track (not necessarily the shortest). The program reads a data file describing the map (including terrain at each milepost, where the rivers are, etc.) and computes the distance and cost of the cheapest track between each pair of cities.

In a few cases we treat part of the map as impassable to eliminate the possibility of track that, though cheaper, would never reasonably get built. (An example is Nippon track that "turns the corner" from Fukui to get to Matsue without going through Osaka. Another example is the Canadian route from Winnepeg to Sudbury on the Empire Builder map.)

If the cost of the cheapest track is not $1 per pip, the payoff varies a bit to account for this, but distance is still the main factor unless the difference is large.

Note: Building costs do not include the cost of building into cities, since in most cases you will already have track to at least one of the cities. Track using a ferry includes the cost of the ferry, but in computing the distance of that track the ferry is treated as 6 pips (1/2 turn for a super). See our rules variants for a suggested variant for ferry movement.

There is no random element. The payoff for a given good to a given city is always the same in every deck. Some destinations pay off a bit extra to encourage going there. Some of these bonuses are computed automatically based on "how far in the dingles" a city is; some are added by hand. Similarly, a few goods may pay an extra dollar or two to encourage picking up those goods. However, there are roughly the same number of demands for each good, so there is no bonus for "rarely demanded" goods such as tobacco in Empire Builder.

The early formula paid too much for particularly long runs, so we reduced the payoff for long runs. This compensates for the value inherent in not having "dead time" while you fetch new loads or toss cards.

The formula is:

D=distance of cheapest track
C=cost of cheapest track
R=ratio of cost to distance = C / D
B=basis of payoff, computed thus:
if R <= 1:B = D * (1 - (R-1)^2)
if sqrt(2) >= R >= 1:B = D * (1 + (R-1)^2)
if R >= sqrt(2):B = C * 2 * (sqrt(2) - 1)
P=payoff = 7/9 * B - D^2 / 1000 + 1.85 + dingles, rounded down

For example, in Empire Builder, Fish to Cincinnati pays $10 by our formula. The best source is Norfolk, and the cheapest route from there to Cincinnati (ignoring the cost of cities) is straight to Pittsburgh, then northwest to finish going around the river, then over to Cincy, a distance of 11 mileposts costing $13. Using the above formula, R = 13/11, so B = 11 plus 11*(2/11)^2 = 11.364 (i.e., slightly more than just the distance of 11, because the track costs slightly more than 11), and the payoff is then 7/9 * 11.364 - 0.121 + 1.85 + 0 (no dingles element) = 10.567, rounded down to $10.

In Lunar Rails and Martian Rails, the "D^2 / 1000" term is reduced to account for the faster engines available (i.e., a set of long runs doesn't keep the train busy for as many turns). There's also an across-the-board 15% bonus added to all Lunar/Martian payoffs in order to generate the cash needed for building on such hostile terrain. This bonus brings our average payoffs up to where they approximately match the average payoffs in the decks that come with the games.

Dingles

The "dingles" term is based on how far the destination is from being on a route connecting major cities. For any given destination, it is computed as follows:

For each major city, note the cost of building from it to the destination. For each pair of major cities, sum the cost of building to the destination from both cities, and subtract the cost of building directly between the two major cities. Take the minimum of all these costs (for single or paired major cities); this is the preliminary dingle metric. Also compute an "access metric" which is the sum of the costs of building to the destination from all major cities.

Next, reduce the dingle metric at the city based on the goods available there. For each good produced, examine all sources of the good to find the one with the lowest access metric. Divide this lowest access metric by this city's access metric. Subtract three times the cube of this ratio from this city's dingle metric. (Thus, in particular, if a city is the most accessible source (possibly the only source) of some good, the city's dingle metric is reduced by 3. The "cube" part of this computation was added in February, 2005 to accomodate the Russian map; see here for more about what changed.)

For each map we manually choose a dingle threshhold T and a rate of increase I. If a destination has a dingle metric of M, then if M < T there is no added payoff. Otherwise the payoff is increased by

1 + (M - T) / I .
The card generation program has a mode in which it computes the dingle metrics and displays them, so we can decide on values for T and I.

In addition to the dingles adjustment, we sometimes toss in a small adjustment (up or down) to the payoffs depending on the commodity and/or the destination, to try to fine tune the values for a particular map. For instance, we pay an extra $1 for deliveries to Calgary in Empire Builder or Matsue in Nippon Rails, and we subtract 2 from the already lucrative Jute payoffs in British Rails.

Generating demands

In the following discussion, we'll assume the deck contains 360 demands (120 cards). It's fairly obvious what parts change for other size decks.

First, we decide on the goods. Start by taking an equal number of each good, such that the total is as close to 360 as possible. If the total is not exactly 360, we add or remove enough different goods to bring the total to 360. (The goods added/removed are chosen randomly from the full complement.) Then, to get just a bit of variety, we take the list of goods, omitting those that were added/removed to adjust the total, and for 1/4 of them we remove one from the mix, and for 1/4 of them we add one to the mix.

Again, we may adjust the number of each good slightly, to try to fine tune for a particular map. So far we do this only for British Rails, slightly reducing the number of payoffs for Jute, Chemicals, and Oats, while increasing the number for Oil, Fish, Sugar, and so forth, to try to pull people away from the standard western corridor.

Having chosen which commodities to use, we now pick the destinations. One of the features we're going for in this step is that cities that are useful as sources for goods tend to appear less often as destinations, while cities that are not useful as sources receive more deliveries than other cities of the same size.

We start by giving the cities relative weights based on their size. It helps if the sum of the weights is about 360; it means the numbers give a first approximation of how often each destination will be used in a 120-card deck. In Empire Builder and Nippon Rails we use 11-8-6 for major-medium-small, but for Eurorails we use 9-7-5. (In each case, we may make small adjustments to tune the decks.) These numbers are the "city weights".

We then track a "usage total" for each city, starting the total at zero for all cities (except as modified below). Each time we need a destination, we pick the city with the lowest usage total, breaking ties randomly. The destination's usage total is then increased by 1 over its city weight. Thus if the cities are chosen in the proportion indicated by their weights, the final usage totals will be all equal.

As mentioned earlier, we want to adjust the city mix so that a city that is useful as a source of goods is not chosen as often to be a destination. How useful a city is as a source depends somewhat on where its good is being demanded, but as a first cut we make an adjustment based solely on how often each good appears in this deck's mix of goods. For each good available at a city, we increase the initial usage total at that city by (number of times the good appears in this deck) times 0.25, divided by (number of cities where the good is produced), divided by the city's weight. The 0.25 means that if a city is the unique source for a good, then for every 4 demands for that good there will be one less demand using this city as a destination.

Now, taking the 360 goods in a random order, pick a destination for each. To pick a destination, find the city with the lowest usage total, ignoring cities that either (a) are within 2 pips of a source for the good or (b) have already been chosen as a destination for the same good earlier in this deck. (A city is also ignored if the payoff there would be below some minimum; on most maps this minimum is $3, but we noticed that the deck that comes with India Rails has no payoffs lower than $7, so we made that the minimum for our India Rails decks as well.) If there is a tie for lowest usage, break the tie randomly. Then adjust the usage total for the destination as follows: First, add 1 over the city weight, to reflect the city's use as a destination. Next, for each city that produces the good we just used, adjust the usage totals for all sources of that good. At each source, subtract 0.25 divided by the number of possible sources, divided by the sources's city weight. (This reverses the initial increment to usage totals caused by this good.) Then compute the sum, across all sources, of 1 over (distance from source to this desti- nation). Call this S. Finally, for each source, increase the usage total by 0.25 times (1 over the distance to the destination), divided by S, divided by the source city's weight. E.g., if there are two sources at distances 10 and 20, the nearer source gets (0.1 / (0.1+0.05)) = 2/3 of the usage increase and the further source gets 1/3, compared to the 1/2 and 1/2 that they got in the initial usage totals (before the actual destination was known).

Combining demands to form cards

Having picked which goods to use, and assigned a city to each to form a set of demands, we next have to combine the demands in sets of three to form cards. Again, this discussion will assume there are 120 cards.

Over time, we came up with various constraints limiting which demands can appear together on a single card. For starters, we require that each card have a "small" payoff and a "large" payoff. The dividing line is chosen to be the median payoff (across these 360 demands), plus 1. Of the payoffs less than or equal to that amount (typically about 190 to 200 of the 360 in the deck), we choose 120 and assign them to different cards. Then we take the demands with higher payoffs and assign one to each card, making sure we don't violate any of the pairwise constraints (described below). (In the unlikely event we come to a small payoff for which no remaining large payoff will work, we replace the small payoff with one of the unused ones.) Finally, we take the remaining 120 demands and assign them to cards, making sure we don't violate any pairwise or triplewise constraints.

It often happens that we get to the last card or two and find that we cannot assign the last demands to the remaining cards without violating a constraint. If so, we back up and swipe the third demand from an earlier card, and then see if we can fulfill the scavenged card using the remaining demands. This process typically settles down after only a few iterations.

The pairwise and triplewise constraints we've developed so far are as follows. Random sampling shows that about 80% of all possible pairs of demands pass the pairwise constraints, while about 40% of all possible triples pass the full constraints. Not everyone will agree with all the constraints we've chosen to use, but we're making the decks, so we make the rules!

Note: Several of the constraints compare distances against limits such as 12, 24, or 30. These limits are scaled up for Lunar Rails and Martian Rails, where the top speed of trains is 16 instead of 12.

Shuffling the deck

Since the program is also handling shuffling the cards (so it can show when taxes appears), it also ensures that none of the first 5N cards (where N is the number of players) includes any run that cannot be built using starting capital; i.e., connecting the preferred source (not just any source) to the destination via a major city must be possible on the initial money. (It may be off slightly since the track-building cost doesn't include building into cities. But each run on the first 5N cards is at least close enough that it should be doable given even a small intermediate payoff.)

In Lunar Rails and Martian Rails, where players start with $60 but can spend only $40 before the first turn of movement, the initial runs are limited to those that can be built using $50, which means that at least the track to the starting city can probably be built for the initial $40.

To do this, the program finds all cards containing demands that cannot be done in the beginning, and sets those aside. It then shuffles the rest, and picks 5N to start the final deck. It then shuffles the remainder back in with those that were set aside, and sticks them after the initial cards.

Having shuffled the deck, the program decides where the taxes card would be if there were a real card for it. For each card (not counting the first 3N cards, which are dealt out before any building is done), it gives a 1/k chance of the card being preceded by the taxes event, where k is initially the number of cards remaining in the deck at the point the given card is being drawn. When a card does turn out to be preceded by taxes, it checks a further 1/k chance that the deck is "reshuffled" at that point (after first resetting k to be at least half the deck if it was smaller). Note that you should not actually reshuffle the deck; the program merely simulates the effect by using a larger value for k when computing whether taxes occurs before subsequent cards.