1
Fork 0

toml config

This commit is contained in:
Andy Killorin 2026-11-09 23:39:41 -05:00
parent 89c153911f
commit 0bdb3ffef0
Signed by: ank
GPG key ID: 23F9463ECB67FE8C
4 changed files with 178 additions and 23 deletions

96
simulator/Cargo.lock generated
View file

@ -395,6 +395,16 @@ dependencies = [
"png",
]
[[package]]
name = "indexmap"
version = "2.14.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cc4e190f5d26ca7051642629da2c52fc03bde85a03197c99408dcd291734c855"
dependencies = [
"equivalent",
"hashbrown 0.17.1",
]
[[package]]
name = "is_terminal_polyfill"
version = "1.70.2"
@ -661,6 +671,45 @@ dependencies = [
"bytemuck",
]
[[package]]
name = "serde"
version = "1.0.229"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba"
dependencies = [
"serde_core",
"serde_derive",
]
[[package]]
name = "serde_core"
version = "1.0.229"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.229"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_spanned"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c187e0a369471c550af028cba56d4f4fa2a489ad28151ae95a4d340a2a8b782"
dependencies = [
"serde_core",
]
[[package]]
name = "simba"
version = "0.10.2"
@ -689,6 +738,8 @@ dependencies = [
"parry2d",
"rand",
"rayon",
"serde",
"toml",
]
[[package]]
@ -752,6 +803,45 @@ dependencies = [
"syn",
]
[[package]]
name = "toml"
version = "1.2.1+spec-1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d5755c51863cdac711f1956baf8eb9588e060755f7d3c4c979e70ea1e1f32cd7"
dependencies = [
"indexmap",
"serde_core",
"serde_spanned",
"toml_datetime",
"toml_parser",
"toml_writer",
"winnow",
]
[[package]]
name = "toml_datetime"
version = "1.1.3+spec-1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "173f25c883cd2176a2d8212155638c0a60d484a9d84546d270866f40f56b6e49"
dependencies = [
"serde_core",
]
[[package]]
name = "toml_parser"
version = "1.1.5+spec-1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baa693a8032d7e1cada7d0041e96126df243179ff061456783ac7f12bda4744c"
dependencies = [
"winnow",
]
[[package]]
name = "toml_writer"
version = "1.2.0+spec-1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "009dbb7700f11c55ef83aebbe4c0e9cf1f1ac0844bd8d6f00dc38f302026e13a"
[[package]]
name = "ttf-parser"
version = "0.25.1"
@ -820,6 +910,12 @@ dependencies = [
"windows-link",
]
[[package]]
name = "winnow"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8c3b93199df0ab874cdf0c6a94f0a0dc3423fe41f1cafb62b8bd7b1deb277aef"
[[package]]
name = "zlib-rs"
version = "0.6.8"

View file

@ -10,3 +10,5 @@ macroquad = "0.4.16"
parry2d = "0.31.1"
rand_gen = { package = "rand", version = "0.10.3" }
rayon = "1.12.0"
serde = { version = "1.0.229", features = ["derive"] }
toml = "1.2.1"

19
simulator/conf.toml Normal file
View file

@ -0,0 +1,19 @@
food_amount = 120
red_count = 10
blu_count = 10
kill_radius = 140
kill_self = false
[red_policy]
aggressive = true
food = [1,0]
kin = [-0.3,0.02]
nonkin = [0.3,-0.02]
none= [0.3, 0.01]
[blu_policy]
aggressive = false
food = [1,0]
kin = [-0.3,0.02]
nonkin = [0.3,-0.02]
none= [0.3, 0.01]

View file

@ -1,6 +1,8 @@
use std::cmp::min;
use std::collections::HashMap;
use std::f32::consts::TAU;
use std::fs;
use std::path::PathBuf;
use std::ptr;
use std::sync::atomic::AtomicBool;
use std::sync::atomic::Ordering;
@ -25,6 +27,8 @@ use rayon::iter::ParallelIterator;
use clap::Parser;
use serde::Deserialize;
const VIEW_DIST: f32 = 180.0;
const BOT_RADIUS: f32 = 16.0;
const KILL_RADIUS: f32 = 140.0;
@ -43,6 +47,7 @@ struct Robot {
collider: Ball,
sensor: Sensor,
team: Color,
policy: Policy,
}
impl Mortal for Robot {
@ -67,11 +72,12 @@ impl Mortal for Robot {
}
impl Robot {
fn new(pose: Pose, team: Color) -> Self {
Self { pose, alive: AtomicBool::new(true), collider: Ball::new(BOT_RADIUS), sensor: Sensor::None, team}
fn new(pose: Pose, team: Color, policy: Policy) -> Self {
Self { pose, alive: AtomicBool::new(true), collider: Ball::new(BOT_RADIUS), sensor: Sensor::None, team, policy}
}
fn move_step(&mut self, forward: f32, right: f32) {
fn move_step(&mut self, forward_right: [f32;2]) {
let [forward, right] = forward_right;
self.pose.translation += self.ahead() * forward;
self.pose.rotation *= Rot2::from_angle(right);
}
@ -117,13 +123,13 @@ impl Robot {
pub fn policy(&mut self, sensor: &Sensor) -> bool{
match sensor {
Sensor::Food => self.move_step(1.0, 0.0),
Sensor::Kin => self.move_step(-0.3, 0.02),
Sensor::NonKin => self.move_step(0.3, -0.02),
Sensor::None => self.move_step(0.3, 0.01),
Sensor::Food => self.move_step(self.policy.food),
Sensor::Kin => self.move_step(self.policy.kin),
Sensor::NonKin => self.move_step(self.policy.nonkin),
Sensor::None => self.move_step(self.policy.none),
}
return *sensor == Sensor::NonKin;
return *sensor == Sensor::NonKin && self.policy.aggressive;
}
}
@ -175,6 +181,26 @@ impl Food {
}
}
#[derive(Deserialize, Clone)]
struct Policy {
aggressive: bool,
food: [f32;2],
kin: [f32;2],
nonkin: [f32;2],
none: [f32;2],
}
#[derive(Deserialize)]
struct SimConfig {
food_amount: usize,
red_count: usize,
red_policy: Policy,
blu_count: usize,
blu_policy: Policy,
kill_radius: f32,
kill_self: bool,
}
struct Simulation {
robots: Vec<Robot>,
food: Vec<Food>,
@ -185,7 +211,7 @@ struct Simulation {
}
impl Simulation {
fn new(seed: u64) -> Self {
fn new(seed: u64, config: &SimConfig) -> Self {
let mut rng = SmallRng::seed_from_u64(seed);
let watchdog = 0; // iterations since something interesting
let mut robots = Vec::new();
@ -195,20 +221,24 @@ impl Simulation {
let score = HashMap::new();
let angle = Uniform::new(0.0, TAU).unwrap();
// blue robots
for i in 5..20 {
let angle = Uniform::new(0.0, TAU).unwrap();
let rand_angle = angle.sample(&mut rng);
let pose:Pose = Pose::from_parts(Vec2 { x: 100.0, y: i as f32*50.0 }, Rot2::from_angle(rand_angle));
robots.push(Robot::new(pose, BLUE));
robots.push(Robot::new(pose, BLUE, config.blu_policy.clone()));
}
//red robots
for i in 5..20 {
let rand_angle = angle.sample(&mut rng);
let pose:Pose = Pose::from_parts(Vec2 { x: 1200.0, y: i as f32*50.0 }, Rot2::from_angle(rand_angle));
robots.push(Robot::new(pose, RED));
robots.push(Robot::new(pose, RED, config.red_policy.clone()));
}
let mut food = Vec::new();
for _ in 0..120 {
for _ in 0..config.food_amount {
let x = rng.random_range(200.0 .. 1100.0);
let y = rng.random_range(200.0 .. 900.0);
food.push(Food::new(Vec2 { x, y }));
@ -310,12 +340,12 @@ impl Simulation {
}
}
async fn run_simulation(seed: u64) -> (i32, i32) {
let mut sim = Simulation::new(seed);
async fn run_simulation(seed: u64, speedup: usize, config: &SimConfig) -> (i32, i32) {
let mut sim = Simulation::new(seed, &config);
let mut loo = 1;
loop {
let rendered = loo % 20 == 0;
let rendered = loo % speedup == 0;
let result = sim.sim_step();
if rendered {
@ -330,8 +360,8 @@ async fn run_simulation(seed: u64) -> (i32, i32) {
}
}
fn run_headless_simulation(seed: u64) -> (i32, i32) {
let mut sim = Simulation::new(seed);
fn run_headless_simulation(seed: u64, config: &SimConfig) -> (i32, i32) {
let mut sim = Simulation::new(seed, config);
loop {
if let Some(result) = sim.sim_step() {
@ -352,9 +382,13 @@ struct Cli {
#[arg(short, long)]
run_count: Option<u64>,
///// Sets a custom config file
//#[arg(short, long, value_name = "FILE")]
//config: Option<PathBuf>,
/// how many simulation steps to skip between frames (default 1)
#[arg(short, long)]
gui_speedup: Option<usize>,
/// Sets a custom config file
#[arg(short, long, value_name = "FILE")]
config: PathBuf,
/// Turn debugging information on
#[arg(short, long, action = clap::ArgAction::Count)]
@ -365,13 +399,17 @@ struct Cli {
async fn main() {
let cli = Cli::parse();
let iters = cli.run_count.unwrap_or(1);
let speedup = cli.gui_speedup.unwrap_or(5);
let config = fs::read_to_string(cli.config).unwrap();
let config: SimConfig = toml::from_str(&config).unwrap();
let (red, blu) = if cli.no_gui {
(0..iters).into_par_iter().map(run_headless_simulation).reduce(|| (0,0), |a,b| (a.0 + b.0, a.1 + b.1))
(0..iters).into_par_iter().map(|s |run_headless_simulation(s,&config)).reduce(|| (0,0), |a,b| (a.0 + b.0, a.1 + b.1))
} else {
let (mut rtot, mut btot) = (0, 0);
for i in 0..iters {
let (red, blu) = run_simulation(i).await;
let (red, blu) = run_simulation(i, speedup, &config).await;
rtot += red;
btot += blu;