-
Notifications
You must be signed in to change notification settings - Fork 11
/
solver.py
80 lines (72 loc) · 3.48 KB
/
solver.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
import strategy
import poker
from scipy.optimize import minimize
import numpy as np
class Solver:
def __init__(self, board, hero_range, villain_range, hero='ip', bet_size=1,
stack_size=1, starting_pot_size=1):
self.hero = hero
self.villain = 'ip' if hero == 'oop' else 'oop'
self.hero_range = hero_range
self.villain_range = villain_range
self.strategy_tree = strategy.StrategyTree(board, starting_pot_size, stack_size,
bet_size)
def create_optimal_strategy(self):
plans = self.strategy_tree.get_plans(self.hero)
num_plans = len(self.strategy_tree.get_plans(self.hero))
num_hands = len(self.hero_range.hand_weights)
num_args = num_plans * num_hands
initial_guess = np.zeros(num_args)
constraints = []
def make_sum_constraint(num_hands, hand_num, desired_total, start=None,
stop=None):
def constraint(arr):
nonlocal start
nonlocal stop
if start is None:
start = 0
if stop is None:
stop = len(arr)
total = 0
for i in range(start, stop):
if i % num_hands == hand_num:
total += arr[i]
return desired_total - total
return constraint
if self.hero == 'oop':
for i, weight in enumerate(self.hero_range.hand_weights.values()):
for j in range(num_plans):
initial_guess[i + j * num_hands] = weight / num_plans
constraints.append({'type': 'eq',
'fun': make_sum_constraint(num_hands, i, weight)})
elif self.hero == 'ip':
num_bet_plans = len([p for p in plans if p[0] == 'r'])
for i, weight in enumerate(self.hero_range.hand_weights.values()):
for j in range(num_bet_plans):
initial_guess[i + j * num_hands] = weight / num_bet_plans
for j in range(num_bet_plans, num_plans):
initial_guess[i + j * num_hands] = (weight
/ (num_plans - num_bet_plans))
constraints.append(
{'type': 'eq',
'fun': make_sum_constraint(num_hands, i, weight, 0,
num_bet_plans * num_hands)})
constraints.append(
{'type': 'eq',
'fun': make_sum_constraint(num_hands, i, weight,
num_bet_plans * num_hands, num_args)})
bounds = [(0, None) for _ in range(num_args)]
return minimize(self.evaluate_strategy, initial_guess, method='SLSQP',
bounds=bounds, constraints=constraints)
def evaluate_strategy(self, arr):
self.strategy_tree.clear_ranges()
plans = self.strategy_tree.get_plans(self.hero)
idx = 0
for plan in plans:
plan_range = poker.Range()
for hand in self.hero_range.hand_weights:
plan_range.hand_weights[hand] = arr[idx]
idx += 1
self.strategy_tree.modify_nodes_by_plan(plan, plan_range)
return self.strategy_tree.create_counter_strategy(self.villain,
self.villain_range.hand_weights)