예제 #1
0
    def __init__(self):
        self.game_object_by_uuid = {}
        self.game_object_by_game_object = {}
        self.player_by_name = {}
        self.planetary_by_name = {}
        self.tick = Tick()
        self.galaxy = Galaxy()

        # generate a bunch of rocks in the universe
        self.galaxy.create_random_bodies(1000)
예제 #2
0
    def __init__(self):
        self.game_object_by_uuid = {}
        self.game_object_by_game_object = {}
        self.player_by_name = {}
        self.planetary_by_name = {}
        self.tick = Tick()
        self.galaxy = Galaxy()

        # generate a bunch of rocks in the universe
        self.galaxy.create_random_bodies(1000)
예제 #3
0
class Game:

    """Represents the game

    Exceptions:
        TODO: make sane list of exceptions. current one is a bit insane
    """

    def __init__(self):
        self.game_object_by_uuid = {}
        self.game_object_by_game_object = {}
        self.player_by_name = {}
        self.planetary_by_name = {}
        self.tick = Tick()
        self.galaxy = Galaxy()

        # generate a bunch of rocks in the universe
        self.galaxy.create_random_bodies(1000)

    def search(self, query):
        result = None

        try:
            by_name = self.get_by_name(query)
        except:
            by_name = None

        try:
            by_id = self.get_by_id(query)
        except:
            by_id = None

        if by_name:
            result = by_name
        elif by_id:
            result = [by_id]

        return result

    def create(self, what, **kwargs):
        """Return a GameObject.

        Keyword arguments:
        what -- the GameObject class (default GameObject)
        args -- arguments to pass on to the GameObject class
        """

        if not what:
            raise TypeError('cannot create %s ' % str(what))

        game_object = what(**kwargs)

        # by uid

        game_object_uuid = str(uuid.uuid4())[:5]
        game_object.set_id(game_object_uuid)
        self.game_object_by_uuid[game_object_uuid] = game_object

        # by game_object

        self.game_object_by_game_object[game_object] = game_object_uuid

        return game_object

    def create_random_player(self, **kwargs):
        kwargs['name'] = 'player_%s' % str(uuid.uuid4())[:3]
        return self.create_player(**kwargs)

    def create_player(self, name, **kwargs):
        """Return None if name is empty or already existing username else create a player object and return it."""

        if type('') != type(name):
            name = str(name)
        name = name.strip()
        if len(name) == 0:
            return None
        if name in self.player_by_name:

            # duplicate username

            return None

        kwargs['name'] = name

        # planetary

        try:
            planetary_name = kwargs['planetary_name']
        except:
            planetary_name = None

        if not planetary_name:
            planetary_name = generate_name()

        kwargs['planetary'] = self.create_planetary(name=planetary_name)

        p = self.create(Player, **kwargs)

        kwargs['planetary'].set_owner(p)

        self.player_by_name[name] = p

        return p

    def create_planetary(self, name, **kwargs):
        """Return None if name is empty or already existing username else create a planetary object and return it."""

        if type('') != type(name):
            name = str(name)
        name = name.strip()
        if len(name) == 0:
            return None
        if name in self.planetary_by_name:

            # duplicate planetary name

            return None

        kwargs['name'] = name

        p = self.create(Planetary, **kwargs)

        self.planetary_by_name[name] = p

        self.galaxy.add_body(p)

        return p

    def install_planetary_system(self, identifier, player):
        """Return True if system was installed, False if not"""

        planetary = player.get_planetary()

        system = planetary.get_available_systems()[identifier]()

        if not player.test_criteria(system.criteria):
            return False

        planetary.install_system(system)

        return True

    def uninstall_planetary_system(self, system, player):
        pass
        #player.get_planetary().uninstall_system(system)

    def activate_planetary_system(self, identifier, player):
        system = player.get_planetary().get_system(identifier)

        if not player.is_costs_applicable(system.costs, coefficient=system.get_level()):
            return False

        player.apply_costs(system.costs, coefficient=system.get_level())

        system.activate()

    def deactivate_planetary_system(self, identifier, player):
        system = player.get_planetary().get_system(identifier)

        player.apply_costs(system.costs, revert=True)

        system.deactivate()

    def create_ship(self, **kwargs):
        return self.create(ship.Ship, **kwargs)

    def get_available_ships(self):
        return ship.TYPES

    def buy_ships(
            self,
            buyer,
            ship_enum,
            amount,
            fleet_index=0,
        ):
        """Return False iff not enough allotropes.

        Keyword arguments:
        """

        available_ships = self.get_available_ships()
        ships = []
        costs_args = [available_ships[ship_enum]['costs']]
        costs_kwargs = {"coefficient": amount}

        if not ship_enum:
            raise ShipTypeError('cannot buy ship of %s type'
                                % str(ship_enum))

        if not buyer:
            raise PlayerError('buyer cannot be %s ' % str(buyer))

        if not type(amount) == type(1):
            raise ValueError('amount must be an int: %s' % str(amount))

        if amount < 0:
            raise ValueError('amount must not be negative: %s'
                             % str(amount))

        if buyer.get_fleet(fleet_index).get_mission():
            raise FleetAbsentError('Cannot buy ships for absent fleet')

        try:
            available_ships[ship_enum]
        except:
            return False

        if not buyer.test_criteria(available_ships[ship_enum]['criteria']):
            return False

        if not buyer.is_costs_applicable(*costs_args, **costs_kwargs):
            return False

        buyer.apply_costs(*costs_args, **costs_kwargs)

        for i in range(amount):
            s = self.create_ship(**available_ships[ship_enum])

            ships.append(s)

        buyer.add_ships(ships, fleet_index)

        return True

    def attack(self, *args):
        """Return Mission which will result in an attack

        The Mission will expose its Fleets, as hostile fleets, to the target Planetary when at destination
        """

        return self.create_mission(mission.ATTACK, *args)

    def defend(self, *args):
        """Return Mission which will result in defending a planetary

        The Mission will expose its Fleets, as friendly fleets, to the target Planetary when at destination
        """

        return self.create_mission(mission.DEFEND, *args)

    def create_mission(
        self,
        modus,
        initiator,
        target,
        fleet_index,
        target_stay,
        ):
        """Create and return a Mission"""

        try:
            initiator.get_planetary()
        except:
            raise PlayerError('Initiator invalid: %s' % str(initiator))

        try:
            target.get_planetary()
        except:
            raise PlayerError('Target invalid: %s' % str(target))

        try:
            initiator.get_fleet(fleet_index)
        except:
            raise FleetAbsentError('Fleet %s cannot accept new mission'
                                   % str(fleet_index))

        if type(target_stay) != type(1):
            raise ValueError('Mission stay length invalid: %s'
                             % str(target_stay))

        if len(initiator.get_fleet(fleet_index).get_ships()) == 0:
            raise FleetEmptyError('Fleet %d empty' % fleet_index)
            return False

        if initiator == target:
            raise AttackNotAllowedError('Initiator cannot target self')

        fleet = initiator.get_fleet(fleet_index)

        if fleet.get_mission():
            raise FleetAbsentError('Fleet already on mission')

        m = mission.Mission(modus, initiator, target, target_stay,
                            fleet)
        fleet.set_mission(m)

        # Wormhole in progress, register it

        self.galaxy.register_wormhole(initiator, target)

        return m

    def get_by_id(self, thing_id):
        return self.game_object_by_uuid[thing_id]

    def get_by_obj(self, obj):
        return self.game_object_by_game_object[obj]

    def get_by_name(self, name, case=False):
        results = []
        for obj in self.game_object_by_game_object:

            # case insensitive

            if not case:
                if name.lower() == obj.get_name().lower():
                    results.append(obj)
            else:

            # case sensitive

                if name == obj.get_name():
                    results.append(obj)

        return results

    def get_all_id(self):
        return self.game_object_by_uuid

    def get_all_gameobjects(self):
        return self.game_object_by_game_object

    def get_all_players(self):
        players = []

        for (name, player) in self.player_by_name.iteritems():
            players.append(player)

        return players

    def get_all_planetaries(self):
        planetaries = []

        for (name, planetary) in self.planetary_by_name.iteritems():
            planetaries.append(planetary)

        return planetaries

    def next_tick(self):
        """Add one to tick and run tick on GameObjects"""

        from time import time

        start = time()
        self.tick.next()

        for p in self.get_all_players():
            p.tick(self)

        for p in self.get_all_planetaries():
            p.tick(self)

        self.galaxy.tick()

        stop = time()
        print round((stop - start) * 1000.0, 2), 'ms'

    def get_current_tick(self):
        """Return current tick"""

        return self.tick.get_tick()
