def __init__(self, surface, b_config, e_config):
        # UI stuff
        self.stfont = pygame.font.SysFont('Consolas', 15, bold=False)
        self.drawing = True
        self.surface = surface

        # neat-python variables
        self.b_conf = b_config
        self.e_conf = e_config
        self.b_pop = neat.Population(b_config)
        self.e_pop = neat.Population(e_config)
        self.b_brains = [
            neat.nn.FeedForwardNetwork.create(self.b_pop.population[i],
                                              b_config)
            for i in self.b_pop.population
        ]
        self.e_brains = [
            neat.nn.FeedForwardNetwork.create(self.e_pop.population[i],
                                              e_config)
            for i in self.e_pop.population
        ]

        # game objects
        self.bow_gen = [
            BowCreature(self.surface, GameObjects.Bow(self.surface))
            for i in range(0, len(self.b_pop.population))
        ]
        self.enemy_gen = [
            SquareCreature(self.surface, GameObjects.Enemy(self.surface, 100))
            for i in range(0, len(self.e_pop.population))
        ]
        self.managers = [
            GameObjects.WaveManager([self.enemy_gen[i].game_model],
                                    self.bow_gen[i].game_model)
            for i in range(0, len(self.bow_gen))
        ]
        self.timers = [0 for i in range(0, len(self.bow_gen))]

        # statistics
        self.generations = 1
        self.avg_b_fitness = []
        self.avg_e_fitness = []
        self.kills = []
        self.e_stdev = None
        self.b_stdev = None

        self.b_gen_fitness = []
        self.e_gen_fitness = []
    def multicycle(self):
        """Runs and draws a game cycle on multiple enemies and bows.
        Restarts when all timers reach 100/all enemies die."""
        view_single = False
        mp = pygame.mouse.get_pos()
        mouse_ind = None

        # check if viewing a single bow-enemy pair
        if int(mp[1]) in range(12, 12 + 10 * len(self.bow_gen)) and int(
                mp[0]) in range(860, 990):
            mouse_ind = (mp[1] - 12) // 10
            view_single = True

        # game loop
        for i in range(0, len(self.bow_gen)):
            if self.timers[i] < 100:

                # updating game objects
                b = self.bow_gen[i].game_model
                e = self.enemy_gen[i].game_model
                self.managers[i].detectCollisions()
                self.enemy_gen[i].avoided = self.managers[i].missed

                # setting input for enemy neural networks
                e_inp = [
                    b.draw_dx, b.draw_dy, (e.pos[0] - 255), (e.pos[1] - 255)
                ]
                for q in e.quadstat:
                    if q:
                        e_inp.append(100)
                    else:
                        e_inp.append(0)
                self.e_brains[i].activate(e_inp)

                # setting input for bow neural networks
                b_inp = [b.draw_dx, b.draw_dy]
                b_inp.extend([(e.pos[0] - 255), (e.pos[1] - 255), e.vel[0] * 3,
                              e.vel[1] * 3])
                self.b_brains[i].activate(b_inp)

                # drawing game objects and timer bars
                time_rect = pygame.Rect(860, 12 + 10 * i,
                                        (100 - self.timers[i]) * 1.3, 5)

                # check for high bow fitness, highlight timer bars
                c = (0, 255, 0)
                if self.generations > 1 and self.bow_gen[i].set_fitness(
                        self.managers[i].avg_dist
                ) > self.avg_b_fitness[-1] + self.b_stdev * 1.2:
                    c = (255, 0, 0)
                pygame.draw.rect(self.surface, c, time_rect)

                # listening for NN interaction, and updating game models
                b_out = [self.b_brains[i].values[ind] for ind in range(0, 3)]
                e_out = [self.e_brains[i].values[ind] for ind in range(0, 4)]
                self.enemy_gen[i].move_model(e_out)
                arrow = self.bow_gen[i].move_model(b_out)
                if arrow is not None:
                    self.managers[i].add_arrow(arrow)

                # check if viewing a single bow-enemy pair, draw respective stats
                if (not view_single) or (i == mouse_ind):
                    self.managers[i].draw()
                    if view_single:
                        self.enemy_gen[i].set_fitness()
                        self.enemy_gen[i].draw_fitness(self.stfont, (600, 60))

                        self.bow_gen[i].set_fitness(self.managers[i].avg_dist)
                        self.bow_gen[i].draw_fitness(self.stfont, (600, 400))

                        self.draw_nn(i, b_out)
                        self.draw_nn(i, e_out, True)

                # countdown when stuck/unstuck, ending timer when enemy dies
                if len(self.managers[i].enemies) < 1:
                    self.timers[i] = 150
                    self.bow_gen[i].killed = True
                elif not e.is_moving() or self.managers[
                        i].failed_shots > 15 or b.arrows > 18 or b.time_between_shots > 300:
                    self.timers[i] += 0.2
                else:
                    self.timers[i] = 0
        self.drawstats()

        # checking all generations finished, select, breed, and mutate
        for i in self.timers:
            if i < 100:
                return None

        self.b_gen_fitness, self.e_gen_fitness = [], []
        self.b_pop.run(self.bow_ff, 1)
        self.e_pop.run(self.enemy_ff, 1)
        self.shuffle_pops()

        # update kill count for generation
        k = 0
        for m in self.managers:
            if len(m.enemies) < 1:
                k += 1
        self.kills.append(k)

        # reset timers and game models, brains
        self.bow_gen = [
            BowCreature(self.surface, GameObjects.Bow(self.surface))
            for i in range(0, len(self.b_pop.population))
        ]
        self.enemy_gen = [
            SquareCreature(self.surface, GameObjects.Enemy(self.surface, 100))
            for i in range(0, len(self.e_pop.population))
        ]
        self.managers = [
            GameObjects.WaveManager([self.enemy_gen[i].game_model],
                                    self.bow_gen[i].game_model)
            for i in range(0, len(self.bow_gen))
        ]
        self.timers = [0 for i in range(0, len(self.bow_gen))]
        self.b_brains = [
            neat.nn.FeedForwardNetwork.create(self.b_pop.population[i],
                                              self.b_conf)
            for i in self.b_pop.population
        ]
        self.e_brains = [
            neat.nn.FeedForwardNetwork.create(self.e_pop.population[i],
                                              self.e_conf)
            for i in self.e_pop.population
        ]
        self.generations += 1
