def poison_check(self, game_frame):
        image_data = skimage.io.imread("plugins/SerpentSlayTheSpireGamePlugin/files/data/sprites/sprite_poison_check_0.png")[..., np.newaxis]

        poison_check = Sprite("poison_check", image_data=image_data)

        # # Full game frame capture
        # print("-----------Full game frame capture-----------")
        # full_game_frame = FrameGrabber.get_frames(
        #     [0],
        #     frame_shape=(self.game.frame_height, self.game.frame_width),
        #     frame_type="PIPELINE"
        # ).frames[0]

        sprite_locator = SpriteLocator()

        poison_check_location = sprite_locator.locate(sprite=poison_check, game_frame=game_frame)
        
        print("poison_check_location: ", poison_check_location)

        if (poison_check_location != None):
            self.game_state["poison_check"].insert(0, True)
            print("POISON_CHECK == TRUE")

        else:
            self.game_state["poison_check"].insert(0, False)
            print("POISON_CHECK == FALSE")

        self.ddqn_setup(game_frame)
    def _measure_actor_hp(self, game_frame):
        hp_area_frame = serpent.cv.extract_region_from_image(
            game_frame.frame, self.game.screen_regions["HP_AREA"])
        hp_area_image = Image.fromarray(hp_area_frame)

        actor_hp = 0

        image_colors = hp_area_image.getcolors(
        )  # TODO: remove in favor of sprite detection and location
        if image_colors:
            actor_hp = len(image_colors) - 7

        for name, sprite in self.game.sprites.items():
            query_sprite = Sprite("QUERY", image_data=sprite.image_data)
            sprite_name = self.sprite_identifier.identify(
                query_sprite, mode="CONSTELLATION_OF_PIXELS"
            )  # Will be "UNKNOWN" if no match
            print(sprite_name)
            sprite_to_locate = Sprite("QUERY", image_data=sprite.image_data)

            sprite_locator = SpriteLocator()
            location = sprite_locator.locate(sprite=sprite_to_locate,
                                             game_frame=game_frame)
            print(location)
            if location:
                actor_hp = 1000000

        return actor_hp
Exemplo n.º 3
0
    def __init__(self, **kwargs):
        super().__init__(**kwargs)

        self.frame_handlers["PLAY"] = self.handle_play

        self.frame_handler_setups["PLAY"] = self.setup_play

        self.printer = TerminalPrinter()
        self.sprite_locator = SpriteLocator()
Exemplo n.º 4
0
    def identify_sprite(self, sprite, game_frame):
        # sprite_identifier = SpriteIdentifier()
        sprite_identify = self.sprite_identifier.identify(
            sprite=sprite, mode="SIGNATURE_COLORS")

        sprite_locator = SpriteLocator()
        location = sprite_locator.locate(sprite=sprite, game_frame=game_frame)

        output = {'sprite_name': sprite_identify, 'location': location}
        return output
    def __init__(self, **kwargs):
        super().__init__(**kwargs)

        self.frame_handlers["PLAY"] = self.handle_play

        self.frame_handler_setups["PLAY"] = self.setup_play

        self.sprite_locator = SpriteLocator()

        self.game_state = None
        self._reset_game_state()
    def __init__(self, game=None):
        self.game = game

        self.mouse_buttons = {
            MouseButton.LEFT.name: "left",
            MouseButton.MIDDLE.name: "middle",
            MouseButton.RIGHT.name: "right"
        }

        self.previous_key_collection_set = set()

        self.sprite_locator = SpriteLocator()
    def __init__(self, game=None):
        super().__init__(game=game)

        self.navigationGameFSM = NavigationGameFSM()

        self._prepare_sprites()

        self.WIDTH = 34
        self.HEIGHT = 32
        self.n_WIDTH = 2
        self.n_HEIGHT = 2

        self.MARIO = 1
        self.MOVING_ENTITY = 2
        self.LADDER = 3
        self.LADDER_DELTA = 18

        self.LEVEL_WIN_HEIGHT = 32

        self.sprite_locator = SpriteLocator()

        self.ladders_positions = dict()
        self.ladders_positions[0] = [453, 10000]
        self.ladders_positions[1] = [102, 249]
        self.ladders_positions[2] = [285, 452]
        self.ladders_positions[3] = [104, 194]
        self.ladders_positions[4] = [452, 10000]
        self.ladders_positions[5] = [324, 10000]

        self.on_ladders = dict()
        self.on_ladders[(0, 453)] = [374, 328]
        self.on_ladders[(1, 102)] = [312, 268]
        self.on_ladders[(1, 249)] = [318, 262]
        self.on_ladders[(2, 285)] = [258, 202]
        self.on_ladders[(2, 452)] = [252, 208]
        self.on_ladders[(3, 104)] = [192, 148]
        self.on_ladders[(3, 194)] = [196, 144]
        self.on_ladders[(4, 452)] = [133, 88]
        self.on_ladders[(5, 324)] = [81, 32]

        self.last_stage = 0
        self.max_stage = 0
        self.last_change_stage = 0
        self.useless_actions = 0

        self.level_direction = dict()
        orientation = 1
        for i in range(6):
            self.level_direction[i] = orientation
            orientation = orientation * (-1)

        self.ladders_thresholds = [384, 328, 268, 208, 148, 88]
    def __init__(self, **kwargs):
        super().__init__(**kwargs)

        self.frame_handlers["PLAY"] = self.handle_play
        self.frame_handlers["PLAY_BOT"] = self.handle_play_bot

        self.frame_handler_setups["PLAY"] = self.setup_play
        self.frame_handler_setups["PLAY_BOT"] = self.setup_play

        self.analytics_client = None

        self.sprite_locator = SpriteLocator()

        self.username_entered = False
