Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added plotting functionality #48

Merged
merged 4 commits into from
Mar 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
234 changes: 234 additions & 0 deletions game_data.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,234 @@
{
"games": [
{
"game_duration": 16.745494375005364,
"total_turns": 129,
"players": [
{
"player_type": "minimax",
"average_time_per_action": 0.2716845485718093,
"move_count": 54,
"expanded_states": 154477,
"max_depth": 6,
"player_id": 1
},
{
"player_type": "minimax",
"average_time_per_action": 0.027594135034208496,
"move_count": 75,
"expanded_states": 24830,
"max_depth": 4,
"player_id": 2
}
],
"winner": 1
},
{
"game_duration": 68.68971466599032,
"total_turns": 131,
"players": [
{
"player_type": "minimax",
"average_time_per_action": 0.25141715974098555,
"move_count": 54,
"expanded_states": 154477,
"max_depth": 6,
"player_id": 1
},
{
"player_type": "minimax",
"average_time_per_action": 0.7157158245840534,
"move_count": 77,
"expanded_states": 701087,
"max_depth": 7,
"player_id": 2
}
],
"winner": 1
},
{
"game_duration": 19.38588395807892,
"total_turns": 165,
"players": [
{
"player_type": "minimax",
"average_time_per_action": 0.2308116701308144,
"move_count": 83,
"expanded_states": 249102,
"max_depth": 6,
"player_id": 1
},
{
"player_type": "minimax",
"average_time_per_action": 0.0027445289959404165,
"move_count": 82,
"expanded_states": 3087,
"max_depth": 2,
"player_id": 2
}
],
"winner": 1
},
{
"game_duration": 14.320972041925415,
"total_turns": 126,
"players": [
{
"player_type": "minimax",
"average_time_per_action": 0.22224802276750485,
"move_count": 62,
"expanded_states": 176173,
"max_depth": 6,
"player_id": 1
},
{
"player_type": "minimax",
"average_time_per_action": 0.008416822915023658,
"move_count": 64,
"expanded_states": 6989,
"max_depth": 3,
"player_id": 2
}
],
"winner": 1
},
{
"game_duration": 14.113730333046988,
"total_turns": 126,
"players": [
{
"player_type": "minimax",
"average_time_per_action": 0.2190078850722902,
"move_count": 62,
"expanded_states": 176173,
"max_depth": 6,
"player_id": 1
},
{
"player_type": "minimax",
"average_time_per_action": 0.008318463627801975,
"move_count": 64,
"expanded_states": 6989,
"max_depth": 3,
"player_id": 2
}
],
"winner": 1
},
{
"game_duration": 18.221036583883688,
"total_turns": 131,
"players": [
{
"player_type": "minimax",
"average_time_per_action": 0.2326052507808156,
"move_count": 54,
"expanded_states": 154477,
"max_depth": 6,
"player_id": 1
},
{
"player_type": "minimax",
"average_time_per_action": 0.07347076082323956,
"move_count": 77,
"expanded_states": 76460,
"max_depth": 5,
"player_id": 2
}
],
"winner": 1
},
{
"game_duration": 28.010977083118632,
"total_turns": 131,
"players": [
{
"player_type": "minimax",
"average_time_per_action": 0.22857431330528385,
"move_count": 54,
"expanded_states": 154477,
"max_depth": 6,
"player_id": 1
},
{
"player_type": "minimax",
"average_time_per_action": 0.20343920993074388,
"move_count": 77,
"expanded_states": 199211,
"max_depth": 6,
"player_id": 2
}
],
"winner": 1
},
{
"game_duration": 166.40177620900795,
"total_turns": 131,
"players": [
{
"player_type": "minimax",
"average_time_per_action": 0.2275209467539012,
"move_count": 54,
"expanded_states": 154477,
"max_depth": 6,
"player_id": 1
},
{
"player_type": "minimax",
"average_time_per_action": 2.0014604518806878,
"move_count": 77,
"expanded_states": 2104428,
"max_depth": 8,
"player_id": 2
}
],
"winner": 1
},
{
"game_duration": 439.06379320891574,
"total_turns": 131,
"players": [
{
"player_type": "minimax",
"average_time_per_action": 0.23054754627540847,
"move_count": 54,
"expanded_states": 154477,
"max_depth": 6,
"player_id": 1
},
{
"player_type": "minimax",
"average_time_per_action": 5.540401767385978,
"move_count": 77,
"expanded_states": 5256645,
"max_depth": 9,
"player_id": 2
}
],
"winner": 1
},
{
"game_duration": 1329.2665478750132,
"total_turns": 131,
"players": [
{
"player_type": "minimax",
"average_time_per_action": 0.23267057559590926,
"move_count": 54,
"expanded_states": 154477,
"max_depth": 6,
"player_id": 1
},
{
"player_type": "minimax",
"average_time_per_action": 17.09996407194813,
"move_count": 77,
"expanded_states": 17763636,
"max_depth": 10,
"player_id": 2
}
],
"winner": 1
}
]
}
6 changes: 4 additions & 2 deletions main.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import argparse
import sys

from src.GameController import GameController
sys.path.append("src")
from GameController import GameController

if __name__ == "__main__":
parser = argparse.ArgumentParser(description='Chinese Checkers game with AI and player options.')
Expand All @@ -16,6 +18,6 @@

args = parser.parse_args()

controller = GameController(verbose=False, use_graphics=True, args=args)
controller = GameController(verbose=False, use_graphics=False, args=args)

controller.game_loop()
20 changes: 11 additions & 9 deletions src/GameController.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import time

from benchmarking.GameAnalytics import GameAnalytics
from players.NonRepeatRandomPlayer import NonRepeatingRandomPlayer
from game_problem.Heuristic import WeightedHeuristic, SumOfPegsInCornerHeuristic, AverageManhattanToCornerHeuristic, \
AverageEuclideanToCornerHeuristic, MaxManhattanToCornerHeuristic, EnsuredNormalizedHeuristic
Expand All @@ -25,6 +26,7 @@ def create_player(player_type, depth=6, gui=None, problem=None, max_player=None,

class GameController:
def __init__(self, verbose=True, use_graphics=True, args=None):
self.analytics = GameAnalytics()
self.verbose = verbose # Flag to print the state and action applied
self.use_graphics = use_graphics # Flag to use the GUI
self.problem = ChineseCheckers(triangle_size=3) # Initialize the game problem
Expand All @@ -42,8 +44,8 @@ def handle_game_setup(self, args):

if args.first_player is None or args.second_player is None:
self.players = [
MinimaxAIPlayer(self.problem, 1, 6, heuristic, verbose=self.verbose),
MinimaxAIPlayer(self.problem, 2, 6, heuristic, verbose=self.verbose)
MinimaxAIPlayer(self.problem, 1, 2, heuristic, verbose=self.verbose),
MinimaxAIPlayer(self.problem, 2, 4, heuristic, verbose=self.verbose)
]
else:
player1_depth = args.first_minimax_depth if args.first_player == 'minimax' else None
Expand Down Expand Up @@ -91,14 +93,14 @@ def game_loop(self):
game_duration = time.perf_counter() - game_start_timer
print(f'Player {state.player} has utility: {self.problem.utility(state, state.player)}')

winner = state.player if self.problem.utility(state, state.player) >= 0 else 3 - state.player

# Print the game duration and the performance metrics of the players
print(f'Game elapsed time: {game_duration:0.8f} | Turns = {turn}')
for i, player in enumerate(self.players):
print('-----')
print(f'Player {i + 1} average time: {player.average_time_spent_on_actions:0.8f}')
print(f'Player {i + 1} move count: {player.moves_count:0.8f}')
if hasattr(player, 'evaluated_states_count'):
print(f'Player {i + 1} expanded states: {player.evaluated_states_count}')
self.analytics.add_game_data(game_duration, turn, self.players, winner)
self.analytics.print_game_data()

self.analytics.load_from_file('game_data.json')
self.analytics.plot()

# Wait until quit is pressed
if self.gui:
Expand Down
Loading
Loading