fix sorting wrong order bug... some cleanup, update results
This commit is contained in:
parent
38bb323d91
commit
58c881130a
@ -45,13 +45,12 @@ For example,
|
|||||||
|
|
||||||
`cargo run -- -n 10000 -s 0 -t 2 -p 3`
|
`cargo run -- -n 10000 -s 0 -t 2 -p 3`
|
||||||
|
|
||||||
## Results (sparsely updated)
|
## Results
|
||||||
|
|
||||||
Currently, on seeds 0-9999, we have:
|
Currently, on seeds 0-9999, we have:
|
||||||
(info strategy is only ran on 1000 seeds)
|
|
||||||
|
|
||||||
| 2p | 3p | 4p | 5p |
|
| 2p | 3p | 4p | 5p |
|
||||||
----------|---------|---------|---------|---------|
|
----------|---------|---------|---------|---------|
|
||||||
cheating | 24.8600 | 24.9781 | 24.9715 | 24.9583 |
|
cheating | 24.8600 | 24.9781 | 24.9715 | 24.9583 |
|
||||||
info | 17.136 | 23.445 | 24.779 | 24.863 |
|
info | 18.5959 | 23.8846 | 24.7753 | 24.8719 |
|
||||||
|
|
||||||
|
@ -105,10 +105,6 @@ impl Discard {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_count(&self, card: &Card) -> u32 {
|
|
||||||
self.counts.get_count(card)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn has_all(&self, card: &Card) -> bool {
|
pub fn has_all(&self, card: &Card) -> bool {
|
||||||
self.counts.remaining(card) == 0
|
self.counts.remaining(card) == 0
|
||||||
}
|
}
|
||||||
|
@ -226,15 +226,6 @@ impl BoardState {
|
|||||||
Some(card.value) == self.get_firework(&card.color).desired_value()
|
Some(card.value) == self.get_firework(&card.color).desired_value()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn was_played(&self, card: &Card) -> bool {
|
|
||||||
let firework = self.fireworks.get(card.color).unwrap();
|
|
||||||
if firework.complete() {
|
|
||||||
true
|
|
||||||
} else {
|
|
||||||
card.value < firework.desired_value().unwrap()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// best possible value we can get for firework of that color,
|
// best possible value we can get for firework of that color,
|
||||||
// based on looking at discard + fireworks
|
// based on looking at discard + fireworks
|
||||||
fn highest_attainable(&self, color: &Color) -> Value {
|
fn highest_attainable(&self, color: &Color) -> Value {
|
||||||
|
@ -270,9 +270,9 @@ impl CardPossibilityTable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// a bit more efficient
|
// a bit more efficient
|
||||||
pub fn borrow_possibilities<'a>(&'a self) -> Vec<&'a Card> {
|
// pub fn borrow_possibilities<'a>(&'a self) -> Vec<&'a Card> {
|
||||||
self.possible.keys().collect::<Vec<_>>()
|
// self.possible.keys().collect::<Vec<_>>()
|
||||||
}
|
// }
|
||||||
|
|
||||||
pub fn decrement_weight_if_possible(&mut self, card: &Card) {
|
pub fn decrement_weight_if_possible(&mut self, card: &Card) {
|
||||||
if self.is_possible(card) {
|
if self.is_possible(card) {
|
||||||
|
@ -46,19 +46,19 @@ fn main() {
|
|||||||
"Log level, one of 'trace', 'debug', 'info', 'warn', and 'error'",
|
"Log level, one of 'trace', 'debug', 'info', 'warn', and 'error'",
|
||||||
"LOGLEVEL");
|
"LOGLEVEL");
|
||||||
opts.optopt("n", "ntrials",
|
opts.optopt("n", "ntrials",
|
||||||
"Number of games to simulate",
|
"Number of games to simulate (default 1)",
|
||||||
"NTRIALS");
|
"NTRIALS");
|
||||||
opts.optopt("t", "nthreads",
|
opts.optopt("t", "nthreads",
|
||||||
"Number of threads to use for simulation",
|
"Number of threads to use for simulation (default 1)",
|
||||||
"NTHREADS");
|
"NTHREADS");
|
||||||
opts.optopt("s", "seed",
|
opts.optopt("s", "seed",
|
||||||
"Seed for PRNG",
|
"Seed for PRNG (default random)",
|
||||||
"SEED");
|
"SEED");
|
||||||
opts.optopt("p", "nplayers",
|
opts.optopt("p", "nplayers",
|
||||||
"Number of players",
|
"Number of players",
|
||||||
"NPLAYERS");
|
"NPLAYERS");
|
||||||
opts.optopt("g", "strategy",
|
opts.optopt("g", "strategy",
|
||||||
"Which strategy to use. One of 'random' and 'cheat'",
|
"Which strategy to use. One of 'random', 'cheat', and 'info'",
|
||||||
"STRATEGY");
|
"STRATEGY");
|
||||||
opts.optflag("h", "help",
|
opts.optflag("h", "help",
|
||||||
"Print this help menu");
|
"Print this help menu");
|
||||||
|
@ -4,21 +4,6 @@ use std::cmp::Ordering;
|
|||||||
use simulator::*;
|
use simulator::*;
|
||||||
use game::*;
|
use game::*;
|
||||||
|
|
||||||
// strategy that recommends other players an action.
|
|
||||||
//
|
|
||||||
// 50 cards, 25 plays, 25 left
|
|
||||||
// with 5 players:
|
|
||||||
// - only 5 + 8 hints total. each player goes through 10 cards
|
|
||||||
// with 4 players:
|
|
||||||
// - only 9 + 8 hints total. each player goes through 12.5 cards
|
|
||||||
//
|
|
||||||
// For any given player with at least 4 cards, and index i, there are at least 3 hints that can be given.
|
|
||||||
// 0. a value hint on card i
|
|
||||||
// 1. a color hint on card i
|
|
||||||
// 2. any hint not involving card i
|
|
||||||
//
|
|
||||||
// for 4 players, can give 6 distinct hints
|
|
||||||
|
|
||||||
#[derive(Debug,Clone)]
|
#[derive(Debug,Clone)]
|
||||||
struct ModulusInformation {
|
struct ModulusInformation {
|
||||||
modulus: u32,
|
modulus: u32,
|
||||||
@ -131,33 +116,6 @@ impl Question for IsPlayable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct IsDead {
|
|
||||||
index: usize,
|
|
||||||
}
|
|
||||||
impl Question for IsDead {
|
|
||||||
fn info_amount(&self) -> u32 { 2 }
|
|
||||||
fn answer(&self, hand: &Cards, view: &OwnedGameView) -> u32 {
|
|
||||||
let ref card = hand[self.index];
|
|
||||||
if view.get_board().is_dead(card) { 1 } else { 0 }
|
|
||||||
}
|
|
||||||
fn acknowledge_answer(
|
|
||||||
&self,
|
|
||||||
answer: u32,
|
|
||||||
hand_info: &mut Vec<CardPossibilityTable>,
|
|
||||||
view: &OwnedGameView,
|
|
||||||
) {
|
|
||||||
let ref mut card_table = hand_info[self.index];
|
|
||||||
let possible = card_table.get_possibilities();
|
|
||||||
for card in &possible {
|
|
||||||
if view.get_board().is_dead(card) {
|
|
||||||
if answer == 0 { card_table.mark_false(card); }
|
|
||||||
} else {
|
|
||||||
if answer == 1 { card_table.mark_false(card); }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct CardPossibilityPartition {
|
struct CardPossibilityPartition {
|
||||||
index: usize,
|
index: usize,
|
||||||
n_partitions: u32,
|
n_partitions: u32,
|
||||||
@ -299,7 +257,8 @@ impl InformationPlayerStrategy {
|
|||||||
|
|
||||||
// sort by probability of play, then by index
|
// sort by probability of play, then by index
|
||||||
augmented_hand_info.sort_by(|&(p1, _, i1), &(p2, _, i2)| {
|
augmented_hand_info.sort_by(|&(p1, _, i1), &(p2, _, i2)| {
|
||||||
let result = p1.partial_cmp(&p2);
|
// *higher* probabilities are better
|
||||||
|
let result = p2.partial_cmp(&p1);
|
||||||
if result == None || result == Some(Ordering::Equal) {
|
if result == None || result == Some(Ordering::Equal) {
|
||||||
i1.cmp(&i2)
|
i1.cmp(&i2)
|
||||||
} else {
|
} else {
|
||||||
@ -628,6 +587,14 @@ impl InformationPlayerStrategy {
|
|||||||
let card_index = self.get_index_for_hint(self.get_player_public_info(&hint_player), view);
|
let card_index = self.get_index_for_hint(self.get_player_public_info(&hint_player), view);
|
||||||
let hint_card = &hand[card_index];
|
let hint_card = &hand[card_index];
|
||||||
|
|
||||||
|
// For any given player with at least 4 cards, and index i, there are at least 3 hints that can be given.
|
||||||
|
// 0. a value hint on card i
|
||||||
|
// 1. a color hint on card i
|
||||||
|
// 2. any hint not involving card i
|
||||||
|
//
|
||||||
|
// for 4 players, can give 6 distinct hints
|
||||||
|
|
||||||
|
|
||||||
let hinted = match hint_type {
|
let hinted = match hint_type {
|
||||||
0 => {
|
0 => {
|
||||||
Hinted::Value(hint_card.value)
|
Hinted::Value(hint_card.value)
|
||||||
@ -650,7 +617,7 @@ impl InformationPlayerStrategy {
|
|||||||
if let Some(hinted) = hinted_opt {
|
if let Some(hinted) = hinted_opt {
|
||||||
hinted
|
hinted
|
||||||
} else {
|
} else {
|
||||||
// Technically possible, but never happens
|
// TODO: Technically possible, but never happens
|
||||||
panic!("Found nothing to hint!")
|
panic!("Found nothing to hint!")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user