add this rules: 7.1 Aftermath Cards: 
Following resolution of a Conflict, all players may play any nu mber of valid Aftermath cards. Aftermath cards reflect the 
change and growth of Characters resulting from their choices and experiences. They are used to tell a Character's story, 
showing how their life has been affected as a consequence of th eir actions. Most Aftermath cards  act like Enhancements, i.e., 
they modify the card they are played on. Like Enhancements, they are discarded if the card they modify is discarded.  
Some Aftermath cards cause an immediate eff ect, such as adding damage to a Character  or altering a tension level. Immediate 
effects are not reversed when the Aftermath that caused them is discarded. Also, like Enhancements, only one of any given 
Aftermath card may affect a given target at the same time. Each  Aftermath card lists Play Conditions and may only be played 
when these conditions are met. If a race name  appears as part of the card type, then the Aftermath is restricted to being playe d 
on targets in a faction of that  race. Unless an Aftermath card specifies Partic ipant as part of its Play Conditions, it may onl y 
target the cards of the faction which initiated the Conflict it is being played in response to. Play Conditions for Aftermath c ards 
are defined as follows:  
• If the player who initiated the Conflict won the Conflict then Aftermath cards that list "Won" may be played.  
• If the player who initiated the Conflict lost the Conflict then Aftermath cards that list 
"Lost" may be played.  
Type Of Conflict 
If a Play Condition gives a Conflict Type (Military, Diplomatic, In trigue, or Psi), then Aftermath cards may only be played 
following the resolution of a Conflict of the appropriate type.  
Participant  
If Participant is one of the Play Conditions then appropriate Afte rmath cards may target cards in play for any faction that eit her 
Supported, Opposed or Attacked during the Conflict. If a card specifies a "Participant Fleet", th en a fleet must have supported , 
opposed or attacked during the Conflict to be a valid target. If  a card specifies a "Participant Character", then a Character m ust 
have supported, opposed or attacked during the Conflict, or led a fleet that participated in the Conflict. Remember: Aftermaths  
can only be played on the initiating faction unless the card specifies "Participant".  
Aftermath Example  
John Initiates a Military Conflict, and supports it with two fleets. Dave Supports the Conflict w ith one fleet. Paul Opposes th e 
Conflict with two fleets. Ran attacks both Dave's fleet and one of Paul's fleets (using 2 differe nt fleets). John Eventually wi ns 
the Conflict. Which Aftermath cards ca n be played on which Characters?  
Military Aftermath John 
Military Participant Aftermath any faction 
Won Military Aftermath John 
Won Military Participant Aftermath any faction 
  
Lost (anything) none 
Won Aftermath John 
Won Participant Aftermath any faction 
If the specific Aftermath type is "Won Military Participant", but the effect text states it may only be played on "participatin g 
Characters who led a fleet that opposed the Conflict"; it could be played on any Character leadin g one of Paul's fleets (only).  If 
it specifies "Any Participant" but says it can only be played on "participating fleet s who attacked" then only Ran's fleets are  
valid targets.  
• Look at Aftermaths this way: 
#1: Unless the Aftermath specifies "participant" in the *card type box*, it can only be 
played on the initiator of the Conflict. 
#2: Having determined whom the Aftermath can be played on (by the above) all other restrictions in the effects text section must also be met. 
• The terms "Lost" and "Won" apply to all words following them in the card type box. 
So interpret Wounded, for example, to be playable on Lost Intrigue or Lost Military conflicts. Ostracized is a Military or Lost Intrigue Aftermath so can be played on a Military Conflict regardless of it being won or lost. 
• If you have a won/lost Aftermath that isn't a participant Character Aftermath but mentions participants in its game text, you may only play the card on a participant of the faction 
that played the Conflict and either won or lost. 
• Aftermaths can be played on neutralized Characters. 
• Global Aftermaths are not "in" any faction, nor does any faction control them.  to code: import random

class Card:
    def __init__(self, name, cost=0, is_sustainable=False):
        self.name = name
        self.cost = cost
        self.rotated = False
        self.is_sustainable = is_sustainable
        self.damage = 0
        self.severe_damage = 0

    def rotate(self):
        if not self.rotated:
            self.rotated = True
            return True
        return False

    def ready(self):
        self.rotated = False

    def heal(self, amount=None):
        if amount is None:
            self.damage = 0
        else:
            self.damage = max(0, self.damage - amount)

    def heal_severe(self):
        if self.severe_damage > 0:
            self.severe_damage -= 1
        else:
            self.rotated = False

    def inflict_damage(self, amount):
        self.damage += amount

    def inflict_severe_damage(self, amount):
        self.severe_damage += amount

    def is_neutralized(self):
        return self.damage >= self.get_max_ability()

    def get_max_ability(self):
        # Placeholder for actual ability logic
        return 3