Exemplo n.º 9
0
    def check_game_state(self, game_frame):
        #game over?
        locationGO = None
        sprite_to_locate = Sprite("QUERY", image_data=self.spriteGO.image_data)
        sprite_locator = SpriteLocator()
        locationGO = sprite_locator.locate(sprite=sprite_to_locate,
                                           game_frame=game_frame)
        print("Location Game over:", locationGO)
        #won game?
        locationWO = None
        sprite_to_locate = Sprite("QUERY", image_data=self.spriteWO.image_data)
        sprite_locator = SpriteLocator()
        locationWO = sprite_locator.locate(sprite=sprite_to_locate,
                                           game_frame=game_frame.frames)
        print("Location Game won:", locationWO)

        self.gamestate.girl_alive = (locationGO == None and locationWO == None)
        self.gamestate.done = not self.gamestate.girl_alive
        self.gamestate.victory = locationWO != None

        print(f"Is alive? {self.gamestate.girl_alive}")
        print(f"Game over? {self.gamestate.lose}")
        print(f"Won? {self.gamestate.victory}")
Exemplo n.º 10
0
    def _measure_actor_hp(self, game_frame):
        hp_area_frame = serpent.cv.extract_region_from_image(
            game_frame.frame, self.game.screen_regions["HP_AREA"])
        hp_area_image = Image.fromarray(hp_area_frame)

        actor_hp = 0

        image_colors = hp_area_image.getcolors(
        )  # TODO: remove in favor of sprite detection and location
        if image_colors:
            actor_hp = len(image_colors) - 7

        for name, sprite in self.game.sprites.items():
            sprite_to_locate = Sprite("QUERY", image_data=sprite.image_data)

            sprite_locator = SpriteLocator()
            location = sprite_locator.locate(sprite=sprite_to_locate,
                                             game_frame=game_frame)
            print(location)
            if location:
                actor_hp = 1000000

        return actor_hp
    def __init__(self, game=None, **kwargs):
        self.game = game

        self.previous_key_collection_set = set()

        self.sprite_locator = SpriteLocator()
Exemplo n.º 12
0
 def find_sprite(self, sprite_name):
     sprite_locator = SpriteLocator()
     location = sprite_locator.locate(sprite=self.game.sprites[sprite_name],
                                      game_frame=self.game_frame)
     return location  # None if not found
from serpent.game_agent import GameAgent
from serpent.input_controller import KeyboardKey
from serpent.sprite_locator import SpriteLocator
from serpent.frame_grabber import FrameGrabber
from serpent.config import config
import serpent.utilities
from serpent.machine_learning.reinforcement_learning.ddqn import DDQN
from serpent.machine_learning.reinforcement_learning.keyboard_mouse_action_space import KeyboardMouseActionSpace
sprite_locator = SpriteLocator()
import serpent.cv
import time
import cv2
import skimage.io
import skimage.filters
import skimage.morphology
import skimage.measure
import skimage.draw
import skimage.segmentation
import skimage.color
import os
import gc
from datetime import datetime
import collections
import numpy as np
from .helpers.memory import readhp
from colorama import init
init()
from colorama import Fore, Style


