With our rules known and our setup complete, we now need to tackle a difficult problem in solving this game: how do we determine the ideal route between two cities?

The Sample Project

As always, there is a sample project on GitHub that has the code we will use here. Check it out!

exceptionnotfound/TicketToRideModelingPractice

Finding Ideal Routes

Let’s imagine that we want to find the best route between San Francisco and Nashville. Both these locations are marked as 1 on the map below.

To start with, let’s determine all the destinations we can reach from each of these cities. From San Francisco, we can reach Portland, Salt Lake City, and Los Angeles. From Nashville, we can reach St. Louis, Pittsburgh, Raleigh, Atlanta, and Little Rock. The “second-order” destinations look like this:

The idea is to continue doing this (i.e. looking at all destinations of all connected cities) until one or more cities show up on both sides.

Continuing this, the “third-order” destinations (i.e. every city connected to each of the second-order cities) would look like this:

Now you might be thinking, “great! On the next order, we will have overlapping cities, and as such can find the connecting routes!” And you’d be right. From the overlapping cities we can isolate routes between San Francisco and Nashville.

Here are all the routes this “naive” algorithm would find:

San Francisco -> Salt Lake City -> Denver -> Kansas City -> Saint Louis -> Nashville (16 spaces)

San Francisco -> Los Angeles -> El Paso -> Dallas -> Little Rock -> Nashville (18 spaces)

San Francisco -> Los Angeles -> El Paso -> Oklahoma City -> Little Rock -> Nashville (19 spaces)

However, we know that these routes are not created equal. The first of these will be easiest to claim because the total length of that route is the smallest of the potential routes. Therefore, the “ideal” route will go through Denver, Kansas City, and Saint Louis.

This kind of algorithm will work perfectly fine if no one has claimed any routes yet. But what if some routes are already claimed?

Finding Best-Possible Routes

Let’s imagine that the game is already well underway, and some routes have already been claimed.

We’re going to try to connect Calgary (top-left of the board, near the number 20) to Denver (middle-left of the board). Note that several routes, including the most direct one, are already claimed by other players (specifically Calgary -> Helena, Helena -> Denver, Helena -> Omaha, and both Duluth -> Omaha routes)

We would prefer to take the routes Calgary -> Helena -> Denver, because that takes the least number of cards and the least number of turns. But that’s impossible now, because those routes are both claimed.

So if our first-order cities are Calgary and Denver, here’s our second order cities, ignoring routes that are already claimed.

From Calgary, our second-order cities are Vancouver, Seattle, and Winnipeg. From Denver, our second-order cities are Salt Lake City, Omaha, Kansas City, Oklahoma City, Santa Fe, and Phoenix.

If we continue this, the algorithm will find the following paths:

Calgary -> Seattle -> Portland -> Salt Lake City -> Denver (14 spaces)

Calgary -> Seattle -> Helena -> Salt Lake City -> Denver (16 spaces)

Calgary -> Winnipeg -> Helena -> Salt Lake City -> Denver (16 spaces)

All these routes will take the same number of turns (4) to claim, However, we know that the first option is the best, because it takes the least amount of trains to claim those routes.

Here’s the secret: the algorithm for both ideal routes and best possible routes is actually the same algorithm! The only difference is that for best-possible routes, the routes which have already been claimed are not even considered. It is like they do not exist in that case.

In short, we expand ever outward from both the origin and destination cities, until the list of cities we can reach from both sides (origin and destination) contains the same city. If there are many of these, we take the one with the least number of total spaces.

With all this in mind, let’s start making this algorithm! Be warned, though: this implementation contains healthy doses of recursion.

#modeling practice #c# #programming-c #csharp

Modeling Ticket to Ride in C# Part 3: Finding Ideal Routes
1.25 GEEK