任务1：
第一步代码（基本模型）：
globals [ market-price total-volume ]
turtles-own [ reservation-price cost-price bid-price ask-price traded? ]

to setup
  clear-all
  reset-ticks
  set market-price 0
  set total-volume 0
  
  ;; 创建买家（蓝色）
  create-turtles 100 [
    set shape "person"
    set color blue
    set reservation-price random-normal 100 20
    set bid-price reservation-price * (1 - buyer-margin)
    set traded? false
    setxy random-xcor random-ycor
  ]
  
  ;; 创建卖家（红色）
  create-turtles 100 [
    set shape "house"
    set color red
    set cost-price 20 + random 80
    set ask-price cost-price * (1 + seller-markup)
    set traded? false
    setxy random-xcor random-ycor
  ]
end

to go
  ;; 交易撮合与价格涌现逻辑
  ask turtles with [not traded? and color = blue] [
    let my-bid bid-price
    let target one-of turtles with [not traded? and color = red and ask-price <= my-bid]
    if target != nobody [
      set traded? true
      ask target [ set traded? true ]
      set market-price (my-bid + [ask-price] of target) / 2
      set total-volume total-volume + 1
    ]
  ]
  tick
end

第二步代码（动态改变市场均价）：
globals [ market-price total-volume ]
turtles-own [ reservation-price cost-price bid-price ask-price traded? ]

to setup
  clear-all
  reset-ticks
  set market-price 0
  set total-volume 0
  
  ;; 创建买家（蓝色）
  create-turtles 100 [
    set shape "person"
    set color blue
    set reservation-price random-normal 100 20
    set bid-price reservation-price * (1 - buyer-margin)
    set traded? false
    setxy random-xcor random-ycor
  ]
  
  ;; 创建卖家（红色）
  create-turtles 100 [
    set shape "house"
    set color red
    set cost-price 20 + random 80
    set ask-price cost-price * (1 + seller-markup)
    set traded? false
    setxy random-xcor random-ycor
  ]
end

to go
  ;; 【升级点1：实时盯盘】每一轮强制让所有人重新读取滑块参数，更新自己的心理价位
  ask turtles with [color = blue] [
    set bid-price reservation-price * (1 - buyer-margin)
  ]
  ask turtles with [color = red] [
    set ask-price cost-price * (1 + seller-markup)
  ]
  
  ;; 原有的撮合逻辑：寻找价格匹配的对手盘
  ask turtles with [not traded? and color = blue] [
    let my-bid bid-price
    let target one-of turtles with [not traded? and color = red and ask-price <= my-bid]
    if target != nobody [
      set traded? true
      ask target [ set traded? true ]
      set market-price (my-bid + [ask-price] of target) / 2
      set total-volume total-volume + 1
    ]
  ]
  
  ;; 【升级点2：连续市场机制】模拟“新的一天”，让完成交易的人第二天重新进入市场
  ;; 这样市场才会有源源不断的流动性，图表才不会变成死水
  ask turtles [
    set traded? false
  ]

  tick
end

任务2步骤1：
第一步代码（引入外部冲击响应）：
globals [ market-price total-volume shock-triggered? ]
turtles-own [ reservation-price cost-price bid-price ask-price traded? untraded-ticks exited? ]

to setup
  clear-all
  reset-ticks
  set market-price 0
  set total-volume 0
  set shock-triggered? false
  
  ;; 创建买家（蓝色）
  create-turtles 100 [
    set shape "person"
    set color blue
    set reservation-price random-normal 100 20
    set bid-price reservation-price * (1 - buyer-margin)
    set traded? false
    set untraded-ticks 0   ;; 记录连续未成交的天数
    set exited? false      ;; 记录是否已退出市场观望
    setxy random-xcor random-ycor
  ]
  
  ;; 创建卖家（红色）
  create-turtles 100 [
    set shape "house"
    set color red
    set cost-price 20 + random 80
    set ask-price cost-price * (1 + seller-markup)
    set traded? false
    setxy random-xcor random-ycor
  ]
end

