Our game is set up and ready to play! But now we face the challenge of needing to model how our players would play an actual game.

We can start solving that challenge by determining how players will keep track of the routes they want to claim, the color of the cards they need, and how they can actually make those claims. Let’s get going!

I think I can I think I can I think I can I think I can! Photo by Michał Parzuchowski / Unsplash

The Sample Project

You might want to check out the sample repository over on GitHub to follow along with this post.

exceptionnotfound/TicketToRideModelingPractice

The Player’s Choices

Let’s remind ourselves what a player can do when it is their turn.

I swear, if you take that Nashville to Atlanta route again… DAMMIT KEVIN!

Players have three choices:

  1. The Player can claim an existing route. But in order for them to do this, they have to know what routes they want; they should not just claim random routes, because that won’t help them win.
  2. The Player can draw new destination cards. But if they don’t complete these cards, they count against the player’s point total, so they player should not just draw these at any time.
  3. The Player can draw new train cards. But do they want to draw from the shown cards pile, or off the deck? To make this decision, they need to know what colors they want.

But there’s also one more major feature we need in order to implement these three scenarios: we need to know what routes and colors the Player wants at any given time! We’re going to call this Scenario 0.

We’re going to tackle each of these scenarios separately. In this post, we will deal with Scenarios 0 and 1. The next post will deal with Scenarios 2 and 3.

The Basic Player Class

We first need a Player class. This object will have several properties, and all of them will be used in this post.

public class Player
{
    //The player's name
    public string Name { get; set; }

    //The player's current collection of destination cards.
    public List<DestinationCard> DestinationCards { get; set; } = new List<DestinationCard>();

    //The routes the player wants to claim at any given time.
    public List<BoardRoute> TargetedRoutes { get; set; } = new List<BoardRoute>();

    //All the cities this Player has already connected.
    public List<City> ConnectedCities { get; set; } = new List<City>();

    //The player's color (e.g. red, blue, black, green, or yellow)
    public PlayerColor Color { get; set; }

    //The Player's current collection of train cards.
    public List<TrainCard> Hand { get; set; } = new List<TrainCard>();

    //When one player has < 2 train cars the remaining, the final turn begins.
    public int RemainingTrainCars { get; set; } = 48;

    //The train card colors this Player wants to draw.
    public List<TrainColor> DesiredColors { get; set; } = new List<TrainColor>();

    //A reference to the game board
    public Board Board { get; set; }

    public void TakeTurn()
    {
        //...Implementation in this post and the next
    }
}

Scenario 0: Finding Targeted Routes

In order for the players to know what routes they’d like to claim, we are going to make them “target” these routes by storing a collection of them. Not surprisingly, this is the TargetedRoutes property in the base Player object.

Let’s pretend our player starts the game with two destination cards: Duluth to Houston, and Winnipeg to New Orleans.

Can you tell me how to get, how to get to Sesame Street?

The ideal routes algorithm will find the following routes for these destination cards.

Duluth -> Omaha -> Kansas City -> Oklahoma City -> Dallas -> Houston

and

Winnipeg -> Duluth -> Omaha -> Kansas City -> Oklahoma City -> Little Rock -> New Orleans

Those two routes share a lot of the same route segments. Therefore, it is more important to the player to claim the ones that are shared amongst different destination card ideal routes, rather than routes that are only used for one card. We will need to make sure the “common” route segments are claimed first, lest another player claim them and our destination cards get more difficult to complete.

(IMPORTANT NOTE: There are many different ways we could say what is “important” to the player; claiming common routes is just one of them. For example, we could say that access to the cities is more important than common routes, and make the Player claim a route leading into the origin and destination cities before worrying about how to connect them. One of the reasons why Ticket to Ride is such a fun game is that there are multiple ways to assess the core problem of connecting city A to city B.)

To accomplish all this, let’s create a CalculateTargetedRoutes() method in the Player object that accepts a Destination Card and returns the ideal routes for that card:

public class Player
{
    //...Properties

    public List<BoardRoute> CalculateTargetedRoutes(DestinationCard card)
    { }
}

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

Modeling Ticket to Ride in C# Part 4: Player Claiming Routes
1.75 GEEK