process CUSTOMER
''
'' AUTHOR: Steve Bailey
'' CREATED: 7-25-90
'' DESCRIPTION:
''     This process simulates a customer placing an order.  Orders are
''     based on number of burgers, and shakes.
''

define ARRIVAL.TIME as a real variable
define MY.ORDER as a pointer variable
define CHOICE as an integer variable
define STATION as an integer variable
define WAITING as a pointer variable
define WAITING.AREA as a 1-dim pointer saved array
define MY.SPOT as an integer variable
define MEAN.BURGERS.ORDER as a real saved variable
define MEAN.SHAKES.ORDER as a real saved variable
define MEAN.FRIES.ORDER as a real saved variable
define I as an integer variable
define .CONSUMPTION.POWER to mean 1.5

'' if first time here
if WAITING.AREA(*) eq 0
    reserve WAITING.AREA(*) as 25

    '' compute the mean order amounts based on current pricing 
    let MEAN.BURGERS.ORDER = ((.BURGER.PRICE / BURGER.PRICE) ** 
      .CONSUMPTION.POWER) * .MEAN.BURGERS.ORDER
    let MEAN.SHAKES.ORDER = ((.SHAKE.PRICE / SHAKE.PRICE) ** 
      .CONSUMPTION.POWER) * .MEAN.SHAKES.ORDER
    let MEAN.FRIES.ORDER = ((.FRY.PRICE / FRY.PRICE) ** 
      .CONSUMPTION.POWER) * .MEAN.FRIES.ORDER
always

let ARRIVAL.TIME = .NOW

'' get in the shortest line, and wait for an order taker and register
let STATION = CHOICE.WORKSTATION(.ORDER1, .ORDER2, .ORDER3)
display .SELF with CONCAT.F("customer", ITOT.F(RANDI.F(1,4,1)), ".icn") at 
  (XLOC(STATION),YLOC(STATION)-(N.Q.WORKSTATION(STATION)+1)*0.5-1)
request 1 WORKSTATION(STATION)
let CHOICE = CHOICE.ORDER.TAKER(STATION)
request 1 ORDER.TAKER(CHOICE)
let OCCUPIER(STATION) = CHOICE

'' create an order for order taker
create an ORDER called MY.ORDER
let NUM.BURGERS(MY.ORDER) = EXPONENTIAL.F(MEAN.BURGERS.ORDER, 3)
let NUM.SHAKES(MY.ORDER) = EXPONENTIAL.F(MEAN.SHAKES.ORDER, 4)
let NUM.FRIES(MY.ORDER) = EXPONENTIAL.F(MEAN.FRIES.ORDER, 5)
let CUSTOMER.WAITING(MY.ORDER) = .SELF

'' give order to order taker
work EXPONENTIAL.F(.MEAN.ORDER.TIME, 6) .SECONDS
activate a TAKE.ORDER given MY.ORDER now

relinquish 1 ORDER.TAKER(CHOICE)
relinquish 1 WORKSTATION(STATION)

'' move into a free spot in the waiting area
for I = 1 to 25 do
    if WAITING.AREA(I) eq 0
        let MY.SPOT = I
        let WAITING.AREA(I) = .SELF
        call MOVE.TO(.SELF, REAL.F(.WAITX+MOD.F(I-1,5)), 
          REAL.F(.WAITY-TRUNC.F((I-1)/5)))
        leave
    always
loop

'' move all customers waiting in line up 1
let WAITING = F.Q.WORKSTATION(STATION)
for I = 1 to N.Q.WORKSTATION(STATION) do
    display WHO.A(WAITING) at (XLOC(STATION),YLOC(STATION)-I*0.5-1)
    wait 1 .SECONDS
    let WAITING = S.Q.WORKSTATION(WAITING)
loop

'' now suspend until order is ready
suspend

let WAITING.TIME = .NOW - ARRIVAL.TIME

'' get up
work 4 .SECONDS

'' clear out this spot
if MY.SPOT ne 0
    let WAITING.AREA(MY.SPOT) = 0
always

'' go to the order pickup station
call MOVE.TO(.SELF, XLOC(.GIVE.ORDER), YLOC(.GIVE.ORDER)-1.0)

'' take the order
remove MY.ORDER from BAG.COUNTER
destroy this ORDER called MY.ORDER

'' leave the order area
call MOVE.TO(.SELF, XLOC(.GIVE.ORDER), -5.0)

return
end