to go
  ;; ==========================================
  ;; 【核心逻辑：外生冲击与危机触发】
  ;; ==========================================
  if ticks = 100 [
    set shock-triggered? true
    
    ;; 1. 卖家生产成本全部提高 shock-severity 比例
    ask turtles with [color = red] [
      set cost-price cost-price * (1 + shock-severity)
    ]
    
    ;; 2. 买家产生恐慌，保留价离散度扩大（从标准差20扩大到40）
    ask turtles with [color = blue and not exited?] [
      set reservation-price random-normal 100 40
    ]
  ]
  
  ;; 【实时盯盘与买家恐慌退出机制】
  ask turtles with [color = blue and not exited?] [
    ;; 如果冲击已发生，且连续5个Tick无法成交，则退出市场观望
    if shock-triggered? and untraded-ticks >= 5 [
      set exited? true
      set color gray  ;; 变成灰色，表示退出市场
    ]
    
    ;; 还在市场中的买家更新出价
    if not exited? [
      set bid-price reservation-price * (1 - buyer-margin)
    ]
  ]
  
  ask turtles with [color = red] [
    set ask-price cost-price * (1 + seller-markup)
  ]
  
  ;; 【撮合逻辑】：剔除已退出的买家，寻找价格匹配的对手盘
  ask turtles with [color = blue and not traded? and not exited?] [
    let my-bid bid-price
    let target one-of turtles with [color = red and not traded? and ask-price <= my-bid]
    
    if target != nobody [
      set traded? true
      ask target [ set traded? true ]
      set market-price (my-bid + [ask-price] of target) / 2
      set total-volume total-volume + 1
      set untraded-ticks 0  ;; 一旦成交，耐心计数器清零
      ;; （此处已将 create-link-with target 相关的黄色连线代码删除）
    ]
  ]
  
  ;; 【连续市场机制与未成交计数】
  ask turtles with [color = blue and not exited?] [
    if not traded? [
      set untraded-ticks untraded-ticks + 1  ;; 没做成交易，未成交天数+1
    ]
    set traded? false
  ]
  ask turtles with [color = red] [
    set traded? false
  ]
  
  tick
end

第二步代码（增加反映交易的黄线）：
globals [ market-price total-volume shock-triggered? ]
turtles-own [ reservation-price cost-price bid-price ask-price traded? untraded-ticks exited? ]

to setup
  clear-all
  reset-ticks
  set market-price 0
  set total-volume 0
  set shock-triggered? false
  
  ;; 每天开市前清理连线
  ask links [ die ]
  
  ;; 创建买家（蓝色）
  create-turtles 100 [
    set shape "person"
    set color blue
    set reservation-price random-normal 100 20
    set bid-price reservation-price * (1 - buyer-margin)
    set traded? false
    set untraded-ticks 0   ;; 记录连续未成交的天数
    set exited? false      ;; 记录是否已退出市场观望
    setxy random-xcor random-ycor
  ]
  
  ;; 创建卖家（红色）
  create-turtles 100 [
    set shape "house"
    set color red
    set cost-price 20 + random 80
    set ask-price cost-price * (1 + seller-markup)
    set traded? false
    setxy random-xcor random-ycor
  ]
end

to go
  ask links [ die ]
  
  ;; ==========================================
  ;; 【新增核心逻辑：外生冲击与危机触发】
  ;; ==========================================
  if ticks = 100 [
    set shock-triggered? true
    
    ;; 1. 卖家生产成本全部提高 shock-severity 比例
    ask turtles with [color = red] [
      set cost-price cost-price * (1 + shock-severity)
    ]
    
    ;; 2. 买家产生恐慌，保留价离散度扩大（从标准差20扩大到40）
    ask turtles with [color = blue and not exited?] [
      set reservation-price random-normal 100 40
    ]
  ]
  
  ;; 【升级点1：实时盯盘与买家恐慌退出机制】
  ask turtles with [color = blue and not exited?] [
    ;; 如果冲击已发生，且连续5个Tick无法成交，则退出市场观望
    if shock-triggered? and untraded-ticks >= 5 [
      set exited? true
      set color gray  ;; 变成灰色，表示退出市场
    ]
    
    ;; 还在市场中的买家更新出价
    if not exited? [
      set bid-price reservation-price * (1 - buyer-margin)
    ]
  ]
  
  ask turtles with [color = red] [
    set ask-price cost-price * (1 + seller-markup)
  ]
  
  ;; 【原有撮合逻辑】：剔除已退出的买家
  ask turtles with [color = blue and not traded? and not exited?] [
    let my-bid bid-price
    let target one-of turtles with [color = red and not traded? and ask-price <= my-bid]
    
    if target != nobody [
      set traded? true
      ask target [ set traded? true ]
      set market-price (my-bid + [ask-price] of target) / 2
      set total-volume total-volume + 1
      set untraded-ticks 0  ;; 一旦成交，耐心计数器清零
      
      create-link-with target [
        set color yellow
        set thickness 0.1
      ]
    ]
  ]
  
  ;; 【连续市场机制与未成交计数】
  ask turtles with [color = blue and not exited?] [
    if not traded? [
      set untraded-ticks untraded-ticks + 1  ;; 没做成交易，未成交天数+1
    ]
    set traded? false
  ]
  ask turtles with [color = red] [
    set traded? false
  ]
  
  tick
