Beispiel #1
0
    def createNewCell(cls) -> None:
        if time.time() - cls.ref_time > cls.DELTA_T_NEW_CELL:
            cls.ref_time = time.time()

            x = random.randrange(Cell.BASE_RADIUS,
                                 cls.size.x - Cell.BASE_RADIUS)
            y = random.randrange(Cell.BASE_RADIUS,
                                 cls.size.y - Cell.BASE_RADIUS)
            cell = Cell(Vect2d(x, y))

            ok = True

            for k in cls.creatures.keys():
                enemy_list = cls.creatures[k]

                for enemy in enemy_list:
                    if Vect2d.dist(enemy.pos,
                                   cell.pos) < cell.radius + enemy.radius:
                        ok = False

            x = int(cell.pos.x / cls.size.x * cls.grid_size.x)
            y = int(cell.pos.y / cls.size.y * cls.grid_size.y)

            if ok:
                cls.all_cells.append(cell)
                cls.grid[x][y].append(cell)

            if len(cls.all_cells) >= cls.MAX_CELLS:
                cls.deleteCell(0)
Beispiel #2
0
    def speedEnemies(self, map_size: Vect2d) -> tuple:
        dist_target = float("inf")
        dist_hunter = float("inf")

        speed_target = None
        speed_hunter = None

        can_split = False

        score_target = None

        for enemy_pos, enemy_radius, enemy_score in self.creatures_info:
            dist = Vect2d.dist(self.pos,
                               enemy_pos) - self.radius - enemy_radius

            if Creature.canEat(enemy_score, self.score):
                if dist < dist_hunter:
                    speed_hunter = enemy_pos - self.pos
                    dist_hunter = dist

            elif Creature.canEat(self.score, enemy_score):
                if dist < dist_target:
                    speed_target = enemy_pos - self.pos
                    dist_target = dist
                    score_target = enemy_score

        if score_target is not None:
            if score_target < self.score // 2:
                if dist_target > self.radius and dist_target < self.radius * 2:
                    can_split = True

        if speed_hunter is None:
            speed_hunter = Vect2d(0, 0)

        if speed_target is None:
            speed_target = Vect2d(0, 0)

        coeff_target = 1 - dist_target / map_size.length()
        coeff_target = abs(coeff_target**3)

        if coeff_target == float("inf"):
            coeff_target = 0
        elif coeff_target >= 1:
            coeff_target = 1

        coeff_target = coeff_target if coeff_target != float("inf") else 0

        coeff_hunter = 1 - dist_hunter / map_size.length()
        coeff_hunter = abs(coeff_hunter**3)

        if coeff_hunter == float("inf"):
            coeff_hunter = 0
        elif coeff_hunter >= 1:
            coeff_hunter = 1

        return speed_target, coeff_target, speed_hunter, coeff_hunter, can_split
Beispiel #3
0
    def handleBushSplit(cls) -> None:
        """Gère le split lié aux buissons"""

        for k in cls.creatures.keys():
            creatures_list = cls.creatures[k]

            for creature in creatures_list:
                if creature.radius > Bush.RADIUS:
                    for bush in cls.bushes:
                        if Vect2d.dist(bush.pos,
                                       creature.pos) < creature.radius:
                            bush.hit()
                            creature.split(is_player=(
                                creature.creature_id == cls.player_id),
                                           override_limit=True)
Beispiel #4
0
    def createEnemy(cls) -> None:
        """Crée un nouvel ennemi en évitant le spawn-kill, apparition sur une
        autre créature"""

        ok = False
        timed_out = False
        compt = 0

        while not ok and not timed_out:
            ok = True

            pos = Vect2d(
                random.randrange(Creature.BASE_RADIUS * 2,
                                 cls.size.x - Creature.BASE_RADIUS * 2),
                random.randrange(Creature.BASE_RADIUS * 2,
                                 cls.size.y - Creature.BASE_RADIUS * 2))

            for k in cls.creatures.keys():
                creatures_list = cls.creatures[k]

                for creature in creatures_list:
                    if Vect2d.dist(pos, creature.pos) < (Creature.BASE_RADIUS +
                                                         creature.radius) * 2:
                        ok = False

            if compt == 10:
                timed_out = True

            compt += 1

        if not timed_out:
            enemy_id = cls.generateId()

            if cls.all_usernames is None:
                size = random.randint(3, 5)
                name = cls.generateNewName(size)
            else:
                name = cls.all_usernames[random.randrange(
                    len(cls.all_usernames))]

            enemy = Enemy(pos, name, Color.randomColor(), enemy_id)

            cls.creatures[enemy_id] = [enemy]
Beispiel #5
0
    def detectEnemyHitbox(cls) -> None:
        """Gère la hitbox des créatures"""

        for k1 in cls.creatures.keys():
            for k2 in cls.creatures.keys():
                enemy_list_1 = cls.creatures[k1]
                enemy_list_2 = cls.creatures[k2]

                for enemy_1 in enemy_list_1:
                    for enemy_2 in enemy_list_2:
                        if enemy_1 is not enemy_2 and enemy_1.is_alive and enemy_2.is_alive:
                            dist = Vect2d.dist(enemy_1.pos, enemy_2.pos)

                            if k1 == k2:
                                t1 = time.time(
                                ) - enemy_1.invincibility_family_time
                                t2 = time.time(
                                ) - enemy_2.invincibility_family_time

                                if t1 > Creature.SPLIT_TIME and t2 > Creature.SPLIT_TIME:
                                    if dist <= max(enemy_1.radius,
                                                   enemy_2.radius):
                                        enemy_1.kill(enemy_2.score)
                                        enemy_2.killed(k1)

                                        family_tmp = []

                                        for creature in enemy_1.family:
                                            if creature is not enemy_2:
                                                family_tmp.append(creature)

                                        enemy_1.family = family_tmp
                            else:
                                if Creature.canEat(enemy_1.radius,
                                                   enemy_2.radius):
                                    if dist <= max(enemy_1.radius,
                                                   enemy_2.radius):
                                        enemy_1.kill(enemy_2.score)
                                        enemy_2.killed(k1)
