diff --git a/ai.py b/ai.py index 751549b..b907125 100644 --- a/ai.py +++ b/ai.py @@ -1,5 +1,7 @@ import random from location import Location +import copy + class AIPlayer: def __init__(self, game, player_number, all_cards): @@ -9,6 +11,7 @@ def __init__(self, game, player_number, all_cards): self.turn_energy_spent = 0 self.energy = 1 self.deck = self.draw_starting_deck(all_cards) + self.starting_deck = copy.deepcopy(self.deck) self.hand = self.draw_starting_hand(self.deck) self.played_cards=[] diff --git a/data.py b/data.py new file mode 100644 index 0000000..13e1acf --- /dev/null +++ b/data.py @@ -0,0 +1,69 @@ +import json +import hashlib + +def deck_hash(deck): + deck_str = ''.join(sorted([card.name for card in deck], key=str.lower)) # Sort card names before hashing + return hashlib.sha1(deck_str.encode()).hexdigest() + +def update_deck_data(deck, result, total_power, decks_data): + deck_id = deck_hash(deck) + + if deck_id in decks_data: + decks_data[deck_id]["total_power"] += total_power + decks_data[deck_id]["games_played"] += 1 + + if result == "win": + decks_data[deck_id]["wins"] += 1 + elif result == "loss": + decks_data[deck_id]["losses"] += 1 + else: + decks_data[deck_id] = { + "cards": [card.name for card in deck], + "wins": 1 if result == "win" else 0, + "losses": 1 if result == "loss" else 0, + "total_power": total_power, + "games_played": 1 + } + +def save_deck_data(decks_data, file_name): + with open(file_name, 'w') as file: + file.write("{\n") + for idx, (key, value) in enumerate(decks_data.items()): + file.write(f'"{key}": {json.dumps(value)}') + if idx < len(decks_data) - 1: + file.write(",\n") + else: + file.write("\n") + file.write("}") + +def load_deck_data(file_name): + try: + with open(file_name, 'r') as file: + return json.load(file) + except FileNotFoundError: + # If the file doesn't exist, create it with an empty dictionary and return it + with open(file_name, 'w') as file: + json.dump({}, file) + return {} + + +def get_average_power(deck_id, decks_data): + total_power = decks_data[deck_id]["total_power"] + games_played = decks_data[deck_id]["games_played"] + return total_power / games_played + +def winrate(decks_data): + return decks_data["wins"] / (decks_data["wins"] + decks_data["losses"]) + +def printwinrate(decks_data): + ranked_decks = sorted(decks_data.items(), key=lambda x: winrate(x[1]), reverse=True) + + for idx, (deck_id, deck_data) in enumerate(ranked_decks, 1): + print(f"{idx}. Deck ID: {deck_id}") + print(f" Winrate: {winrate(deck_data) * 100:.2f}%") + print(f" Wins: {deck_data['wins']}") + print(f" Losses: {deck_data['losses']}") + print(f" Total Power: {deck_data['total_power']}") + print(f" Average Power: {deck_data['total_power'] / deck_data['games_played']}") + print(f" Games Played: {deck_data['games_played']}") + print() diff --git a/decks_data.json b/decks_data.json new file mode 100644 index 0000000..2f2f23b --- /dev/null +++ b/decks_data.json @@ -0,0 +1,15 @@ +{ +"e5fca0112973e69bc7402bd7319c53d88aa5f755": {"cards": ["Sentinel", "The Punisher", "Abomination", "Shocker", "Hulk", "The Thing", "Cyclops", "Iron Man", "Hawkeye", "Misty Knight", "Quicksilver", "Star Lord"], "wins": 125, "losses": 134, "total_power": 5411, "games_played": 259}, +"f9a7f666b90e4974008ef32b4974442cb776504b": {"cards": ["Hulk", "Sentinel", "Iron Man", "Medusa", "Misty Knight", "Cyclops", "Star Lord", "Quicksilver", "Hawkeye", "Abomination", "Shocker", "The Punisher"], "wins": 121, "losses": 146, "total_power": 5406, "games_played": 267}, +"eb39800df6a0b9faa278eb5b3adbc2576f641c76": {"cards": ["Hulk", "The Punisher", "Misty Knight", "Medusa", "Star Lord", "Iron Man", "The Thing", "Abomination", "Hawkeye", "Sentinel", "Quicksilver", "Cyclops"], "wins": 147, "losses": 144, "total_power": 6176, "games_played": 291}, +"e8a2b0720bd929be139dd82d7878f72a3d803dee": {"cards": ["Sentinel", "Quicksilver", "Shocker", "Iron Man", "The Punisher", "Cyclops", "Hawkeye", "The Thing", "Hulk", "Medusa", "Misty Knight", "Abomination"], "wins": 134, "losses": 122, "total_power": 5543, "games_played": 256}, +"bf4e2ce13ddbe0a52f9e06f91a534c102050ea3b": {"cards": ["Hawkeye", "Misty Knight", "Cyclops", "Abomination", "The Thing", "Medusa", "Hulk", "Iron Man", "Sentinel", "Star Lord", "Quicksilver", "Shocker"], "wins": 150, "losses": 164, "total_power": 6560, "games_played": 314}, +"a4fd260d8d291f5683c167f00f8b873106172e75": {"cards": ["Hulk", "Cyclops", "Sentinel", "Quicksilver", "Iron Man", "The Thing", "Medusa", "Abomination", "The Punisher", "Star Lord", "Shocker", "Hawkeye"], "wins": 134, "losses": 136, "total_power": 5777, "games_played": 270}, +"07b58e21fdf36c0a0d0c66e63b2810137a8d04b3": {"cards": ["Medusa", "Star Lord", "Hawkeye", "Misty Knight", "The Punisher", "Sentinel", "Abomination", "Hulk", "Shocker", "Cyclops", "The Thing", "Quicksilver"], "wins": 108, "losses": 122, "total_power": 4804, "games_played": 230}, +"8547382b7d2056f64b68181f50405770729f0031": {"cards": ["Sentinel", "The Punisher", "Misty Knight", "Medusa", "Quicksilver", "Star Lord", "Shocker", "Hawkeye", "The Thing", "Cyclops", "Hulk", "Iron Man"], "wins": 126, "losses": 145, "total_power": 5246, "games_played": 271}, +"ec3360ef2a55f6f3bb6103121352232a96fa569d": {"cards": ["Cyclops", "Shocker", "Quicksilver", "Sentinel", "Abomination", "Hawkeye", "The Thing", "Misty Knight", "The Punisher", "Medusa", "Star Lord", "Iron Man"], "wins": 131, "losses": 126, "total_power": 5089, "games_played": 257}, +"36318860d633a9605ac4e3abe0212196c06607f2": {"cards": ["Medusa", "Hulk", "Iron Man", "Star Lord", "Cyclops", "Misty Knight", "The Thing", "Hawkeye", "The Punisher", "Shocker", "Sentinel", "Abomination"], "wins": 141, "losses": 109, "total_power": 5380, "games_played": 250}, +"a57f3fdb8fe85a4cfa0b56c0b523f904a3de0af6": {"cards": ["Abomination", "Hulk", "Hawkeye", "Sentinel", "The Punisher", "Medusa", "The Thing", "Iron Man", "Quicksilver", "Star Lord", "Shocker", "Misty Knight"], "wins": 128, "losses": 133, "total_power": 5437, "games_played": 261}, +"07ff7fd3924cf934a185dad837619352f3aa76c9": {"cards": ["Star Lord", "Abomination", "Quicksilver", "Hulk", "Shocker", "Iron Man", "The Thing", "Misty Knight", "Cyclops", "Sentinel", "The Punisher", "Medusa"], "wins": 144, "losses": 117, "total_power": 5705, "games_played": 261}, +"b2371c11552e25f46eb59f5192a7a643e254aee5": {"cards": ["Medusa", "Quicksilver", "Shocker", "Hawkeye", "Cyclops", "The Thing", "The Punisher", "Misty Knight", "Star Lord", "Iron Man", "Hulk", "Abomination"], "wins": 155, "losses": 146, "total_power": 6526, "games_played": 301} +} \ No newline at end of file diff --git a/game.py b/game.py index 04d7990..fb83069 100644 --- a/game.py +++ b/game.py @@ -3,7 +3,8 @@ from card import Card, generate_all_cards from location import Location, generate_all_locations from ai import AIPlayer - +from data import update_deck_data, save_deck_data, load_deck_data, get_average_power +import json class Game: def __init__(self): @@ -15,6 +16,7 @@ def __init__(self): self.current_turn = 0 self.current_location = 0 self.prepare_game() + self.winner=2 def play_card(self, card, player_number, location_number): player = self.players[player_number - 1] @@ -26,7 +28,7 @@ def play_card(self, card, player_number, location_number): # Ensuring the location does not already have 4 cards from the player. if sum(1 for card in location.cards if card.owner == player_number - 1) >= 4: - print(f"Player {player_number} cannot play {card.name} at this location. It already has 4 cards from the player.") + #print(f"Player {player_number} cannot play {card.name} at this location. It already has 4 cards from the player.") return if card.energy_cost <= player.energy: @@ -56,7 +58,8 @@ def play_card(self, card, player_number, location_number): hawkeye_card.power += 2 # Apply the effect hawkeye_card.hawkeye_effect_applied = True # Set the flag after applying the effect else: - print(f"Player {player_number} cannot play {card.name} yet. It costs more energy than the current turn.") + #print(f"Player {player_number} cannot play {card.name} yet. It costs more energy than the current turn.") + return def reveal_location(self): if self.current_location >= len(self.locations): @@ -90,7 +93,7 @@ def play_turn(self): player.played_cards.append(card) player.played_card_locations.append(location_index) else: - print(f"Player {player_number} cannot play {card.name} yet. It costs more energy than the current turn.") + #print(f"Player {player_number} cannot play {card.name} yet. It costs more energy than the current turn.") break else: break @@ -134,7 +137,7 @@ def reveal_cards(self, player_number): # Update the location card's power value as well if location_card is not None: location_card.power = card.power # Update the power of the card in location.cards - print("Card: ", card.name, "Has increased from ", card.base_power, "to ", card.power) + #print("Card: ", card.name, "Has increased from ", card.base_power, "to ", card.power) def apply_ongoing_abilities(self): for player_number in range(1, 3): @@ -228,8 +231,8 @@ def display_game_state(self): def determine_winner(self): player1_score = sum(location.calculate_total_power(0) for location in self.locations) player2_score = sum(location.calculate_total_power(1) for location in self.locations) - print("Player 1 had a total power of:", player1_score) - print("Player 2 had a total power of:", player2_score) + #print("Player 1 had a total power of:", player1_score) + #print("Player 2 had a total power of:", player2_score) player1_wins = 0 player2_wins = 0 for location in self.locations: @@ -238,20 +241,30 @@ def determine_winner(self): elif location.calculate_total_power(0) < location.calculate_total_power(1): player2_wins += 1 + decks_data = load_deck_data('decks_data.json') if player1_wins > player2_wins: - print("Player 1 Wins!") + #print("Player 1 Wins!") + update_deck_data(self.players[0].starting_deck, "win", player1_score, decks_data) + update_deck_data(self.players[1].starting_deck, "loss", player2_score, decks_data) + elif player1_wins < player2_wins: - print("Player 2 Wins!") + #print("Player 2 Wins!") + update_deck_data(self.players[0].starting_deck, "loss", player1_score, decks_data) + update_deck_data(self.players[1].starting_deck, "win", player2_score, decks_data) + + save_deck_data(decks_data, 'decks_data.json') + def play_game(self): for turn in range(6): # Loop through the 6 turns self.current_turn = turn + 1 - print(f"Turn {self.current_turn}") + #print(f"Turn {self.current_turn}") if 4 > self.current_turn > 1: self.reveal_location() self.play_turn() self.apply_ongoing_abilities() self.end_of_turn() - self.display_game_state() + #self.display_game_state() self.determine_winner() + diff --git a/main.py b/main.py index 1c08d60..ca2e6bb 100644 --- a/main.py +++ b/main.py @@ -1,9 +1,13 @@ from card import generate_all_cards from location import generate_all_locations from game import Game +from data import load_deck_data, printwinrate all_cards = generate_all_cards() all_locations = generate_all_locations() -for i in range (1,20): +for i in range (1,1): game = Game() - game.play_game() \ No newline at end of file + game.play_game() + +decks_data = load_deck_data('decks_data.json') +printwinrate(decks_data)