From 8bb58c0fb294a771b7459e2ea13f69c7c0c8d519 Mon Sep 17 00:00:00 2001 From: Max Fierro Date: Sun, 5 Nov 2023 01:32:46 -0700 Subject: [PATCH] Tested zero-by on 2 players; added 10 player option --- src/database/bpdb.rs | 2 +- src/database/record.rs | 4 +-- src/games/zero_by/mod.rs | 68 +++++++++++++++++++++++++++++++++++++--- src/solvers/acyclic.rs | 9 +++--- 4 files changed, 70 insertions(+), 13 deletions(-) diff --git a/src/database/bpdb.rs b/src/database/bpdb.rs index cf069ed..5c477c9 100644 --- a/src/database/bpdb.rs +++ b/src/database/bpdb.rs @@ -37,7 +37,7 @@ impl Database for BPDatabase fn put(&mut self, state: State, record: Record) { - self.mem.insert(state, Mutex::new(Record::::default())); + self.mem.insert(state, Mutex::new(record)); } fn get(&self, state: State) -> Option> diff --git a/src/database/record.rs b/src/database/record.rs index 38b282b..5cef7fa 100644 --- a/src/database/record.rs +++ b/src/database/record.rs @@ -127,8 +127,8 @@ impl Display for Record { write!( f, - "{} {}\n{} {}\n{} {}\n{} {}", - "Utility:".green().bold(), + "{}\n{}{} {}\n{} {}\n{} {}", + "Utility vector:".green().bold(), self.util, "Remoteness:".bold(), self.rem, diff --git a/src/games/zero_by/mod.rs b/src/games/zero_by/mod.rs index 3162a46..2b429dd 100644 --- a/src/games/zero_by/mod.rs +++ b/src/games/zero_by/mod.rs @@ -89,9 +89,20 @@ impl Game for Session fn solvers(&self) -> HashMap> { - let acyclic: Solver = >::solve; - collection! { - >::name() => acyclic, + match self.players { + 2 => { + let acyclic: Solver = >::solve; + collection! { + >::name() => acyclic, + } + }, + 10 => { + let acyclic: Solver = >::solve; + collection! { + >::name() => acyclic, + } + } + _ => todo!() } } } @@ -109,9 +120,16 @@ impl Automaton for Session self.by .iter() .cloned() + .map(|choice| if state <= choice { state } else { choice }) .filter(|&choice| state >= choice) .map(|choice| state - choice) - .map(|output| utils::pack_turn(output, turn, self.players)) + .map(|output| { + utils::pack_turn( + output, + (turn + 1) % self.players, + self.players + ) + }) .collect::>() } @@ -125,7 +143,8 @@ impl Automaton for Session /* SOLVABLE DECLARATIONS */ implement! { for Session => - AcyclicallySolvable<2> + AcyclicallySolvable<2>, + AcyclicallySolvable<10> } impl Solvable<2> for Session @@ -155,3 +174,42 @@ impl Solvable<2> for Session ) } } + +impl Solvable<10> for Session +{ + fn weights(&self) -> SMatrix + { + SMatrix::::identity() + } + + fn utility(&self, state: State) -> Option> + { + let (state, turn) = utils::unpack_turn(state, 10); + if !self.accepts(state) { + None + } else { + let mut result: SVector = SVector::::zeros(); + for i in 0..10 { + if turn == i { + result[i as usize] = -9; + } else { + result[i as usize] = 1; + } + } + Some(result) + } + } + + fn coalesce(&self, state: State) -> SVector { + let (_, turn) = utils::unpack_turn(state, 10); + let mut result: SVector = SVector::::zeros(); + for i in 0..10 { + if turn == i { + result[i as usize] = 1; + } else { + result[i as usize] = 0; + } + } + result + } +} diff --git a/src/solvers/acyclic.rs b/src/solvers/acyclic.rs index 2f7e083..ff426fa 100644 --- a/src/solvers/acyclic.rs +++ b/src/solvers/acyclic.rs @@ -62,13 +62,12 @@ fn traverse, const N: usize>( ) } let mut available: HashSet> = HashSet::new(); - for state in game.transition(state) { - if let Some(out) = db.get(state) { + for next in game.transition(state) { + if let Some(out) = db.get(next) { available.insert(out); } else { - let out = traverse(state, game, db); + let out = traverse(next, game, db); available.insert(out); - db.put(state, out); } } let matrix = game.weights(); @@ -98,7 +97,7 @@ fn select_record( let curr_dot = (matrix * r.util).dot(&coalition); if curr_dot > dot || (curr_dot == dot && rem > r.rem) { result.util = r.util; - result.rem = rem + 1; + result.rem = r.rem + 1; dot = curr_dot; rem = r.rem; }