Beispiel #1
0
def create_offhand_item(name, material):
    _bonus = material_dict[material][0]
    _color = material_dict[material][1]
    _base, _equip, _skill = None, None, None
    _name = material.capitalize() + ' ' + name.capitalize()

    if name == 'buckler':
        _base = Base(name=_name,
                     char=u'\u03C3',
                     color=_color,
                     render_order=RenderOrder.ITEM)
        _equip = Equippable(slot=Bodyparts.OffHand.name)
        _skill = Skill(cooldown=5, name='bash', nature='direct')
        _skill.knockback_force = 2

    if name == 'shield':
        _base = Base(name=_name,
                     char=u'\u0398',
                     color=_color,
                     render_order=RenderOrder.ITEM)
        _equip = Equippable(slot=Bodyparts.OffHand.name)
        _skill = Skill(cooldown=5, name='bash', nature='direct')
        _skill.knockback_force = 4

    return _base, _equip, _skill
Beispiel #2
0
def create_mainhand_item(name, material):
    _bonus = material_dict[material][0]
    _color = material_dict[material][1]
    _name = material.capitalize() + ' ' + name.capitalize()

    _base, _equip, _skill = None, None, None

    if name == 'sword':
        _base = Base(name=_name,
                     char=u'\u2193',
                     color=_color,
                     render_order=RenderOrder.ITEM)

        _profile = {}
        _profile = example_profile()
        _profile['ATK']['ATK'] = 1.8 + _bonus

        _equip = Equippable(slot=Bodyparts.MainHand.name, profile=_profile)

        _profile = {}
        _profile = example_profile()
        _profile['ATK']['ATK'] = 1.6 + _bonus
        _profile['ATK']['MAG'] = 0.2 + _bonus

        _skill = Skill(cooldown=12,
                       name='pierce',
                       nature='direct',
                       profile=_profile)

    if name == 'spear':
        _base = Base(name=_name,
                     char=u'\u2191',
                     color=_color,
                     render_order=RenderOrder.ITEM)

        _profile = {}
        _profile = example_profile()
        _profile['ATK']['ATK'] = 1.2 + _bonus

        _equip = Equippable(slot=Bodyparts.MainHand.name, profile=_profile)

        _profile = {}
        _profile = example_profile()
        _profile['ATK']['ATK'] = 1.6 + _bonus
        _profile['ATK']['SPD'] = 0.2 + _bonus

        _skill = Skill(cooldown=5,
                       name='pierce',
                       nature='direct',
                       profile=_profile)

    return _base, _equip, _skill
Beispiel #3
0
    def reset(self) -> None:
        """
        Resets game to prepare for a generation
        :return: None
        """

        self.score = 0

        self.gen += 1

        self.birds = []

        self.pipes = [Pipe(WIN_WIDTH)]
        self.base = Base(FLOOR_HEIGHT)
Beispiel #4
0
def create_monster(name):
    _base = Base(name='player',
                 char='@',
                 color=libtcod.white,
                 render_order=RenderOrder.ACTOR)
    _body = Body()
    _health = Health()
    _inv = Inventory()
    _job = Job.BARBARIAN
    _pos = Position()
    _race = Race.HUMAN
    _soul = Soul(eccentricity=5, rank=10)
    _status = Status()

    monster = Entity(base=_base,
                     body=_body,
                     health=_health,
                     inv=_inv,
                     job=_job,
                     pos=_pos,
                     race=_race,
                     soul=_soul,
                     status=_status)
    monster.health.points = monster.health.max

    return monster
Beispiel #5
0
def create_stairs():
    _base = Base(name='stairs',
                 char=u'\u2261',
                 color=libtcod.black,
                 render_order=RenderOrder.STAIRS)
    _pos = Position()

    return Entity(base=_base, pos=_pos)
Beispiel #6
0
def create_torso_item(name, material):
    _bonus = material_dict[material][0]
    _color = material_dict[material][1]
    _name = material.capitalize() + ' ' + name.capitalize()

    _base, _equip, _skill = None, None, None

    if name == 'chain mail':
        _base = Base(name=_name,
                     char=u'\u2593',
                     color=_color,
                     render_order=RenderOrder.ITEM)

        _profile = {}
        _profile = example_profile()
        _profile['DEF']['DEF'] = 1.2 + _bonus
        _profile['MAG']['MAG'] = 1.0 + _bonus

        _equip = Equippable(slot=Bodyparts.Torso.name, profile=_profile)

        _skill = Skill()

    if name == 'plate mail':
        _base = Base(name=_name,
                     char=u'\u2588',
                     color=_color,
                     render_order=RenderOrder.ITEM)

        _profile = {}
        _profile = example_profile()
        _profile['DEF']['DEF'] = 1.9 + _bonus
        _profile['MAG']['MAG'] = 0.7 + _bonus

        _equip = Equippable(slot=Bodyparts.Torso.name, profile=_profile)

        _skill = Skill()

    return _base, _equip, _skill