Beispiel #3
0
def play_function(difficulty, value):
    # Define globals
    global main_menu
    global clock

    pygame.mixer.music.pause()

    # Заглушка
    value = None

    # Путь до изображений к игре
    path_from_background = 'Data\\Image\\Map1.png'
    path_from_person = pygame.image.load('Data\\Image\\12345.png')
    path_from_person = pygame.transform.scale2x(path_from_person)
    path_from_zombie = [
        'Data\\Image\\Zombie.png', 'Data\\Image\\Zombie1.png',
        'Data\\Image\\Zombie2.png', 'Data\\Image\\Zombie3.png',
        'Data\\Image\\Zombie4.png'
    ]

    # Изменение игровых коэфицентов в зависимости от сложности
    if difficulty[0] == 'EASY':
        add_hp, add_speed, add_damage = 0.0625, 0.0625, 0.0625
    elif difficulty[0] == 'MEDIUM':
        add_hp, add_speed, add_damage = 0.125, 0.125, 0.125
    else:
        add_hp, add_speed, add_damage = 0.25, 0.25, 0.25

    counter_kill = 0  # Счётчик убийст зомби

    # Иницилизация групп

    # Сюда входят все обьекты кроме игрока и камеры
    all_sprite = pygame.sprite.Group()

    # Сюда входят только видимые обьекты
    visible_objects = pygame.sprite.Group()

    # Сюда входят только выстрелы
    bullet = pygame.sprite.Group()

    # Сюда входят только враги
    enemy = pygame.sprite.Group()

    # Шрифты применяющиеся в игре
    counter = pygame.font.Font(None, 48)  # Для счётчика убийст зомби
    damage_indicator = pygame.font.Font(None, 16)  # Для отображения дамага
    hp_indicator = pygame.font.Font(None, 32)  # Для отоброжения хп персонажа

    # Добавления Фона
    background = GameObjects.GameObject((0, 0), path_from_background)
    background.set_mask()
    background.disabled_alpha()
    all_sprite.add(background)
    visible_objects.add(background)

    # Добавления игрока
    person = GameObjects.Person((900, 900),
                                path_from_person,
                                hp=10000,
                                speed_move=(600, 600))
    visible_objects.add(person)

    # Добавление границ
    wall_up = GameObjects.EmptyObject((0, 0), (WINDOW_SIZE[0] + 1, 1))
    wall_botton = GameObjects.EmptyObject((0, WINDOW_SIZE[1] - 1),
                                          (WINDOW_SIZE[0] + 1, 1))
    wall_left = GameObjects.EmptyObject((0, 0), (1, WINDOW_SIZE[1] + 1))
    wall_right = GameObjects.EmptyObject((WINDOW_SIZE[0] - 1, 0),
                                         (1, WINDOW_SIZE[1] + 1))

    # Создание камеры
    camera = GameObjects.TargetCamera(
        all_sprite,
        person,
        traffic_restriction=background.get_size(),
        flags=pygame.FULLSCREEN | pygame.HWSURFACE)
    screen = camera.get_screen()  # Поялучаем экран камеры

    clock = pygame.time.Clock()  # Регулятор FPS
    pause = False  # Переменная отвечающая за паузу

    counter_shot = 0
    # Основной цикл игры
    command_exit = False
    while not command_exit and person.get_hp() > 0:
        screen.fill((0, 0, 0))  # Избавление от шлейфов

        # Обрабатываем нажаните клавишь
        for event in pygame.event.get():
            if event.type == pygame.QUIT:  # По нажатию на кнопки выхода выход
                command_exit = True
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:  # Если нажата, остановка игры
                    pause = not pause
                if event.key == pygame.K_z:  # Если нажата +100 к счётчику
                    counter_kill += 100
                elif event.key == pygame.K_g:  # Если нажата, обнуляет счётчик
                    counter_kill = 0

        if not pause:
            # Получаем всё нажатые клавиши
            keys = pygame.key.get_pressed()
            buttons = pygame.mouse.get_pressed()

            # Обрабатываем все удержанные клавиши
            x, y = 0, 0
            if keys[pygame.K_d]:
                x += 1
            if keys[pygame.K_a]:
                x -= 1
            if keys[pygame.K_w]:
                y -= 1
            if keys[pygame.K_s]:
                y += 1
            if buttons[0]:
                if not counter_shot % 2:
                    person.shoot().add(all_sprite, visible_objects, bullet)

            if counter_shot == 999:
                counter_shot = 0

            counter_shot += 1

            # Определяем столкновение персонажа с границами
            top, botton, left, right = True, True, True, True
            if pygame.sprite.collide_rect(person, wall_up):
                top = False
            if pygame.sprite.collide_rect(person, wall_botton):
                botton = False
            if pygame.sprite.collide_rect(person, wall_left):
                left = False
            if pygame.sprite.collide_rect(person, wall_right):
                right = False

            # Устанавливаем куда персонаж не может ходить
            person.set_ability_move(top=top,
                                    botton=botton,
                                    left=left,
                                    right=right)

            # Двигаем камеру с персонажем
            camera.sled((x, y))

            # Обнавление всех обьектов
            person.update()
            all_sprite.update()

            # Добавляем зомби если их < 100
            if len(enemy) < 100:
                pos_spanw_x = randrange(-200, WINDOW_SIZE[0] * 1.5)
                if 0 < pos_spanw_x < WINDOW_SIZE[0]:
                    pos_spanw_y = -200 if randrange(
                        2) else WINDOW_SIZE[1] * 1.5
                else:
                    pos_spanw_y = randrange(-200, WINDOW_SIZE[1] * 1.5)

                GameObjects.Enemy(
                    (pos_spanw_x, pos_spanw_y),
                    choice(path_from_zombie),
                    speed_move=randrange(100,
                                         round(101 +
                                               counter_kill * add_speed)),
                    target=person,
                    damage=randrange(1, round(2 + counter_kill * add_damage)),
                    rotate=(1, lambda: person.get_rect().center),
                    hp=randrange(1, round(2 + counter_kill * add_hp))).add(
                        all_sprite, visible_objects, enemy)

            # Изменяем скорость персанажу в зависимости от убитых зомби
            person.edit_speed_move(round(600 + (counter_kill**0.5)))

            # Обработка столкновение зомби с персонажем
            for enem in pygame.sprite.spritecollide(
                    person, enemy, False, collided=pygame.sprite.collide_rect):
                if pygame.sprite.collide_mask(person, enem):
                    person.hit(enem.get_damage())
                    pos = person.get_rect().center
                    indicator = GameObjects.GameObject(
                        (pos[0] + randrange(25), pos[1] + randrange(25)),
                        path_image=damage_indicator.render(
                            str(-enem.get_damage()), True, (255, 255, 0)),
                        time_life=10)
                    indicator.add(all_sprite, visible_objects)

            # Обработка пуль с зомби
            for bull, enem in pygame.sprite.groupcollide(
                    bullet, enemy, False, False).items():
                for enemys in enem:
                    if pygame.sprite.collide_mask(bull, enemys):
                        enemys.hit(bull.get_damage())
                        pos = enemys.get_rect().center
                        indicator = GameObjects.GameObject(
                            (pos[0] + randrange(25), pos[1] + randrange(25)),
                            path_image=damage_indicator.render(
                                str(-enemys.get_damage()), True, (255, 0, 0)),
                            time_life=10)
                        indicator.add(all_sprite, visible_objects)
                        if randrange(4):
                            bull.kill()
                        if not enemys.get_hp():
                            counter_kill += 1

        # Отрисовка всех элементов на экране
        visible_objects.draw(screen)
        xol = counter.render(f"Всего убито: {counter_kill}", True, [0, 0, 0])
        screen.blit(xol, (0, 0))
        xol = hp_indicator.render(f"Hp: {person.get_hp()}", True,
                                  [255, 0, 255])
        screen.blit(xol, (WINDOW_SIZE[0] - xol.get_rect().size[0],
                          WINDOW_SIZE[1] - xol.get_rect().size[1]))
        clock.tick(FPS)
        pygame.display.flip()

    # Вывод конечного экрана и выход в меню
    screen.blit(
        pygame.transform.scale(pygame.image.load("Data\\Image\\End.jpg"),
                               WINDOW_SIZE), (0, 0))
    pygame.display.flip()
    pygame.time.wait(2500)

    main_menu.reset(True)
    pygame.mixer.music.play(True)
    return
Beispiel #4
0
def play_function():
    # Define globals
    global clock
    global cursor_angle
    global difficulty
    global screen_size

    flag = True
    pause_time = timedelta()
    delta_quit = timedelta()
    time_now = datetime.now()
    con = sqlite3.connect('records.db')
    cur = con.cursor()
    pygame.mouse.set_visible(False)
    # Путь до изображений к игре
    path_from_background = 'Data\\Image\\Map1.png'
    path_from_person = pygame.image.load('Data\\Image\\persona.png')
    path_from_person = pygame.transform.scale2x(path_from_person)
    path_from_zombie = [
        'Data\\Image\\Zombie.png', 'Data\\Image\\Zombie1.png',
        'Data\\Image\\Zombie2.png', 'Data\\Image\\Zombie3.png',
        'Data\\Image\\Zombie4.png'
    ]

    # Изменение игровых коэфицентов в зависимости от сложности
    if difficulty == 'EASY':
        add_hp, add_speed, add_damage = 0.0625, 0.0625, 0.0625
    elif difficulty == 'MEDIUM':
        add_hp, add_speed, add_damage = 0.125, 0.125, 0.125
    else:
        add_hp, add_speed, add_damage = 0.25, 0.25, 0.25

    counter_kill = 0  # Счётчик убийст зомби

    # Иницилизация групп

    # Сюда входят все обьекты кроме игрока и камеры
    all_sprite = pygame.sprite.Group()

    # Сюда входят только видимые обьекты
    visible_objects = pygame.sprite.Group()

    # Сюда входят только выстрелы
    bullet = pygame.sprite.Group()

    # Сюда входят только враги
    enemy = pygame.sprite.Group()

    # Шрифты применяющиеся в игре
    counter = pygame.font.Font(None, 48)  # Для счётчика убийст зомби
    damage_indicator = pygame.font.Font(None, 16)  # Для отображения дамага
    bullet_reload_indicator = pygame.font.Font(
        None, 48)  # Для отображения перезарядки
    hp_indicator = pygame.font.Font(None, 48)  # Для отоброжения хп персонажа

    # Добавления Фона
    background = GameObjects.GameObject((0, 0), path_from_background)
    background.set_mask()
    background.disabled_alpha()
    all_sprite.add(background)
    visible_objects.add(background)

    # Добавления игрока
    person = GameObjects.Person((900, 900),
                                path_from_person,
                                hp=1000,
                                speed_move=(600, 600))
    visible_objects.add(person)

    # Добавление границ
    wall_up = GameObjects.EmptyObject((0, 0), (screen_size[0] + 1, 1))
    wall_botton = GameObjects.EmptyObject((0, screen_size[0] - 1),
                                          (screen_size[0] + 1, 1))
    wall_left = GameObjects.EmptyObject((0, 0), (1, screen_size[1] + 1))
    wall_right = GameObjects.EmptyObject((screen_size[1] - 1, 0),
                                         (1, screen_size[1] + 1))

    # Создание камеры
    camera = GameObjects.TargetCamera(
        all_sprite,
        person,
        traffic_restriction=background.get_size(),
        size=screen_size)
    # Поялучаем экран камеры
    screen = camera.get_screen()
    # Регулятор FPS
    clock = pygame.time.Clock()
    # Переменная отвечающая за паузу
    pause = False

    # Счетчик выстрелов
    counter_shot = 0
    # Основной цикл игры
    command_exit = False
    while not command_exit and person.get_hp() > 0:
        screen.fill((0, 0, 0))  # Избавление от шлейфов

        # Обрабатываем нажаните клавишь
        for event in pygame.event.get():
            if event.type == pygame.QUIT:  # По нажатию на кнопки выхода выход
                delta = datetime.now() - time_now - delta_quit
                result = cur.execute(
                    f"""INSERT INTO records(rec) VALUES('{delta.seconds}') """)
                con.commit()
                command_exit = True
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:  # Если нажата, остановка игры
                    if not pause:
                        pause_time = datetime.now()
                    else:
                        delta_pause = pause_time - datetime.now()
                    pause = not pause
                if event.key == pygame.K_z:  # Если нажата, выход в меню
                    delta = datetime.now() - time_now - delta_quit
                    result = cur.execute(
                        f"""INSERT INTO records(rec) VALUES('{delta.seconds}') """
                    )
                    con.commit()
                    command_exit = True

        if not pause:
            # Получаем всё нажатые клавиши
            keys = pygame.key.get_pressed()
            buttons = pygame.mouse.get_pressed()
            try:
                delta_quit += delta_pause
            except:
                pass
            # Обрабатываем все удержанные клавиши
            x, y = 0, 0
            if keys[pygame.K_d]:
                x += 1
            if keys[pygame.K_a]:
                x -= 1
            if keys[pygame.K_w]:
                y -= 1
            if keys[pygame.K_s]:
                y += 1
            if buttons[0]:
                try:
                    person.shoot().add(all_sprite, visible_objects, bullet)
                except:
                    pass

            if counter_shot == 999:
                counter_shot = 0

            counter_shot += 1

            # Определяем столкновение персонажа с границами
            top, botton, left, right = True, True, True, True
            if pygame.sprite.collide_rect(person, wall_up):
                top = False
            if pygame.sprite.collide_rect(person, wall_botton):
                botton = False
            if pygame.sprite.collide_rect(person, wall_left):
                left = False
            if pygame.sprite.collide_rect(person, wall_right):
                right = False

            # Устанавливаем куда персонаж не может ходить
            person.set_ability_move(top=top,
                                    botton=botton,
                                    left=left,
                                    right=right)

            # Двигаем камеру с персонажем
            camera.sled((x, y))

            # Обнавление всех обьектов
            person.update()
            all_sprite.update()

            # Добавляем зомби если их < 30
            if len(enemy) < 30:
                pos_spanw_x = randrange(-200, screen_size[0] * 1.5)
                if 0 < pos_spanw_x < screen_size[0]:
                    pos_spanw_y = -200 if randrange(
                        2) else screen_size[1] * 1.5
                else:
                    pos_spanw_y = randrange(-200, screen_size[1] * 1.5)

                GameObjects.Enemy(
                    (pos_spanw_x, pos_spanw_y),
                    choice(path_from_zombie),
                    speed_move=randrange(100,
                                         round(101 +
                                               counter_kill * add_speed)),
                    target=person,
                    damage=randrange(1, round(2 + counter_kill * add_damage)),
                    rotate=(1, lambda: person.get_rect().center),
                    hp=randrange(1, round(2 + counter_kill * add_hp))).add(
                        all_sprite, visible_objects, enemy)

            # Изменяем скорость персанажу в зависимости от убитых зомби
            person.edit_speed_move(round(600 + (counter_kill**0.5)))

            # Обработка столкновение зомби с персонажем
            for enem in pygame.sprite.spritecollide(
                    person, enemy, False, collided=pygame.sprite.collide_rect):
                if pygame.sprite.collide_mask(person, enem):
                    person.hit(enem.get_damage())
                    pos = person.get_rect().center
                    if person.get_hp() <= 0 and flag:
                        flag = False
                        delta = datetime.now() - time_now - delta_quit
                        result = cur.execute(
                            f"""INSERT INTO records(rec) VALUES('{delta.seconds}') """
                        )
                        con.commit()
                    indicator = GameObjects.GameObject(
                        (pos[0] + randrange(25), pos[1] + randrange(25)),
                        path_image=damage_indicator.render(
                            str(-enem.get_damage()), True, (255, 255, 0)),
                        time_life=10)
                    indicator.add(all_sprite, visible_objects)

            # Обработка пуль с зомби
            for bull, enem in pygame.sprite.groupcollide(
                    bullet, enemy, False, False).items():
                for enemys in enem:
                    if pygame.sprite.collide_mask(bull, enemys):
                        enemys.hit(bull.get_damage())
                        pos = enemys.get_rect().center
                        indicator = GameObjects.GameObject(
                            (pos[0] + randrange(25), pos[1] + randrange(25)),
                            path_image=damage_indicator.render(
                                str(-enemys.get_damage()), True, (255, 0, 0)),
                            time_life=10)
                        indicator.add(all_sprite, visible_objects)
                        if randrange(4):
                            bull.kill()
                        if enemys.get_hp() <= 0:
                            counter_kill += 1

        # Отрисовка всех элементов на экране
        visible_objects.draw(screen)
        xol = counter.render(f"Всего убито: {counter_kill}", True, [0, 0, 0])
        screen.blit(xol, (0, 0))
        hp_ind = hp_indicator.render(f"Hp: {person.get_hp()}", True,
                                     [255, 0, 255])
        screen.blit(hp_ind, (screen_size[0] - 200, screen_size[1] - 100))
        bul = bullet_reload_indicator.render(
            f"Bullet: {60 - person.get_count()}", True, [255, 0, 255])
        screen.blit(bul, (screen_size[0] - 200, 50))
        cursor_angle += 1
        screen.blit(pygame.transform.rotate(MANUAL_CURSOR, cursor_angle),
                    (pygame.mouse.get_pos()))
        clock.tick(FPS)
        pygame.display.flip()

    pygame.display.flip()
    main()
    return