Skip to content
This repository has been archived by the owner on Jul 16, 2024. It is now read-only.

Commit

Permalink
setting up support for card type in lut
Browse files Browse the repository at this point in the history
  • Loading branch information
big-c-note committed Jun 30, 2020
1 parent 9a2b93f commit 9d34ec6
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 15 deletions.
4 changes: 3 additions & 1 deletion poker_ai/ai/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ def resume(server_config_path: str):
)
@click.option(
"--lut_path",
default="./card_info_lut.joblib",
default=".",
help=(
"The path to the files for clustering the infosets."
),
Expand Down Expand Up @@ -275,6 +275,8 @@ def start(
simple_search(
config=config,
save_path=save_path,
lut_path=lut_path,
pickle_dir=pickle_dir,
strategy_interval=strategy_interval,
n_iterations=n_iterations,
lcfr_threshold=lcfr_threshold,
Expand Down
13 changes: 10 additions & 3 deletions poker_ai/ai/singleprocess/train.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ def print_strategy(strategy: Dict[str, Dict[str, int]]):
def simple_search(
config: Dict[str, int],
save_path: Path,
lut_path: Union[str, Path],
pickle_dir: bool,
strategy_interval: int,
n_iterations: int,
lcfr_threshold: int,
Expand Down Expand Up @@ -81,14 +83,19 @@ def simple_search(
"""
utils.random.seed(42)
agent = Agent(use_manager=False)
info_set_lut = {}
card_info_lut = {}
for t in trange(1, n_iterations + 1, desc="train iter"):
if t == 2:
logging.disable(logging.DEBUG)
for i in range(n_players): # fixed position i
# Create a new state.
state: ShortDeckPokerState = new_game(n_players, info_set_lut)
info_set_lut = state.info_set_lut
state: ShortDeckPokerState = new_game(
n_players,
card_info_lut,
lut_path=lut_path,
pickle_dir=pickle_dir
)
card_info_lut = state.card_info_lut
if t > update_threshold and t % strategy_interval == 0:
ai.update_strategy(agent=agent, state=state, i=i, t=t)
if t > prune_threshold:
Expand Down
4 changes: 2 additions & 2 deletions poker_ai/clustering/card_info_lut_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@ def compute(
"""
log.info("Starting computation of clusters.")
start = time.time()
if "preflop" not in self.card_info_lut:
self.card_info_lut["preflop"] = compute_preflop_lossless_abstraction(
if "pre_flop" not in self.card_info_lut:
self.card_info_lut["pre_flop"] = compute_preflop_lossless_abstraction(
builder=self
)
joblib.dump(self.card_info_lut, self.card_info_lut_path)
Expand Down
38 changes: 29 additions & 9 deletions poker_ai/games/short_deck/state.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,18 @@ def new_game(
]
if card_info_lut:
# Don't reload massive files, it takes ages.
state = ShortDeckPokerState(players=players, load_card_lut=False, **kwargs)
state = ShortDeckPokerState(
players=players,
load_card_lut=False,
**kwargs
)
state.card_info_lut = card_info_lut
else:
# Load massive files.
state = ShortDeckPokerState(players=players, **kwargs)
state = ShortDeckPokerState(
players=players,
**kwargs
)
return state


Expand All @@ -79,8 +86,9 @@ def __init__(
f"At least 2 players must be provided but only {n_players} "
f"were provided."
)
self._pickle_dir = pickle_dir
if load_card_lut:
self.card_info_lut = self.load_card_lut(lut_path, pickle_dir)
self.card_info_lut = self.load_card_lut(lut_path, self._pickle_dir)
else:
self.card_info_lut = {}
# Get a reference of the pot from the first player.
Expand Down Expand Up @@ -227,7 +235,10 @@ def apply_action(self, action_str: Optional[str]) -> ShortDeckPokerState:
return new_state

@staticmethod
def load_card_lut(lut_path: str = ".", pickle_dir: bool = False) -> Dict[str, Dict[Tuple[int, ...], str]]:
def load_card_lut(
lut_path: str = ".",
pickle_dir: bool = False
) -> Dict[str, Dict[Tuple[int, ...], str]]:
"""
Load card information lookup table.
Expand Down Expand Up @@ -267,7 +278,7 @@ def load_card_lut(lut_path: str = ".", pickle_dir: bool = False) -> Dict[str, Di
card_info_lut[betting_stage] = joblib.load(fp)
elif lut_path:
logger.info(f"Loading card from single file at path: {lut_path}")
card_info_lut = joblib.load(lut_path)
card_info_lut = joblib.load(lut_path + '/card_info_lut.joblib')
else:
card_info_lut = {}
return card_info_lut
Expand Down Expand Up @@ -373,20 +384,29 @@ def betting_round(self) -> int:
@property
def info_set(self) -> str:
"""Get the information set for the current player."""
if self._pickle_dir:
key = operator.attrgetter("eval_card")
else:
key = None
cards = sorted(
self.current_player.cards,
key=operator.attrgetter("eval_card"),
key=key,
reverse=True,
)
cards += sorted(
self._table.community_cards,
key=operator.attrgetter("eval_card"),
key=key,
reverse=True,
)
eval_cards = tuple([card.eval_card for card in cards])
if self._pickle_dir:
lookup_cards = tuple([card.eval_card for card in cards])
else:
lookup_cards = tuple(cards)
try:
cards_cluster = self.card_info_lut[self._betting_stage][eval_cards]
cards_cluster = self.card_info_lut[self._betting_stage][lookup_cards]
except KeyError:
import ipdb;
ipdb.set_trace()
return "default info set, please ensure you load it correctly"
# Convert history from a dict of lists to a list of dicts as I'm
# paranoid about JSON's lack of care with insertion order.
Expand Down

0 comments on commit 9d34ec6

Please sign in to comment.