add toml config file parsing to tidepool
This commit is contained in:
parent
e64b11cefe
commit
14024f63ff
|
@ -20,6 +20,12 @@ version = "1.0.66"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "216261ddc8289130e551ddcd5ce8a064710c0d064a4d2895c67151c92b5443f6"
|
checksum = "216261ddc8289130e551ddcd5ce8a064710c0d064a4d2895c67151c92b5443f6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "autocfg"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
version = "1.3.2"
|
version = "1.3.2"
|
||||||
|
@ -110,7 +116,7 @@ dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"bumpalo",
|
"bumpalo",
|
||||||
"clap",
|
"clap",
|
||||||
"hashbrown",
|
"hashbrown 0.13.1",
|
||||||
"mino",
|
"mino",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
@ -129,6 +135,12 @@ dependencies = [
|
||||||
"wasi",
|
"wasi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hashbrown"
|
||||||
|
version = "0.12.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hashbrown"
|
name = "hashbrown"
|
||||||
version = "0.13.1"
|
version = "0.13.1"
|
||||||
|
@ -153,6 +165,16 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "indexmap"
|
||||||
|
version = "1.9.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
"hashbrown 0.12.3",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "io-lifetimes"
|
name = "io-lifetimes"
|
||||||
version = "1.0.3"
|
version = "1.0.3"
|
||||||
|
@ -217,6 +239,12 @@ dependencies = [
|
||||||
"regex-automata",
|
"regex-automata",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "memchr"
|
||||||
|
version = "2.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mino"
|
name = "mino"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
@ -429,6 +457,15 @@ dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_spanned"
|
||||||
|
version = "0.6.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0efd8caf556a6cebd3b285caf480045fcc1ac04f6bd786b09a6f11af30c4fcf4"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sharded-slab"
|
name = "sharded-slab"
|
||||||
version = "0.1.4"
|
version = "0.1.4"
|
||||||
|
@ -488,10 +525,46 @@ dependencies = [
|
||||||
"mino",
|
"mino",
|
||||||
"rand",
|
"rand",
|
||||||
"rand_xoshiro",
|
"rand_xoshiro",
|
||||||
|
"serde",
|
||||||
|
"toml",
|
||||||
"tracing",
|
"tracing",
|
||||||
"tracing-subscriber",
|
"tracing-subscriber",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml"
|
||||||
|
version = "0.7.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b403acf6f2bb0859c93c7f0d967cb4a75a7ac552100f9322faf64dc047669b21"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
"serde_spanned",
|
||||||
|
"toml_datetime",
|
||||||
|
"toml_edit",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml_datetime"
|
||||||
|
version = "0.6.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3ab8ed2edee10b50132aed5f331333428b011c99402b5a534154ed15746f9622"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml_edit"
|
||||||
|
version = "0.19.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "239410c8609e8125456927e6707163a3b1fdb40561e4b803bc041f466ccfdc13"
|
||||||
|
dependencies = [
|
||||||
|
"indexmap",
|
||||||
|
"serde",
|
||||||
|
"serde_spanned",
|
||||||
|
"toml_datetime",
|
||||||
|
"winnow",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tracing"
|
name = "tracing"
|
||||||
version = "0.1.37"
|
version = "0.1.37"
|
||||||
|
@ -665,3 +738,12 @@ name = "windows_x86_64_msvc"
|
||||||
version = "0.42.0"
|
version = "0.42.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5"
|
checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winnow"
|
||||||
|
version = "0.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ae8970b36c66498d8ff1d66685dc86b91b29db0c7739899012f63a63814b4b28"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
|
@ -8,8 +8,15 @@ edition = "2021"
|
||||||
mino = { path = "../mino" }
|
mino = { path = "../mino" }
|
||||||
fish = { path = "../fish" }
|
fish = { path = "../fish" }
|
||||||
|
|
||||||
|
# lib
|
||||||
rand = "0.8"
|
rand = "0.8"
|
||||||
rand_xoshiro = "0.6"
|
rand_xoshiro = "0.6"
|
||||||
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
tracing = { version = "0.1" }
|
tracing = { version = "0.1" }
|
||||||
|
|
||||||
|
# cli
|
||||||
tracing-subscriber = { version = "0.3", features = ["fmt", "env-filter"]}
|
tracing-subscriber = { version = "0.3", features = ["fmt", "env-filter"]}
|
||||||
|
toml = { version = "0.7" }
|
||||||
|
|
||||||
|
# anyhow = { version = "1.0" }
|
||||||
|
# clap = { version = "4.0", features = ["derive"] }
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
[game]
|
||||||
|
goal = 100
|
||||||
|
rules = "jstris"
|
||||||
|
|
||||||
|
[bot]
|
||||||
|
iters = 9000
|
|
@ -0,0 +1,2 @@
|
||||||
|
game.goal = 18
|
||||||
|
bot.iters = 5000
|
|
@ -0,0 +1,177 @@
|
||||||
|
//! Config file schema (serde) for tidepool. See `example-configs/` for usage samples.
|
||||||
|
|
||||||
|
use serde::Deserialize;
|
||||||
|
|
||||||
|
#[derive(Deserialize, PartialEq, Debug)]
|
||||||
|
pub struct Config {
|
||||||
|
pub game: GameConfig,
|
||||||
|
#[serde(default)]
|
||||||
|
pub bot: BotConfig,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, PartialEq, Debug)]
|
||||||
|
pub struct GameConfig {
|
||||||
|
pub goal: usize,
|
||||||
|
#[serde(default = "defaults::rules", deserialize_with = "game_rules_config")]
|
||||||
|
pub rules: GameRulesConfig,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, PartialEq, Debug)]
|
||||||
|
pub struct GameRulesConfig {
|
||||||
|
#[serde(default = "defaults::min_garbage")]
|
||||||
|
pub min: usize,
|
||||||
|
#[serde(default = "defaults::max_garbage")]
|
||||||
|
pub max: usize,
|
||||||
|
#[serde(default = "defaults::previews")]
|
||||||
|
pub previews: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GameRulesConfig {
|
||||||
|
pub const JSTRIS: Self = Self {
|
||||||
|
min: 3,
|
||||||
|
max: 9,
|
||||||
|
previews: 5,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn game_rules_config<'de, D>(deserializer: D) -> Result<GameRulesConfig, D::Error>
|
||||||
|
where
|
||||||
|
D: serde::Deserializer<'de>,
|
||||||
|
{
|
||||||
|
// all this nonsense is to support `rules = "jstris"` as an entry
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
#[serde(untagged)]
|
||||||
|
enum Variant {
|
||||||
|
Jstris(Jstris),
|
||||||
|
Custom(GameRulesConfig),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
enum Jstris {
|
||||||
|
#[serde(rename = "jstris")]
|
||||||
|
Tag,
|
||||||
|
}
|
||||||
|
|
||||||
|
Variant::deserialize(deserializer).map(|var| match var {
|
||||||
|
Variant::Jstris(_) => GameRulesConfig::JSTRIS,
|
||||||
|
Variant::Custom(c) => c,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, PartialEq, Debug)]
|
||||||
|
pub struct BotConfig {
|
||||||
|
// TODO: weights
|
||||||
|
// TODO: algorithm
|
||||||
|
// TODO: capabililties
|
||||||
|
#[serde(default = "defaults::iters")]
|
||||||
|
pub iters: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BotConfig {
|
||||||
|
pub const DEFAULT: Self = Self { iters: 10_000 };
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for BotConfig {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::DEFAULT
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mod defaults {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
pub const fn min_garbage() -> usize {
|
||||||
|
GameRulesConfig::JSTRIS.min
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const fn max_garbage() -> usize {
|
||||||
|
GameRulesConfig::JSTRIS.max
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const fn previews() -> usize {
|
||||||
|
GameRulesConfig::JSTRIS.previews
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const fn rules() -> GameRulesConfig {
|
||||||
|
GameRulesConfig::JSTRIS
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const fn iters() -> usize {
|
||||||
|
BotConfig::DEFAULT.iters
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_de_1() {
|
||||||
|
assert_eq!(
|
||||||
|
toml::from_str::<Config>(
|
||||||
|
"
|
||||||
|
[game]
|
||||||
|
goal = 100
|
||||||
|
|
||||||
|
[bot]
|
||||||
|
iters = 5_000
|
||||||
|
"
|
||||||
|
)
|
||||||
|
.unwrap(),
|
||||||
|
Config {
|
||||||
|
game: GameConfig {
|
||||||
|
goal: 100,
|
||||||
|
rules: GameRulesConfig::JSTRIS,
|
||||||
|
},
|
||||||
|
bot: BotConfig { iters: 5_000 }
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_de_2() {
|
||||||
|
assert_eq!(
|
||||||
|
toml::from_str::<Config>(
|
||||||
|
"
|
||||||
|
game.goal = 100
|
||||||
|
game.rules = { min = 4, previews = 8 }
|
||||||
|
bot = {}
|
||||||
|
"
|
||||||
|
)
|
||||||
|
.unwrap(),
|
||||||
|
Config {
|
||||||
|
game: GameConfig {
|
||||||
|
goal: 100,
|
||||||
|
rules: GameRulesConfig {
|
||||||
|
min: 4,
|
||||||
|
max: 9,
|
||||||
|
previews: 8,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
bot: BotConfig::default(),
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_de_3() {
|
||||||
|
assert_eq!(
|
||||||
|
toml::from_str::<Config>(
|
||||||
|
"
|
||||||
|
[game]
|
||||||
|
goal = 18
|
||||||
|
rules = \"jstris\"
|
||||||
|
"
|
||||||
|
)
|
||||||
|
.unwrap(),
|
||||||
|
Config {
|
||||||
|
game: GameConfig {
|
||||||
|
goal: 18,
|
||||||
|
rules: GameRulesConfig::JSTRIS,
|
||||||
|
},
|
||||||
|
bot: BotConfig::default()
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,3 +1,4 @@
|
||||||
|
pub mod config;
|
||||||
pub mod garbage;
|
pub mod garbage;
|
||||||
pub mod queue;
|
pub mod queue;
|
||||||
pub mod sim;
|
pub mod sim;
|
||||||
|
|
|
@ -1,12 +1,10 @@
|
||||||
use fish::bot::Bot;
|
use fish::bot::Bot;
|
||||||
use mino::srs::Queue;
|
use mino::srs::Queue;
|
||||||
use rand::RngCore as _;
|
use rand::RngCore as _;
|
||||||
use tidepool::sim;
|
use std::io::Read as _;
|
||||||
|
use tidepool::{config, sim};
|
||||||
|
|
||||||
pub fn main() -> std::io::Result<()> {
|
pub fn main() -> std::io::Result<()> {
|
||||||
const THINK_CYCLES: usize = 5_000;
|
|
||||||
const GOAL: usize = 18;
|
|
||||||
|
|
||||||
tracing_subscriber::fmt::fmt()
|
tracing_subscriber::fmt::fmt()
|
||||||
.with_writer(std::io::stderr)
|
.with_writer(std::io::stderr)
|
||||||
.with_env_filter(tracing_subscriber::filter::EnvFilter::from_default_env())
|
.with_env_filter(tracing_subscriber::filter::EnvFilter::from_default_env())
|
||||||
|
@ -15,7 +13,25 @@ pub fn main() -> std::io::Result<()> {
|
||||||
let seed = rand::thread_rng().next_u64();
|
let seed = rand::thread_rng().next_u64();
|
||||||
println!("using seed: {seed}");
|
println!("using seed: {seed}");
|
||||||
|
|
||||||
let mut sim = sim::Simul::new(seed, sim::Options::jstris(GOAL));
|
let mut config_file = match std::env::args().nth(1) {
|
||||||
|
Some(f) => std::fs::File::open(f)?,
|
||||||
|
None => {
|
||||||
|
eprintln!("usage: tidepool <CONFIG_FILE>");
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut config = String::new();
|
||||||
|
config_file.read_to_string(&mut config)?;
|
||||||
|
|
||||||
|
let config = toml::from_str::<config::Config>(&config).unwrap();
|
||||||
|
|
||||||
|
let opts = sim::Options {
|
||||||
|
goal: config.game.goal,
|
||||||
|
garbage: config.game.rules.min..=config.game.rules.max,
|
||||||
|
previews: config.game.rules.previews,
|
||||||
|
};
|
||||||
|
let mut sim = sim::Simul::new(seed, opts);
|
||||||
|
|
||||||
let mut ds = 0;
|
let mut ds = 0;
|
||||||
let mut ps = 0;
|
let mut ps = 0;
|
||||||
|
@ -38,7 +54,7 @@ pub fn main() -> std::io::Result<()> {
|
||||||
let queue = Queue::new(hold, &next);
|
let queue = Queue::new(hold, &next);
|
||||||
let mut bot = Bot::new(mat, queue);
|
let mut bot = Bot::new(mat, queue);
|
||||||
|
|
||||||
for i in 0..THINK_CYCLES {
|
for i in 0..config.bot.iters {
|
||||||
if i > 0 && i % 1000 == 0 {
|
if i > 0 && i % 1000 == 0 {
|
||||||
tracing::debug!("iteration {i}");
|
tracing::debug!("iteration {i}");
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,16 +15,6 @@ pub struct Options {
|
||||||
pub previews: usize,
|
pub previews: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Options {
|
|
||||||
pub const fn jstris(goal: usize) -> Self {
|
|
||||||
Self {
|
|
||||||
goal,
|
|
||||||
garbage: 3..=9,
|
|
||||||
previews: 5,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type Rng = rand_xoshiro::Xoshiro256StarStar;
|
type Rng = rand_xoshiro::Xoshiro256StarStar;
|
||||||
|
|
||||||
pub struct Simul {
|
pub struct Simul {
|
||||||
|
|
Loading…
Reference in New Issue