toml config
This commit is contained in:
parent
89c153911f
commit
0bdb3ffef0
4 changed files with 178 additions and 23 deletions
96
simulator/Cargo.lock
generated
96
simulator/Cargo.lock
generated
|
|
@ -395,6 +395,16 @@ dependencies = [
|
||||||
"png",
|
"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]]
|
[[package]]
|
||||||
name = "is_terminal_polyfill"
|
name = "is_terminal_polyfill"
|
||||||
version = "1.70.2"
|
version = "1.70.2"
|
||||||
|
|
@ -661,6 +671,45 @@ dependencies = [
|
||||||
"bytemuck",
|
"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]]
|
[[package]]
|
||||||
name = "simba"
|
name = "simba"
|
||||||
version = "0.10.2"
|
version = "0.10.2"
|
||||||
|
|
@ -689,6 +738,8 @@ dependencies = [
|
||||||
"parry2d",
|
"parry2d",
|
||||||
"rand",
|
"rand",
|
||||||
"rayon",
|
"rayon",
|
||||||
|
"serde",
|
||||||
|
"toml",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -752,6 +803,45 @@ dependencies = [
|
||||||
"syn",
|
"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]]
|
[[package]]
|
||||||
name = "ttf-parser"
|
name = "ttf-parser"
|
||||||
version = "0.25.1"
|
version = "0.25.1"
|
||||||
|
|
@ -820,6 +910,12 @@ dependencies = [
|
||||||
"windows-link",
|
"windows-link",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winnow"
|
||||||
|
version = "1.0.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8c3b93199df0ab874cdf0c6a94f0a0dc3423fe41f1cafb62b8bd7b1deb277aef"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zlib-rs"
|
name = "zlib-rs"
|
||||||
version = "0.6.8"
|
version = "0.6.8"
|
||||||
|
|
|
||||||
|
|
@ -10,3 +10,5 @@ macroquad = "0.4.16"
|
||||||
parry2d = "0.31.1"
|
parry2d = "0.31.1"
|
||||||
rand_gen = { package = "rand", version = "0.10.3" }
|
rand_gen = { package = "rand", version = "0.10.3" }
|
||||||
rayon = "1.12.0"
|
rayon = "1.12.0"
|
||||||
|
serde = { version = "1.0.229", features = ["derive"] }
|
||||||
|
toml = "1.2.1"
|
||||||
|
|
|
||||||
19
simulator/conf.toml
Normal file
19
simulator/conf.toml
Normal 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]
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
use std::cmp::min;
|
use std::cmp::min;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::f32::consts::TAU;
|
use std::f32::consts::TAU;
|
||||||
|
use std::fs;
|
||||||
|
use std::path::PathBuf;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use std::sync::atomic::AtomicBool;
|
use std::sync::atomic::AtomicBool;
|
||||||
use std::sync::atomic::Ordering;
|
use std::sync::atomic::Ordering;
|
||||||
|
|
@ -25,6 +27,8 @@ use rayon::iter::ParallelIterator;
|
||||||
|
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
|
|
||||||
|
use serde::Deserialize;
|
||||||
|
|
||||||
const VIEW_DIST: f32 = 180.0;
|
const VIEW_DIST: f32 = 180.0;
|
||||||
const BOT_RADIUS: f32 = 16.0;
|
const BOT_RADIUS: f32 = 16.0;
|
||||||
const KILL_RADIUS: f32 = 140.0;
|
const KILL_RADIUS: f32 = 140.0;
|
||||||
|
|
@ -43,6 +47,7 @@ struct Robot {
|
||||||
collider: Ball,
|
collider: Ball,
|
||||||
sensor: Sensor,
|
sensor: Sensor,
|
||||||
team: Color,
|
team: Color,
|
||||||
|
policy: Policy,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Mortal for Robot {
|
impl Mortal for Robot {
|
||||||
|
|
@ -67,11 +72,12 @@ impl Mortal for Robot {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Robot {
|
impl Robot {
|
||||||
fn new(pose: Pose, team: Color) -> Self {
|
fn new(pose: Pose, team: Color, policy: Policy) -> Self {
|
||||||
Self { pose, alive: AtomicBool::new(true), collider: Ball::new(BOT_RADIUS), sensor: Sensor::None, team}
|
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.translation += self.ahead() * forward;
|
||||||
self.pose.rotation *= Rot2::from_angle(right);
|
self.pose.rotation *= Rot2::from_angle(right);
|
||||||
}
|
}
|
||||||
|
|
@ -117,13 +123,13 @@ impl Robot {
|
||||||
|
|
||||||
pub fn policy(&mut self, sensor: &Sensor) -> bool{
|
pub fn policy(&mut self, sensor: &Sensor) -> bool{
|
||||||
match sensor {
|
match sensor {
|
||||||
Sensor::Food => self.move_step(1.0, 0.0),
|
Sensor::Food => self.move_step(self.policy.food),
|
||||||
Sensor::Kin => self.move_step(-0.3, 0.02),
|
Sensor::Kin => self.move_step(self.policy.kin),
|
||||||
Sensor::NonKin => self.move_step(0.3, -0.02),
|
Sensor::NonKin => self.move_step(self.policy.nonkin),
|
||||||
Sensor::None => self.move_step(0.3, 0.01),
|
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 {
|
struct Simulation {
|
||||||
robots: Vec<Robot>,
|
robots: Vec<Robot>,
|
||||||
food: Vec<Food>,
|
food: Vec<Food>,
|
||||||
|
|
@ -185,7 +211,7 @@ struct Simulation {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Simulation {
|
impl Simulation {
|
||||||
fn new(seed: u64) -> Self {
|
fn new(seed: u64, config: &SimConfig) -> Self {
|
||||||
let mut rng = SmallRng::seed_from_u64(seed);
|
let mut rng = SmallRng::seed_from_u64(seed);
|
||||||
let watchdog = 0; // iterations since something interesting
|
let watchdog = 0; // iterations since something interesting
|
||||||
let mut robots = Vec::new();
|
let mut robots = Vec::new();
|
||||||
|
|
@ -195,20 +221,24 @@ impl Simulation {
|
||||||
|
|
||||||
let score = HashMap::new();
|
let score = HashMap::new();
|
||||||
|
|
||||||
for i in 5..20 {
|
|
||||||
let angle = Uniform::new(0.0, TAU).unwrap();
|
let angle = Uniform::new(0.0, TAU).unwrap();
|
||||||
|
// blue robots
|
||||||
|
for i in 5..20 {
|
||||||
let rand_angle = angle.sample(&mut rng);
|
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));
|
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 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));
|
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();
|
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 x = rng.random_range(200.0 .. 1100.0);
|
||||||
let y = rng.random_range(200.0 .. 900.0);
|
let y = rng.random_range(200.0 .. 900.0);
|
||||||
food.push(Food::new(Vec2 { x, y }));
|
food.push(Food::new(Vec2 { x, y }));
|
||||||
|
|
@ -310,12 +340,12 @@ impl Simulation {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run_simulation(seed: u64) -> (i32, i32) {
|
async fn run_simulation(seed: u64, speedup: usize, config: &SimConfig) -> (i32, i32) {
|
||||||
let mut sim = Simulation::new(seed);
|
let mut sim = Simulation::new(seed, &config);
|
||||||
|
|
||||||
let mut loo = 1;
|
let mut loo = 1;
|
||||||
loop {
|
loop {
|
||||||
let rendered = loo % 20 == 0;
|
let rendered = loo % speedup == 0;
|
||||||
let result = sim.sim_step();
|
let result = sim.sim_step();
|
||||||
|
|
||||||
if rendered {
|
if rendered {
|
||||||
|
|
@ -330,8 +360,8 @@ async fn run_simulation(seed: u64) -> (i32, i32) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_headless_simulation(seed: u64) -> (i32, i32) {
|
fn run_headless_simulation(seed: u64, config: &SimConfig) -> (i32, i32) {
|
||||||
let mut sim = Simulation::new(seed);
|
let mut sim = Simulation::new(seed, config);
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
if let Some(result) = sim.sim_step() {
|
if let Some(result) = sim.sim_step() {
|
||||||
|
|
@ -352,9 +382,13 @@ struct Cli {
|
||||||
#[arg(short, long)]
|
#[arg(short, long)]
|
||||||
run_count: Option<u64>,
|
run_count: Option<u64>,
|
||||||
|
|
||||||
///// Sets a custom config file
|
/// how many simulation steps to skip between frames (default 1)
|
||||||
//#[arg(short, long, value_name = "FILE")]
|
#[arg(short, long)]
|
||||||
//config: Option<PathBuf>,
|
gui_speedup: Option<usize>,
|
||||||
|
|
||||||
|
/// Sets a custom config file
|
||||||
|
#[arg(short, long, value_name = "FILE")]
|
||||||
|
config: PathBuf,
|
||||||
|
|
||||||
/// Turn debugging information on
|
/// Turn debugging information on
|
||||||
#[arg(short, long, action = clap::ArgAction::Count)]
|
#[arg(short, long, action = clap::ArgAction::Count)]
|
||||||
|
|
@ -365,13 +399,17 @@ struct Cli {
|
||||||
async fn main() {
|
async fn main() {
|
||||||
let cli = Cli::parse();
|
let cli = Cli::parse();
|
||||||
let iters = cli.run_count.unwrap_or(1);
|
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 {
|
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 {
|
} else {
|
||||||
let (mut rtot, mut btot) = (0, 0);
|
let (mut rtot, mut btot) = (0, 0);
|
||||||
for i in 0..iters {
|
for i in 0..iters {
|
||||||
let (red, blu) = run_simulation(i).await;
|
let (red, blu) = run_simulation(i, speedup, &config).await;
|
||||||
rtot += red;
|
rtot += red;
|
||||||
btot += blu;
|
btot += blu;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue