def __init__(self): super(T4Env, self).__init__() # Define action and observation space # They must be gym.spaces objects # Example when using discrete actions: self.action_space = spaces.Discrete(2) # Example for using image as input: self.game = serpent.initialize_game('T4v2') game_frame = self.game.screen_regions['GAME_REGION'] width = game_frame[2] - game_frame[0] height = game_frame[3] - game_frame[1] self.observation_space = spaces.Box(low=0, high=255, shape=(int(width / 2), int(height / 2), 1), dtype=np.uint8) self.game.launch() self.input_controller = InputController(game=self.game) self.sell_point = (671, 447) self.buy_point = (669, 476) self.visual_debugger = VisualDebugger() self.scraper = T4Scraper(game=self.game, visual_debugger=self.visual_debugger)
async def onJoin(self, details): self.redis_client = await self._initialize_redis_client() game_class_name = await self.redis_client.get("SERPENT:GAME") game_class = offshoot.discover("Game")[game_class_name.decode("utf-8")] game = game_class() game.launch(dry_run=True) backend_string = config["input_controller"]["backend"] backend = InputControllers.NATIVE_WIN32 if is_windows( ) else InputControllers.PYAUTOGUI if backend_string != "DEFAULT": try: backend = InputControllers[backend_string] except KeyError: pass self.input_controller = InputController(game=game, backend=backend) while True: payload = await self.redis_client.brpop( config["input_controller"]["redis_key"]) payload = pickle.loads(payload[1]) input_controller_func_string, *args, kwargs = payload getattr(self.input_controller, input_controller_func_string)(*args, **kwargs) await asyncio.sleep(0.01)
class T4Env(gym.Env): metadata = {'render.modes': ['human']} def __init__(self): super(T4Env, self).__init__() # Define action and observation space # They must be gym.spaces objects # Example when using discrete actions: self.action_space = spaces.Discrete(2) # Example for using image as input: self.observation_space = spaces.Box(low=0, high=255, shape=(0, 0, 0), dtype=np.uint8) self.game = serpent.initialize_game('T4v2') self.game.launch() self.input_controller = InputController(game=self.game) self.sell_point = (671, 447) self.buy_point = (669, 476) self.visual_debugger = VisualDebugger() self.scraper = T4Scraper(game=self.game, visual_debugger=self.visual_debugger) def step(self, action): pass # Execute one time step within the environment def reset(self): pass # Reset the state of the environment to an initial state def render(self, mode='human', close=False): pass # Render the environment to the screen def click(self): self.game.launch() self.input_controller.move(x=self.buy_point[0], y=self.buy_point[1]) self.input_controller.click()
def __init__(self, game=None): self.game = game if not self.game.is_launched: self.game.launch(dry_run=True) self.input_controller = InputController(game=game) self.game_inputs = dict() self.__class__.instance = self
def __init__(self): super(T4Env, self).__init__() # Define action and observation space # They must be gym.spaces objects # Example when using discrete actions: self.action_space = spaces.Discrete(2) # Example for using image as input: self.observation_space = spaces.Box(low=0, high=255, shape=(0, 0, 0), dtype=np.uint8) self.game = serpent.initialize_game('T4v2') self.game.launch() self.input_controller = InputController(game=self.game) self.sell_point = (671, 447) self.buy_point = (669, 476) self.visual_debugger = VisualDebugger() self.scraper = T4Scraper(game=self.game, visual_debugger=self.visual_debugger)
def play(self, game_agent_class_name=None, frame_handler=None, **kwargs): if not self.is_launched: raise GameError( f"Game '{self.__class__.__name__}' is not running...") game_agent_class = offshoot.discover("GameAgent").get( game_agent_class_name, GameAgent) if game_agent_class is None: raise GameError( "The provided Game Agent class name does not map to an existing class..." ) game_agent = game_agent_class( game=self, input_controller=InputController(game=self)) self.start_frame_grabber() self.redis_client.delete(config["frame_grabber"]["redis_key"]) while self.redis_client.llen( config["frame_grabber"]["redis_key"]) == 0: time.sleep(0.1) self.window_controller.focus_window(self.window_id) while True: self.game_frame_limiter.start() game_frame = self.grab_latest_frame() try: if self.is_focused: game_agent.on_game_frame(game_frame, frame_handler=frame_handler, **kwargs) else: serpent.utilities.clear_terminal() print("PAUSED\n") game_agent.on_pause(frame_handler=frame_handler, **kwargs) time.sleep(1) except Exception as e: raise e # print(e) # time.sleep(0.1) self.game_frame_limiter.stop_and_delay()
def init_constants(game_title=u'阴阳师-网易游戏', move_window=False): global TIRED_SCALE global TIRED_LIMIT global WINDOW_OFFSET global INPUT_CONTROLLER global WINDOW_ATTRIBUTES config = {'window_name': game_title} onmyoji_game = Game(window_name=config['window_name'], move_window=move_window) WINDOW_ATTRIBUTES = onmyoji_game.after_launch() WINDOW_OFFSET = [ WINDOW_ATTRIBUTES['x_offset'] - 12, WINDOW_ATTRIBUTES['y_offset'] - 47, WINDOW_ATTRIBUTES['width'] + WINDOW_ATTRIBUTES['x_offset'], WINDOW_ATTRIBUTES['height'] + WINDOW_ATTRIBUTES['y_offset'] ] INPUT_CONTROLLER = InputController(backend=InputControllers.NATIVE_WIN32, game=onmyoji_game) TIRED_SCALE = 1 TIRED_LIMIT = random.random() * 100
async def onJoin(self, details): #self.redis_client = await self._initialize_redis_client() #game_class_name = await self.redis_client.get("SERPENT:GAME") #game_class = offshoot.discover("Game")[game_class_name.decode("utf-8")] from serpent.game import Game game = Game() #game.launch(dry_run=True) backend_string=config["input_controller"]["backend"] backend = InputControllers.NATIVE_WIN32 if is_windows() else InputControllers.PYAUTOGUI if backend_string != "DEFAULT": try: backend = InputControllers[backend_string] except KeyError: pass self.input_controller = InputController(game=game, backend=backend) #while True: #payload = await self.redis_client.brpop(config["input_controller"]["redis_key"]) #payload = pickle.loads(payload[1]) #input_controller_func_string, *args, kwargs = payload #getattr(self.input_controller, input_controller_func_string)(*args, **kwargs) #await asyncio.sleep(0.01) def input_controller_sub_func(payload): input_controller_func_string, *args, kwargs = payload getattr(self.input_controller, input_controller_func_string)(*args, **kwargs) self.subscribe(input_controller_sub_func, config["input_controller"]["redis_key"]) print("subscribed to topic")
def play(self, game_agent_class_name="GameAgent", frame_handler=None, **kwargs): if not self.is_launched: raise GameError( f"Game '{self.__class__.__name__}' is not running...") self.start_crossbar() time.sleep(3) self.start_input_controller() game_agent_class = offshoot.discover( "GameAgent", selection=game_agent_class_name).get(game_agent_class_name, GameAgent) if game_agent_class is None: raise GameError( "The provided Game Agent class name does not map to an existing class..." ) game_agent = game_agent_class(game=self, input_controller=InputController( game=self, backend=self.input_controller), **kwargs) # Look if we need to auto-append PNG to frame transformation pipeline based on given frame_handler png_frame_handlers = ["RECORD"] if frame_handler in png_frame_handlers and self.frame_transformation_pipeline_string is not None: if not self.frame_transformation_pipeline_string.endswith("|PNG"): self.frame_transformation_pipeline_string += "|PNG" self.start_frame_grabber() self.redis_client.delete(config["frame_grabber"]["redis_key"]) while self.redis_client.llen( config["frame_grabber"]["redis_key"]) == 0: time.sleep(0.1) self.window_controller.focus_window(self.window_id) # Override FPS Config? if frame_handler == "RECORD": self.game_frame_limiter = GameFrameLimiter(fps=10) try: while True: self.game_frame_limiter.start() game_frame, game_frame_pipeline = self.grab_latest_frame() try: if self.is_focused: self.pause_callback_fired = False game_agent.on_game_frame(game_frame, game_frame_pipeline, frame_handler=frame_handler, **kwargs) else: if not self.pause_callback_fired: print("PAUSED\n") game_agent.on_pause(frame_handler=frame_handler, **kwargs) self.pause_callback_fired = True time.sleep(1) except Exception as e: raise e # print(e) # time.sleep(0.1) self.game_frame_limiter.stop_and_delay() except Exception as e: raise e finally: self.stop_frame_grabber() self.stop_input_controller() self.stop_crossbar()
from serpent.input_controller import InputController import sys from serpent.input_controller import KeyboardKey from time import sleep step_keys = [ KeyboardKey.KEY_LEFT_SHIFT, KeyboardKey.KEY_LEFT_CTRL, KeyboardKey.KEY_F ] input_controller = InputController(game=None) command = sys.argv[1] if command is 'f': input_controller.press_keys(step_keys) sleep(0.001) input_controller.release_keys(step_keys)
def handle_play(self, game_frame, test=False): if test: mouse = None else: mouse = InputController(game = self.game) game_reader = GameReader.GameReader("Windows") with io.open(r'Logs\wins.log', 'r') as f: data = [] for line in f.readlines(): string = line.split(' ') data.append((string[-1].strip())) wins, losses, total, prev_oppo = (int)(data[0]), (int)(data[1]), (int)(data[2]), data[3] curr_oppo = prev_oppo hand, turn, board, game_step, mana = game_reader.update_state() if board.enemy: curr_oppo = board.enemy.name if game_step == Step.BEGIN_MULLIGAN: time.sleep(9) mull = HearthstoneAI.get_mulligan(hand.hand) self.mull_card(mouse, hand, mull) while game_step == Step.BEGIN_MULLIGAN: self.mull_card(mouse, hand, mull) print("Waiting for opponent to mulligan") time.sleep(3) hand, turn, board, game_step, mana = game_reader.update_state() elif game_step == Step.FINAL_GAMEOVER: self.start_game(mouse) elif turn: time.sleep(2) t0 = time.time() ## CARD PLAY PHASE # 1. Calculate best chain of cards to play using HearthstoneAI.play_cards # 2. Play first card and wait in case of drawing card # 3. Repeat steps 1-2 chain, val= HearthstoneAI.play_card(hand, mana) playstate = game_reader.friendly_player.tags.get(GameTag.PLAYSTATE, None) game_end = playstate == PlayState.WON or playstate == PlayState.LOST print("Hand: " + str(hand)) print("Play_chain" + str(chain)) timeout = 0 hp = 1 while chain and turn and len(board.ally_minions) != 7 and not game_end and timeout < 11: playstate = game_reader.friendly_player.tags.get(GameTag.PLAYSTATE, None) print("Playstate: " + str(playstate)) self.play_card(mouse, hand.size, chain[0]) hp = chain[0] != -2 time.sleep(1) t3 = time.time() hand, turn, board, game_step, mana = game_reader.update_state(hp) t4 = time.time() print("update state time: " + str(t4-t3)) if mana == 0: break t5 = time.time() chain, val = HearthstoneAI.play_card(hand, mana) print("Hand" + str(hand)) print("Play_chain" + str(chain)) t6 = time.time() print("play_card AI: " + str(t6-t5)) timeout += 1 t1 = time.time() print("PLAY PHASE: " + str(t1-t0)) ## ATTACK PHASE # Attacking strategy: # 1. Calculate chain of attack actions # 2. Execute first attack action and wait (in case of deathrattle summons) # 3. Repeat steps 1-2 until no minions can attack anymore t0 = time.time() timeout = 0 hand, turn, board, game_step, mana = game_reader.update_state() chain = HearthstoneAI.smarter_smorc(board) playstate = game_reader.friendly_player.tags.get(GameTag.PLAYSTATE, None) game_end = playstate == PlayState.WON or playstate == PlayState.LOST print("Attack Chain: " + str(chain)) while chain and turn and not game_end and timeout < 10: self.attack(mouse, len(board.ally_minions), len(board.enemy_minions), chain[0]) time.sleep(1) # Update state timeout += 1 hand, turn, board, game_step, mana = game_reader.update_state() chain = HearthstoneAI.smarter_smorc(board) space = len(board.ally_minions) == 7 playstate = game_reader.friendly_player.tags.get(GameTag.PLAYSTATE, None) game_end = playstate == PlayState.WON or playstate == PlayState.LOST print("Attack Chain: " + str(chain)) t1 = time.time() print("ATTACK PHASE: " + str(t1-t0)) if mana >= 2 and hp: self.hero_power(mouse) self.end_turn(mouse) try: playstate = game_reader.friendly_player.tags.get(GameTag.PLAYSTATE, None) except: time.sleep(3) hand, turn, board, game_step, mana = game_reader.update_state() playstate = game_reader.friendly_player.tags.get(GameTag.PLAYSTATE, None) if playstate == PlayState.WON or playstate == PlayState.LOST: if prev_oppo != curr_oppo: if playstate == PlayState.WON: time.sleep(3) self.concede(mouse, game_reader) wins += 1 elif playstate == PlayState.LOST: losses += 1 total += 1 # print("Win ratio: " + str(wins/total)) with io.open(r'Logs/wins.log', 'w') as f: f.write('Wins: ' + str(wins) + '\n') f.write('Losses: ' + str(losses) + '\n') f.write('Total: ' + str(total) + '\n') f.write('Previous Opponnent: ' + curr_oppo + '\n')
def setup_play(self): mouse = InputController(game = self.game) self.start_game(mouse)
def __init__(self, fake=False, metrics_key='001'): with open('running', 'w') as f: f.write(str(os.getpid())) self._episode_ended = False self.game = serpent.initialize_game('T4TF1') game_frame = self.game.screen_regions['GAME_REGION'] self.width = 10 self.height = 10 self.state_shape = (int(self.height / 2), int(self.width / 2), 1) self._action_spec = array_spec.BoundedArraySpec( shape=(), dtype=np.int32, minimum=0, maximum=1, name='action') self._observation_spec = array_spec.BoundedArraySpec( shape=self.state_shape, dtype=np.float32, minimum=0.0, name='observation') self._state = np.zeros(self.state_shape).astype(np.float32) if fake: return self.interrupted = False self.game.launch() self.game.start_frame_grabber() self.input_controller = InputController(game=self.game) # self.input_proc = self.frame_buffer = FrameGrabber.get_frames([0]) self.frame_buffer = self.extract_game_area(self.frame_buffer) self.width = self.frame_buffer[0].shape[1] self.height = self.frame_buffer[0].shape[0] print('width: %d' % self.width) print('height: %d' % self.height) self.state_shape = (self.height, self.width, 3) self._action_spec = array_spec.BoundedArraySpec( shape=(), dtype=np.int32, minimum=0, maximum=1, name='action') self._observation_spec = array_spec.BoundedArraySpec( shape=self.state_shape, dtype=np.float32, minimum=0.0, name='observation') self._state = np.zeros(self.state_shape).astype(np.float32) # print('created input with pid: %s' % self.input_proc.pid) self.sell_keys = [KeyboardKey.KEY_LEFT_SHIFT, KeyboardKey.KEY_LEFT_CTRL, KeyboardKey.KEY_S] self.buy_keys = [KeyboardKey.KEY_LEFT_SHIFT, KeyboardKey.KEY_LEFT_CTRL, KeyboardKey.KEY_B] self.step_keys = [KeyboardKey.KEY_LEFT_SHIFT, KeyboardKey.KEY_LEFT_CTRL, KeyboardKey.KEY_F] self.visual_debugger = VisualDebugger() self.scraper = T4Scraper(game=self.game, visual_debugger=self.visual_debugger) frame = self.game.grab_latest_frame() self.scraper.current_frame = frame self.pl = 0 self.working_trade = 0 self.current_action = '' self.held = False self.fill_count = 0 self.window_controller = WindowController() self.window_id = self.window_controller.locate_window(".*Mini-Dow .*") # self.window_id = self.window_controller.locate_window(".*S&P .*") self.keys = RedisKeys(metrics_key) # self.redis = redis.Redis(port=6001) self.number_of_trades = 0 self.number_of_wins = 0 self.buys = 0 self.sells = 0 self.holds = 0 self.history = list() self.actions = 0 self.last_action = '' self.previous_write = -1 self.get_metadata() self.active_frame = None self.start_time = time.time() self.step_read_time = 0 self.step_write_time = 0
class T4Env(gym.Env): metadata = {'render.modes': ['human']} def __init__(self): super(T4Env, self).__init__() # Define action and observation space # They must be gym.spaces objects # Example when using discrete actions: self.action_space = spaces.Discrete(2) # Example for using image as input: self.game = serpent.initialize_game('T4v2') game_frame = self.game.screen_regions['GAME_REGION'] width = game_frame[2] - game_frame[0] height = game_frame[3] - game_frame[1] self.observation_space = spaces.Box(low=0, high=255, shape=(int(width / 2), int(height / 2), 1), dtype=np.uint8) self.game.launch() self.input_controller = InputController(game=self.game) self.sell_point = (671, 447) self.buy_point = (669, 476) self.visual_debugger = VisualDebugger() self.scraper = T4Scraper(game=self.game, visual_debugger=self.visual_debugger) def step(self, action): if action == 1: # perform buy self.working_trade = True self.input_controller.move(x=self.buy_point[0], y=self.buy_point[1]) self.input_controller.click() elif action == 2: # perform sell self.working_trade = True self.input_controller.move(x=self.sell_point[0], y=self.sell_point[1]) self.input_controller.click() while self.has_open_positions(): sleep(0.1) frame = FrameGrabber.get_frames([0]).frames[0] self.scraper.current_frame = frame pass reward = self.reward_agent() self.frame_buffer = FrameGrabber.get_frames([0], frame_type="PIPELINE") self.frame_buffer = self.extract_game_area(self.frame_buffer) # states = np.stack( # self.frame_buffer, # axis=2 # ) print('GETTING STATES') # print(states.shape) return self.frame_buffer[0], reward, False, {} def has_open_positions(self): pos, fills = self.scraper.get_position_and_fill_count() if self.working_trade: if pos == 0 and fills == self.fill_count: return True self.working_trade = False self.fill_count = fills if pos > 0: return True return False def reset(self): self.frame_buffer = FrameGrabber.get_frames([0], frame_type="PIPELINE") self.frame_buffer = self.extract_game_area(self.frame_buffer) # states = np.stack( # self.frame_buffer, # axis=2 # ) print('GETTING STATES') print(self.frame_buffer[0]) print(self.frame_buffer[0].shape) return self.frame_buffer[0], 0, False, {} # Reset the state of the environment to an initial state def render(self, mode='human', close=False): pass # Render the environment to the screen def click(self): self.game.launch() self.input_controller.move(x=self.buy_point[0], y=self.buy_point[1]) self.input_controller.click() def reward_agent(self): # get pl for last trade newPL = int(self.scraper.get_pl()) print('old pl: %d' % self.pl) print('new pl: %d' % newPL) print('---') if newPL > self.pl: reward = 1 else: reward = -1 if self.held: reward = 0.25 if self.last_action == self.current_action: reward = 0 self.held = False self.last_action = self.current_action print('REWARD: %d' % reward) self.pl = newPL return reward def extract_game_area(self, frame_buffer): game_area_buffer = [] for game_frame in frame_buffer.frames: game_area = cv.extract_region_from_image( game_frame.grayscale_frame, self.game.screen_regions["GAME_REGION"]) frame = FrameTransformer.rescale(game_area, 0.5) game_area_buffer.append(frame) return game_area_buffer