;;; ;;; 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 nodes-own [ radius owner iconColor name latitude longitude dist previous is-depot? depot-queue dist-from-soldier ] links-own[ path-weight trains-using higher-queue lower-queue ] ;; ;; determine-owner - node method ;; ;; Calculates the proper owner of a node given the proximity of each army unit ;; to-report determine-owner let side1 0 let side2 0 let nodeOwner owner set nodeOwner "contested" ask soldiers in-radius radius [ if owner = "German" [ set side1 (side1 + 1) ] if owner = "French" [ set side2 (side2 + 1) ] ] let node-x xcor let node-y ycor let this-node self ask soldiers[ if(node-x > xcor and node-y > ycor and node-y > 206)[ set nodeOwner "German" ] ] if side1 > 0 and side2 = 0 [ set nodeOwner "German" ] report nodeOwner end ;; ;; dispatch-trains - global method ;; ;; loads trains and puts them on the rail lines. ;; to dispatch-trains ask depots[ if(empty? depot-queue = false)[ let departures train-departures-this-tick let this-depot self if(length depot-queue < departures)[ set departures length depot-queue ] let index 0 while[index < departures][ let departing-train first depot-queue ask departing-train[ ask calling-soldier[ let soldier self ask nodes [ set dist-from-soldier distance soldier ] ] ;;get the node that is closest to the soldier set destination first sort-on [dist-from-soldier] german-stations set-path self set previous-path path set active? true set in-queue? false if(length path = 1)[ set active? false set in-queue? false ] let this-train self ask this-depot [set depot-queue remove this-train depot-queue] ] set index index + 1 ] ] ] end ;; ;;link-distance - global method ;; ;;reports the path weight for each rail line. Path weights are based off of the number of trains using a line, the lenght of the line, ;;and the amount of trains being released each tick ;; to-report link-distance [u v] let result 0 ask railway [ who ] of u [ who ] of v [ let trains-per-minute (trains-per-day / (24 * 60)) let trains-per-tick (trains-per-minute * minutes-per-tick) if(trains-per-tick = 0)[set trains-per-tick 0.1] set result link-length + trains-using * (1 / trains-per-tick) ] report result end ;; ;; release-from-node-queues - global method ;; ;; releases trains from the station queues ;; to release-from-node-queues ask railways[ ;;get how many trains need to be released from both of the stations if(empty? higher-queue = false)[ let departures (round (train-departures-this-tick / 2)) let this-depot self ;;if there are less trains in the queue than departures this tick, switch departures to the length of the queue if(length higher-queue < departures)[ set departures length higher-queue ] let index 0 ;; release trains from queue while[index < departures][ set trains-using trains-using - 1 let departing-train first higher-queue set higher-queue remove departing-train higher-queue if (departing-train != nobody) [ ask departing-train [ set in-queue? false ] ] set index index + 1 ] ] ;;get how many trains need to be released from both of the stations if(empty? lower-queue = false)[ let departures train-departures-this-tick let this-depot self ;;if there are less trains in the queue than departures this tick, switch departures to the length of the queue if(length lower-queue < departures)[ set departures length lower-queue ] let index 0 ;; release trains from queue while[index < departures][ let departing-train first lower-queue set lower-queue remove departing-train lower-queue if (departing-train != nobody) [ ask departing-train [ set in-queue? false ] ] set index index + 1 ] ] ] end ;; ;; set-node-owners - global method ;; ;; Sets the owner and color-coding of each node in the rail network ;; to set-node-owners ask nodes[ set owner determine-owner if owner = "German" [ set iconColor red ] if owner = "French" [ set iconColor blue ] if owner = "contested" [ set iconColor grey ] set color iconColor ] end ;; ;; supply-trains - global method ;; ;; Consumes supply requests from the supply-request-queue, loads trains with cargo, ;; sets each trains route, and dispatches trains from the depots ;; to supply-trains if(empty? supply-request-queue = false) [ while[empty? supply-request-queue = false and count trains with [active? = false and in-queue? = false] != 0][ let shortest-depot-queue one-of depots let queue-length 0 ask shortest-depot-queue[ set queue-length length depot-queue ] ask depots[ if(length depot-queue < queue-length)[ set shortest-depot-queue self set queue-length length depot-queue ] ] ask shortest-depot-queue [ let this-train nobody let this self ask one-of trains with [active? = false and in-queue? = false] [ set color blue let temp first supply-request-queue set in-queue? true set this-train self set home-node this ;; Figure out how much cargo to load on this train ifelse ((last temp) < train-capacity) [ ;; If the amount of requested supplies will fit all in one train, consume the request set supply-request-queue but-first supply-request-queue set cargo last temp ] [ ;; Otherwise, just decrement the requested amount by this train's capacity and fully load this train set temp replace-item 1 temp ((last temp) - train-capacity) set supply-request-queue replace-item 0 supply-request-queue temp set cargo train-capacity ] ;; Calculate the route to the calling soldier before departure set calling-soldier first temp ;; Create a link between this train and its target corps if show-train-targets [ let train-target-link (list self calling-soldier) create-train-target-to calling-soldier ask my-links [ set color blue ] ] ] set depot-queue lput this-train depot-queue ] ] ] end