From 0d5dc967fe5675d5e28a7265094151c94ea81c37 Mon Sep 17 00:00:00 2001 From: Krasto Date: Sun, 21 Jan 2024 23:44:16 +0000 Subject: [PATCH] cleanup --- .github/workflows/python-app.yml | 6 +- ci_quixo/__main__.py | 93 +++++++------------- ci_quixo/game.py | 5 ++ ci_quixo/helper.py | 121 ++++++++++++++++++++++++--- ci_quixo/mcts.py | 3 + ci_quixo/minmax.py | 8 +- ci_quixo/results/players_wr.png | Bin 0 -> 23769 bytes ci_quixo/results/time_comparison.png | Bin 0 -> 20040 bytes 8 files changed, 160 insertions(+), 76 deletions(-) create mode 100644 ci_quixo/results/players_wr.png create mode 100644 ci_quixo/results/time_comparison.png diff --git a/.github/workflows/python-app.yml b/.github/workflows/python-app.yml index 5e7b63f..1a0f928 100644 --- a/.github/workflows/python-app.yml +++ b/.github/workflows/python-app.yml @@ -31,4 +31,8 @@ jobs: - name: Test with pytest if: contains(github.event.head_commit.message, 'EVAL') run: | - python -m pytest ci_quixo/__main__.py -m evaluate -s + python -m ci_quixo + - name: Create Pull Request + uses: peter-evans/create-pull-request@v5 + title: Generate nuove foto di eval + commit-message: updated results picture \ No newline at end of file diff --git a/ci_quixo/__main__.py b/ci_quixo/__main__.py index e472e4c..32cd5ff 100644 --- a/ci_quixo/__main__.py +++ b/ci_quixo/__main__.py @@ -1,82 +1,53 @@ try: from _players import MinMaxPlayer, MCTSPlayer, RandomPlayer - from helper import evaluate + from helper import evaluate, Result, gen_plots + from main import Player except: from ._players import * - from .helper import evaluate -import pytest + from .main import Player + from .helper import evaluate, Result, gen_plots from pprint import pprint +import dill, multiprocessing +dill.Pickler.dumps, dill.Pickler.loads = dill.dumps, dill.loads +multiprocessing.reduction.ForkingPickler = dill.Pickler +multiprocessing.reduction.dump = dill.dump GAMES = 10 HIDE_PBAR = True -@pytest.mark.evaluate -def test_minmax_vs_random(): - minmax = MinMaxPlayer() +minmax2 = MinMaxPlayer() +minmax3 = MinMaxPlayer(3, pruning=2) +mcts_r = MCTSPlayer() +mcts_h = MCTSPlayer(sim_heuristic=True) - print("\n--- --- ---") - print(f"{minmax.name} VS RandomPlayer") - evaluate(minmax, RandomPlayer(), games=GAMES, display=True, hide_pbar=HIDE_PBAR) - print(f"{minmax.name} Stats:") - pprint(minmax.stats, sort_dicts=False) -@pytest.mark.evaluate -def test_minmax3_vs_random(): - minmax = MinMaxPlayer(3, pruning=2) +def test_minmax_vs_random() -> Result: + return evaluate(minmax2, RandomPlayer(), games=GAMES, display=True, hide_pbar=HIDE_PBAR) - print("\n--- --- ---") - print(f"{minmax.name} VS RandomPlayer") - evaluate(minmax, RandomPlayer(), games=GAMES, display=True, hide_pbar=HIDE_PBAR) - print(f"{minmax.name} Stats:") - pprint(minmax.stats, sort_dicts=False) +def test_minmax3_vs_random() -> Result: + return evaluate(minmax3, RandomPlayer(), games=GAMES, display=True, hide_pbar=HIDE_PBAR) -@pytest.mark.evaluate -def test_mcts_r_vs_random(): - mcts = MCTSPlayer() +def test_mcts_r_vs_random() -> Result: + return evaluate(mcts_r, RandomPlayer(), games=GAMES, display=True, hide_pbar=HIDE_PBAR) - print("\n--- --- ---") - print(f"{mcts.name} vs RandomPlayer") - evaluate(mcts, RandomPlayer(), games=GAMES, display=True, hide_pbar=HIDE_PBAR) - print(f"{mcts.name} Stats:") - pprint(mcts.stats, sort_dicts=False) +def test_mcts_h_vs_random() -> Result: + return evaluate(mcts_h, RandomPlayer(), games=GAMES, display=True, hide_pbar=HIDE_PBAR) -@pytest.mark.evaluate -def test_mcts_h_vs_random(): - mcts = MCTSPlayer(sim_heuristic=True) - print("\n--- --- ---") - print(f"{mcts.name} vs RandomPlayer") - evaluate(mcts, RandomPlayer(), games=GAMES, display=True, hide_pbar=HIDE_PBAR) - print(f"{mcts.name} Stats:") - pprint(mcts.stats, sort_dicts=False) +def test_minmax_vs_mcts_random() -> Result: + return evaluate(minmax2, mcts_r, games=GAMES, display=True, hide_pbar=HIDE_PBAR) +def test_minmax_vs_mcts_heuristic() -> Result: + return evaluate(minmax2, mcts_h, games=GAMES, display=True, hide_pbar=HIDE_PBAR) -@pytest.mark.evaluate -def test_minmax_vs_mcts_random(): - minmax = MinMaxPlayer() - mcts = MCTSPlayer() - print("\n--- --- ---") - print(f"{minmax.name} VS {mcts.name}") - evaluate(minmax, mcts, games=GAMES, display=True, hide_pbar=HIDE_PBAR) - print(f"{minmax.name} Stats:") - pprint(minmax.stats, sort_dicts=False) - print(f"{mcts.name} Stats:") - pprint(mcts.stats, sort_dicts=False) - -@pytest.mark.evaluate -def test_minmax_vs_mcts_heuristic(): - minmax = MinMaxPlayer() - mcts = MCTSPlayer(sim_heuristic=True) - - print("\n--- --- ---") - print(f"{minmax.name} VS {mcts.name}") - evaluate(minmax, mcts, games=GAMES, display=True, hide_pbar=HIDE_PBAR) - print(f"{minmax.name} Stats:") - pprint(minmax.stats, sort_dicts=False) - print(f"{mcts.name} Stats:") - pprint(mcts.stats, sort_dicts=False) - +def call(it: callable) -> Result: + return it() if __name__ == "__main__": - print("Use `python -m pytest ci_quixo/__main__.py -m evaluate -s`") \ No newline at end of file + evals = [test_minmax_vs_random, test_minmax3_vs_random, test_mcts_r_vs_random, test_mcts_h_vs_random, test_minmax_vs_mcts_random, test_minmax_vs_mcts_heuristic] + + with multiprocessing.Pool() as p: + RESULTS = p.map(call, evals[:-2]) + + gen_plots(RESULTS) \ No newline at end of file diff --git a/ci_quixo/game.py b/ci_quixo/game.py index b3d1524..20e2e6b 100644 --- a/ci_quixo/game.py +++ b/ci_quixo/game.py @@ -22,6 +22,11 @@ def __init__(self) -> None: '''You can change this for your player if you need to handle state/have memory''' pass + @property + def name(self) -> None: + '''Player Name''' + "Player" + @abstractmethod def make_move(self, game: 'Game') -> tuple[tuple[int, int], Move]: ''' diff --git a/ci_quixo/helper.py b/ci_quixo/helper.py index 047779e..4e49436 100644 --- a/ci_quixo/helper.py +++ b/ci_quixo/helper.py @@ -1,4 +1,4 @@ -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, TypedDict try: from main import Move, RandomPlayer, Game, Player from custom_game import CustomGame @@ -10,8 +10,14 @@ if TYPE_CHECKING: from .custom_game import CompleteMove +import time import numpy as np from tqdm.auto import trange +from os import path +import matplotlib.pyplot as plt +from dataclasses import dataclass, field +from pprint import pformat +PLOT_FOLDER = path.join(path.dirname(path.abspath(__file__)), "results") def pprint_board(game: "Game"): board: np.ndarray = game.get_board() @@ -24,29 +30,120 @@ def pprint_board(game: "Game"): print(c, end="") print() -def evaluate(p1: "Player", p2: "Player" = None, games: int = 10, display: bool = False, hide_pbar: bool = False) -> tuple[int]: +@dataclass +class Result: + p1: Player + p2: Player + wrfs: tuple[float] + """Player 1 Win Rate (as first, as second)""" + avg_time: float + + @property + def wr(self) -> float: + return sum(self.wrfs)/2 + + +def evaluate(p1: "Player", p2: "Player" = None, games: int = 10, display: bool = False, hide_pbar: bool = False) -> Result: if games % 2 != 0: games += 1 if p2 is None: p2 = RandomPlayer() - won_as_first, won_as_second = 0, 0 + wins_as_first, wins_as_second = 0, 0 pbar = trange(games, desc="Evaluating player", unit="game") if not hide_pbar else range(games) + p1name = "RandomPlayer" if isinstance(p1, RandomPlayer) else p1.name + p2name = "RandomPlayer" if isinstance(p2, RandomPlayer) else p2.name + + durations = [] for i in pbar: game = Game() + s = time.time() if i % 2 == 0: - won_as_first += 1 if game.play(p1, p2) == 0 else 0 + wins_as_first += 1 if game.play(p1, p2) == 0 else 0 else: - won_as_second += 1 if game.play(p2, p1) == 1 else 0 - wins = won_as_first + won_as_second + wins_as_second += 1 if game.play(p2, p1) == 1 else 0 + wins = wins_as_first + wins_as_second + durations.append(time.time() - s) not hide_pbar and pbar.set_postfix({"wins": f"{(wins/(i+1)):.1%}"}) wins /= games - won_as_first /= games/2 - won_as_second /= games/2 + wins_as_first /= games/2 + wins_as_second /= games/2 + avg=sum(durations)/len(durations) if display: - print(f"Total wins : {wins:.2%}") - print(f"Wins as 1st: {won_as_first:.2%}") - print(f"Wins as 2nd: {won_as_second:.2%}") - return wins, won_as_first, won_as_second + print(f"----- {p1name} vs {p2name} w/ {games} games -----") + print(f"Total wins : {wins:>6.2%}") + print(f"Wins as 1st : {wins_as_first:>6.2%}") + print(f"Wins as 2nd : {wins_as_second:>6.2%}") + print(f"Average Time: {avg:>6.2f}s") + try: + print(f"{p1.name} stats: \n{pformat(p1.stats)}") + except: + pass + try: + print(f"{p2.name} stats: \n{pformat(p2.stats)}") + except: + pass + print("----- ------") + # gen_plot("a", ("a", "a"), [1, 0]) + return Result(p1, p2, (wins_as_first, wins_as_second), avg) + + +def gen_plots(results: list[Result]) -> None: + plot_time_comparison(results) + plot_wr_vs_random(results) + + pass + +def plot_wr_vs_random(results: list[Result]) -> None: + results = [r for r in results if isinstance(r.p2, RandomPlayer)] + + player_names = [r.p1.short_name for r in results] + wr1 = [r.wrfs[0] * 100 for r in results] + wr2 = [r.wrfs[1] * 100 for r in results] + wr = [r.wr * 100 for r in results] + + values = { + "Played as 1st": wr1, + "Played as 2nd": wr2, + "Overall": wr + } + + x = np.arange(len(player_names)) * 1.6 + width = 0.30 # the width of the bars + + + fig, ax = plt.subplots(layout='constrained') + multiplier = 0 + for attribute, measurement in values.items(): + offset = width * multiplier + rects = ax.bar(x + offset, measurement, width, label=attribute) + ax.bar_label(rects, padding=3) + multiplier += 1 + + # Add some text for labels, title and custom x-axis tick labels, etc. + ax.set_ylabel('Win Rate (%)') + ax.set_title('Agents Win Rate vs Random') + ax.set_xticks(x + width, player_names) + ax.legend(loc='upper left', ncols=3) + ax.set_ylim(0, 120) + + plt.savefig(path.join(PLOT_FOLDER, "players_wr.png")) + + +def plot_time_comparison(results: list[Result]) -> None: + # Only vs Random + results = sorted([r for r in results if isinstance(r.p2, RandomPlayer)], key=lambda it: it.avg_time) + ys = [r.avg_time for r in results] + xs = [r.p1.short_name for r in results] + plt_title = "Average Seconds per Game (vs Random)" + plt.plot(xs, ys, 'o') + plt.title(plt_title) + plt.ylabel("seconds") + plt.yticks(ys) + plt.xticks(list(range(len(xs))), xs, rotation=0) + plt.savefig(path.join(PLOT_FOLDER, "time_comparison.png")) + + + class HumanPlayer(Player): def make_move(self, game: "Game") -> "CompleteMove": diff --git a/ci_quixo/mcts.py b/ci_quixo/mcts.py index a11887e..1c6c16a 100644 --- a/ci_quixo/mcts.py +++ b/ci_quixo/mcts.py @@ -71,6 +71,9 @@ class MCTSPlayer(Player): _stats: dict[str, int] = field(default_factory=lambda: defaultdict(int), init=False) """Simple dict used to keep track of basic statistics, see property stats for a prettified version""" + @property + def short_name(self) -> str: + return f"MCTS({'H' if self.sim_heuristic else 'R'}, {self.games})" @property def name(self) -> str: diff --git a/ci_quixo/minmax.py b/ci_quixo/minmax.py index 900257e..df32336 100644 --- a/ci_quixo/minmax.py +++ b/ci_quixo/minmax.py @@ -64,6 +64,10 @@ def __init__( self._stats = defaultdict(int) + @property + def short_name(self) -> str: + return f"MinMax({'AB, ' if self.use_alpha_beta_pruning else ''}D{self.max_depth}, P{self.pruning_level}{', H' if self.use_htable else ''})" + @property def name(self) -> str: return f"MinMax(depth={self.max_depth}, alpha_beta={self.use_alpha_beta_pruning}, pruning={self.pruning_level}, use_htable={self.use_htable})" @@ -77,7 +81,7 @@ def make_move(self, game: Game) -> "CompleteMove": best_move = random.choice(cg.valid_moves()) else: self._stats['evals'] += 1 - self._stats['evals-ms'] += time.time() - start + self._stats['evals-ms'] += (time.time() - start) return best_move @@ -236,7 +240,7 @@ def max_side( def _avg_time(self): if self._stats['evals'] == 0: return 0 - return self._stats['eval-ms'] / self._stats['evals'] + return self._stats['evals-ms'] / self._stats['evals'] @property diff --git a/ci_quixo/results/players_wr.png b/ci_quixo/results/players_wr.png new file mode 100644 index 0000000000000000000000000000000000000000..89654d84cd614a8c2d047c9ffa2d99565cf856a1 GIT binary patch literal 23769 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 literal 0 HcmV?d00001