From d1d342ee0f5a7b804130b7a9229d87f6273a5673 Mon Sep 17 00:00:00 2001
From: Tyler Hallada <tyler@hallada.net>
Date: Sun, 15 Apr 2018 02:54:35 -0400
Subject: [PATCH] Trains have own color, passengers can stay on

---
 src/Train.ts     |  6 +++++-
 src/transport.ts | 31 ++++++++++++++++++++++---------
 2 files changed, 27 insertions(+), 10 deletions(-)

diff --git a/src/Train.ts b/src/Train.ts
index 36f2ca5..b5f14e9 100644
--- a/src/Train.ts
+++ b/src/Train.ts
@@ -1,3 +1,5 @@
+import * as tinycolor from 'tinycolor2';
+
 import Station from './Station';
 
 let trainCount = 0;
@@ -10,14 +12,16 @@ export default class Train {
   public passengers: number;
   public id: number;
   public label: PIXI.Text;
+  public color: tinycolorInstance;
 
   constructor(location: PIXI.Point, speed: number, passengers: number, origin: Station,
-              destination: Station) {
+              destination: Station, color: tinycolorInstance) {
     this.location = location;
     this.speed = speed;
     this.origin = origin;
     this.destination = destination;
     this.passengers = passengers;
+    this.color = color;
 
     // for debugging
     trainCount += 1;
diff --git a/src/transport.ts b/src/transport.ts
index 24c7f63..4fd4802 100644
--- a/src/transport.ts
+++ b/src/transport.ts
@@ -37,7 +37,7 @@ const initTrains = (numTrains: number, stations: Station[]): Train[] => {
     const originStation = stations[Math.floor(Math.random() * stations.length)];
     trains.push(new Train(
       new PIXI.Point(originStation.location.x, originStation.location.y),
-      0, 0, originStation, undefined),
+      0, 0, originStation, undefined, tinycolor('grey')),
     );
   }
   return trains;
@@ -54,8 +54,20 @@ const moveTrains = (trains: Train[], stations: Station[]) => {
       train.destination = weightedRandom(closeStations, closeStationWeights);
 
       // board passengers
-      train.passengers += randomInt(0, TRAIN_CAPACITY);
-      train.origin.population -= randomInt(0, TRAIN_CAPACITY);
+      const boardingPassengers = randomInt(0, Math.min(TRAIN_CAPACITY - train.passengers,
+                                                       train.origin.population));
+      // set or mix train color with the color of new passenger origin
+      if (train.passengers === 0) {
+        train.color = train.origin.color;
+      } else {
+        train.color = tinycolor.mix(
+          train.color,
+          train.origin.color,
+          Math.round((boardingPassengers / train.passengers) * 100),
+        );
+      }
+      train.passengers += boardingPassengers;
+      train.origin.population -= boardingPassengers;
     }
 
     // train reached destination, stop moving and let passengers off
@@ -71,8 +83,9 @@ const moveTrains = (trains: Train[], stations: Station[]) => {
       );
 
       // transfer passengers to destination
-      train.destination.population += train.passengers;
-      train.passengers = 0;
+      const disembarkingPassengers = randomInt(0, train.passengers);
+      train.destination.population += disembarkingPassengers;
+      train.passengers -= disembarkingPassengers;
 
       // prepare for next journey
       train.origin = train.destination;
@@ -111,7 +124,7 @@ const drawStations = (stations: Station[], graphics: PIXI.Graphics) => {
 
 const drawTrains = (trains: Train[], graphics: PIXI.Graphics) => {
   for (const train of trains) {
-    graphics.beginFill(parseInt(train.origin.color.toHex(), 16), 0.8);
+    graphics.beginFill(parseInt(train.color.toHex(), 16), 0.8);
     graphics.drawCircle(train.location.x, train.location.y,
                         rangeMap(train.passengers, 0, TRAIN_CAPACITY, 1, 5));
     graphics.endFill();
@@ -186,9 +199,9 @@ const run = () => {
   app.stage.addChild(graphics);
   app.stage.addChild(fpsText);
   // Add debug labels
-  // for (const train of trains) {
-    // app.stage.addChild(train.label);
-  // }
+  for (const train of trains) {
+    app.stage.addChild(train.label);
+  }
   for (const station of stations) {
     app.stage.addChild(station.label);
   }