Strategies

Struct Strategies 

Source
pub struct Strategies<'a, Infoset, Action> { /* private fields */ }
Expand description

A compact strategy for both players

Strategies are tied to a specific game and maintain a reference back to them. Create these from original data using Game::from_named.

Implementations§

Source§

impl<'a, I, A> Strategies<'a, I, A>

Source

pub fn as_named<'b: 'a>(&'b self) -> [NamedStrategyIter<'a, I, A>; 2]

Attach player, infoset, and action information to a strategy

Use this to convert a strategy profile into an exportable format.

§Examples
let game = // ...
let (strats, _) = game.solve(
    // ...
).unwrap();
let [player_one_strat, player_two_strat] = strats.as_named();
for (infoset, actions) in player_one_strat {
    for (action, prob) in actions {
        // ...
    }
}
Examples found in repository?
examples/kuhn_poker.rs (line 185)
172fn main() {
173    let args = Args::parse();
174    let game = create_kuhn(args.num_cards);
175    let (mut strats, _) = game
176        .solve(
177            SolveMethod::External,
178            args.iterations,
179            0.0,
180            args.parallel,
181            None,
182        )
183        .unwrap();
184    strats.truncate(5e-3); // not visible
185    let [player_one_strat, player_two_strat] = strats.as_named();
186    println!("Player One");
187    println!("==========");
188    let mut init = Vec::with_capacity(3);
189    let mut raised = Vec::with_capacity(3);
190    for (&(card, raise), actions) in player_one_strat {
191        if raise { &mut raised } else { &mut init }.push((card, actions));
192    }
193    println!("Initial Action");
194    println!("--------------");
195    print_card_strat(init, args.num_cards);
196    println!("If Player Two Raised");
197    println!("--------------------");
198    print_card_strat(raised, args.num_cards);
199    println!("Player Two");
200    println!("==========");
201    let mut called = Vec::with_capacity(3);
202    let mut raised = Vec::with_capacity(3);
203    for (&(card, raise), actions) in player_two_strat {
204        if raise { &mut raised } else { &mut called }.push((card, actions));
205    }
206    println!("If Player One Called");
207    println!("--------------------");
208    print_card_strat(called, args.num_cards);
209    println!("If Player One Raised");
210    println!("--------------------");
211    print_card_strat(raised, args.num_cards);
212}
Source

pub fn truncate(&mut self, thresh: f64)

Truncate actions with small probability

Since CFR produces approximate equilibria, often it will return a strategy with very low probability of playing an action that should never actually be played. Use this to truncate the probability of small actions when they’re played less than thresh of the time.

Examples found in repository?
examples/kuhn_poker.rs (line 184)
172fn main() {
173    let args = Args::parse();
174    let game = create_kuhn(args.num_cards);
175    let (mut strats, _) = game
176        .solve(
177            SolveMethod::External,
178            args.iterations,
179            0.0,
180            args.parallel,
181            None,
182        )
183        .unwrap();
184    strats.truncate(5e-3); // not visible
185    let [player_one_strat, player_two_strat] = strats.as_named();
186    println!("Player One");
187    println!("==========");
188    let mut init = Vec::with_capacity(3);
189    let mut raised = Vec::with_capacity(3);
190    for (&(card, raise), actions) in player_one_strat {
191        if raise { &mut raised } else { &mut init }.push((card, actions));
192    }
193    println!("Initial Action");
194    println!("--------------");
195    print_card_strat(init, args.num_cards);
196    println!("If Player Two Raised");
197    println!("--------------------");
198    print_card_strat(raised, args.num_cards);
199    println!("Player Two");
200    println!("==========");
201    let mut called = Vec::with_capacity(3);
202    let mut raised = Vec::with_capacity(3);
203    for (&(card, raise), actions) in player_two_strat {
204        if raise { &mut raised } else { &mut called }.push((card, actions));
205    }
206    println!("If Player One Called");
207    println!("--------------------");
208    print_card_strat(called, args.num_cards);
209    println!("If Player One Raised");
210    println!("--------------------");
211    print_card_strat(raised, args.num_cards);
212}
Source

pub fn distance(&self, other: &Self, p: f64) -> [f64; 2]

Get the distance between this strategy and another strategy

This computes the avg of the l-p earth movers distance between the strategies for each player, thus the value is between 0 and 1 where 0 represents identical strategies, and 1 represents strategies that share no support.

This is only a valid distance if p is at least 1, which should also be the default setting.

§Panics

Panics if other isn’t from the same game, or if p isn’t positive

Source

pub fn get_info(&self) -> StrategiesInfo

Get regret and utility information for this strategy profile

Trait Implementations§

Source§

impl<'a, Infoset: Clone, Action: Clone> Clone for Strategies<'a, Infoset, Action>

Source§

fn clone(&self) -> Strategies<'a, Infoset, Action>

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<'a, Infoset: Debug, Action: Debug> Debug for Strategies<'a, Infoset, Action>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<I, A> PartialEq for Strategies<'_, I, A>

Strategies are equal if they contain identical values and are from the same game

Equality is strict since action probabilities can’t be nan.

Source§

fn eq(&self, other: &Self) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl<I, A> Eq for Strategies<'_, I, A>

Auto Trait Implementations§

§

impl<'a, Infoset, Action> Freeze for Strategies<'a, Infoset, Action>

§

impl<'a, Infoset, Action> RefUnwindSafe for Strategies<'a, Infoset, Action>
where Infoset: RefUnwindSafe, Action: RefUnwindSafe,

§

impl<'a, Infoset, Action> Send for Strategies<'a, Infoset, Action>
where Infoset: Sync, Action: Sync,

§

impl<'a, Infoset, Action> Sync for Strategies<'a, Infoset, Action>
where Infoset: Sync, Action: Sync,

§

impl<'a, Infoset, Action> Unpin for Strategies<'a, Infoset, Action>

§

impl<'a, Infoset, Action> UnwindSafe for Strategies<'a, Infoset, Action>
where Infoset: RefUnwindSafe, Action: RefUnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
Source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V