veloren_world/civ/
econ.rs1#![expect(dead_code)]
2
3use super::GenCtx;
4use rand::prelude::*;
5
6pub struct SellOrder {
7 pub quantity: f32,
8 pub price: f32,
9
10 pub q_sold: f32,
12}
13
14pub struct BuyOrder {
15 quantity: f32,
16 max_price: f32,
17}
18
19#[derive(Clone, Debug)]
20pub struct Belief {
21 pub price: f32,
22 pub confidence: f32,
23}
24
25impl Belief {
26 pub fn choose_price(&self, ctx: &mut GenCtx<impl Rng>) -> f32 {
27 self.price + ctx.rng.gen_range(-1.0..1.0) * self.confidence
28 }
29
30 pub fn update_buyer(&mut self, _years: f32, new_price: f32) {
31 if (self.price - new_price).abs() < self.confidence {
32 self.confidence *= 0.8;
33 } else {
34 self.price += (new_price - self.price) * 0.5; self.confidence = (self.price - new_price).abs();
36 }
37 }
38
39 pub fn update_seller(&mut self, proportion: f32) {
40 self.price *= 1.0 + (proportion - 0.5) * 0.25;
41 self.confidence /= 1.0 + (proportion - 0.5) * 0.25;
42 }
43}
44
45pub fn buy_units<'a>(
46 _ctx: &mut GenCtx<impl Rng>,
47 sellers: impl Iterator<Item = &'a mut SellOrder>,
48 max_quantity: f32,
49 max_price: f32,
50 max_spend: f32,
51) -> (f32, f32) {
52 let mut sell_orders = sellers.filter(|so| so.quantity > 0.0).collect::<Vec<_>>();
53 sell_orders.sort_by(|a, b| {
55 a.price
56 .partial_cmp(&b.price)
57 .unwrap_or_else(|| panic!("{} and {}", a.price, b.price))
58 });
59
60 let mut quantity = 0.0;
61 let mut spent = 0.0;
62
63 for order in sell_orders {
64 if quantity >= max_quantity || spent >= max_spend || order.price > max_price
67 {
69 break;
70 } else {
71 let q = (max_quantity - quantity)
72 .min(order.quantity - order.q_sold)
73 .min((max_spend - spent) / order.price);
74 order.q_sold += q;
75 quantity += q;
76 spent += q * order.price;
77 }
78 }
79
80 (quantity, spent)
81}