DATA_DIR = "data"
SETTINGS_FILE = "settings.json"
MAGIC_DIR = "magic"
MAGIC_FILE = "magic.xml"
TEAM_FILE = "teams.json"
ALEX_BRUSH_FILE = "alexbrushregular.ttf"
SETTINGS_PATH = os.path.join(DATA_DIR, SETTINGS_FILE)
TEAM_PATH = os.path.join(DATA_DIR, TEAM_FILE)
IMAGE_DIR = os.path.join(DATA_DIR, "images")
MUSIC_DIR = os.path.join(DATA_DIR, "music")
FONT_DIR = os.path.join(DATA_DIR, "fonts")
SOUND_DIR = os.path.join(DATA_DIR, "sounds")
MAGIC_PATH = os.path.join(os.path.join(DATA_DIR, MAGIC_DIR), MAGIC_FILE)
FONT_ALEX_BRUSH = os.path.join(FONT_DIR, ALEX_BRUSH_FILE) class TitleBanner:
class State:
class StateTeamView(State):
class StateSettings(State):
class StateAnimatedIntro(State):
class StateAnimatedOutro(State):
class StateDefault(State):
class MainMenu:
    def __init__(self, text):
    def render(self):
    def render(self):
    def update(self, delta_t):
    def handle_event(self, event):
    def exit_state(self):
    def __init__(self, main_menu):
    def render(self):
    def handle_keypress(self, event):
    def finished(self):
    def update(self, delta_t):
    def exit_state(self):
    def __init__(self, main_menu):
    def render(self):
    def handle_keypress(self, event):
    def finished(self):
    def update(self, delta_t):
    def exit_state(self):
    def __init__(self, main_menu):
    def set_alpha(self, alpha):
    def render(self):
    def update(self, delta_t):
    def skip(self):
    def handle_keypress(self, event):
    def exit_state(self):
    def __init__(self, main_menu):
    def set_alpha(self, alpha):
    def render(self):
    def update(self, delta_t):
    def skip(self):
    def handle_keypress(self, event):
    def exit_state(self):
    def __init__(self, main_menu):
    def render(self):
    def handle_keypress(self, event):
    def update(self, delta_t):
    def exit_state(self):
    def __init__(self, parent, state_seed='default'):
    def set_state(self, state):
    def update_display(self):
    def compute_widget_positions(self):
    def render(self):
    def update(self, delta_t):
    def handle_event(self, event):
    def show_settings(self):
    def show_teams(self):
    def start_game(self):
    def trigger_exit(self): def filled_rounded_rect(surface,rect,color,radius=0.4):
