Skip to content

Commit af5fa82

Browse files
committed
some shit wip
1 parent e9ef83a commit af5fa82

File tree

3 files changed

+43
-39
lines changed

3 files changed

+43
-39
lines changed

README.md

+12-8
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,12 @@ robopoker
33
[![license](https://img.shields.io/github/license/krukah/robopoker)](LICENSE)
44
[![build](https://github.com/krukah/robopoker/actions/workflows/rust.yml/badge.svg)](https://github.com/krukah/robopoker/actions/workflows/rust.yml)
55

6+
# Overview
7+
68
`robopoker` is a Rust library to play, learn, analyze, track, and solve No-Limit Texas Hold'em.
79

810
The guiding philosophy of this package was to use very tangible abstractions to represent the rules, mechanics, and strategies of NLHE. Every module is modeled as closely as possible to its real-world analogue, while also utilizing clever representations and transformations to be as memory- and compute-efficient as possible. Focus on Rust idiomatics is also a goal, avoiding use of unsafe and exploiting strong typing.
911

10-
# System Requirements
11-
12-
- Minimum 8GB RAM for shortdeck. 50GB+ recommended for full.
13-
- Multi-core CPU. Clustering and CFR scale embarassingly.
14-
1512
# Modules
1613

1714
## `cards`
@@ -22,7 +19,8 @@ Core functionality for working with standard playing cards and Texas Hold'em rul
2219
- **Equity Calculation**: Fast equity calculations between ranges of hands, supporting both exact enumeration and Monte Carlo simulation
2320
- **Exhaustive Iteration**: Efficient iteration over cards, hands, decks, and private-public observations with lazy bitwise advancing
2421
- **Distribution Analysis**: Tools for analyzing equity distributions and range vs range scenarios
25-
- **Bijective Representations**: Multiple card representations (u8/u16/u32/u64) allowing for maximally efficient operations and transformations
22+
- **Short Deck Support**: Full support for 36-card short deck variant with adjusted hand rankings and iterators
23+
- **Bijective Representations**: Multiple card representations `(u8/u16/u32/u64)` allow for maximally efficient operations and transformations
2624

2725
## `gameplay`
2826

@@ -48,7 +46,7 @@ Advanced clustering capabilities for poker hand analysis:
4846

4947
Monte Carlo Counterfactual Regret Minimization solver:
5048

51-
- **RPS Convergence**: Previously demonstrated convergence on Rock-Paper-Scissors as validation
49+
- **Blueprint Convergence**: Previously demonstrated convergence on Rock-Paper-Scissors as validation
5250
- **External Sampling**: Implementation of external sampling MCCFR variant
5351
- **Dynamic Tree Building**: On-the-fly game tree construction for memory efficiency
5452
- **Linear Strategy Weighting**: Efficient strategy updates using iterative weighting and discount schemes
@@ -58,7 +56,13 @@ Monte Carlo Counterfactual Regret Minimization solver:
5856

5957
Coming soon. A distributed and scalable single-binary WebSocket-based HTTP server that allows players to play, learn, analyze, and track hands remotely.
6058

61-
## References
59+
# System Requirements
60+
61+
- 8GB RAM for shortdeck abstraction
62+
- 5GB disk space for stored blueprint, abstraction, and metric tables
63+
- Multi-core CPU. Clustering and CFR scale embarassingly.
64+
65+
# References
6266

6367
1. (2007). Regret Minimization in Games with Incomplete Information. [(NIPS)](https://papers.nips.cc/paper/3306-regret-minimization-in-games-with-incomplete-information)
6468
2. (2015). Discretization of Continuous Action Spaces in Extensive-Form Games. [(AAMAS)](http://www.cs.cmu.edu/~sandholm/discretization.aamas15.fromACM.pdf)

src/clustering/encoding.rs

+23-23
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,29 @@ impl Encoder {
8989
* methods for unraveling the Tree
9090
*/
9191
impl Encoder {
92+
/// laying groundwork for pseudo-harmonic support
93+
/// using the n-bet-filtered set of actions that we can take
94+
/// we generalize using the raise granularity abstraction algorithm
95+
/// of pseudo-harmonic mapping. then we spawn the children as if
96+
/// these were the only actions available to us.
97+
/// Self::spawn may be pub on Game
98+
/// Self::unfold only takes River -> [River]
99+
fn futures(&self, node: &Node) -> Vec<(Data, Edge)> {
100+
let edges = self.children(node).into_iter().map(|(_, e)| e).collect();
101+
let edges = Self::unfold(node, edges);
102+
let datum = node.data();
103+
edges
104+
.into_iter()
105+
.map(|action| Self::spawn(datum, action))
106+
.collect()
107+
}
108+
fn unfold(node: &Node, edges: Vec<Edge>) -> Vec<Edge> {
109+
todo!()
110+
}
111+
fn spawn(data: &Data, edge: Edge) -> (Data, Edge) {
112+
todo!()
113+
}
114+
92115
pub fn root(&self) -> Data {
93116
let game = Game::root();
94117
let info = self.chance_abstraction(&game);
@@ -138,29 +161,6 @@ impl Encoder {
138161
}
139162
}
140163

141-
/// laying groundwork for pseudo-harmonic support
142-
/// using the n-bet-filtered set of actions that we can take
143-
/// we generalize using the raise granularity abstraction algorithm
144-
/// of pseudo-harmonic mapping. then we spawn the children as if
145-
/// these were the only actions available to us.
146-
/// Self::spawn may be pub on Game
147-
/// Self::unfold only takes River -> [River]
148-
fn futures(&self, node: &Node) -> Vec<(Data, Edge)> {
149-
let edges = self.children(node).into_iter().map(|(_, e)| e).collect();
150-
let edges = Self::unfold(edges);
151-
let datum = node.data();
152-
edges
153-
.into_iter()
154-
.map(|action| Self::spawn(datum, action))
155-
.collect()
156-
}
157-
fn unfold(edges: Vec<Edge>) -> Vec<Edge> {
158-
todo!()
159-
}
160-
fn spawn(data: &Data, edge: Edge) -> (Data, Edge) {
161-
todo!()
162-
}
163-
164164
/// i like to think of this as "positional encoding"
165165
/// i like to think of this as "positional encoding"
166166
/// later in the same round where the stakes are higher

src/mccfr/profile.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -248,15 +248,15 @@ impl Profile {
248248
.get_mut(bucket)
249249
.expect("bucket been witnessed");
250250
for (action, &regret) in regrets {
251-
let strategy = strategy.get_mut(action).expect("action been witnessed");
251+
let decision = strategy.get_mut(action).expect("action been witnessed");
252252
let discount = match phase {
253253
Phase::Discount => discount.regret(t, regret),
254254
Phase::Explore => 1.,
255255
Phase::Prune => 1.,
256256
};
257-
strategy.regret *= discount;
258-
strategy.regret += regret;
259-
log::trace!("{} : {}", action, strategy.regret);
257+
decision.regret *= discount;
258+
decision.regret += regret;
259+
log::trace!("{} : {}", action, decision.regret);
260260
}
261261
}
262262
pub fn update_policy(&mut self, bucket: &Bucket, policys: &BTreeMap<Edge, Probability>) {
@@ -269,10 +269,10 @@ impl Profile {
269269
.expect("bucket been witnessed");
270270
for (action, &policy) in policys {
271271
let discount = discount.policy(t);
272-
let strategy = strategy.get_mut(action).expect("action been witnessed");
273-
strategy.policy *= discount;
274-
strategy.policy += policy;
275-
log::trace!("{} : {}", action, strategy.policy);
272+
let decision = strategy.get_mut(action).expect("action been witnessed");
273+
decision.policy *= discount;
274+
decision.policy += policy;
275+
log::trace!("{} : {}", action, decision.policy);
276276
}
277277
}
278278

0 commit comments

Comments
 (0)