Beispiel #7
0
def create_head_item(name, material):
    _bonus = material_dict[material][0]
    _color = material_dict[material][1]
    _name = material.capitalize() + ' ' + name.capitalize()
    _base, _equip, _skill = None, None, None

    if name == 'helm':
        _base = Base(name=_name,
                     char=u'\u00A3',
                     color=_color,
                     render_order=RenderOrder.ITEM)
        _equip = Equippable(slot=Bodyparts.Head.name)
        _skill = Skill()

    if name == 'cap':
        _base = Base(name=_name,
                     char=u'\u207F',
                     color=_color,
                     render_order=RenderOrder.ITEM)
        _equip = Equippable(slot=Bodyparts.Head.name)
        _skill = Skill(cooldown=10, name='healing buff', nature='direct')

    return _base, _equip, _skill
Beispiel #8
0
    def __init__(self, draw_lines=True):
        """
        Initialise the game object
        :param draw_lines: defines whether to draw lines from bird to pipe, defaults to True
        """

        self.draw_lines = draw_lines

        self.score = 0
        self.max_score = 0

        self.gen = 0
        self.clock = pygame.time.Clock()

        self.birds = []  # birds list

        self.pipes = [Pipe(WIN_WIDTH)]
        self.base = Base(FLOOR_HEIGHT)

        self.window = pygame.display.set_mode((WIN_WIDTH, WIN_HEIGHT))

        self.LINE_THICKNESS = 1
        self.tick_rate = 30
Beispiel #9
0
def create_ring_finger_item(name, material):
    _bonus = material_dict[material][0]
    _color = material_dict[material][1]
    _name = material.capitalize() + ' ' + name.capitalize()
    _base, _equip, _skill = None, None, None

    if name == 'ring':
        _base = Base(name=_name,
                     char=u'\u00F6',
                     color=_color,
                     render_order=RenderOrder.ITEM)
        _equip = Equippable(slot=Bodyparts.Head.name)
        _skill = Skill()

    return _base, _equip, _skill
Beispiel #10
0
def create_feet_item(name, material):
    _bonus = material_dict[material][0]
    _color = material_dict[material][1]
    _name = material.capitalize() + ' ' + name.capitalize()
    _base, _equip, _skill = None, None, None

    if name == 'boots':
        _base = Base(name=_name,
                     char=u'\u221F',
                     color=_color,
                     render_order=RenderOrder.ITEM)
        _equip = Equippable(slot=Bodyparts.Feet.name)
        _skill = Skill(cooldown=5, name='leap', nature='direct')

    return _base, _equip, _skill
Beispiel #11
0
def create_soul(entity):
    _soul_rank = entity.soul.rank
    _soul_eccentricity = entity.soul.eccentricity
    _soul_number = entity.soul.soul

    _soul = Soul(_soul_eccentricity, _soul_rank)
    _soul.number = _soul_number

    _base = Base(name='soul',
                 char='*',
                 color=libtcod.dark_green,
                 render_order=RenderOrder.SOUL)
    _pos = Position()

    soul_item = Entity(base=_base, pos=_pos, soul=_soul)

    return soul_item
Beispiel #12
0
def create_monster_(difficulty):
    _rank = pick_rank(difficulty)
    _race = pick_race(difficulty)
    _job = pick_job(_race)

    _ai = AI(brain=BRAIN.ZOMBIE)
    _body = Body()
    _health = Health()
    _pos = Position()
    _soul = Soul(eccentricity=_race.value['eccentricity'],
                 rank=_rank.value['rank'])
    _status = Status()

    _name = str(_rank.value['name']).capitalize() + ' ' + str(
        _race.value['name']).capitalize() + ' ' + str(
            _job.value['name']).capitalize()
    _color = _rank.value['color']
    _char = _race.value['char']

    _base = Base(name=_name,
                 char=_char,
                 color=_color,
                 render_order=RenderOrder.ACTOR)

    monster = Entity(ai=_ai,
                     base=_base,
                     body=_body,
                     health=_health,
                     job=_job,
                     pos=_pos,
                     race=_race,
                     soul=_soul,
                     status=_status)
    monster.health.points = monster.health.max

    equip_monster(monster)

    return monster
