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

Commit

Permalink
we dump results that log performances seperately for all different AI…
Browse files Browse the repository at this point in the history
… models we may face
  • Loading branch information
fedden committed May 17, 2020
1 parent b226ff2 commit a850a58
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 8 deletions.
33 changes: 28 additions & 5 deletions pluribus/poker/card.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import List, Set, Union
from typing import Dict, List, Set, Union

from pluribus.poker.evaluation.eval_card import EvaluationCard

Expand Down Expand Up @@ -48,6 +48,11 @@ def __init__(self, rank: Union[str, int], suit: str):
suit_char = self.suit.lower()[0]
self._eval_card = EvaluationCard.new(f"{rank_char}{suit_char}")

def __repr__(self):
"""Pretty printing the object."""
icon = self._suit_to_icon(self.suit)
return f"<Card card=[{self.rank} of {self.suit} {icon}]>"

def __int__(self):
return self._eval_card

Expand Down Expand Up @@ -152,7 +157,25 @@ def _suit_to_icon(self, suit: str) -> str:
"""Icons for pretty printing."""
return {"hearts": "♥", "diamonds": "♦", "clubs": "♣", "spades": "♠"}[suit]

def __repr__(self):
"""Pretty printing the object."""
icon = self._suit_to_icon(self.suit)
return f"<Card card=[{self.rank} of {self.suit} {icon}]>"
def to_dict(self) -> Dict[str, Union[int, str]]:
"""Turn into dict."""
return dict(rank=self._rank, suit=self._suit)

@staticmethod
def from_dict(x: Dict[str, Union[int, str]]):
"""From dict turn into class."""
if set(x) != {"rank", "suit"}:
raise NotImplementedError(f"Unrecognised dict {x}")
return Card(rank=x["rank"], suit=x["suit"])

def to_dict(self) -> Dict[str, Union[int, str]]:
"""Turn into dict."""
return dict(rank=self._rank, suit=self._suit)

@staticmethod
def from_dict(x: Dict[str, Union[int, str]]):
"""From dict turn into class."""
if set(x) != {"rank", "suit"}:
raise NotImplementedError(f"Unrecognised dict {x}")
return Card(rank=x["rank"], suit=x["suit"])

63 changes: 60 additions & 3 deletions pluribus/terminal/results.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import collections
import os
from typing import Dict, Any

import numpy as np
import yaml

from pluribus.games.short_deck.state import ShortDeckPokerState
Expand All @@ -12,18 +15,72 @@ def __init__(self, file_path: str = "results.yaml"):
""""""
self._file_path = file_path
try:
with open(self._file_path, "w") as stream:
with open(self._file_path, "r") as stream:
self._results: Dict[str, Any] = yaml.safe_load(stream=stream)
except FileNotFoundError:
self._results: Dict[str, Any] = {
"stats": {},
"results": [],
}

def add_result(self, state: ShortDeckPokerState, **players):
def add_result(
self,
strategy_path: str,
agent: str,
state: ShortDeckPokerState,
og_name_to_name: Dict[str, str],
):
"""Adds results to file."""
ai_key = f"{agent}_{os.path.basename(strategy_path)}"
players = []
for player_i, player in enumerate(state.players):
name = og_name_to_name[player.name]
player_info_dict = dict(
name=name,
args=dict(
cards=[c.to_dict() for c in player.cards],
value=state.payout[player_i],
is_big_blind=player.is_big_blind,
is_small_blind=player.is_small_blind,
is_dealer=player.is_dealer,
),
)
players.append(player_info_dict)
result_entry = dict(
ai_key=ai_key,
players=players,
community_cards=[c.to_dict() for c in state.community_cards],
)
self._results["results"].append(result_entry)
self._compute_human_stats()
self._write_to_file()

def _compute_human_stats(self):
""""""
values = collections.defaultdict(lambda: collections.defaultdict(list))
for result_entry in self._results["results"]:
ai_key = result_entry["ai_key"]
for player in result_entry["players"]:
if player["name"].lower() == "human":
if player["args"]["is_big_blind"]:
key = "BB"
elif player["args"]["is_small_blind"]:
key = "SB"
elif player["args"]["is_dealer"]:
key = "D"
else:
raise NotImplementedError("")
values[ai_key][key].append(player["args"]["value"])
break
self._results["stats"] = {
ai_key: {
p: {"mean": float(np.mean(v)), "std": float(np.std(v))}
for p, v in positions_to_values.items()
}
for ai_key, positions_to_values in values.items()
}

def _write_to_file(self):
""""""
with open(self._file_path, "r") as stream:
with open(self._file_path, "w") as stream:
yaml.safe_dump(self._results, stream=stream, default_flow_style=False)
3 changes: 3 additions & 0 deletions pluribus/terminal/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from pluribus.terminal.ascii_objects.player import AsciiPlayer
from pluribus.terminal.ascii_objects.logger import AsciiLogger
from pluribus.terminal.render import print_footer, print_header, print_log, print_table
from pluribus.terminal.results import UserResults
from pluribus.utils.algos import rotate_list


Expand Down Expand Up @@ -56,6 +57,7 @@ def run_terminal_app(
offline_strategy = joblib.load(strategy_path)
else:
offline_strategy = {}
user_results: UserResults = UserResults()
with term.cbreak(), term.hidden_cursor():
while True:
# Construct ascii objects to be rendered later.
Expand Down Expand Up @@ -88,6 +90,7 @@ def run_terminal_app(
if state.is_terminal:
legal_actions = ["quit", "new game"]
human_should_interact = True
user_results.add_result(strategy_path, agent, state, og_name_to_name)
else:
og_current_name = state.current_player.name
human_should_interact = og_name_to_position[og_current_name] == "right"
Expand Down

0 comments on commit a850a58

Please sign in to comment.