end

任务2步骤2：
globals [ market-price total-volume shock-triggered? ]
turtles-own [ reservation-price cost-price bid-price ask-price traded? untraded-ticks exited? ]

to setup
  clear-all
  reset-ticks
  set market-price 0
  set total-volume 0
  set shock-triggered? false
  
  ask links [ die ]
  
  ;; 创建买家（蓝色）
  create-turtles 100 [
    set shape "person"
    set color blue
    set reservation-price random-normal 100 20
    set bid-price reservation-price * (1 - buyer-margin)
    set traded? false
    set untraded-ticks 0
    set exited? false
    setxy random-xcor random-ycor
  ]
  
  ;; 创建卖家（红色）- 紧平衡成本 40~60
  create-turtles 100 [
    set shape "house"
    set color red
    set cost-price 40 + random 20   
    set ask-price cost-price * (1 + seller-markup)
    set traded? false
    setxy random-xcor random-ycor
  ]
end

to go
  ask links [ die ]
  
  ;; 外生冲击发生
  if ticks = 100 [
    set shock-triggered? true
    
    ask turtles with [color = red] [
      set cost-price cost-price * (1 + shock-severity)
    ]
    
    ask turtles with [color = blue and not exited?] [
      set reservation-price random-normal 100 40
    ]
  ]
  
  ;; 状态更新与观望退出机制
  ask turtles with [color = blue and not exited?] [
    if shock-triggered? and untraded-ticks >= 10 [
      set exited? true
      set color gray  ;; 变成灰色退出市场
    ]
    
    if not exited? [
      set bid-price reservation-price * (1 - buyer-margin)
    ]
  ]
  
  ask turtles with [color = red] [
    set ask-price cost-price * (1 + seller-markup)
  ]
  
  ;; 撮合交易
  ask turtles with [color = blue and not traded? and not exited?] [
    let my-bid bid-price
    let target one-of turtles with [color = red and not traded? and ask-price <= my-bid]
    
    if target != nobody [
      set traded? true
      ask target [ set traded? true ]
      set market-price (my-bid + [ask-price] of target) / 2
      set total-volume total-volume + 1
      set untraded-ticks 0
      
      create-link-with target [
        set color yellow
        set thickness 0.1
      ]
    ]
  ]
  
  ;; 未成交计数
  ask turtles with [color = blue and not exited?] [
    if not traded? [
      set untraded-ticks untraded-ticks + 1
    ]
    set traded? false
  ]
  ask turtles with [color = red] [
    set traded? false
  ]
  
  tick
end


;; ==========================================
;; 核心修复：基于内存列表存储数据的压力测试
;; ==========================================
to experiment-scan
  no-display  ;; 后台高速盲算提速
  
  ;; 1. 创建一个局部变量列表，它不会被 setup 里的 clear-all 清除
  let plot-data []
  
  ;; 2. 锁定基准参数
  set buyer-margin 0.1
  set seller-markup 0.1
  
  let current-shock 0.1
  while [current-shock <= 2.1] [
    let collapse-count 0
    let repeat-times 20
    
    let i 0
    while [i < repeat-times] [
      set shock-severity current-shock
      
      setup  ;; 这里的 clear-all 会清空图表，但摧毁不了我们的 plot-data
      
      repeat 150 [ go ]
      
      ;; 判定坍塌（灰色退出人数 > 60）
      if (count turtles with [shape = "person" and color = gray]) > 60 [
        set collapse-count collapse-count + 1
      ]
      
      set i i + 1
    ]
    
    ;; 算完一个强度后，把结果打包成列表 [X, Y]，塞进 plot-data 内存里
    set plot-data lput (list current-shock (collapse-count / repeat-times)) plot-data
    
    set current-shock current-shock + 0.1
  ]
  
  ;; 3. 终于算完了全部几百次模拟！现在霸占图表，一口气画出 S 曲线
  set-current-plot "Phase Transition"
  clear-plot             ;; 抹掉系统自作主张画的 200 的横线
  set-plot-x-range 0 2.0 ;; 强制 X 轴
  set-plot-y-range 0 1.0 ;; 强制 Y 轴
  
  
  ;; 遍历内存里的数据点并绘制
  let j 0
  while [j < length plot-data] [
    let point item j plot-data
    plotxy (item 0 point) (item 1 point)
    set j j + 1
  ]
  
  display  ;; 恢复画面显示
  user-message "压力测试完成！S 型相变曲线已完美生成。"
end
