def get_action(self, gamestate: GameState): self.gamestate = gamestate # get all possible actions actions = Action.get_all_move_commands() # pick an action at random print(self.gamestate.get_player_stats_vector(verbose=True)) return random.choice(self.action_sequence())
async def send_and_receive_command_ws(self, command): # send data to server #print("AWAITING ON WEBSOCKET_1 SEND - sending command: "+str(command)) await self.websocket.send( GameConnection.json_encode(Action.get_execution_repr(command))) # print("POST-AWAITING ON WEBSOCKET_1 SEND") # wait for server to get back await self.get_all_server_messages()
self.client.has_next_action_direct = True def get_game_state(self): return self.client.game_state def start(self): factory = WebSocketClientFactory(config.WebserverConfig.server_uri) factory.protocol = DCSSProtocol #channel_id = DCSSProtocol.get_channel_id() loop = asyncio.get_event_loop() coro = loop.create_connection(factory, config.WebserverConfig.server_ip, config.WebserverConfig.server_port) self.client = loop.run_until_complete(coro) self.has_started = True loop.run_forever() if __name__ == "__main__": commands = Action.get_all_move_commands() game1 = WebSockGame() while game1.has_started: gamestate = game1.get_game_state() # type: GameState print("Agent now at location {}".format(gamestate.get_player_xy())) next_action = random.choice(commands) game1.send_action(next_action) print("Sent action {}".format(next_action)) time.sleep(0.1)
def get_action(self, gamestate: GameState): self.gamestate = gamestate cellmap = self.gamestate.get_cell_map() cellmaprad = cellmap.get_radius_around_agent_cells() print(cellmaprad) currenthp = self.gamestate.player_current_hp maxhp = self.gamestate.player_hp_max autoexplore = self.gamestate.is_exploration_done() autofight = self.gamestate.is_enemy_around() on_stairs = self.gamestate.can_go_down() too_injured = self.gamestate.too_injured() levelup = self.gamestate.leveling_up() print(currenthp) print(maxhp) print(maxhp * .45) print(autofight) print(autoexplore) print(on_stairs) # need to move toward > symbol def what_is_around(): #What can we see? Hoping for more intelligent pathing. cellitems = [] for cell in cellmap.get_xy_to_cells_dict().values(): cellitems.append(cell) return cellitems def path_to_stairs(): cells_with_stairs = [] for cell in cellmap.get_xy_to_cells_dict().values(): if cell.has_stairs_down: cells_with_stairs.append(cell) if len(cells_with_stairs) > 0: player_goal_str = "(playerat {})".format( random.choice(cells_with_stairs)) print(player_goal_str) return player_goal_str else: return False def monster_exists(): cells_with_monsters = [] for cell in cellmap.get_xy_to_cells_dict().values(): if cell.monster: cells_with_monsters.append(cell) if len(cells_with_monsters) > 0: return False else: return True path_to_stairs() what_is_around() autofight = monster_exists() # get all possible actions if too_injured: return Command.REST_AND_LONG_WAIT elif levelup: # Funky, I know, but the save game command a capital S, which is required for the prompt to level strength. return Command.SAVE_GAME_AND_EXIT elif on_stairs: return Command.TRAVEL_STAIRCASE_DOWN # These commands lead to an infinte loop? elif not autofight: return Command.AUTO_FIGHT #elif not autoexplore : # return Command.AUTO_EXPLORE else: actions = Action.get_all_move_commands() # currentaction = self.gamestate.get # # pick an action at random # chosen = random.choice(actions) # if chosen is return random.choice(actions)
def get_action(self, gamestate: GameState): self.gamestate = gamestate # get all possible actions actions = Action.get_all_move_commands() # pick an action at random return random.choice(actions)
async def onOpen(self): print("WebSocket connection open.") # start sending messages every second .. while True: if self._CONNECTED and self._NEEDS_PONG: print("SENDING PONG MESSAGE") pong_msg = {"msg": "pong"} self.sendMessage(json.dumps(pong_msg).encode('utf-8')) self._NEEDS_PONG = False elif self._CONNECTED and self._NEEDS_ENTER: print("SENDING ENTER KEY BECAUSE OF PROMPT") enter_key_msg = {"text": "\r", "msg": "input"} self.sendMessage(json.dumps(enter_key_msg).encode('utf-8')) self._NEEDS_ENTER = False else: if self._CONNECTED and not self._LOGGED_IN: print("SENDING LOGIN MESSAGE") login_msg = { 'msg': 'login', 'username': self.config.agent_name, 'password': self.config.agent_password } self.sendMessage(json.dumps(login_msg).encode('utf-8')) elif self._LOGGED_IN and self._IN_LOBBY and not self._GAME_STARTED: print("SENDING GAME MODE SELECTION MESSAGE") play_game_msg = { 'msg': 'play', 'game_id': self.config.game_id } self.sendMessage(json.dumps(play_game_msg).encode('utf-8')) #### BEGIN SEEDED GAME MENU NAVIGATION #### elif self.config.game_id == 'seeded-web-trunk' and self._IN_GAME_SEED_MENU and not self._SENT_GAME_SEED: print("SENDING GAME SEED") game_seed_msg = { "text": str(config.WebserverConfig.seed), "generation_id": 1, "widget_id": "seed", "msg": "ui_state_sync" } self.sendMessage(json.dumps(game_seed_msg).encode('utf-8')) self._SENT_GAME_SEED = True elif self.config.game_id == 'seeded-web-trunk' and self._SENT_GAME_SEED and not self._CHECKED_BOX_FOR_PREGENERATION: print( "SENDING CHECKMARK TO CONFIRM PREGENERATION OF DUNGEON" ) pregeneration_checkbox_msg = { "checked": True, "generation_id": 1, "widget_id": "pregenerate", "msg": "ui_state_sync" } self.sendMessage( json.dumps(pregeneration_checkbox_msg).encode('utf-8')) self._CHECKED_BOX_FOR_PREGENERATION = True elif self.config.game_id == 'seeded-web-trunk' and self._READY_TO_SEND_SEED_GAME_START and self._SENT_GAME_SEED and self._CHECKED_BOX_FOR_PREGENERATION and not self._SENT_SEEDED_GAME_START: print( "SENDING MESSAGE TO START THE SEEDED GAME WITH CLICK BUTTON MESSAGE" ) start_seeded_game_msg_button = { "generation_id": 1, "widget_id": "btn-begin", "msg": "ui_state_sync" } self.sendMessage( json.dumps(start_seeded_game_msg_button).encode( 'utf-8')) self._SENT_SEEDED_GAME_START = True elif self.config.game_id == 'seeded-web-trunk' and self._SENT_SEEDED_GAME_START and not self._SENT_SEEDED_GAME_START_CONFIRMATION: print( "SENDING MESSAGE TO CONFIRM THE SEEDED GAME WITH CLICK BUTTON MESSAGE" ) confirm_seeded_game_msg_button = { "keycode": 13, "msg": "key" } self.sendMessage( json.dumps(confirm_seeded_game_msg_button).encode( 'utf-8')) self._SENT_SEEDED_GAME_START_CONFIRMATION = True #### END SEEDED GAME MENU NAVIGATION #### #### BEGIN TUTORIAL GAME MENU NAVIGATION #### elif self.config.game_id == 'tut-web-trunk' and self._IN_MENU == Menu.TUTORIAL_SELECTION_MENU: print( "SENDING MESSAGE TO SELECT THE TUTORIAL #{} IN THE TUTORIAL MENU" .format(config.WebserverConfig.tutorial_number)) hotkey = MenuBackgroundKnowledge.tutorial_lesson_number_to_hotkey[ config.WebserverConfig.tutorial_number] tutorial_lesson_selection_message = { "keycode": hotkey, "msg": "key" } self.sendMessage( json.dumps(tutorial_lesson_selection_message).encode( 'utf-8')) self._IN_MENU = Menu.NO_MENU self._CREATED_A_NEW_CHARACTER = True #### END TUTORIAL GAME MENU NAVIGATION #### #### BEGIN TUTORIAL GAME MENU NAVIGATION #### elif self.config.game_id == 'sprint-web-trunk' and self._IN_MENU == Menu.SPRINT_MAP_SELECTION_MENU: print( "SENDING MESSAGE TO SELECT THE TUTORIAL #{} IN THE SPRINT MENU" .format(config.WebserverConfig.tutorial_number)) hotkey = MenuBackgroundKnowledge.sprint_map_letter_to_hotkey[ config.WebserverConfig.sprint_map_letter] sprint_map_selection_message = { "keycode": hotkey, "msg": "key" } self.sendMessage( json.dumps(sprint_map_selection_message).encode( 'utf-8')) self._IN_MENU = Menu.NO_MENU #### END TUTORIAL GAME MENU NAVIGATION #### elif self._GAME_STARTED: if self._IN_MENU == Menu.CHARACTER_CREATION_SELECT_SPECIES and not self._SENT_SPECIES_SELECTION: if self.config.species not in self.species_options.keys( ): print( "ERROR species {} specified in config is not available. Available choices are: {}" .format(self.config.species, self.species_options.keys())) else: species_selection_hotkey = self.species_options[ self.config.species] species_selection_msg = self.get_hotkey_json_as_msg( species_selection_hotkey) print("SENDING SPECIES SELECTION MESSAGE OF: {}". format(species_selection_msg)) self._SENT_SPECIES_SELECTION = True # Right before we send the message, clear the menu - this only fails if the message being sent fails self._IN_MENU = Menu.NO_MENU self.sendMessage( json.dumps(species_selection_msg).encode( 'utf-8')) if self._IN_MENU == Menu.CHARACTER_CREATION_SELECT_BACKGROUND and not self._SENT_BACKGROUND_SELECTION: if self.config.background not in self.background_options.keys( ): print( "ERROR background {} specified in config is not available. Available choices are: {}" .format(self.config.background, self.background_options.keys())) else: background_selection_hotkey = self.background_options[ self.config.background] background_selection_msg = self.get_hotkey_json_as_msg( background_selection_hotkey) print( "SENDING BACKGROUND SELECTION MESSAGE OF: {}". format(background_selection_msg)) self._SENT_BACKGROUND_SELECTION = True self._CREATED_A_NEW_CHARACTER = True # Right before we send the message, clear the menu - this only fails if the message being sent fails self._IN_MENU = Menu.NO_MENU self.sendMessage( json.dumps(background_selection_msg).encode( 'utf-8')) if self._IN_MENU == Menu.CHARACTER_CREATION_SELECT_WEAPON and not self._SENT_WEAPON_SELECTION: if self.config.starting_weapon not in self.weapon_options.keys( ): print( "ERROR weapon {} specified in config is not available. Available choices are: {}" .format(self.config.starting_weapon, self.weapon_options.keys())) else: weapon_selection_hotkey = self.weapon_options[ self.config.starting_weapon] weapon_selection_msg = self.get_hotkey_json_as_msg( weapon_selection_hotkey) print("SENDING WEAPON SELECTION MESSAGE OF: {}". format(weapon_selection_msg)) self._SENT_WEAPON_SELECTION = True # Right before we send the message, clear the menu - this only fails if the message being sent fails self._IN_MENU = Menu.NO_MENU self.sendMessage( json.dumps(weapon_selection_msg).encode( 'utf-8')) if self._PLAYER_DIED and self._IN_MENU == Menu.CHARACTER_INVENTORY_MENU: print( "SENDING ENTER KEY BECAUSE WE ARE IN THE INVENTORY AFTER DEATH MENU" ) enter_key_msg = {"text": "\r", "msg": "input"} self.sendMessage( json.dumps(enter_key_msg).encode('utf-8')) if self._IN_MENU in [ Menu.NO_MENU, Menu.CHARACTER_INVENTORY_MENU, Menu.CHARACTER_ITEM_SPECIFIC_MENU, Menu.ALL_SPELLS_MENU, Menu.ABILITY_MENU, Menu.SKILL_MENU ] and self._RECEIVED_MAP_DATA and not self._BEGIN_DELETING_GAME: self.game_state.draw_cell_map() # the following executes the next action if we are using an instance of Agent to control # sending actions if self.agent: next_action = self.agent.get_action( self.game_state) # If you've gotten to the point of sending actions and a character was not created # then delete game if config has always_start_new_game set to True if config.WebserverConfig.always_start_new_game and not self._CREATED_A_NEW_CHARACTER: self._BEGIN_DELETING_GAME = True elif next_action: print("We are about to send action: {}".format( next_action)) self.sendMessage( json.dumps( Action.get_execution_repr( next_action)).encode('utf-8')) self.last_message_sent = next_action self.actions_sent += 1 else: raise Exception( "next_action is {}".format(next_action)) else: print("Game Connection Does Not Have An Agent") # State machine to abandon character and delete the game if self._BEGIN_DELETING_GAME and not self._SENT_CTRL_Q_TO_DELETE_GAME: # send abandon character and quit game (mimics ctrl-q) abandon_message = {"msg": "key", "keycode": 17} print("SENDING CTRL-Q TO ABANDON CHARACTER") self.sendMessage( json.dumps(abandon_message).encode('utf-8')) self._SENT_CTRL_Q_TO_DELETE_GAME = True elif self._BEGIN_DELETING_GAME and self._SENT_CTRL_Q_TO_DELETE_GAME and not self._SENT_YES_TEXT_TO_DELETE_GAME: # send 'yes' confirmation string confirmation_message = { "text": "yes\r", "msg": "input" } print("SENDING YES CONFIRMATION TO ABANDON CHARACTER") self.sendMessage( json.dumps(confirmation_message).encode('utf-8')) self._SENT_YES_TEXT_TO_DELETE_GAME = True elif self._BEGIN_DELETING_GAME and self._SENT_YES_TEXT_TO_DELETE_GAME and not self._SENT_ENTER_1_TO_DELETE_GAME: # send first enter to clear the menu first_enter_msg = {"text": "\r", "msg": "input"} print( "SENDING FIRST ENTER FOLLOWING TO ABANDON CHARACTER" ) self.sendMessage( json.dumps(first_enter_msg).encode('utf-8')) self._SENT_ENTER_1_TO_DELETE_GAME = True elif self._BEGIN_DELETING_GAME and self._SENT_ENTER_1_TO_DELETE_GAME and not self._SENT_ENTER_2_TO_DELETE_GAME: # send first enter to clear the menu second_enter_msg = {"text": "\r", "msg": "input"} print( "SENDING SECOND ENTER FOLLOWING TO ABANDON CHARACTER" ) self.sendMessage( json.dumps(second_enter_msg).encode('utf-8')) self._SENT_ENTER_2_TO_DELETE_GAME = True elif self._BEGIN_DELETING_GAME and self._SENT_ENTER_2_TO_DELETE_GAME and not self._SENT_ENTER_3_TO_DELETE_GAME: # send first enter to clear the menu third_enter_msg = {"text": "\r", "msg": "input"} print( "SENDING THIRD ENTER FOLLOWING TO ABANDON CHARACTER" ) self.sendMessage( json.dumps(third_enter_msg).encode('utf-8')) self._SENT_ENTER_3_TO_DELETE_GAME = True self.reset_before_next_game() print("About to sleep for delay {}".format( config.WebserverConfig.delay)) await asyncio.sleep(config.WebserverConfig.delay)
async def _send_command_ws(self, command): await self.websocket.send( GameConnection.json_encode(Action.get_execution_repr(command)))
def _send_command(self, command): self._send_message( GameConnection.json_encode(Action.get_execution_repr(command)))