Beispiel #6
0
    def createBush(cls) -> None:
        """Crée un buisson qui ne soit pas en collision avec un autre buisson"""

        ok = False
        timeout = 0

        while not ok and timeout < 1000:
            ok = True

            pos = Vect2d(
                random.randrange(Bush.RADIUS * 2,
                                 cls.size.x - Bush.RADIUS * 2),
                random.randrange(Bush.RADIUS * 2,
                                 cls.size.x - Bush.RADIUS * 2))

            for bush in cls.bushes:
                if Vect2d.dist(pos, bush.pos) < Bush.RADIUS * 4:
                    ok = False

            timeout += 1

        if ok:
            cls.bushes.append(Bush(pos))
Beispiel #7
0
    def searchCellDest(self, radius: int, map_size: Vect2d) -> None:
        maxi = 0
        liste_pos_maxi = []

        score = 0

        grid_size = Vect2d(len(self.map_cell), len(self.map_cell[0]))

        map_pos = self.getMapPos(map_size, grid_size)

        for x in range(map_pos.x - radius, map_pos.x + radius + 1):
            for y in range(map_pos.y - radius, map_pos.y + radius + 1):
                if x in range(grid_size.x) and y in range(grid_size.y):
                    taille = len(self.map_cell[x][y])

                    if taille == maxi:
                        liste_pos_maxi += [(x, y)]
                    elif taille > maxi:
                        maxi = taille
                        liste_pos_maxi = [(x, y)]

        distance_mini = float("inf")
        coords_mini = None

        for x, y in liste_pos_maxi:
            for j in range(len(self.map_cell[x][y])):
                pos = self.map_cell[x][y][j]

                dist = Vect2d.dist(pos, self.pos)

                if dist < distance_mini:
                    score = len(self.map_cell[x][y])
                    distance_mini = dist
                    coords_mini = self.map_cell[x][y][j]

        return coords_mini, score
Beispiel #8
0
    def update(self, map_size: Vect2d) -> None:
        grid_size = Vect2d(len(self.map_cell), len(self.map_cell[0]))

        max_radius = grid_size.x
        radius = 1
        speed_cell = None
        cell_score = 0
        can_split = False

        while speed_cell is None and radius < max_radius:
            speed_cell, cell_score = self.searchCellDest(radius, map_size)
            radius += 1

        if speed_cell is None:
            speed_cell = Vect2d(0, 0)
        else:
            speed_cell = speed_cell - self.pos

        speed_target, coeff_target, speed_hunter, coeff_hunter, can_split = self.speedEnemies(
            map_size)

        bords = [
            Vect2d(self.pos.x, self.radius),
            Vect2d(self.pos.x, map_size.y - self.radius),
            Vect2d(self.radius, self.pos.y),
            Vect2d(map_size.x - self.radius, self.pos.y)
        ]

        coeff_bords = []

        for bord in bords:
            dist_bord = Vect2d.dist(bord, self.pos)
            coeff_bord = math.exp(-(dist_bord**0.2) / 2)**3
            coeff_bord = coeff_bord if coeff_bord <= 1 else 0
            coeff_bords.append(coeff_bord)

        speed_family = Vect2d(0, 0)

        coeff_family = 0
        taille = 0

        for creature in self.family:
            if self is not creature:
                taille += 1

                coeff = (time.time() -
                         creature.invincibility_family_time) / self.SPLIT_TIME

                if coeff > 1:
                    coeff = 1

                coeff = coeff**3
                coeff_family += coeff
                speed_family += (creature.pos - self.pos) * coeff

        self.speed *= 0.98 + self.inertia

        if taille != 0:
            coeff_family /= taille

        direction = (speed_cell*(1-coeff_target)*(1-coeff_hunter)*(1-coeff_family)).normalize()\
                  + (speed_target*coeff_target*(1-coeff_hunter)*(1-coeff_family)).normalize()\
                  - (speed_hunter*(1-coeff_target)*coeff_hunter*(1-coeff_family)).normalize()\
                  + (speed_family*coeff_target*(1-coeff_hunter)*coeff_family).normalize()

        if can_split:
            if self.speed != Vect2d(0, 0) and speed_target != Vect2d(0, 0):
                angle = Vect2d.angleBetween(self.speed, speed_target)

                if abs(angle) < 10:
                    self.split()

        self.speed += direction

        self.speed.x -= 1 * coeff_bords[0] * self.speed.y
        self.speed.y += 1 * coeff_bords[0] * abs(self.speed.y)

        self.speed.x -= 1 * coeff_bords[1] * self.speed.y
        self.speed.y -= 1 * coeff_bords[1] * abs(self.speed.y)

        self.speed.y += 1 * coeff_bords[2] * self.speed.x
        self.speed.x += 1 * coeff_bords[2] * abs(self.speed.x)

        self.speed.y += 1 * coeff_bords[3] * self.speed.x
        self.speed.x -= 1 * coeff_bords[3] * abs(self.speed.x)

        self.direction = self.speed.normalize()

        self.applySpeed(map_size)