process SHIP
   define SHIP.ICON as a pointer variable
   define PORT, LAST.PORT as an integer variable
   define ARRIVAL.TIME, LOAD.TIME as real variables
   define BERTH, TUG as pointer variables

     '' pick a destination port
   let PORT = RANDI.F(1, NO.OF.PORTS, 1)

   until .END.OF.SIMULATION,
   do
      call MOVE.TO(SHIP, PORT.X.LOCATION(PORT), PORT.Y.LOCATION(PORT), 
           SHIP.SPEED(SHIP), .FALSE)

      let SHIP.PORT(SHIP) = PORT
      let TUG = PORT.TUG(PORT)

      let ARRIVAL.TIME = TIME.V
      let SHIP.LOCATION(SHIP) = .IN.HARBOR
      let VELOCITY.A(SHIP) = 0

      select case SHIP.TYPE(SHIP)
       case "tanker"
         let LOAD.TIME = exponential.f(21.0,4)
       case "freighter"
         let LOAD.TIME = PORT.LOADING.TIME(PORT)
      endselect

        '' display SHIP in the "port" window
      let VXFORM.V = .PORT.TRANSFORMS + PORT - 1
      let SHIP.ICON = SHIP
      display SHIP.ICON with SHIP.TYPE(SHIP) at 
         (PORT.X.ENTRANCE(PORT), PORT.Y.ENTRANCE(PORT))

      file SHIP in PORT.HARBOR(PORT)
      call HARBOR.UPDATE given PORT

      request 1 DOCK(PORT)

      for each BERTH in PORT.BERTH.SET(PORT),
         with BERTH.STATUS(BERTH) eq .IDLE
         find SHIP.BERTH(SHIP) = the first BERTH
      let BERTH.STATUS(SHIP.BERTH(SHIP)) = .BUSY

      file SHIP in the TUG.QUEUE(TUG)
      if TUG.STATUS(TUG) eq .IDLE
         let TUG.STATUS(TUG) = .BUSY
         reactivate the TUG now
      always

      suspend   ''Awaiting TUG to pull SHIP into the berth

      let SHIP.LOCATION(SHIP) = .AT.DOCK
      add 1 to PORT.DOCKS.IN.USE(PORT)
      work LOAD.TIME hours
      subtract 1 from PORT.DOCKS.IN.USE(PORT)
      file SHIP in TUG.QUEUE(TUG)
      if TUG.STATUS(TUG) eq .IDLE
         let TUG.STATUS(TUG) = .BUSY
         reactivate the TUG now
      always

      suspend   ''Awaiting TUG to pull SHIP out of the berth

      let BERTH.STATUS(SHIP.BERTH(SHIP)) = .IDLE
      relinquish 1 DOCK(PORT)
      let PORT.IN.PORT.TIME(PORT) = (TIME.V - ARRIVAL.TIME) * HOURS.V

        '' redisplaying the ship will cause it to appear in the OCEAN window
      let VXFORM.V = .OCEAN
      let SHIP.LOCATION(SHIP) = .AT.SEA
      let SHIP.ICON = SHIP
      display SHIP.ICON with SHIP.TYPE(SHIP) at 
         (PORT.X.LOCATION(PORT), PORT.Y.LOCATION(PORT))

        '' decide on a port to go to
      let LAST.PORT = PORT
      let PORT = RANDI.F(1, NO.OF.PORTS-1, 1)
      if PORT ge LAST.PORT       '' dont pick same port
         add 1 TO PORT
      always
   loop

end  '' SHIP
