;;; ;;; Schlieffen Plan Rail Logistics Model ;;; ;;; Spring 2013 ;;; ;;; Robert Allen - averyallen71@gmail.com ;;; Brian Coffey - btpcoffey@gmail.com ;;; Dante Montgomery - dante.e.montgomery@gmail.com ;;; Ashley Rawson - ashleyrawson@gmail.com ;;; Brian Stebar - stebar2@gmail.com soldiers-own [ owner ;; Nation to which this corps belongs army ;; Army assignment within the nation corps ;; Corps assignment within the army num-infantry num-cavalry num-artillery waypoints ;; List of dated waypoints that this corps will traverse ticks-delayed ;; Number of ticks this corps is delayed in traversing the waypoints supply-capacity ;; Maximum supply load that can be carried by this corps current-supplies supplies-requested ;; Number of supplies for which supply requests have been sent ] ;; ;; cause-troop-attrition - global method ;; ;; Kills off a number of troops based on the troop-attrition-rate ;; NOTE: this should only be used with the 'original plan' ;; to cause-troop-attrition ;; If the attrition rate is zero, we have nothing to do if (troop-attrition-rate > 0) [ ;; Convert attrition rate from attition rate per month to attrition per tick for each unit type let attrition-rate-per-minute (troop-attrition-rate / 100 / (24 * 60 * 30)) let attrition-rate-per-tick (attrition-rate-per-minute * minutes-per-tick) let infantry-deaths-per-tick (attrition-rate-per-tick * (sum [num-infantry] of soldiers)) let infantry-deaths-this-tick (round ((ticks + 1) * infantry-deaths-per-tick)) - (round (ticks * infantry-deaths-per-tick)) let cavalry-deaths-per-tick (attrition-rate-per-tick * (sum [num-cavalry] of soldiers)) let cavalry-deaths-this-tick (round ((ticks + 1) * cavalry-deaths-per-tick)) - (round (ticks * cavalry-deaths-per-tick)) let artillery-deaths-per-tick (attrition-rate-per-tick * (sum [num-artillery] of soldiers)) let artillery-deaths-this-tick (round ((ticks + 1) * artillery-deaths-per-tick)) - (round (ticks * artillery-deaths-per-tick)) ;; Check if we need to cause some infantry death if (infantry-deaths-this-tick > 0) [ ask one-of soldiers [ set num-infantry ifelse-value (num-infantry > infantry-deaths-this-tick) [ num-infantry - infantry-deaths-this-tick ] [ 0 ] ] ] ;; Check if we need to cause some cavalry death if (cavalry-deaths-this-tick > 0) [ ask one-of soldiers [ set num-cavalry ifelse-value (num-cavalry > cavalry-deaths-this-tick) [ num-cavalry - cavalry-deaths-this-tick ] [ 0 ] ] ] ;; Check if we need to cause some artillery death if (artillery-deaths-this-tick > 0) [ ask one-of soldiers [ set num-artillery ifelse-value (num-artillery > artillery-deaths-this-tick) [ num-artillery - artillery-deaths-this-tick ] [ 0 ] ] ] ] end ;; ;; color-code-soldiers - soldier method ;; ;; Updates the color-coding of each corps to reflect its current supply situation ;; - Green: Greater than three days of supplies remaining ;; - Orange: Between one and three days of supplies remaining ;; - Red: Less than a day's supplies remaining to color-code-soldiers ;; Calculate this corps' daily supply burn rate let daily-supply-burn-rate (num-infantry * infantry-burn-rate) + (num-cavalry * cavalry-burn-rate) + (num-artillery * artillery-burn-rate) if (current-supplies < daily-supply-burn-rate) [ set color red ] if (current-supplies < (3 * daily-supply-burn-rate)) and (current-supplies >= daily-supply-burn-rate) [ set color orange ] if (current-supplies >= (3 * daily-supply-burn-rate)) [ set color green ] end ;; ;; consume-and-request-supplies - soldier method ;; ;; Adjusts each corps' supply levels and calls for more supplies when needed ;; to consume-and-request-supplies ;; Update corps maximum supply level set supply-capacity ((num-infantry * infantry-capacity) + (num-artillery * artillery-capacity) + (num-cavalry * cavalry-capacity)) ;; Consume supplies let burn-rate-per-minute floor ((((num-infantry * infantry-burn-rate) + (num-artillery * artillery-burn-rate) + (num-cavalry * cavalry-burn-rate)) / 24 / 60 ) * minutes-per-tick) ifelse ((current-supplies - burn-rate-per-minute) > 0) [ set current-supplies (current-supplies - burn-rate-per-minute) ] [ set current-supplies 0 ] ;; Determine if we need to request more supplies ;; NOTE: As soon as we can carry another full train load of supplies, ask for them ;; We need to know how many supplies to request based on how far away we are from the depots; ;; We want to ask for enough supplies to compensate in the delay in their delivery let dist-from-depot (distance min-one-of depots [distance myself]) let time-to-delivery (round (dist-from-depot / train-speed-in-patches)) let supplies-burned-during-delivery (round (burn-rate-per-minute * minutes-per-tick * time-to-delivery)) let supplies-required (supply-capacity + supplies-burned-during-delivery - current-supplies - supplies-requested) if supplies-required > train-capacity [ ;; Build the supply request let supply-request (list self supplies-required) set supply-request-queue lput supply-request supply-request-queue set supplies-requested (supplies-requested + supplies-required) ] ;; If current supply level is higher than maximum capacity, jettison some stuff if (current-supplies > supply-capacity) [ set current-supplies supply-capacity ] end ;; ;; size-code-soldiers - soldier method ;; ;; Updates the display size of each corps to reflect its current supply situation ;; to size-code-soldiers set size 20 * (current-supplies / supply-capacity) + 10 end ;; ;; traverse-waypoints - soldier method ;; ;; Coordinates the movement of a unit along its list of waypoints ;; to traverse-waypoints if not empty? waypoints [ let destination-x (calculate-x item 3 first waypoints) let destination-y (calculate-y item 2 first waypoints) ;; If we're already at the destination, we've got nothing to do ifelse (destination-x = xcor and destination-y = ycor) [] [ ;; Otherwise, let's move toward the destination let ticks-until-arrival ((tick-from-timestamp item 0 first waypoints) - ticks) if ticks-until-arrival != 0 [ facexy destination-x destination-y fd ((distancexy destination-x destination-y) / ticks-until-arrival) ] ] ;; If the ETD of the current waypoint has arrived, let's pull it off the waypoints list if (tick-from-timestamp item 1 first waypoints) = ticks [ if (path-of-advance = "executed plan") [ ;; Update this corps troop levels if the waypoint had troop level data if (item 4 first waypoints != "") [ set num-infantry read-from-string (item 4 first waypoints) ] if (item 5 first waypoints != "") [ set num-cavalry read-from-string (item 5 first waypoints) ] if (item 6 first waypoints != "") [ set num-artillery read-from-string (item 6 first waypoints) ] ] set waypoints but-first waypoints ] ] end