Beispiel #13
0
class Game:
    """
    Game object
    """
    def __init__(self, draw_lines=True):
        """
        Initialise the game object
        :param draw_lines: defines whether to draw lines from bird to pipe, defaults to True
        """

        self.draw_lines = draw_lines

        self.score = 0
        self.max_score = 0

        self.gen = 0
        self.clock = pygame.time.Clock()

        self.birds = []  # birds list

        self.pipes = [Pipe(WIN_WIDTH)]
        self.base = Base(FLOOR_HEIGHT)

        self.window = pygame.display.set_mode((WIN_WIDTH, WIN_HEIGHT))

        self.LINE_THICKNESS = 1
        self.tick_rate = 30

    def reset(self) -> None:
        """
        Resets game to prepare for a generation
        :return: None
        """

        self.score = 0

        self.gen += 1

        self.birds = []

        self.pipes = [Pipe(WIN_WIDTH)]
        self.base = Base(FLOOR_HEIGHT)

    @staticmethod
    def should_quit(events) -> bool:
        """
        Determines if we should quit the game
        :param events: pygame events
        :return: whether to quit game
        """

        for event in events:
            if event.type == pygame.QUIT:
                return True

        return False

    def draw_window(self, pipe_ind) -> None:
        """
        Draw window with all the elements
        :param pipe_ind: index of upcoming pipe in self.pipes
        :return: None
        """

        # background
        self.window.blit(BG_IMG, (0, 0))

        # pipes
        for pipe in self.pipes:
            pipe.draw(self.window)

        # base
        self.base.draw(self.window)

        # draw lines from bird to pipe
        for bird in self.birds:
            if self.draw_lines:
                try:
                    # line to left corners of pipes
                    pygame.draw.line(
                        self.window, (255, 0, 100),
                        (bird.x + bird.img.get_width() / 2,
                         bird.y + bird.img.get_height() / 2),
                        (self.pipes[pipe_ind].x, self.pipes[pipe_ind].height),
                        self.LINE_THICKNESS)
                    pygame.draw.line(self.window, (255, 0, 100),
                                     (bird.x + bird.img.get_width() / 2,
                                      bird.y + bird.img.get_height() / 2),
                                     (self.pipes[pipe_ind].x,
                                      self.pipes[pipe_ind].y_bottom),
                                     self.LINE_THICKNESS)

                    # line to right corners of pipes
                    pygame.draw.line(
                        self.window, (255, 100, 0),
                        (bird.x + bird.img.get_width() / 2,
                         bird.y + bird.img.get_height() / 2),
                        (self.pipes[pipe_ind].x +
                         self.pipes[pipe_ind].PIPE_TOP_IMG.get_width(),
                         self.pipes[pipe_ind].height), self.LINE_THICKNESS)
                    pygame.draw.line(
                        self.window, (255, 100, 0),
                        (bird.x + bird.img.get_width() / 2,
                         bird.y + bird.img.get_height() / 2),
                        (self.pipes[pipe_ind].x +
                         self.pipes[pipe_ind].PIPE_BOTTOM_IMG.get_width(),
                         self.pipes[pipe_ind].y_bottom), self.LINE_THICKNESS)
                except:
                    pass

            # birds
            bird.draw(self.window)

        # score and max_score
        score_text = STAT_FONT.render('Score: ' + str(self.score), 1,
                                      (255, 255, 255))
        max_score_text = STAT_FONT.render('Max: ' + str(self.max_score), 1,
                                          (255, 255, 255))
        self.window.blit(score_text,
                         (WIN_WIDTH - 10 - score_text.get_width(), 10))
        self.window.blit(max_score_text,
                         (WIN_WIDTH - 10 - max_score_text.get_width(), 50))

        # generation
        score_label = STAT_FONT.render("Gen: " + str(self.gen), 1,
                                       (255, 255, 255))
        self.window.blit(score_label, (10, 10))

        # alive
        score_label = STAT_FONT.render("Alive: " + str(len(self.birds)), 1,
                                       (255, 255, 255))
        self.window.blit(score_label, (10, 50))

        pygame.display.update()

    def init_birds(self, genomes, config) -> None:
        """
        Initialise birds, genomes, neural networks
        :param genomes: genomes
        :param config: nn config
        :return: None
        """

        for genome_id, genome in genomes:
            genome.fitness = 0
            net = neat.nn.FeedForwardNetwork.create(genome, config)

            bird = Bird(230, 350)
            bird.genome = genome
            bird.network = net

            self.birds.append(bird)

    def kill_bird(self,
                  bird,
                  decrease_fitness=True,
                  decrease_amount=3) -> None:
        """
        Kill a bird at index i and decrease fitness if necessary
        :param bird: bird object to be killed
        :param decrease_fitness: whether to decrease fitness
        :param decrease_amount: amount to decrease fitness by
        :return: None
        """

        if decrease_fitness:
            bird.genome.fitness -= decrease_amount

        # remove birds from lists
        self.birds.remove(bird)

    def increase_fitness(self) -> None:
        """
        Increase fitness of all birds alive
        :return: None
        """

        for bird in self.birds:
            bird.genome.fitness += 5

    def make_birds_jump(self, pipe_ind) -> None:
        """
        Make birds jump based on output from neural network
        :param pipe_ind: index of upcoming pipe
        :return: None
        """

        for bird in self.birds:
            bird.genome.fitness += 1
            bird.move()

            output = bird.network.activate(
                (bird.y, abs(bird.y - self.pipes[pipe_ind].y_bottom),
                 abs(bird.y - self.pipes[pipe_ind].height),
                 abs(bird.x - self.pipes[pipe_ind].x),
                 abs(bird.x - self.pipes[pipe_ind].x -
                     self.pipes[pipe_ind].PIPE_BOTTOM_IMG.get_width())))

            # if output value is more than the min threshold to jump, jump
            if output[0] > MIN_JUMP_THRESHOLD:
                bird.jump()

    def get_pipe_ind(self) -> int:
        """
        Get the index of the upcoming pipe
        :return: index of upcoming pipe
        """

        pipe_ind = 0
        if len(self.birds) > 0 and len(
                self.pipes
        ) > 1 and self.birds[0].x + self.pipes[0].PIPE_TOP_IMG.get_width():
            pipe_ind = 1

        return pipe_ind

    def add_score_and_update_fitness(self):
        self.score += 1

        if self.max_score < self.score:
            self.max_score = self.score

        self.increase_fitness()
        self.pipes.append(Pipe(WIN_WIDTH))

    def move_pipes_and_collision_detection(self) -> list:
        """
        Move pipes and perform collision detection with birds.
        :return: if pipe has passed, list of pipes to remove
        """

        removed_pipes = []
        passed_pipe = False

        for pipe in self.pipes:
            pipe.move()

            # collision detection with pipe
            for bird in self.birds:
                if pipe.collide(bird):
                    self.kill_bird(bird, decrease_fitness=True)

            if not pipe.passed and pipe.x + pipe.PIPE_TOP_IMG.get_width(
            ) < bird.x:
                pipe.passed = True

                if not passed_pipe:
                    passed_pipe = True

            if pipe.x + pipe.PIPE_TOP_IMG.get_width() < 0:
                # pipe is offscreen, remove this pipe
                removed_pipes.append(pipe)

        if passed_pipe:
            self.add_score_and_update_fitness()

        return removed_pipes

    def update_birds(self) -> None:
        """
        Kill birds that are touching the ceiling or the floor
        :return: None
        """

        for bird in self.birds:
            if bird.y + bird.img.get_height(
            ) - 10 >= FLOOR_HEIGHT or bird.y < -50:
                self.kill_bird(bird, decrease_fitness=True)

    def update_pipes_and_score(self, removed_pipes) -> None:
        """
        Remove pipes that are offscreen
        :param removed_pipes: list of pipes to be removed
        :return: None
        """

        for removed in removed_pipes:
            self.pipes.remove(removed)

    def start(self, genomes, config) -> None:
        """
        Initialise and start game
        :param genomes: genomes
        :param config: nn config
        :return: None
        """

        self.init_birds(genomes, config)
        self.game()

    def quit_game(self) -> None:
        """
        Quit game
        :return: None
        """

        print('Max score reached:', self.max_score)
        pygame.quit()
        quit()

    def game(self) -> None:
        """
        Start game
        :return: None
        """

        run = True
        while run and len(self.birds) > 0:
            self.clock.tick(self.tick_rate)

            if self.should_quit(pygame.event.get()):
                run = False
                self.quit_game()
                break

            # move ground
            self.base.move()

            # get appropriate pipe index depending on position of pipes
            pipe_ind = self.get_pipe_ind()

            # make birds jump
            self.make_birds_jump(pipe_ind)

            # move pipes and determine if birds have collided with pipe
            removed_pipes = self.move_pipes_and_collision_detection()

            # remove birds that have hit the ground or ceiling
            self.update_birds()

            # update pipes list and score
            self.update_pipes_and_score(removed_pipes)

            # re-render window
            self.draw_window(pipe_ind)

        self.reset()