class SerpentRoboGameAgent(GameAgent):
Exemplo n.º 14
0
    def handle_play(self, game_frame):
        #self.printer.add("")
        #self.printer.add("BombermanAI")
        #self.printer.add("Reinforcement Learning: Training a PPO Agent")
        #self.printer.add("")
        #self.printer.add(f"Stage Started At: {self.started_at}")
        #self.printer.add(f"Current Run: #{self.current_attempts}")
        #self.printer.add("")
        #self.check_game_state(game_frame)

        #####################CHECK STATE###########################
        #game over?
        locationGO = None
        sprite_to_locate = Sprite("QUERY", image_data=self.spriteGO.image_data)
        sprite_locator = SpriteLocator()
        locationGO = sprite_locator.locate(sprite=sprite_to_locate,
                                           game_frame=game_frame)
        #print("Location Game over:",locationGO)

        #won game?
        locationWO = None
        sprite_to_locate = Sprite("QUERY", image_data=self.spriteWO.image_data)
        sprite_locator = SpriteLocator()
        locationWO = sprite_locator.locate(sprite=sprite_to_locate,
                                           game_frame=game_frame)
        #print("Location Game won:",locationWO)

        self.gamestate.victory = locationWO != None
        self.gamestate.lose = locationGO != None
        self.gamestate.girl_alive = (locationGO == None and locationWO == None)
        self.gamestate.done = not self.gamestate.girl_alive

        print(f"Is alive? {self.gamestate.girl_alive}")
        print(f"Game over? {self.gamestate.lose}")
        print(f"Won? {self.gamestate.victory}")
        #####################VISUAL DEBUGGER###########################
        for i, game_frame in enumerate(self.game_frame_buffer.frames):
            self.visual_debugger.store_image_data(game_frame.frame,
                                                  game_frame.frame.shape,
                                                  str(i))

        #####################MODEL###########################
        #get buffer
        frame_buffer = FrameGrabber.get_frames([0, 1, 2, 3],
                                               frame_type="PIPELINE")
        game_frame_buffer = self.extract_game_area(frame_buffer)
        state = game_frame_buffer.reshape(4, 104, 136, 1)

        if (self.gamestate.done):
            print(f"Game over, attemp {self.epoch}")
            if (self.epoch % 10) == 0:
                print("saving model")
                self.dqn_agent.save_model(
                    f"bombergirl_epoch_{self.epoch}.model")
                self.printer.save_file()
            self.printer.add(
                f"{self.gamestate.victory},{self.gamestate.lose},{self.epoch},{self.gamestate.time},{self.total_reward}"
            )
            self.total_reward = 0
            self.dqn_agent.remember(self.prev_state, self.prev_action,
                                    self.prev_reward, state, True)
            self.dqn_agent.replay()
            self.input_controller.tap_key(KeyboardKey.KEY_ENTER)
            self.epoch += 1
            self.total_reward = 0
            self.gamestate.restartState()
            self.prev_state = None
            self.prev_action = None
        else:
            #update time
            self.gamestate.updateTime()

            #print(np.stack(game_frame_buffer,axis=1).shape)
            #print(game_frame_buffer.shape)
            #print(state.shape)
            if (not (self.prev_state is None)
                    and not (self.prev_action is None)):
                self.dqn_agent.remember(self.prev_state, self.prev_action,
                                        self.prev_reward, state, False)

            #do something
            action_index = self.dqn_agent.act(state)
            #get key
            action = self.game_actions[action_index]
            #get random frame from buffer
            game_frame_rand = random.choice(frame_buffer.frames).frame
            #update enviroment accorind to frame
            ###################FUN UPDATE STATE#########################################
            game_area = \
                    serpent.cv.extract_region_from_image(game_frame_rand,self.game.screen_regions['GAME_REGION'])
            #game ...
            # 0,0
            # 32,32
            game_squares = [[None for j in range(0, 11)] for i in range(0, 15)]
            const_offset = 8
            const = 32
            #game variables
            self.gamestate.bombs = []  #{x, y}
            self.gamestate.enemies = []  #{x,y}
            #force girl to die if not found
            girl_found = False
            for i in range(0, 15):
                for j in range(0, 11):
                    izq = ((j + 1) * const - const_offset,
                           (i + 1) * const - const_offset)
                    der = ((j + 2) * const + const_offset,
                           (i + 2) * const + const_offset)
                    reg = (izq[0], izq[1], der[0], der[1])
                    square = serpent.cv.extract_region_from_image(
                        game_area, reg)
                    square = self.convert_to_rgba(square)
                    sprite_to_locate = Sprite("QUERY",
                                              image_data=square[...,
                                                                np.newaxis])
                    sprite = self.sprite_identifier.identify(
                        sprite_to_locate, mode="SIGNATURE_COLORS")
                    game_squares[i][j] = sprite
                    if ("SPRITE_BETTY" in sprite):
                        self.girl = {"x": i, "y": j}
                        girl_found = True
                    elif ("SPRITE_GEORGE" in sprite):
                        self.gamestate.enemies.append({"x": i, "y": j})
                    elif ("SPRITE_BOMB" in sprite):
                        self.gamestate.bombs.append({"x": i, "y": j})
                    elif ("SPRITE_BONUSES" in sprite):
                        self.gamestate.bonus.append({"x": i, "y": j})
            #####################CHECK STATE###########################
            #game over?
            locationGO = None
            sprite_to_locate = Sprite("QUERY",
                                      image_data=self.spriteGO.image_data)
            sprite_locator = SpriteLocator()
            locationGO = sprite_locator.locate(sprite=sprite_to_locate,
                                               game_frame=game_frame)
            #print("Location Game over:",locationGO)

            #won game?
            locationWO = None
            sprite_to_locate = Sprite("QUERY",
                                      image_data=self.spriteWO.image_data)
            sprite_locator = SpriteLocator()
            locationWO = sprite_locator.locate(sprite=sprite_to_locate,
                                               game_frame=game_frame)
            #print("Location Game won:",locationWO)

            self.gamestate.lose = locationGO != None
            self.gamestate.victory = locationWO != None
            self.gamestate.girl_alive = (locationGO == None
                                         and locationWO == None)
            self.gamestate.done = not self.gamestate.girl_alive

            print(f"Is alive? {self.gamestate.girl_alive}")
            print(f"Game over? {self.gamestate.lose}")
            print(f"Won? {self.gamestate.victory}")

            ###################REWARD#########################################

            #get reward
            reward = self.gamestate.getReward(action_index)
            self.total_reward += reward
            self.prev_state = state
            self.prev_action = action_index
            self.prev_reward = reward

            if (action):
                self.input_controller.tap_key(
                    action, 0.15 if action_index < 4 else 0.01)
            print(
                f"Action: {self.gamestate.game_inputs[action_index]}, reward: {reward}, total_reward: {self.total_reward}"
            )
    def enemy_action_capture(self, game_frame):
        final_cultist_attack = []
        attack_cultist_temp_list= []

        # Unselect anything just incase
        self.input_controller.click(button=MouseButton.RIGHT, duration=0.25)
        time.sleep(.5)

        # Home hover
        self.input_controller.move(x=636, y=375, duration=0.25, absolute=True)
        time.sleep(1)

        # Enemy hover
        self.input_controller.move(x=959, y=410, duration=0.25, absolute=True)

        time.sleep(.75)

        image_data = skimage.io.imread("plugins/SerpentSlayTheSpireGamePlugin/files/data/sprites/sprite_Attack_for_0.png")[..., np.newaxis]

        attack_for_cultist = Sprite("attack_for_cultist", image_data=image_data)

        # Full game frame capture
        # print("-----------Full game frame capture-----------")
        # full_game_frame = FrameGrabber.get_frames(
        #     [0],
        #     frame_shape=(self.game.frame_height, self.game.frame_width),
        #     frame_type="PIPELINE"
        # ).frames[0]

        # Allows for dynamic capture of enemy attack
        sprite_locator = SpriteLocator()
        
        attack_for_cultist_location = sprite_locator.locate(sprite=attack_for_cultist, game_frame=game_frame)
        
        print("attack_for_cultist_location: ", attack_for_cultist_location)

        # Tuples are immutable :(
        if (attack_for_cultist_location != None):
            attack_cultist_temp_list = list(attack_for_cultist_location)

            attack_cultist_temp_list[1] = attack_cultist_temp_list[1] + 45
            attack_cultist_temp_list[3] = attack_cultist_temp_list[3] + 15

            attack_for_cultist_location = tuple(attack_cultist_temp_list)

            print("Updated - attack_for_cultist_location: ", attack_for_cultist_location)
            time.sleep(1)

            cultist_attack = serpent.cv.extract_region_from_image(game_frame.frame, attack_for_cultist_location)
            cultist_attack_grayscale = np.array(skimage.color.rgb2gray(cultist_attack) * 255, dtype="uint8")

            cultist_attack = serpent.ocr.perform_ocr(image=cultist_attack_grayscale, scale=15, order=5, horizontal_closing=2, vertical_closing=1)
            
            # This is actually an awkward work around for limitations in how tesseract works.  By default it doesn't capture single char values so when dynamically 
            # searching and capturing the enemy attack the region it's looking for the region that includes the word "for " + attack value (i.e. "for 6").  There 
            # are ways of swapping the mode of tesseract to do a capture for single char values but because the attack values are dynamic it sometimes is 
            # less than 10 or much greater than 10 which is now multiple char's and messes with the capture. For the sake of just getting it working I did this

            # TLDR: Awkward workaround for limitation in tesseract when capturing single char values.  Likely easier way to capture then parse attack value
            for elem in cultist_attack:
                if (elem.isdigit() == True):
                    final_cultist_attack.append(elem)
                    print("final_cultist_attack", final_cultist_attack)

            final_cultist_attack = ''.join(final_cultist_attack)

            print("final_cultist_attack: ", final_cultist_attack)
            print("------------------------------------")
        
            self.game_state["final_cultist_attack"].insert(0, final_cultist_attack)

            self.poison_check(game_frame)

        else:
            return print("Failed to capture enemy attack")