1
+ use crate :: cards:: hand:: Hand ;
1
2
use crate :: cards:: hole:: Hole ;
2
3
use crate :: transport:: support:: Support ;
3
4
use crate :: Probability ;
@@ -6,47 +7,57 @@ use std::u64;
6
7
7
8
/// Abstraction represents a lookup value for a given set of Observations.
8
9
///
9
- /// - River: we use a i8 to represent the equity bucket, i.e. Equity(0) is the worst bucket, and Equity(50) is the best bucket.
10
+ /// - River: we use a u8 to represent the equity bucket, i.e. Equity(0) is the worst bucket, and Equity(50) is the best bucket.
10
11
/// - Pre-Flop: we do not use any abstraction, rather store the 169 strategically-unique hands as u64.
11
12
/// - Other Streets: we use a u64 to represent the hash signature of the centroid Histogram over lower layers of abstraction.
12
13
#[ derive( Copy , Clone , Hash , Eq , PartialEq , Debug , PartialOrd , Ord ) ]
13
14
pub enum Abstraction {
14
- Equity ( i8 ) , // river
15
- Random ( u64 ) , // flop, turn
15
+ Equity ( u8 ) , // river
16
+ Unique ( u64 ) , // flop, turn
16
17
Pocket ( Hole ) , // preflop
17
18
}
18
19
19
20
impl Support for Abstraction { }
20
21
21
22
impl Abstraction {
22
- pub const fn range ( ) -> & ' static [ Self ] {
23
- & Self :: BUCKETS
24
- }
25
23
pub fn random ( ) -> Self {
26
- Self :: Random ( rand:: random :: < u64 > ( ) )
24
+ Self :: Unique ( loop {
25
+ let x = rand:: random :: < u64 > ( ) ;
26
+ if x & EQUITY_TAG == EQUITY_TAG {
27
+ continue ;
28
+ }
29
+ if x & POCKET_TAG == POCKET_TAG {
30
+ continue ;
31
+ }
32
+ break x;
33
+ } )
27
34
}
28
- fn quantize ( p : Probability ) -> i8 {
29
- ( p * Probability :: from ( Self :: N ) ) . round ( ) as i8
35
+ fn quantize ( p : Probability ) -> u8 {
36
+ ( p * Probability :: from ( Self :: N ) ) . round ( ) as u8
30
37
}
31
- fn floatize ( q : i8 ) -> Probability {
38
+ fn floatize ( q : u8 ) -> Probability {
32
39
Probability :: from ( q) / Probability :: from ( Self :: N )
33
40
}
34
- const N : i8 = 63 ;
41
+
42
+ const N : u8 = 63 ;
35
43
const BUCKETS : [ Self ; Self :: N as usize + 1 ] = Self :: buckets ( ) ;
36
44
const fn buckets ( ) -> [ Self ; Self :: N as usize + 1 ] {
37
45
let mut buckets = [ Self :: Equity ( 0 ) ; Self :: N as usize + 1 ] ;
38
46
let mut i = 0 ;
39
47
while i <= Self :: N {
40
- buckets[ i as usize ] = Self :: Equity ( i as i8 ) ;
48
+ buckets[ i as usize ] = Self :: Equity ( i as u8 ) ;
41
49
i += 1 ;
42
50
}
43
51
buckets
44
52
}
53
+ pub const fn range ( ) -> & ' static [ Self ] {
54
+ & Self :: BUCKETS
55
+ }
45
56
}
46
57
47
58
/// probability isomorphism
48
59
///
49
- /// for river, we use a i8 to represent the equity bucket,
60
+ /// for river, we use a u8 to represent the equity bucket,
50
61
/// i.e. Equity(0) is the 0% equity bucket,
51
62
/// and Equity(N) is the 100% equity bucket.
52
63
impl From < Probability > for Abstraction {
@@ -60,27 +71,33 @@ impl From<Abstraction> for Probability {
60
71
fn from ( abstraction : Abstraction ) -> Self {
61
72
match abstraction {
62
73
Abstraction :: Equity ( n) => Abstraction :: floatize ( n) ,
63
- Abstraction :: Random ( _) => unreachable ! ( "no cluster into probability" ) ,
74
+ Abstraction :: Unique ( _) => unreachable ! ( "no cluster into probability" ) ,
64
75
Abstraction :: Pocket ( _) => unreachable ! ( "no preflop into probability" ) ,
65
76
}
66
77
}
67
78
}
68
79
80
+ const EQUITY_TAG : u64 = 0xEEE ;
81
+ const POCKET_TAG : u64 = 0xFFF ;
69
82
/// u64 isomorphism
70
83
///
71
84
/// conversion to u64 for SQL storage.
72
85
impl From < Abstraction > for u64 {
73
86
fn from ( a : Abstraction ) -> Self {
74
87
match a {
75
- Abstraction :: Random ( n) => n,
76
- Abstraction :: Equity ( _ ) => unreachable ! ( "no equity into u64" ) ,
77
- Abstraction :: Pocket ( _ ) => unreachable ! ( "no preflop into u64" ) ,
88
+ Abstraction :: Unique ( n) => n,
89
+ Abstraction :: Equity ( e ) => ( EQUITY_TAG << 52 ) | ( e as u64 & 0xFF ) << 44 ,
90
+ Abstraction :: Pocket ( h ) => ( POCKET_TAG << 52 ) | u64:: from ( Hand :: from ( h ) ) ,
78
91
}
79
92
}
80
93
}
81
94
impl From < u64 > for Abstraction {
82
95
fn from ( n : u64 ) -> Self {
83
- Self :: Random ( n)
96
+ match n >> 52 {
97
+ EQUITY_TAG => Self :: Equity ( ( ( n >> 44 ) & 0xFF ) as u8 ) ,
98
+ POCKET_TAG => Self :: Pocket ( Hole :: from ( Hand :: from ( n & 0x000FFFFFFFFFFFFF ) ) ) ,
99
+ _ => Self :: Unique ( n) ,
100
+ }
84
101
}
85
102
}
86
103
@@ -94,7 +111,7 @@ impl From<Abstraction> for i64 {
94
111
}
95
112
impl From < i64 > for Abstraction {
96
113
fn from ( n : i64 ) -> Self {
97
- Self :: Random ( n as u64 )
114
+ Self :: Unique ( n as u64 )
98
115
}
99
116
}
100
117
@@ -108,7 +125,7 @@ impl From<Hole> for Abstraction {
108
125
impl std:: fmt:: Display for Abstraction {
109
126
fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
110
127
match self {
111
- Self :: Random ( n) => write ! ( f, "{:016x}" , n) ,
128
+ Self :: Unique ( n) => write ! ( f, "{:016x}" , n) ,
112
129
Self :: Equity ( n) => write ! ( f, "Equity({:00.2})" , Self :: floatize( * n) ) ,
113
130
Self :: Pocket ( h) => write ! ( f, "Pocket({})" , h) ,
114
131
}
@@ -118,6 +135,8 @@ impl std::fmt::Display for Abstraction {
118
135
#[ cfg( test) ]
119
136
mod tests {
120
137
use super :: * ;
138
+ use crate :: cards:: observation:: Observation ;
139
+ use crate :: cards:: street:: Street ;
121
140
122
141
#[ test]
123
142
fn is_quantize_inverse_floatize ( ) {
@@ -136,4 +155,22 @@ mod tests {
136
155
assert ! ( q == i) ;
137
156
}
138
157
}
158
+
159
+ #[ test]
160
+ fn bijective_u64_random ( ) {
161
+ let random = Abstraction :: random ( ) ;
162
+ assert_eq ! ( random, Abstraction :: from( u64 :: from( random) ) ) ;
163
+ }
164
+
165
+ #[ test]
166
+ fn bijective_u64_equity ( ) {
167
+ let equity = Abstraction :: Equity ( Abstraction :: N / 2 ) ;
168
+ assert_eq ! ( equity, Abstraction :: from( u64 :: from( equity) ) ) ;
169
+ }
170
+
171
+ #[ test]
172
+ fn bijective_u64_pocket ( ) {
173
+ let pocket = Abstraction :: Pocket ( Hole :: from ( Observation :: from ( Street :: Pref ) ) ) ;
174
+ assert_eq ! ( pocket, Abstraction :: from( u64 :: from( pocket) ) ) ;
175
+ }
139
176
}
0 commit comments