예제 #4
0
class Game:
    """Represents the game

    Exceptions:
        TODO: make sane list of exceptions. current one is a bit insane
    """
    def __init__(self):
        self.game_object_by_uuid = {}
        self.game_object_by_game_object = {}
        self.player_by_name = {}
        self.planetary_by_name = {}
        self.tick = Tick()
        self.galaxy = Galaxy()

        # generate a bunch of rocks in the universe
        self.galaxy.create_random_bodies(1000)

    def search(self, query):
        result = None

        try:
            by_name = self.get_by_name(query)
        except:
            by_name = None

        try:
            by_id = self.get_by_id(query)
        except:
            by_id = None

        if by_name:
            result = by_name
        elif by_id:
            result = [by_id]

        return result

    def create(self, what, **kwargs):
        """Return a GameObject.

        Keyword arguments:
        what -- the GameObject class (default GameObject)
        args -- arguments to pass on to the GameObject class
        """

        if not what:
            raise TypeError('cannot create %s ' % str(what))

        game_object = what(**kwargs)

        # by uid

        game_object_uuid = str(uuid.uuid4())[:5]
        game_object.set_id(game_object_uuid)
        self.game_object_by_uuid[game_object_uuid] = game_object

        # by game_object

        self.game_object_by_game_object[game_object] = game_object_uuid

        return game_object

    def create_random_player(self, **kwargs):
        kwargs['name'] = 'player_%s' % str(uuid.uuid4())[:3]
        return self.create_player(**kwargs)

    def create_player(self, name, **kwargs):
        """Return None if name is empty or already existing username else create a player object and return it."""

        if type('') != type(name):
            name = str(name)
        name = name.strip()
        if len(name) == 0:
            return None
        if name in self.player_by_name:

            # duplicate username

            return None

        kwargs['name'] = name

        # planetary

        try:
            planetary_name = kwargs['planetary_name']
        except:
            planetary_name = None

        if not planetary_name:
            planetary_name = generate_name()

        kwargs['planetary'] = self.create_planetary(name=planetary_name)

        p = self.create(Player, **kwargs)

        kwargs['planetary'].set_owner(p)

        self.player_by_name[name] = p

        return p

    def create_planetary(self, name, **kwargs):
        """Return None if name is empty or already existing username else create a planetary object and return it."""

        if type('') != type(name):
            name = str(name)
        name = name.strip()
        if len(name) == 0:
            return None
        if name in self.planetary_by_name:

            # duplicate planetary name

            return None

        kwargs['name'] = name

        p = self.create(Planetary, **kwargs)

        self.planetary_by_name[name] = p

        self.galaxy.add_body(p)

        return p

    def install_planetary_system(self, identifier, player):
        """Return True if system was installed, False if not"""

        planetary = player.get_planetary()

        system = planetary.get_available_systems()[identifier]()

        if not player.test_criteria(system.criteria):
            return False

        planetary.install_system(system)

        return True

    def uninstall_planetary_system(self, system, player):
        pass
        #player.get_planetary().uninstall_system(system)

    def activate_planetary_system(self, identifier, player):
        system = player.get_planetary().get_system(identifier)

        if not player.is_costs_applicable(system.costs,
                                          coefficient=system.get_level()):
            return False

        player.apply_costs(system.costs, coefficient=system.get_level())

        system.activate()

    def deactivate_planetary_system(self, identifier, player):
        system = player.get_planetary().get_system(identifier)

        player.apply_costs(system.costs, revert=True)

        system.deactivate()

    def create_ship(self, **kwargs):
        return self.create(ship.Ship, **kwargs)

    def get_available_ships(self):
        return ship.TYPES

    def buy_ships(
        self,
        buyer,
        ship_enum,
        amount,
        fleet_index=0,
    ):
        """Return False iff not enough allotropes.

        Keyword arguments:
        """

        available_ships = self.get_available_ships()
        ships = []
        costs_args = [available_ships[ship_enum]['costs']]
        costs_kwargs = {"coefficient": amount}

        if not ship_enum:
            raise ShipTypeError('cannot buy ship of %s type' % str(ship_enum))

        if not buyer:
            raise PlayerError('buyer cannot be %s ' % str(buyer))

        if not type(amount) == type(1):
            raise ValueError('amount must be an int: %s' % str(amount))

        if amount < 0:
            raise ValueError('amount must not be negative: %s' % str(amount))

        if buyer.get_fleet(fleet_index).get_mission():
            raise FleetAbsentError('Cannot buy ships for absent fleet')

        try:
            available_ships[ship_enum]
        except:
            return False

        if not buyer.test_criteria(available_ships[ship_enum]['criteria']):
            return False

        if not buyer.is_costs_applicable(*costs_args, **costs_kwargs):
            return False

        buyer.apply_costs(*costs_args, **costs_kwargs)

        for i in range(amount):
            s = self.create_ship(**available_ships[ship_enum])

            ships.append(s)

        buyer.add_ships(ships, fleet_index)

        return True

    def attack(self, *args):
        """Return Mission which will result in an attack

        The Mission will expose its Fleets, as hostile fleets, to the target Planetary when at destination
        """

        return self.create_mission(mission.ATTACK, *args)

    def defend(self, *args):
        """Return Mission which will result in defending a planetary

        The Mission will expose its Fleets, as friendly fleets, to the target Planetary when at destination
        """

        return self.create_mission(mission.DEFEND, *args)

    def create_mission(
        self,
        modus,
        initiator,
        target,
        fleet_index,
        target_stay,
    ):
        """Create and return a Mission"""

        try:
            initiator.get_planetary()
        except:
            raise PlayerError('Initiator invalid: %s' % str(initiator))

        try:
            target.get_planetary()
        except:
            raise PlayerError('Target invalid: %s' % str(target))

        try:
            initiator.get_fleet(fleet_index)
        except:
            raise FleetAbsentError('Fleet %s cannot accept new mission' %
                                   str(fleet_index))

        if type(target_stay) != type(1):
            raise ValueError('Mission stay length invalid: %s' %
                             str(target_stay))

        if len(initiator.get_fleet(fleet_index).get_ships()) == 0:
            raise FleetEmptyError('Fleet %d empty' % fleet_index)
            return False

        if initiator == target:
            raise AttackNotAllowedError('Initiator cannot target self')

        fleet = initiator.get_fleet(fleet_index)

        if fleet.get_mission():
            raise FleetAbsentError('Fleet already on mission')

        m = mission.Mission(modus, initiator, target, target_stay, fleet)
        fleet.set_mission(m)

        # Wormhole in progress, register it

        self.galaxy.register_wormhole(initiator, target)

        return m

    def get_by_id(self, thing_id):
        return self.game_object_by_uuid[thing_id]

    def get_by_obj(self, obj):
        return self.game_object_by_game_object[obj]

    def get_by_name(self, name, case=False):
        results = []
        for obj in self.game_object_by_game_object:

            # case insensitive

            if not case:
                if name.lower() == obj.get_name().lower():
                    results.append(obj)
            else:

                # case sensitive

                if name == obj.get_name():
                    results.append(obj)

        return results