class ConflictCard:
    def __init__(self, name, target=None):
        self.name = name
        self.target = target
        self.face_down = True

    def reveal(self):
        self.face_down = False


class AgendaCard(Card):
    def __init__(self, name, cost=0, is_major=False, hidden=False, race_restriction=None):
        super().__init__(name, cost)
        self.is_major = is_major
        self.hidden = hidden
        self.race_restriction = race_restriction

    def can_be_sponsored(self):
        # Placeholder for actual logic
        return True

    def reveal(self):
        self.hidden = False
        print(f"Agenda '{self.name}' is now revealed.")

    def can_be_played_by(self, faction_race):
        return self.race_restriction is None or self.race_restriction == faction_race


class MercenaryCard(Card):
    def __init__(self, name, cost=0):
        super().__init__(name, cost)
        self.bids = {}

    def bid(self, player, amount):
        if player in self.bids:
            self.bids[player] += amount
        else:
            self.bids[player] = amount

    def highest_bidder(self):
        if self.bids:
            return max(self.bids, key=self.bids.get)
        return None


class Player:
    def __init__(self, name, influence_rating, cards=[], ambassador=None, faction_race=None):
        self.name = name
        self.influence_rating = influence_rating
        self.current_influence = influence_rating
        self.cards = cards
        self.ambassador = ambassador
        self.initiative = 0
        self.conflict_card = None
        self.passed = False
        self.agenda = None
        self.mercenaries = []
        self.conflicts_initiated = []
        self.draw_deck = self.initialize_draw_deck()
        self.inner_circle = []  # Assuming inner_circle needs initialization as an empty list
        self.faction_race = faction_race  # Adding faction race for agenda restrictions

    def initialize_draw_deck(self):
        # Placeholder method to create an initial draw deck
        return [Card(f"DrawCard{i}", cost=random.randint(1, 5)) for i in range(10)]

    def ready_cards(self):
        for card in self.cards:
            if card.is_sustainable and card.rotated:
                continue
            card.ready()

    def restore_influence(self):
        self.current_influence = self.influence_rating

    def determine_initiative(self, players):
        players.sort(key=lambda p: p.influence_rating)
        for i, player in enumerate(players):
            player.initiative = i
            print(f"{player.name} initiative: {player.initiative}")

    def declare_conflict(self, conflict_card):
        if self.conflict_card is None:
            self.conflict_card = conflict_card
            self.conflicts_initiated.append(conflict_card)
            print(f"{self.name} declares a conflict: {conflict_card.name}")

    def perform_action(self, action_type, *args):
        if action_type == "rotate":
            self.use_card_effect(*args)
        elif action_type == "play_event":
            self.play_event(*args)
        elif action_type == "build_influence":
            self.build_influence(*args)
        elif action_type == "sponsor":
            self.sponsor(*args)
        elif action_type == "promote":
            self.promote(*args)
        elif action_type == "replace":
            self.replace_character(*args)
        elif action_type == "support":
            self.support_conflict(*args)
        elif action_type == "oppose":
            self.oppose_conflict(*args)
        elif action_type == "attack":
            self.attack(*args)
        elif action_type == "heal":
            self.heal_character(*args)
        elif action_type == "repair":
            self.repair_location_or_fleet(*args)
        elif action_type == "lead_fleet":
            self.lead_fleet(*args)
        elif action_type == "discard_agenda":
            self.discard_agenda()
        elif action_type == "play_agenda":
            self.play_agenda(*args)
        elif action_type == "reveal_agenda":
            self.reveal_agenda()
        elif action_type == "replace_agenda":
            self.replace_agenda(*args)
        elif action_type == "bid_mercenary":
            self.bid_mercenary(*args)
        elif action_type == "pass":
            self.pass_action()
        else:
            print(f"Unknown action type: {action_type}")

    def use_card_effect(self, card):
        if card in self.cards and card.rotate():
            print(f"{self.name} uses effect of {card.name}")

    def play_event(self, event_card):
        print(f"{self.name} plays event card: {event_card.name}")

    def build_influence(self):
        if self.influence_rating <= 9:
            self.influence_rating += 1
            self.current_influence += 1
            print(f"{self.name} builds influence. New influence rating: {self.influence_rating}")

    def sponsor(self, new_card):
        if self.current_influence >= new_card.cost:
            self.current_influence -= new_card.cost
            self.cards.append(new_card)
            print(f"{self.name} sponsors new card: {new_card.name}")
        else:
            print(f"{self.name} cannot afford to sponsor {new_card.name}")

    def promote(self, supporting_card):
        if supporting_card in self.cards:
            print(f"{self.name} promotes {supporting_card.name} to Inner Circle")

    def replace_character(self, old_card, new_card):
        if old_card in self.cards:
            self.cards.remove(old_card)
            self.cards.append(new_card)
            new_card.ready()
            print(f"{self.name} replaces {old_card.name} with {new_card.name}")

    def support_conflict(self, conflict, supporting_card):
        if supporting_card in self.cards and supporting_card.rotate():
            print(f"{self.name} supports conflict {conflict.name} with {supporting_card.name}")

    def oppose_conflict(self, conflict, opposing_card):
        if opposing_card in self.cards and opposing_card.rotate():
            print(f"{self.name} opposes conflict {conflict.name} with {opposing_card.name}")

    def attack(self, target_card, attacker):
        if attacker in self.cards and attacker.rotate():
            target_card.inflict_damage(attacker.get_max_ability())
            print(f"{self.name} attacks {target_card.name} with {attacker.name}")

    def heal_character(self, card):
        if card in self.cards and card.rotate():
            if card.is_neutralized():
                card.heal_severe()
            else:
                card.heal()
            print(f"{self.name} heals {card.name}")

    def repair_location_or_fleet(self, card):
        if card in self.cards and card.rotate():
            repair_cost = card.damage
            if self.current_influence >= repair_cost:
                self.current_influence -= repair_cost
                card.heal(card.damage)
                print(f"{self.name} repairs {card.name}")
            else:
                print(f"{self.name} cannot afford to repair {card.name}")

    def lead_fleet(self, fleet, leader):
        if leader in self.cards and fleet in self.cards and leader.rotate():
            print(f"{self.name} leads {fleet.name} with {leader.name}")

    def discard_agenda(self):
        if self.agenda and not self.agenda.is_major:
            print(f"{self.name} discards agenda: {self.agenda.name}")
            self.agenda = None
            # Apply effect of losing the agenda
        else:
            print(f"{self.name} cannot discard a major agenda or has no agenda.")

    def play_agenda(self, new_agenda, character):
        if character in self.cards and character.rotate():
            if self.agenda:
                print(f"{self.name} already has an agenda in play.")
                return
            if new_agenda.can_be_played_by(self.faction_race):
                self.agenda = new_agenda
                if new_agenda.hidden:
                    print(f"{self.name} plays a hidden agenda.")
                else:
                    print(f"{self.name} plays agenda: {new_agenda.name}")
            else:
                print(f"{new_agenda.name} cannot be played by {self.faction_race} faction.")

    def reveal_agenda(self):
        if self.agenda and self.agenda.hidden:
            self.agenda.reveal()
            if not self.agenda.can_be_sponsored():
                print(f"{self.name}'s agenda {self.agenda.name} cannot be sponsored and is discarded.")
                self.agenda = None
        else:
            print(f"{self.name} has no hidden agenda to reveal.")

    def replace_agenda(self, new_agenda):
        if self.agenda and new_agenda.can_be_played_by(self.faction_race):
            if self.agenda.is_major and new_agenda.is_major:
                print(f"{self.name} replaces major agenda {self.agenda.name} with {new_agenda.name}")
                self.agagenda.nnal = new_agend
            elif not self.agenda.is_major and not new_agenda.is_major:
                print(f"{self.name} replaces agenda {self.agenda.name} with {new_agenda.name}")
                self.agenda = new_agenda
            else:
                print(f"{self.name} cannot mix major and non-major agenda replacements.")

            # Apply effect of replacing the agenda
        else:
            print(f"{self.name} cannot replace agenda or has no agenda.")

    def bid_mercenary(self, mercenary, amount):
        if self.current_influence >= amount:
            self.current_influence -= amount
            mercenary.bid(self, amount)
            print(f"{self.name} bids {amount} influence on mercenary {mercenary.name}")
        else:
            print(f"{self.name} does not have enough influence to bid on mercenary {mercenary.name}")

    def pass_action(self):
        self.passed = True
        print(f"{self.name} passes their action.")