def fill_gradient(surface, color, gradient, rect=None, vertical=True, forward=True):
    def __init__(self, battle):
    def render(self):
    def get_pos(self):
    def update(self, delta_t):
    def __init__(self, parent):
    def set_message(self, message):
    def get_pos(self):
    def set_pos(self, pos):
    def render(self):
    def animate_show(self):
    def animate_hide(self):
    def animate_set_message_show(self, message):
    def animate_hide_set_message_show(self, message):
    def __init__(self, sprite_sheet, has_direction, relative_position, n_frames, x_offset, y_offset):
    def get_pos(self):
    def render(self):
    def set_frame(self, frame):
    def fix_target(self, target):
    def show(self):
    def hide(self):
    def sync(self):
    def update(self, delta_t):
    def set_animation(self, key, animation):
    def play_sound_effect(self):
    def animate_cast(self, target):
    def __init__(self):
    def assemble(self, blueprint):
    def build_spell(self, spell_id):
    def __init__(self, mage, direction, start, combat_zone, depth):
    def set_frame(self, frame):
    def set_state(self, state):
    def get_pos(self):
    def sync(self):
    def flip(self):
    def set_direction(self, direction):
    def set_pos(self, pos):
    def update(self, delta_t):
    def hide(self):
    def show(self):
    def render(self):
    def play_sound_faint(self):
    def animate_move_start_to_combat(self):
    def animate_turn_around(self):
    def animate_move_combat_to_start(self):
    def animate_cast_spell(self):
    def animate_evade(self):
    def animate_faint(self):
    def animate_take_damage(self, critical = False):
    def __init__(self, team1, team2, width, height):
    def update(self, delta_t):
    def set_mage_health(self, health, mage):
    def get_mage_health(self, mage):
    def sync(self):
    def render(self):
    def animate_update_health(self, mage):
    def __init__(self, battle, resolution):
    def restore_positions(self):
    def sync(self):
    def get_spell(self, spell):
    def get_mage(self, mage):
    def render(self):
    def update(self, delta_t):
    def __init__(self, team1, team2):
    def render(self):
    def __init__(self, league):
    def render(self):
    def __init__(self, league):
    def render(self):
    def __init__(self, parent):
    def set_alpha(self, alpha):
    def next_window(self):
    def render(self):
    def update(self, delta_t):
    def handle_event(self, event):
    def exit_state(self):
    def __init__(self, parent, root):
    def set_alpha(self, alpha):
    def render(self):
    def switch_music(self):
    def update(self, delta_t):
    def handle_event(self, event):
    def exit_state(self):
    def __init__(self, parent, root):
    def play_sound_effect(self, effect):
    def render(self):
    def play_all_move_animations(self):
    def toggle_pause(self):
    def skip_animations(self):
    def play_whole_game(self):
    def update(self, delta_t):
    def handle_event(self, event):
    def exit_state(self):
    def animate_unknown_spell(self, move_result):
    def gen_do_nothing_string(self, mage):
    def animate_does_nothing(self, move_result):
    def process_move_failed(self, move_result):
    def process_move_succeed(self, move_result):
    def process_spell_cast(self, cast, caster, spell, report_fainted=True):
    def process_attack_spell(self, cast, caster, spell, report_fainted=True):
    def process_stat_boost_spell(self, cast, caster, spell):
    def process_stat_reduce_spell(self, cast, caster, spell):
    def process_healing_spell(self, cast, caster, spell):
    def process_move_result(self, move_result):
    def __init__(self, parent, root):
    def set_game_alpha(self, value):
    def set_overlay_alpha(self, value):
    def render(self):
    def update(self, delta_t):
    def handle_event(self, event):
    def exit_state(self):
    def __init__(self, parent, state_seed='intro'):
    def render(self):
    def update(self, delta_t):
    def handle_event(self, event):
    def set_state(self, state):
    def exit_state(self):
    def __init__(self, parent, state_seed='league_view'):
    def set_state(self, state):
    def render(self):
    def update(self, delta_t):
    def handle_event(self, event):
    def trigger_exit_to_announce_winners(self):
    def trigger_exit_to_main(self):
class RoundCounter:
class MessageBar:
class SpellSprite:
class SpellFactory:
class MageSprite:
class MageStatusWindow:
class BattleWindow:
class VersusBanner:
class ScoreTable:
class MatchTable:
class StateLeagueView:
class StateBattleStart:
class StateInBattle:
class StateBattleEnd:
class StateBattleView:
class Game:
    IN_FRONT =  1
    OVERLAY  =  0
    BEHIND   = -1 class StateWinnersView:
class AnnounceWinners:
    def __init__(self, parent):
    def update_fireworks(self):
    def set_alpha(self, alpha):
    def spawn_burst(self, x, y):
    def render(self):
    def update(self, delta_t):
    def handle_event(self, event):
    def exit_state(self):
    def __init__(self, parent, state_seed='default'):
    def set_state(self, state):
    def render(self):
    def update(self, delta_t):
    def handle_event(self, event):
    def trigger_exit_to_main(self): class SpellBook:
    spells   = {}
    elements = {}

    spell_constructors  = {
        'group'  : GroupSpell,
        'single' : Spell
    }

    effect_constructors = {
        'attack'        : AttackEffect,
        'rebound_attack' : ReboundAttackEffect,
        'leech_attack'   : LeechAttackEffect,
        'stat_boost'    : BoostStatEffect,
        'stat_reduce'   : ReduceStatEffect,
        'heal'          : HealingEffect
    }

    def __init__(self):
        self.magic = Magic()

    def cast_spell(self, spell, caster, target):
        spell = SpellBook.get_spell_object(spell)
        if spell != None:
            return self.magic.execute(CastSpell(spell, caster, target))
        else:
            return { "success" : False }

    @staticmethod
    def __load_elements(xml_tree):
        elements = xml_tree.find('elements').findall('element')

        # Load element types from the XML file
        for element in elements:
            # Get the name of the element
            name = element.attrib['name']

            # Get strengths, weaknesses and compatabilities
            strong = [elem.text for elem in element.findall('strong/element')]
            weak = [elem.text for elem in element.findall('weak/element')]
            compatible = [elem.text for elem in element.findall('compatible/element')]

            # Element has to be part of its own compatibility list
            compatible.append(name)

            # Add the element to our spell book
            SpellBook.elements[name] = Element(name, strong, weak, compatible)

    @staticmethod
    def __load_spells(xml_tree):
        spells   = xml_tree.find('spells').findall('spell')

        # Load spells into our spell book
        for spell in spells:
            # Get the name of the spell
            name    = spell.attrib['name']

            # Determine the spell's element type (with error checking)
            element = spell.find('element')

            # Element tag is missing
            if element == None:
                print("{} does not have element. Skipping".format(name))
                continue

            element = element.text

            # Element tag contained invalid text
            if element not in SpellBook.elements:
                print("{} has invalid element {}. Skipping".format(name, element))
                continue

            # Get the element from the list of elements loaded
            element = SpellBook.elements[element]

            # Load the effects that the spell has
            effects = []
            for effect in spell.findall('effect'):
                # Get the effect's type and remove that entry from the dictionary
                effect_type = effect.attrib.pop('type', None)

                # Cast dictionary elements to ints where possible
                for key in effect.attrib:
                    try:
                        new_val = int(effect.attrib[key])
                        effect.attrib[key] = new_val
                    except ValueError:
                        pass

                # Create the effect and append it to our list
                effects.append(SpellBook.effect_constructors[effect_type](element, **effect.attrib))

            # Create the spell from all that we've loaded
            SpellBook.spells[name] = SpellBook.spell_constructors[spell.attrib['type']](name, effects, element)

    @staticmethod
    def load_spell_book(spell_book):
        data = ET.parse(spell_book)
        tree = data.getroot()

        SpellBook.__load_elements(tree)
        SpellBook.__load_spells(tree)

    @staticmethod
    def get_element_object(identifier):
        if identifier not in SpellBook.elements:
            print("{} is not a real element".format(identifier))
            return None
        else:
            return SpellBook.elements[identifier]

    @staticmethod
    def get_spell_object(identifier):
        if identifier not in SpellBook.spells:
            print("{} is not a real spell".format(identifier))
            return None
        else:
            return SpellBook.spells[identifier] class Battle:
    def __init__(self, team1, team2):
        self.team1 = team1
        self.team2 = team2

        self.team1.reinitialize()
        self.team2.reinitialize()

        self.cur_round = None
        self.round_counter = 0
        self.max_round = 10

        self.start_new_round()

    def set_state(self, state):
        if state not in self.states:
            return

        self.cur_state = state
        self.state = self.states[self.cur_state](self)

    def play_next_move(self):
        if not self.is_battle_over():
            result = self.cur_round.next_move()
            if self.cur_round.round_over():
                self.start_new_round()
            result["finished"] = False
            return result
        return { "finished" : True }

    def start_new_round(self):
        self.cur_round = BattleRound(self.team1, self.team2)
        self.round_counter += 1

    def get_round_number(self):
        return self.round_counter

    def is_battle_over(self):
        return self.team2.is_defeated() or self.team1.is_defeated() or self.round_counter > self.max_round

    def award_victory(self, team_no):
        if team_no == 2:
            for mage in self.team1:
                mage.cur_hp = 0
        elif team_no == 1:
            for mage in self.team2:
                mage.cur_hp = 0

    def get_winner(self):
        if self.team2.is_defeated():
            return self.team1.get_short_name()

        if self.team1.is_defeated():
            return self.team2.get_short_name()

        if self.round_counter > self.max_round:
            dt1 = [tm.get_remaining_health_percentage() for tm in self.team1]
            dt2 = [tm.get_remaining_health_percentage() for tm in self.team2]
            dt1 = sum(dt1)
            dt2 = sum(dt2)

            return self.team1.get_short_name() if dt1 > dt2 else self.team2.get_short_name()

        return None

    def __str__(self):
        text = "Round {}\n".format(self.round_counter) if not self.is_battle_over() else "{} won\n".format(self.get_winner())
        text += str(self.team1)
        text += '\n'
        text += str(self.team2)

        return text class MusicManager:

    class __MusicManager:
        def __init__(self, settings):
            self.music = {}
            self.now_playing = ""

            if settings == None:
                self.settings = {
                    "sound" :
                    {
                        "sound_volume":0.3,
                        "sound_enabled" : True
                    }
                }
            else:
                self.settings = settings

            self.track_no     = 0
            self.cur_playlist = []
            self.default_volume = self.settings['sound']['music_volume']
            self.volume         = self.default_volume
            self.enabled        = self.settings['sound']['music_enabled']

            pygame.mixer.init()
            music_files = os.listdir(MUSIC_DIR)
            for music_name in music_files:
                self.music[os.path.splitext(music_name)[0]] = music_name

            self.soundtrack = {
                "main_menu" : [ "long_road" ],
                # "in_game"   : [ "preliator", "killers", "ff8", "skyrim" ]
            }

        def play_song(self, song_name, volume = -1, loops=1):
            if not self.enabled:
                return

            if volume < 0:
                pygame.mixer.music.set_volume(self.volume)
            else:
                pygame.mixer.music.set_volume(volume)

            if song_name not in self.music:
                print("Failed to load song \"{}\"".format(song_name))
                pygame.mixer.music.stop()
                return

            if self.now_playing != song_name or not pygame.mixer.music.get_busy():
                pygame.mixer.music.load(os.path.join(MUSIC_DIR, self.music[song_name]))
                pygame.mixer.music.play(loops)
                self.now_playing = song_name

        def load_playlist(self, playlist):
            if playlist in self.soundtrack:
                self.cur_playlist = self.soundtrack[playlist]
            else:
                self.cur_playlist = []
            self.track_no = -1

        def get_music_volume(self):
            return pygame.mixer.music.get_volume()

        def set_music_volume(self, volume):
            self.volume = volume
            pygame.mixer.music.set_volume(volume)

        def set_default_music_volume(self, volume):
            self.default_volume = volume

        def restore_music_volume(self):
            self.set_music_volume(self.default_volume)

        def set_enabled(self, enabled):
            self.enabled = enabled
            if not self.enabled:
                pygame.mixer.music.stop()
            else:
                self.load_next_song()

        def handle_settings_update(self, event):
            self.set_music_volume(self.settings['sound']['music_volume'])
            self.set_default_music_volume(self.settings['sound']['music_volume'])

            if self.enabled != self.settings['sound']['music_enabled']:
                self.set_enabled(self.settings['sound']['music_enabled'])

        def handle_song_stopped(self, event):
            self.load_next_song()

        def handle_state_change(self, event):
            self.set_music_volume(self.default_volume)
            self.load_playlist(event.state)
            self.load_next_song()

        def set_music_stopped_event(self, event):
            pygame.mixer.music.set_endevent(event)

        def load_next_song(self):
            if len(self.cur_playlist) > 0:
                self.track_no += 1
                self.track_no %= len(self.cur_playlist)
                self.play_song(self.cur_playlist[self.track_no])

    instance = None

    def __init__(self, settings = None):
        if MusicManager.instance == None:
            MusicManager.instance = MusicManager.__MusicManager(settings)

    def __getattr__(self, name):
        return getattr(self.instance, name) class SoundManager:

    class __SoundManager:
        def __init__(self, settings):
            self.sounds = {}

            sound_files = os.listdir(SOUND_DIR)

            if settings == None:
                self.settings = {
                    "sound" :
                    {
                        "sound_volume":0.8,
                        "sound_enabled" : True
                    }
                }
            else:
                self.settings = settings

            self.volume  = self.settings['sound']['sound_volume']
            self.enabled = self.settings['sound']['sound_enabled']

            for sound_name in sound_files:
                self.sounds[os.path.splitext(sound_name)[0]] = pygame.mixer.Sound(os.path.join(SOUND_DIR, sound_name))
                self.sounds[os.path.splitext(sound_name)[0]].set_volume(self.volume)

            self.sound_effects = {
                'menu_move'       : 'menu_move',
                'menu_click'      : 'menu_click',
                'menu_scroll'     : 'menu_scroll',
                'revenge_of_tesla': 'revenge_of_tesla',
                'jolt'            : 'jolt',
                'lightning_bolt'  : 'lightning_bolt',
                'lightning_blade' : 'lightning_blade',
                'thunder_storm'   : 'thunder_storm',
                'voltage_slam'    : 'voltage_slam',
                'charge'          : 'charge',
                'shattering_bolt' : 'shattering_bolt',
                'stalactite_drop' : 'stalactite_drop',
                'bassault'        : 'bassault',
                'rock_smash'      : 'rock_smash',
                'earthquake'      : 'earthquake',
                'fracture'        : 'fracture',
                'landslide'       : 'landslide',
                'granite_armour'  : 'granite_armour',
                'faint'           : 'faint',
                'quicksand'       : 'quicksand',
                'blizzard'        : 'blizzard',
                'frost_storm'     : 'frost_storm',
                'glacier'         : 'glacier',
                'ice_cage'        : 'ice_cage',
                'frostbite'       : 'frost_bite',
                'chill_strike'    : 'chill_strike',
                'ice_breaker'     : 'ice_breaker',
                'ice_wall'        : 'ice_wall',
                'drop_mixtape'    : 'drop_mixtape',
                'blazing_salvo'   : 'blazing_salvo',
                'fireball'        : 'fireball',
                'lava_storm'      : 'lava_storm',
                'flame_wave'      : 'flame_wave',
                'backdraft'       : 'backdraft',
                'solar_blaze'     : 'solar_blaze',
                'unmake'          : 'unmake',
                'power_swirl'     : 'power_swirl',
                'sting_of_neptune': 'sting_of_neptune',
                'water_jet'       : 'water_jet',
                'riptide'         : 'riptide',
                'tidal_wave'      : 'tidal_wave',
                'monsoon'         : 'monsoon',
                'healing_wave'    : 'healing_wave',
                'absorb'          : 'absorb',
                'nope'            : 'nope',
            }

        def play_sound(self, sound_name):
            if not self.enabled:
                return

            if sound_name not in self.sounds:
                print("Failed to load sound \"{}\"".format(sound_name))
                return

            self.sounds[sound_name].play()

        def set_volume(self, volume):
            self.volume = volume
            for sound in self.sounds:
                self.sounds[sound].set_volume(volume)

        def set_enabled(self, enabled):
            self.enabled = enabled

        def handle_settings_update(self, event):
            self.set_volume(self.settings['sound']['sound_volume'])

            if self.enabled != self.settings['sound']['sound_enabled']:
                self.enabled = self.settings['sound']['sound_enabled']

        def handle_sound_effect(self, event):
            if event.message in self.sound_effects:
                self.play_sound(self.sound_effects[event.message])

        def still_playing(self):
            return pygame.mixer.get_busy()

    instance = None

    def __init__(self, settings = None):
        if SoundManager.instance == None:
            SoundManager.instance = SoundManager.__SoundManager(settings)

    def __getattr__(self, name):
        return getattr(self.instance, name) class ImageManager:

    class __ImageManager:
        def __init__(self):
            self.images = {}

            image_files = os.listdir(IMAGE_DIR)

            for image_name in image_files:
                self.images[os.path.splitext(image_name)[0]] = pygame.image.load(os.path.join(IMAGE_DIR, image_name))

            self.tile_size = 100

        def get_image(self, image_name):
            if image_name not in self.images:
                s = pygame.Surface((self.tile_size,self.tile_size))
                s.fill((0,0,0))
                return s
            return self.images[image_name]

        def get_tile(self, image_name, clip_x, clip_y):
            if image_name not in self.images:
                s = pygame.Surface((self.tile_size,self.tile_size))
                s.fill((0,0,0))
                return s

            surface = self.images[image_name]

            rect = pygame.Rect(
                (
                    clip_x*self.tile_size,
                    clip_y*self.tile_size,
                    self.tile_size,
                    self.tile_size
                )
            )
            image = pygame.Surface(rect.size, pygame.SRCALPHA)
            image.fill((0,0,0,0))

            image.blit(surface, (0, 0), rect)
            return image

    instance = None

    def __init__(self):
        if ImageManager.instance == None:
            ImageManager.instance = ImageManager.__ImageManager()

    def __getattr__(self, name):
        return getattr(self.instance, name) class EventHandler:
    def __init__(self):
        self.callbacks = {
            pygame.KEYDOWN           : self.key_state_change,
            pygame.KEYUP             : self.key_state_change,
            pygame.MOUSEMOTION       : self.mouse_motion,
            pygame.MOUSEBUTTONUP     : self.mouse_button_state_change,
            pygame.MOUSEBUTTONDOWN   : self.mouse_button_state_change,
            pygame.QUIT              : self.quit,
            STATE_CHANGED            : self.state_change,
            SOUND_EFFECT             : self.sound_effect,
            SETTINGS_UPDATED         : self.settings_updated,
            SET_GAME_STATE           : self.set_game_state,
            MUSIC_STOPPED            : self.music_stopped
        }

        self.key_states = defaultdict(int)
        self.mouse_button_states = defaultdict(int)

        self.key_listeners  = []
        self.state_change_listeners = []
        self.sound_effect_listeners = []
        self.mouse_button_listeners = []
        self.settings_listeners     = []
        self.set_game_state_listeners = []
        self.quit_listeners = []
        self.game_start_listeners = []
        self.music_stopped_listeners = []

    def handle_event(self, event):
        if event.type in self.callbacks:
            self.callbacks[event.type](event)

    def register_key_listener(self, listener):
        self.key_listeners.append(listener)

    def unregister_key_listener(self, listener):
        self.key_listeners.remove(listener)

    def register_quit_listener(self, listener):
        self.quit_listeners.append(listener)

    def unregister_quit_listener(self, listener):
        self.quit_listeners.remove(listener)

    def register_mouse_button_listener(self, listener):
        self.mouse_button_listeners.append(listener)

    def unregister_mouse_button_listener(self, listener):
        self.mouse_button_listeners.remove(listener)

    def register_state_change_listener(self, listener):
        self.state_change_listeners.append(listener)

    def unregister_state_change_listener(self, listener):
        self.state_change_listeners.remove(listener)

    def register_sound_effect_listener(self, listener):
        self.sound_effect_listeners.append(listener)

    def unregister_state_change_listener(self, listener):
        self.sound_effect_listeners.remove(listener)

    def register_settings_update_listener(self, listener):
        self.settings_listeners.append(listener)

    def unregister_settings_update_listener(self, listener):
        self.settings_listeners.remove(listener)

    def register_set_game_state_listener(self, listener):
        self.set_game_state_listeners.append(listener)

    def unregister_set_game_state_listener(self, listener):
        self.set_game_state_listeners.remove(listener)

    def register_music_stopped_listener(self, listener):
        self.music_stopped_listeners.append(listener)

    def unregiste_music_stopped_listener(self, listener):
        self.music_stopped_listeners.remove(listener)

    def settings_updated(self, event):
        for listener in self.settings_listeners:
            listener(event)

    def key_state_change(self, event):
        self.key_states[event.key] = pygame.time.get_ticks()
        for listener in self.key_listeners:
            listener(event)

    def state_change(self, event):
        for listener in self.state_change_listeners:
            listener(event)

    def sound_effect(self, event):
        for listener in self.sound_effect_listeners:
            listener(event)

    def mouse_motion(self, event):
        return

    def mouse_button_state_change(self, event):
        self.mouse_button_states[event.button] = pygame.time.get_ticks()
        for listener in self.mouse_button_listeners:
            listener(event)

    def get_key_event_time(self, key):
        if key in self.key_states:
            return self.key_states[key]

    def quit(self, event):
        for listener in self.quit_listeners:
            listener(event)

    def set_game_state(self, event):
        for listener in self.set_game_state_listeners:
            listener(event)

    def music_stopped(self, event):
        for listener in self.music_stopped_listeners:
            listener(event) STATE_CHANGED    = pygame.USEREVENT + 1 MUSIC_STOPPED    = pygame.USEREVENT + 5 class Team(list):
    def __init__(self, team_name, team_members):
    def initialize_team_members(self):
    def reinitialize(self):
    def is_defeated(self):
    def get_short_name(self):
    def get_name(self):
    def __str__(self):
def load_teams(path):
import pygame
import json
import sys
from app.resources import directories
from app.view import main_menu, in_game, winners
from app.models.magic import SpellBook
from app.models.battle import Battle
from app.resources.music import MusicManager
from app.resources.sounds import SoundManager
from app.resources.images import ImageManager
from app.resources.event_handler import EventHandler, STATE_CHANGED, MUSIC_STOPPED
from app.models import team

class Walton:
    def __init__(self):
        pygame.mixer.pre_init(44100, -16, 1, 2048)
        pygame.init()

        # Load settings from JSON file
        json_data=open(directories.SETTINGS_PATH).read()
        self.settings = json.loads(json_data)
        self.resolution_key = self.settings['screen']['resolution']
        resolution = self.settings['valid_resolutions'][self.resolution_key]
        self.resolution = (resolution['width'], resolution['height'])
        self.title = self.settings['title']


        self.winners = []