Skip to content

Commit

Permalink
Merge branch 'main' into shortdeck
Browse files Browse the repository at this point in the history
  • Loading branch information
reinismu authored Oct 16, 2024
2 parents 51b46bc + b9fcfce commit 33ae780
Show file tree
Hide file tree
Showing 8 changed files with 34 additions and 25 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@
.env
.swp
profile.json
*.pgcopy
*.pgcopy
14 changes: 12 additions & 2 deletions src/clustering/abstractor.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
use crate::cards::isomorphism::Isomorphism;
use crate::cards::observation::Observation;
// use crate::cards::observation::Observation as Equivalence;
use crate::cards::street::Street;
use crate::clustering::abstraction::Abstraction;
use crate::clustering::histogram::Histogram;
// use crate::clustering::progress::Progress;
use std::collections::BTreeMap;

/// this is the output of the clustering module
Expand All @@ -22,6 +20,9 @@ impl Abstractor {
let mut map = BTreeMap::default();
map.extend(Self::load(Street::Turn).0);
map.extend(Self::load(Street::Flop).0);
// TODO
// extend map with preflop
// alternatively, handle lossless preflop abstractions in Self::abstraction
Self(map)
}

Expand All @@ -43,6 +44,15 @@ impl Abstractor {
}
/// lookup the pre-computed abstraction for the outer observation
pub fn abstraction(&self, outer: &Isomorphism) -> Abstraction {
// TODO
// match on street
// river => compute equity on the fly**
// turn | flop => lookup
// preflop => isomorphism into Hole
//
// ** this is expensive ?
// ** could implement mc_equity to not iterate over villain cards exhaustively ?
// ** should check benchmarks to see how much this matters
self.0
.get(outer)
.cloned()
Expand Down
3 changes: 1 addition & 2 deletions src/clustering/metric.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use crate::clustering::abstraction::Abstraction;
use crate::clustering::histogram::Histogram;
// use crate::clustering::progress::Progress;
use crate::clustering::xor::Pair;
use std::collections::BTreeMap;

Expand All @@ -24,7 +23,7 @@ impl Metric {
/// we only have the luxury of this efficient O(N) calculation on Street::Turn,
/// where the support is over the Abstraction::Equity(i8) variant.
pub fn emd(&self, source: &Histogram, target: &Histogram) -> f32 {
match target.peek() {
match source.peek() {
Abstraction::Equity(_) => Self::difference(source, target),
Abstraction::Random(_) => self.wasserstein(source, target),
Abstraction::Pocket(_) => unreachable!("no preflop emd"),
Expand Down
12 changes: 6 additions & 6 deletions src/clustering/sampling.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ use super::abstractor::Abstractor;
use crate::cards::isomorphism::Isomorphism;
use crate::mccfr::bucket::Bucket;
use crate::mccfr::bucket::Path;
use crate::mccfr::data::Vertex;
use crate::mccfr::edge::Edge;
use crate::mccfr::node::Node;
use crate::mccfr::player::Player;
use crate::mccfr::profile::Profile;
use crate::mccfr::spot::Spot;
use crate::play::game::Game;
use crate::Probability;
use rand::distributions::Distribution;
Expand Down Expand Up @@ -35,7 +35,7 @@ impl Sampler {
/// compared to chance sampling, internal sampling, or full tree sampling.
///
/// i think this could also be modified into a recursive CFR calcuation
pub fn sample(&self, node: &Node, profile: &Profile) -> Vec<(Vertex, Edge)> {
pub fn sample(&self, node: &Node, profile: &Profile) -> Vec<(Spot, Edge)> {
let mut children = self.children(node);
// terminal nodes have no children and we sample all possible actions for the traverser
if node.player() == profile.walker() || children.is_empty() {
Expand Down Expand Up @@ -68,7 +68,7 @@ impl Sampler {

/// produce the children of a Node.
/// we may need some Trainer-level references to produce children
fn children(&self, node: &Node) -> Vec<(Vertex, Edge)> {
fn children(&self, node: &Node) -> Vec<(Spot, Edge)> {
let ref game = node.datum().game();
let ref past = node.history().into_iter().collect::<Vec<&Edge>>();
game.children()
Expand All @@ -79,16 +79,16 @@ impl Sampler {
}
/// extend a path with an Edge
/// wrap the (Game, Bucket) in a Data
fn explore(&self, game: Game, edge: Edge, history: &Vec<&Edge>) -> (Vertex, Edge) {
fn explore(&self, game: Game, edge: Edge, history: &Vec<&Edge>) -> (Spot, Edge) {
let mut history = history.clone();
history.push(&edge);
(self.data(game, history), edge)
}
/// generate a Bucket from Game
/// wrap the (Game, Bucket) in a Data
fn data(&self, game: Game, path: Vec<&Edge>) -> Vertex {
fn data(&self, game: Game, path: Vec<&Edge>) -> Spot {
let bucket = self.bucket(&game, &path);
Vertex::from((game, bucket))
Spot::from((game, bucket))
}
/// inddd
fn bucket(&self, game: &Game, path: &Vec<&Edge>) -> Bucket {
Expand Down
2 changes: 1 addition & 1 deletion src/mccfr/mod.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
pub mod bucket;
pub mod data;
pub mod edge;
pub mod info;
pub mod memory;
pub mod node;
pub mod player;
pub mod profile;
pub mod spot;
pub mod trainer;
pub mod tree;
10 changes: 5 additions & 5 deletions src/mccfr/node.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use super::bucket::Bucket;
use super::player::Player;
use crate::mccfr::data::Vertex;
use crate::mccfr::edge::Edge;
use crate::mccfr::spot::Spot;
use crate::play::continuation::Transition;
use crate::Utility;
use petgraph::graph::DiGraph;
Expand All @@ -13,11 +13,11 @@ use std::ptr::NonNull;
pub struct Node {
graph: NonNull<DiGraph<Self, Edge>>,
index: NodeIndex,
datum: Vertex,
datum: Spot,
}

impl From<(NodeIndex, NonNull<DiGraph<Node, Edge>>, Vertex)> for Node {
fn from((index, graph, datum): (NodeIndex, NonNull<DiGraph<Node, Edge>>, Vertex)) -> Self {
impl From<(NodeIndex, NonNull<DiGraph<Node, Edge>>, Spot)> for Node {
fn from((index, graph, datum): (NodeIndex, NonNull<DiGraph<Node, Edge>>, Spot)) -> Self {
Self {
index,
graph,
Expand All @@ -28,7 +28,7 @@ impl From<(NodeIndex, NonNull<DiGraph<Node, Edge>>, Vertex)> for Node {

/// collection of these three is what you would get in a Node, which may be too restrictive for a lot of the use so we'll se
impl Node {
pub fn datum(&self) -> &Vertex {
pub fn datum(&self) -> &Spot {
&self.datum
}
pub fn index(&self) -> NodeIndex {
Expand Down
6 changes: 3 additions & 3 deletions src/mccfr/data.rs → src/mccfr/spot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,18 @@ use crate::mccfr::player::Player;
use crate::play::continuation::Transition;
use crate::play::game::Game;

pub struct Vertex {
pub struct Spot {
game: Game,
bucket: Bucket,
}

impl From<(Game, Bucket)> for Vertex {
impl From<(Game, Bucket)> for Spot {
fn from((game, bucket): (Game, Bucket)) -> Self {
Self { game, bucket }
}
}

impl Vertex {
impl Spot {
pub fn game(&self) -> &Game {
&self.game
}
Expand Down
10 changes: 5 additions & 5 deletions src/mccfr/trainer.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use super::data::Vertex;
use super::edge::Edge;
use super::node::Node;
use super::player::Player;
use super::profile::Profile;
use super::spot::Spot;
use super::tree::Tree;
use crate::clustering::sampling::Sampler;
use petgraph::graph::NodeIndex;
Expand Down Expand Up @@ -72,7 +72,7 @@ impl Explorer {
/// recursively build the Tree from the given Node, according to the distribution defined by Profile.
/// we assert the Tree property of every non-root Node having exactly one parent Edge
/// we construct the appropriate references in self.attach() to ensure safety.
fn dfs(&mut self, head: Vertex, edge: Edge, root: NodeIndex) {
fn dfs(&mut self, head: Spot, edge: Edge, root: NodeIndex) {
let head = self.witness(head);
let head = self.tree.graph_mut().add_node(head);
let edge = self.tree.graph_mut().add_edge(root, head, edge);
Expand All @@ -87,7 +87,7 @@ impl Explorer {
/// attach a Node to the Tree,
/// update the Profile to witness the new Node
/// update the InfoPartition to witness the new Node.
fn witness(&mut self, data: Vertex) -> Node {
fn witness(&mut self, data: Spot) -> Node {
let player = data.player().clone();
let graph = self.tree.graph_ptr();
let count = self.tree.graph_ref().node_count();
Expand All @@ -106,13 +106,13 @@ impl Explorer {
/// Game::root() -> Observation -> Abstraction
///
/// NOT deterministic, hole cards are thread_rng
fn root(&self) -> Vertex {
fn root(&self) -> Spot {
use crate::mccfr::bucket::Bucket;
use crate::play::game::Game;
let node = Game::root();
let path = self.sampler.path_abstraction(&Vec::new());
let abstraction = self.sampler.card_abstraction(&node);
let bucket = Bucket::from((path, abstraction));
Vertex::from((node, bucket))
Spot::from((node, bucket))
}
}

0 comments on commit 33ae780

Please sign in to comment.