class Game:
    def __init__(self, players):
        self.players = players
        self.mercenaries = []
        self.conflicts = []

    def ready_round(self):
        print("Ready Round…")
        for player in self.players:
            player.ready_cards()
            player.restore_influence()
        print("All cards are ready, and influence is restored.")

    def conflict_round(self):
        print("Conflict Round…")
        self.declare_conflicts()
        self.reveal_conflicts()

    def declare_conflicts(self):
        print("Declare Conflicts…")
        for player in sorted(self.players, key=lambda p: p.initiative):
            if player.conflicts_initiated:
                conflict_card = player.conflicts_initiated.pop(0)
                self.conflicts.append(conflict_card)
                print(f"{player.name} declares a conflict: {conflict_card.name}")

    def reveal_conflicts(self):
        print("Reveal and Initiate Conflicts…")
        for conflict in self.conflicts:
            conflict.reveal()
            print(f"Conflict revealed: {conflict.name}")

    def action_round(self):
        print("Action Round…")
        for player in self.players:
            player.passed = False
        while not all(player.passed for player in self.players):
            for player in sorted(self.players, key=lambda p: p.initiative):
                if not player.passed:
                    action_choice = self.choose_action(player)
                    if action_choice:
                        player.perform_action(*action_choice)
                    else:
                        player.pass_action()

        # Heal Ambassador if all Inner Circle cards are rotated
        for player in self.players:
            if all(card.rotated for card in player.cards):
                if player.ambassador:
                    player.ambassador.damage = 0
                    player.ambassador.severe_damage = 0
                    player.ambassador.ready()
                    print(f"{player.name}'s ambassador is fully healed.")

    def choose_action(self, player):
        actions = ["rotate", "play_event", "build_influence", "sponsor", "promote", "replace", "support", "oppose",
                   "attack", "heal", "repair", "lead_fleet", "discard_agenda", "play_agenda", "reveal_agenda",
                   "replace_agenda", "bid_mercenary", "pass"]
        action_type = random.choice(actions)

        if action_type == "rotate" and player.cards:
            return action_type, player.cards[0]
        elif action_type == "play_event" and player.cards:
            return action_type, player.cards[0]
        elif action_type == "build_influence":
            return action_type,
        elif action_type == "sponsor" and player.current_influence >= 3:
            return action_type, Card("New Supporting Card", cost=3)  # Example cost
        elif action_type == "promote" and player.cards:
            return action_type, player.cards[0]
        elif action_type == "replace" and len(player.cards) >= 2:
            return action_type, player.cards[0], Card("Replacement Card", cost=5)  # Example
        elif action_type == "support" and self.conflicts and player.cards:
            return action_type, self.conflicts[0], player.cards[0]
        elif action_type == "oppose" and self.conflicts and player.cards:
            return action_type, self.conflicts[0], player.cards[0]
        elif action_type == "attack" and player.cards:
            for opponent in self.players:
                if opponent != player and opponent.cards:
                    return action_type, opponent.cards[0], player.cards[0]
        elif action_type == "heal" and player.cards:
            return action_type, player.cards[0]
        elif action_type == "repair" and player.cards:
            return action_type, player.cards[0]
        elif action_type == "lead_fleet" and len(player.cards) >= 2:
            return action_type, player.cards[0], player.cards[1]  # Placeholder fleet and leader
        elif action_type == "discard_agenda" and player.agenda:
            return action_type,
        elif action_type == "play_agenda" and player.cards:
            return action_type, AgendaCard("New Agenda", cost=2), player.cards[0]  # Example cost and character
        elif action_type == "reveal_agenda" and player.agenda and player.agenda.hidden:
            return action_type,
        elif action_type == "replace_agenda":
            return (action_type,
                    AgendaCard("Replacement Agenda", cost=3, is_major=True))  # Example for major agenda replacement
        elif action_type == "bid_mercenary" and self.mercenaries:
            return action_type, self.mercenaries[0], 1  # Example bid amount
        else:
            return "pass",

    def resolution_round(self):
        print("Resolution Round…")
        for conflict in self.conflicts:  # Resolve conflicts in the order they were declared
            self.resolve_conflict(conflict)

    def resolve_conflict(self, conflict):
        print(f"Resolving conflict: {conflict.name}")
        # Placeholder for resolving conflict logic
        support = 0
        opposition = 0
        for player in self.players:
            for card in player.cards:
                if card.rotated:
                    support += card.get_max_ability()  # Placeholder for actual logic
                else:
                    opposition += card.get_max_ability()  # Placeholder for actual logic

        if support > opposition:
            print(f"Conflict {conflict.name} succeeded with support {support} vs. opposition {opposition}.")
            # Apply success effects
        else:
            print(f"Conflict {conflict.name} failed with support {support} vs. opposition {opposition}.")
            # Apply failure effects

        self.play_aftermath()

        # Discard conflict and aftermath cards
        self.conflicts.remove(conflict)
        print(f"Conflict {conflict.name} is discarded.")

    def play_aftermath(self):
        print("Playing aftermath cards…")
        for player in sorted(self.players, key=lambda p: p.initiative):
            # Placeholder for playing aftermath logic
            print(f"{player.name} plays aftermath card.")

    def draw_round(self):
        print("Draw Round…")

        # Step 1: Discarding neutralized supporting cards
        print("Step 1: Discarding neutralized supporting cards")
        for player in sorted(self.players, key=lambda p: p.initiative):
            neutralized_cards = [card for card in player.cards if card.is_neutralized() and not isinstance(card, Card)]
            for card in neutralized_cards:
                player.cards.remove(card)
                print(f"{player.name} discards neutralized card: {card.name}")

        # Step 2: Discarding cards from hand
        print("Step 2: Discarding cards from hand")
        for player in sorted(self.players, key=lambda p: p.initiative):
            # Allowing every player to discard as many cards as they wish
            # For simplicity, let's assume they discard any card
            for card in player.cards[:]:
                player.cards.remove(card)
                print(f"{player.name} discards card: {card.name}")

        # Step 3: Drawing cards
        print("Step 3: Drawing cards")
        for player in sorted(self.players, key=lambda p: p.initiative):
            if player.cards:
                if not player.draw_deck:
                    if hasattr(player, 'inner_circle') and player.inner_circle:
                        ic_card = player.inner_circle.pop()
                        print(f"{player.name} must discard Inner Circle card: {ic_card.name} due to empty draw deck.")
                    else:

                        print(f"{player.name} must discard {player.cards[0].name} due to empty draw deck.")
                        print(f"{player.name} cannot draw and has no Inner Circle cards left (game lost scenario not fully implemented).")
                        continue
                else:
                    new_card = player.draw_deck.pop()
                    player.cards.append(new_card)
                    print(f"{player.name} draws card: {new_card.name}")

            for _ in range(player.current_influence // 3):
                if not player.draw_deck:
                    if hasattr(player, 'inner_circle') and player.inner_circle:
                        ic_card = player.inner_circle.pop()
                        print(f"{player.name} must discard Inner Circle card: {ic_card.name} due to empty draw deck.")
                    else:
                        print(
                            f"{player.name} cannot draw and has no Inner Circle cards left (game lost scenario not fully implemented).")
                        break
                else:
                    new_card = player.draw_deck.pop()
                    player.cards.append(new_card)
                    print(f"{player.name} draws another card: {new_card.name}")

        # Step 4: Victory Check
        self.victory_check()

        # Step 5: End of Turn
        self.end_of_turn_cleanup()

    def end_of_turn_cleanup(self):
        print("End of turn cleanup…")
        # Placeholder for any end of turn cleanup logic
        pass

    def process_mercenaries(self):
        for mercenary in self.mercenaries:
            highest_bidder = mercenary.highest_bidder()
            if highest_bidder:
                highest_bidder.mercenaries.append(mercenary)
                print(f"{highest_bidder.name} wins control of mercenary {mercenary.name}")
            mercenary.bids = {}  # Reset bids for the next turn

    def victory_check(self):
        print("Victory Check…")
        for player in sorted(self.players, key=lambda p: p.current_influence, reverse=True):
            # Placeholder for a proper power check and determining a winner
            if player.current_influence >= 20:
                others = [p for p in self.players if p != player]
                if all(player.current_influence > other.current_influence for other in others):
                    print(f"{player.name} wins with a Standard Victory by having 20 or more power!")
                    return True

        return False

    def play_turn(self):
        print("New Turn Begins…")
        self.ready_round()
        for player in self.players:
            player.determine_initiative(self.players)
        self.conflict_round()
        self.action_round()
        self.resolution_round()
        self.draw_round()
        if self.victory_check():
            print("We have a winner!")
            return False
        print("Turn Ends.\n")
        return True


def main():
    # Example game setup
    players = [
        Player("Alice", influence_rating=10, cards=[Card("Card1", cost=2), Card("Card2", cost=3)], faction_race="Race1"),
        Player("Bob", influence_rating=8, cards=[Card("Card3", cost=1), Card("Card4", cost=4)], faction_race="Race2"),
        Player("Eve", influence_rating=12, cards=[Card("Card5", cost=5), Card("Card6", cost=6)], faction_race="Race3")
    ]

    game = Game(players)

    # Loop through turns until a player wins
    while game.play_turn():
        pass


if __name__ == "__main__":
    main()