;; coroutine example, simplified from Tower Institute of Linguistics
;; https://technomancy.itch.io/tower-institute-of-linguistics
(local state {:map {} :order-queue [] :help-queue [] :threshold 1024})

(fn move [self target]
  (if (= self.y target.y)
      (set self.x (+ self.x (if (< self.x target.x) 1 -1)))
      (= :stairs (state.map:tile-type self.x self.y))
      (set self.y (+ self.y (if (< self.y target.y) 1 -1)))
      (move self (state.map:find-on-level self.x self.y :stairs)))
  (coroutine.yield)
  (when (not (self:at? target))
    (move self target)))

(fn build-order [self order helper?]
  (each [tx ty (order.tiles helper?)]
    (move self {:x tx :y ty})
    (self:build (. order.blueprint ty tx))))

(fn give-help [self other-worker]
  (move self other-worker)
  (set other-worker.waiting? false)
  (build-order self other-worker.order true))

(fn take-order [self order]
  (table.insert state.help-queue self)
  (set (self.order self.waiting?) (values order true))
  (move self order)
  (while self.waiting?
    (set self.frustration (+ self.frustration 1))
    (coroutine.yield))
  (build-order self order false))

(fn start [self]
  (case (table.remove state.order-queue 1)
    order (take-order self order)
    _ (case (table.remove state.help-queue 1)
        other-worker (give-help self other-worker)))
  (when (< state.threshold self.frustration)
    (self:leave ["no one understands me.\nI'm tired of this."]))
  (coroutine.yield)
  (start self))

Generated by Phil Hagelberg using scpaste at Thu Dec 26 16:06:50 2024. PST. (original)