text: import os
  os.environ['PYGAME_HIDE_SUPPORT_PROMPT'] = "hide"
  import pygame
  from pygame import sprite
  import random
  import cards
  from gamestate import *
  
  X = 0
  Y = 1
  
  class EnemyFleet(sprite.Group):
      def __init__(self):
          super().__init__()
  
      def draw_rect(self, screen):
          for s in self.sprites():
              s.show_box(screen)
  
      def draw(self, screen):
          for sp in self.sprites():
              sp.draw(screen)
  
      def process_attack(self, card, target=None):
          if target:
              target.damage(card.damage)
          else:
              for sp in self.sprites():
                  sp.damage(card.damage)
  
      def dead(self, screen, board, player, enemy_group):
          loot = 0
          for sp in self.sprites():
              loot = sp.dead(screen, board, player, enemy_group)
          return loot
  
      def spawn(self, assets, boss):
          if boss:
              self.add(assets.enemy_choices.sprite_buffer['boss'].copy())
          else:
              group = random.choice(assets.enemy_choices.groupings)
              for sp in group:
                  self.add(assets.enemy_choices.sprite_buffer[sp].copy())
          self.place()
  
      def place(self):
          coords = [(450, 250),
                    (550, 150),
                    (650, 50),
                    (550, 350),
                    (650, 450)]
          for pos, sp in zip(coords, self.sprites()):
              sp.move(pos[0], pos[1])
  
      def drain_shields(self):
          for sp in self.sprites():
              sp.drain_shields()
  
  class Character(sprite.Sprite):
      def __init__(self, img_path=None, image=None, explosion_path=None,
                  explosions=None, max_health=40, credits=40):
          super().__init__()
          if img_path:
              self.image = pygame.image.load(img_path)
          else:
              self.image = image
          if explosion_path:
              path = os.path.join(EXPLOSIONS_PATH, explosion_path + '_Explosion')
              imgs = list(os.scandir(path))
              self.explosions = [pygame.image.load(png.path).convert_alpha() for png in imgs]
          else:
              self.explosions = explosions
          self.pos = [0, 0]
          self.rect = self.image.get_rect(midleft=self.pos)
          self.bounding_rect = self.image.get_bounding_rect()
          self.bounding_rect.center = self.rect.center
          self.health_bar = self.health_init()
          # stats
          self.max_health = max_health
          self.current_health = max_health
          self.shield = 0
          self.credits = credits
  
      def update(self):
          self.rect = self.image.get_rect(midleft=self.pos)
          self.bounding_rect = self.image.get_bounding_rect()
          self.bounding_rect.center = self.rect.center
          self.health_init()
  
      def health_init(self):
          left, top, width, height = self.bounding_rect
          self.health_bar = pygame.Rect((left, top + height, width, 8))
  
      def collision(self, position):
          return self.bounding_rect.collidepoint(position)
  
      def rescale(self, w, h):
          self.image = pygame.transform.scale(self.image, (w, h))
  
      def rescale_factor(self, n):
          width, height = self.image.get_size()
          self.image = pygame.transform.scale(self.image, (width * n, height * n))
          self.update()
  
      def copy(self):
          return Character(image=self.image)
  
      def move(self, x, y):
          self.pos = [x, y]
          self.update()
  
      def flip(self):
          self.image = pygame.transform.flip(self.image, True, False)
  
      def get_img(self):
          return self.image
  
      def show_box(self, screen):
          pygame.draw.rect(screen, WHITE, self.bounding_rect, 1)
  
      def draw(self, screen):
          screen.blit(self.image, self.rect)
          self.draw_health_bar(screen)
  
      def draw_health_bar(self, screen):
          font = pygame.font.Font(None, 16)
          if self.max_health > 0:
              if self.shield:
                  pygame.draw.rect(screen, BLUE, self.health_bar)
                  val = font.render(str(self.shield), True, YELLOW)
                  valr = val.get_rect(center=self.health_bar.center)
              else:
                  pygame.draw.rect(screen, GRAY, self.health_bar)
                  health = self.health_bar.copy()
                  health.width *= self.current_health / self.max_health
                  pygame.draw.rect(screen, RED, health)
                  val = font.render("{} / {}".format(self.current_health, self.max_health), True, YELLOW)
                  valr = val.get_rect(center=self.health_bar.center)
              screen.blit(val, valr)
  
      def damage(self, ndmg):
          if self.shield:
              if self.shield > ndmg:
                  self.shield -= ndmg
              else:
                  ndmg -= self.shield
                  self.shield = 0
                  self.current_health -= ndmg
          else:
              self.current_health -= ndmg
          self.current_health = max(0, self.current_health)
  
      def drain_shields(self):
          self.shield = 0
  
      def explode(self, screen, board, player, enemy_group):
          board.draw(screen, player.power, player.max_power)
          player.hand.draw(screen)
          player.draw(screen)
          enemy_group.draw(screen)
          if self in enemy_group:
              self.remove(self.groups())
          if self.explosions is None:
              return
          pygame.display.update()
          for boom in self.explosions:
              rect = boom.get_rect(center=self.rect.center)
              screen.blit(boom, rect)
              pygame.display.update()
              pygame.time.wait(150)
  
  class Player(Character):
      def __init__(self,
                  img_path=os.path.join(SHIPS_PATH, 'Ship3/Ship3.png'),
                  ctype='fighter', health=40, power=3, hand=5):
          super().__init__(img_path=img_path, max_health=health, explosion_path='Ship3')
          self.max_handsize = hand
          self.max_power = power
          self.power = 0
          # all cards in the players current deck
          self.all_cards = []
          # player class
          self.ctype = ctype
          # battle hands
          self.hand = cards.Hand()
          self.graveyard = []
          self.deck = []
          self.in_play = []
  
      def draw_hand(self):
          for _ in range(self.max_handsize):
              # If deck is empty reshuffle graveyard into deck before drawing cards
              if not self.deck:
                  random.shuffle(self.graveyard)
                  self.deck = self.graveyard.copy()
                  self.graveyard = []
              c = self.deck.pop()
              c.highlight = False
              self.hand.add(c)
  
      def reset_decks(self):
          self.hand.empty()
          self.deck = self.all_cards.copy()
          random.shuffle(self.deck)
          self.graveyard = []
          self.in_play = []
  
      def end_turn(self, board):
          for card in self.hand:
              self.graveyard.append(card)
              card.remove(self.hand)
          self.draw_hand()
          self.hand.position_hand()
  
      def dead(self, screen, board, player, enemy_group):
          if self.current_health <= 0:
              self.explode(screen, board, player, enemy_group)
              return True
          return False
  
  class Enemy(Character):
      def __init__(self, image, health, shield, credits, atk_pattern, explosion_path=None, explosions=None, is_boss=False):
          super().__init__(image=image, credits=credits, max_health=health, explosion_path=explosion_path, explosions=explosions)
          if is_boss:
              self.image = pygame.transform.scale2x(pygame.transform.rotate(self.image, -90))
          self.shield = shield
          self.attacks = atk_pattern
          self.attack_idx = 0
          self.is_boss = is_boss
  
      def dead(self, screen, board, player, enemy_group):
          if self.current_health <= 0:
              if self.is_boss:
                  self.remove(enemy_group)
              else:
                  self.explode(screen, board, player, enemy_group)
              return self.credits
          return 0
  
      def attack(self, screen, player, assets):
          card = assets.enemy_cards[self.attacks[self.attack_idx]]
          if card.ctype == "BOOST":
              self.shield += card.shield
          elif card.ctype == "TARGET_ATTACK":
              laser, l_rect = assets.laser_img, assets.laser_rect
              l_rect.midright = self.rect.midleft
              # Shoot laser
              for i in range(5):
                  screen.blit(laser, l_rect)
                  pygame.display.update()
                  pygame.time.wait(50)
                  pygame.draw.rect(screen, BLACK, l_rect)
                  l_rect.x -= 50
              player.damage(card.damage)
          self.attack_idx = (self.attack_idx + 1) % len(self.attacks)
  
  
      def copy(self):
          return Enemy(self.image, self.max_health, self.shield, self.credits, self.attacks, explosions=self.explosions)
  
  class Target(sprite.Sprite):
      def __init__(self):
          super().__init__()
          self.image = pygame.transform.scale(pygame.image.load("assets/Misc/red_target.png"), TARGET_SIZE)
          self.attack_img = pygame.transform.scale(pygame.image.load("assets/Misc/green_target.png"), TARGET_SIZE)
          self.boost_img = pygame.transform.scale(pygame.image.load("assets/Misc/blue_target.png"), TARGET_SIZE)
          self.rect = self.image.get_rect()
  
      def update(self, position):
          self.rect = self.image.get_rect(center=position)
  
      def get_img(self):
          return self.image
  
      def get_atk(self):
          return self.attack_img
  
      def get_bst(self):
          return self.boost_img
  
      def show_box(self, screen):
          pygame.draw.rect(screen, WHITE, self.rect, 1)
  