fix: number of players when reading deck from file

This commit is contained in:
Maximilian Keßler 2023-11-21 16:00:46 +01:00
parent b6986def06
commit a85e095b0d
Signed by: max
GPG key ID: BCC5A619923C0BA5
3 changed files with 86 additions and 26 deletions

48
Cargo.lock generated
View file

@ -71,6 +71,24 @@ dependencies = [
"cfg-if",
]
[[package]]
name = "proc-macro2"
version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
dependencies = [
"proc-macro2",
]
[[package]]
name = "rand"
version = "0.3.23"
@ -128,6 +146,8 @@ dependencies = [
"getopts",
"log 0.3.9",
"rand 0.3.23",
"serde",
"serde_derive",
"serde_json",
]
@ -143,6 +163,17 @@ version = "1.0.152"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb"
[[package]]
name = "serde_derive"
version = "1.0.192"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d6c7207fbec9faa48073f3e3074cbe553af6ea512d7c21ba46e434e70ea9fbc1"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_json"
version = "1.0.91"
@ -154,6 +185,23 @@ dependencies = [
"serde",
]
[[package]]
name = "syn"
version = "2.0.39"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "unicode-ident"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]]
name = "unicode-width"
version = "0.1.9"

View file

@ -83,23 +83,29 @@ fn convert_card(
return Card { color: c, value: json_card.rank };
}
pub fn parse_deck(
pub fn parse_deck_and_players(
game_json: &String
) -> Vec<Card> {
) -> (u32, Vec<Card>) {
let game: serde_json::Value = match serde_json::from_str(game_json) {
Ok(v) => v,
Err(_) => panic!("Invalid file format: Could not parse contents as JSON.")
};
let deck_val: serde_json::Value = match game {
serde_json::Value::Object(m) => m["deck"].clone(),
let (players_json, deck_json): (serde_json::Value, serde_json::Value) = match game {
serde_json::Value::Object(m) => (m["players"].clone(), m["deck"].clone()),
_ => panic!("No deck field found")
};
let deck: Vec<JsonCard> = match serde_json::from_value(deck_val) {
let deck: Vec<JsonCard> = match serde_json::from_value(deck_json) {
Ok(v) => v,
Err(e) => panic!("Could not parse cards from deck entry: {e}")
};
let players: Vec<String> = match serde_json::from_value(players_json) {
Ok(v) => v,
Err(e) => panic!("Coud not parse players form entry: {e}")
};
// The deck is reversed since in our implementation we draw from the end of the deck.
return deck.iter().map(convert_card).rev().collect();
return (players.len() as u32, deck.iter().map(convert_card).rev().collect());
}

View file

@ -23,7 +23,7 @@ use std::fs;
use getopts::Options;
use std::str::FromStr;
use crate::game::DeckSpec;
use crate::json_output::parse_deck;
use crate::json_output::parse_deck_and_players;
use crate::simulator::simulate_once;
struct SimpleLogger;
@ -176,6 +176,28 @@ fn main() {
}
fn get_game_opts(
n_players: u32
) -> game::GameOptions {
let hand_size = match n_players {
2 => 5,
3 => 5,
4 => 4,
5 => 4,
_ => {
panic!("There should be 2 to 5 players, not {n_players}");
}
};
return game::GameOptions {
num_players: n_players,
hand_size,
num_hints: 8,
num_lives: 3,
// Hanabi rules are a bit ambiguous about whether you can give hints that match 0 cards
allow_empty_hints: false,
};
}
fn sim_games(
n_players: u32,
strategy_str: &str,
@ -187,24 +209,6 @@ fn sim_games(
json_output_pattern: Option<String>,
json_losses_only: bool,
) -> Option<simulator::SimResult> {
let hand_size = match n_players {
2 => 5,
3 => 5,
4 => 4,
5 => 4,
_ => {
panic!("There should be 2 to 5 players, not {n_players}");
}
};
let game_opts = game::GameOptions {
num_players: n_players,
hand_size,
num_hints: 8,
num_lives: 3,
// hanabi rules are a bit ambiguous about whether you can give hints that match 0 cards
allow_empty_hints: false,
};
let strategy_config: Box<dyn strategy::GameStrategyConfig + Sync> = match strategy_str {
"random" => Box::new(strategies::examples::RandomStrategyConfig {
@ -222,7 +226,8 @@ fn sim_games(
return if let Some(file) = filename {
let contents = fs::read_to_string(&file).expect("Failed to open file");
let deck = parse_deck(&contents);
let (json_n_players, deck) = parse_deck_and_players(&contents);
let game_opts = get_game_opts(json_n_players);
let (_, json_output) = simulate_once(
&game_opts,
strategy_config.initialize(&game_opts),
@ -237,6 +242,7 @@ fn sim_games(
Option::None
} else {
let game_opts = get_game_opts(n_players);
let sim_result = simulator::simulate(
&game_opts,
strategy_config,