def __init__(self): self.start_time = None self.gui = None self.session = None self.state = None self.running = True self.game_url = None self.config = Config() self.bot = Curses_ui_bot() # Our bot self.states = [] self.delay = 0.5 # Delay in s between turns in replay mode self.victory = 0 self.time_out = 0
def replay(self): """Replay last game""" # Restart with a new bot self.bot = Curses_ui_bot() for i in range(self.config.number_of_games): # start a new game if self.bot.running: self.restart_game() gold = 0 winner = "Noone" for player in self.bot.game.heroes: if int(player.gold) > gold: winner = player.name gold = int(player.gold) self.pprint("**** " + winner + " wins. ****") self.pprint("Game finished: " + str(i + 1) + "/" + str(self.config.number_of_games))
def replay(self): """Replay last game""" # Restart with a new bot self.bot = Curses_ui_bot() for i in range(self.config.number_of_games): # start a new game if self.bot.running: self.restart_game() self.pprint("Game finished.")
def start_game(self): """Starts a game with all the required parameters""" self.running = True # Delete prévious game states self.states = [] # Restart game with brand new bot self.bot = Curses_ui_bot() # Default move is no move ! direction = "Stay" # Create a requests session that will be used throughout the game self.pprint('Connecting...') self.session = requests.session() if self.config.game_mode == 'arena': self.pprint('Waiting for other players to join...') try: # Get the initial state self.state = self.get_new_game_state() self.states.append(self.state) self.pprint("Playing at: " + self.state['viewUrl']) except (KeyError, TypeError) as e: self.pprint("Error: Please verify your settings.") self.pprint("Settings:", self.config.__dict__) self.running = False return for i in range(self.config.number_of_turns + 1): if self.running: # Choose a move self.start_time = time.time() try: while sys.stdin in select.select([sys.stdin], [], [], 0)[0]: line = sys.stdin.read(1) if line.strip() == "q": self.running = False self.bot.running = False break elif line.strip() == "p": self.gui.pause() elif line.strip() == "s": self.save_game() if self.bot.running: direction = self.bot.move(self.state) self.display_game() except Exception, e: if self.gui.log_win: self.pprint("Error at client.start_game:", str(e)) self.pprint("If your code or your settings are not responsible of this error, please report this error to:") self.pprint("[email protected].") self.gui.pause() self.running = False return if not self.is_game_over(): # Send the move and receive the updated game state self.game_url = self.state['playUrl'] self.state = self.send_move(direction) self.states.append(self.state)
def __init__(self): self.start_time = None self.gui = None self.session = None self.state = None self.running = True self.game_url = None self.config = Config() self.bot = Curses_ui_bot() # Our bot self.states = [] self.delay = 0.5 # Delay in s between turns in replay mode
def replay(self): """Replay last game""" # Restart with a new bot self.bot = Curses_ui_bot() for i in range(self.config.number_of_games): # start a new game if self.bot.running: self.restart_game() gold = 0 winner = "Noone" for player in self.bot.game.heroes: if int(player.gold) > gold: winner = player.name gold = int(player.gold) self.pprint("**** " + winner + " wins. ****") self.pprint("Game finished: "+str(i+1)+"/"+str(self.config.number_of_games))
class Client: def __init__(self): self.start_time = None self.gui = None self.session = None self.state = None self.running = True self.game_url = None self.config = Config() self.bot = Curses_ui_bot() # Our bot self.states = [] self.delay = 0.5 # Delay in s between turns in replay mode self.victory = 0 self.time_out = 0 def pprint(self, *args, **kwargs): """Display args in the bot gui or print it if no gui is available For debugging purpose consider using self.gui.append_log() """ printable = "" for arg in args: printable = printable + str(arg) + " " if kwargs and len(kwargs): a = 1 coma = "" printable = printable + "[" for k, v in kwargs.items(): if 1 < a < len(kwargs): coma = ", " else: coma = "]" printable = printable + str(k) + ": " + str(v) + coma a = a + 1 if self.gui and self.gui.running: # bot has a gui so we add this entries to its log panel if self.gui.log_win: self.gui.append_log(printable) self.gui.refresh() else: print(printable) def load_config(self): """Load saved config from file ~/.vindinium/config""" config_parser = configparser.ConfigParser() user_home_dir = os.path.expanduser("~") config_file_name = os.path.join(user_home_dir, ".vindinium", "config") try: if os.path.isfile(config_file_name): config_parser.read(config_file_name) self.config.server_url = config_parser.get( "game", "server_url") self.config.game_mode = config_parser.get("game", "game_mode") self.config.map_name = config_parser.get("game", "map_name") self.config.key = config_parser.get("game", "key") self.config.number_of_games = config_parser.getint( "game", "number_of_games") self.config.number_of_turns = config_parser.getint( "game", "number_of_turns") except (IOError, configparser.Error) as e: self.gui.quit_ui() print("Error while loading config file", config_file_name, ":", e) quit(1) def save_config(self): """Save config to file in ~/.vindinium/config""" config_parser = configparser.ConfigParser() user_home_dir = os.path.expanduser("~") config_file_name = os.path.join(user_home_dir, ".vindinium", "config") try: if not os.path.isdir(os.path.join(user_home_dir, ".vindinium")): os.makedirs(os.path.join(user_home_dir, ".vindinium")) config_parser.add_section("game") with open(config_file_name, "w") as config_file: for key, value in self.config.__dict__.items(): config_parser.set("game", key, value) config_parser.write(config_file) except (IOError, configparser.Error) as e: self.gui.quit_ui() print("Error while saving config file", config_file_name, ":", e) quit(1) def load_game(self, game_file_name): """Load saved game from file""" # Reset our bot and self.states self.states = [] try: with open(game_file_name, "r") as game_file: for line in game_file.readlines(): if len(line.strip(chr(0)).strip()) > 0: self.states.append(ast.literal_eval(line)) self.state = self.states[0] except (IOError, IndexError) as e: self.gui.quit_ui() print("Error while loading game file", game_file_name, ":", e) quit(1) def save_game(self): """Save game to file in ~/.vindinium/save/<game ID>""" user_home_dir = os.path.expanduser("~") try: # Get game_id from game sate game_id = self.state['game']["id"] except KeyError: try: # State has not been downloaded # Try to get game_id from last state saved if any game_id = self.states[0]['game']["id"] except IndexError: self.pprint( "No states available for this game, unable to save game.") return game_file_name = os.path.join(user_home_dir, ".vindinium", "save", game_id) try: if not os.path.isdir( os.path.join(user_home_dir, ".vindinium", "save")): os.makedirs(os.path.join(user_home_dir, ".vindinium", "save")) with open(game_file_name, "w") as game_file: for state in self.states: game_file.write(str(state) + "\n") self.pprint("Game saved: " + game_file_name) except IOError as e: self.gui.append_log("Error while saving game file", game_file_name, ":", e) def download_game_file(self, game_file_url): # I will treat no other forbidden char than space char. game_file_url = game_file_url.replace(" ", "%20") # # FIXME : # # Game file available online at http://vindinium.org/events/<gameId> # are not parsable by ast.literal_eval() ???? # # self.session = requests.session() # response = self.session.get(game_file_url, timeout=10*60) # if response.status_code == 200: # for line in response.text: # line = line.strip(chr(0)).strip() # if len(line) > 0: # self.states.append(ast.literal_eval(line)) <<< Here is the problem # # MUST TRY: # games=[json.loads(line[6:]) for line in requests.get(game_file_url).content.splitlines() if line.startswith("data: ")] # self.gui.quit_ui() os.system('cls' if os.name == 'nt' else 'clear') print("********************************************************") print("* Feature not available yet. *") print("* Please wait for U.I restart *") print("********************************************************") for i in reversed(range(1, 6)): print(i) time.sleep(1) self.start_ui() def start_ui(self): """Start the curses UI""" self.bot = Curses_ui_bot() self.running = True self.game_url = None self.states = [] self.state = None self.gui = ui.tui() choice = self.gui.ask_main_menu() if choice == '1': # Load config then play game self.load_config() self.gui.draw_game_windows() self.play() elif choice == '2': # Setup game self.config = Config() choice = self.gui.ask_game_mode() if choice == '1': # Arena mode config self.config.game_mode = "arena" self.config.number_of_turns = 300 self.config.number_of_games = self.gui.ask_number_games() elif choice == '2': # Training mode config self.config.game_mode = "training" self.config.number_of_games = 1 self.config.number_of_turns = self.gui.ask_number_turns() self.config.map_name = "m" + str(self.gui.ask_map()) self.config.server_url = self.gui.ask_server_url( self.config.game_mode) self.config.key = self.gui.ask_key(self.config.game_mode) if self.gui.ask_save_config(): self.save_config() if self.gui.ask_play_game(): self.gui.draw_game_windows() self.play() else: self.start_ui() elif choice == '3': # Load game from file game_file_name = self.gui.ask_game_file_path() self.load_game(game_file_name) self.gui.draw_game_windows() self.replay() elif choice == '4': # Load game from URL game_file_url = self.gui.ask_game_file_url() self.download_game_file(game_file_url) self.gui.draw_game_windows() self.replay() elif choice == '5': # quit self.gui.quit_ui() exit(0) if self.gui.running and self.gui.help_win: key = None while key != 'm': key = self.gui.ask_quit() if key == 's': self.save_game() elif key == 'r': self.replay() self.gui.clear() self.start_ui() def play(self): """Play all games""" self.victory = 0 self.time_out = 0 for i in range(self.config.number_of_games): # start a new game if self.bot.running: self.start_game() gold = 0 winner = ("Noone", -1) for player in self.bot.game.heroes: if int(player.gold) > gold: winner = (player.name, player.bot_id) gold = int(player.gold) if winner[1] == self.bot.game.hero.bot_id: self.victory += 1 self.pprint("* " + winner[0] + " wins. ******************") self.gui.display_summary( str(i + 1) + "/" + str(self.config.number_of_games), str(self.victory) + "/" + str(i + 1), str(self.time_out) + "/" + str(i + 1)) self.pprint("Game finished: " + str(i + 1) + "/" + str(self.config.number_of_games)) def replay(self): """Replay last game""" # Restart with a new bot self.bot = Curses_ui_bot() for i in range(self.config.number_of_games): # start a new game if self.bot.running: self.restart_game() gold = 0 winner = "Noone" for player in self.bot.game.heroes: if int(player.gold) > gold: winner = player.name gold = int(player.gold) self.pprint("**** " + winner + " wins. ****") self.pprint("Game finished: " + str(i + 1) + "/" + str(self.config.number_of_games)) def start_game(self): """Starts a game with all the required parameters""" self.running = True # Delete prévious game states self.states = [] # Restart game with brand new bot self.bot = Curses_ui_bot() # Default move is no move ! direction = "Stay" # Create a requests session that will be used throughout the game self.pprint('Connecting...') self.session = requests.session() if self.config.game_mode == 'arena': self.pprint('Waiting for other players to join...') try: # Get the initial state # May raise error if self.get_new_state() returns # no data or inconsistent data (network problem) self.state = self.get_new_game_state() self.states.append(self.state) self.pprint("Playing at: " + self.state['viewUrl']) except (KeyError, TypeError) as e: # We can not play a game without a state self.pprint("Error: Please verify your settings.") self.pprint("Settings:", self.config.__dict__) self.running = False return for i in range(self.config.number_of_turns + 1): if self.running: # Choose a move self.start_time = time.time() try: while sys.stdin in select.select([sys.stdin], [], [], 0)[0]: line = sys.stdin.read(1) if line.strip() == "q": self.running = False self.bot.running = False break elif line.strip() == "p": self.gui.pause() elif line.strip() == "s": self.save_game() if self.bot.running: direction = self.bot.move(self.state) self.display_game() except Exception as e: # Super error trap ! if self.gui.log_win: self.pprint("Error at client.start_game:", str(e)) self.pprint( "If your code or your settings are not responsible of this error, please report this error to:" ) self.pprint("[email protected].") self.gui.pause() self.running = False return if not self.is_game_over(): # Send the move and receive the updated game state self.game_url = self.state['playUrl'] self.state = self.send_move(direction) self.states.append(self.state) # Clean up the session self.session.close() def restart_game(self): """Starts a game with all the required parameters""" self.running = True try: # Get the initial state self.state = self.states[0] self.pprint("Replaying: " + self.state['viewUrl']) except (IndexError, KeyError) as e: self.pprint("Error while trying to replay game.") self.pprint("Game states length:", len(self.states)) self.running = False return self.gui.draw_help_win() for state in self.states: self.state = state if self.running: # Choose a move self.start_time = time.time() try: while sys.stdin in select.select([sys.stdin], [], [], 0)[0]: line = sys.stdin.read(1) if line.strip() == "q": self.running = False self.bot.running = False break elif line.strip() == "p": self.gui.pause() elif line.strip() == "s": self.save_game() if self.bot.running: self.bot.process_game(state) self.display_game() except Exception as e: if self.gui.log_win: self.pprint("Error at client.restart_game:", str(e)) self.pprint( "If your code or your settings are not responsible of this error, please report this error to:" ) self.pprint("[email protected].") self.gui.pause() self.running = False return if not self.is_game_over(): # Replay next turn self.game_url = state['playUrl'] time.sleep(self.delay) def get_new_game_state(self): """Get a JSON from the server containing the current state of the game""" if self.config.game_mode == 'training': # Don't pass the 'map' parameter if no map has been selected if len(self.config.map_name) > 0: params = { 'key': self.config.key, 'turns': self.config.number_of_turns, 'map': self.config.map_name } else: params = { 'key': self.config.key, 'turns': self.config.number_of_turns } api_endpoint = '/api/training' elif self.config.game_mode == 'arena': params = {'key': self.config.key} api_endpoint = '/api/arena' else: raise Exception('Unknown game mode') # Wait for 10 minutes try: r = self.session.post(self.config.server_url + api_endpoint, params, timeout=10 * 60) if r.status_code == 200: return r.json() else: self.pprint("Error when creating the game:", str(r.status_code)) self.running = False self.pprint(r.text) except requests.ConnectionError as e: self.pprint("Error when creating the game:", e) self.running = False def is_game_over(self): """Return True if game defined by state is over""" try: return self.state['game']['finished'] except (TypeError, KeyError): return True def send_move(self, direction): """Send a move to the server Moves can be one of: 'Stay', 'North', 'South', 'East', 'West'""" try: response = self.session.post(self.game_url, {'dir': direction}, timeout=TIMEOUT) if response.status_code == 200: return response.json() else: self.pprint("Error HTTP ", str(response.status_code), ": ", response.text) self.time_out += 1 self.running = False return {'game': {'finished': True}} except requests.exceptions.RequestException as e: self.pprint("Error at client.move;", str(e)) self.running = False return {'game': {'finished': True}} def display_game(self): """Display game data on the U.I""" if not self.gui.paused: # Draw the map self.gui.draw_map(self.bot.game.board_map, self.bot.path_to_goal, self.bot.game.heroes) # Use the following methods to display datas # within the interface self.gui.display_url(self.bot.game.url) self.gui.display_bot_name(self.bot.game.hero.name) self.gui.display_last_move(self.bot.hero_last_move) self.gui.display_pos(self.bot.game.hero.pos) self.gui.display_last_pos(self.bot.last_pos) self.gui.display_last_life(self.bot.last_life) self.gui.display_life(self.bot.game.hero.life) self.gui.display_last_action(self.bot.last_action) self.gui.display_turn((self.bot.game.turn / 4) - 1, self.bot.game.max_turns / 4) self.gui.display_elo(self.bot.game.hero.elo) self.gui.display_gold(self.bot.game.hero.gold) self.gui.display_last_gold(self.bot.last_gold) self.gui.display_mine_count( str(self.bot.game.hero.mine_count) + "/" + str(len(self.bot.game.mines))) self.gui.display_last_mine_count( str(self.bot.last_mine_count) + "/" + str(len(self.bot.game.mines))) # You can also use those methods to display more information # Function names are explicit, don't they ? self.gui.display_nearest_mine(self.bot.nearest_mine_pos) self.gui.display_nearest_hero(self.bot.nearest_enemy_pos) self.gui.display_nearest_tavern(self.bot.nearest_tavern_pos) self.gui.display_last_nearest_mine(self.bot.last_nearest_mine_pos) self.gui.display_last_nearest_hero(self.bot.last_nearest_enemy_pos) self.gui.display_last_nearest_tavern( self.bot.last_nearest_tavern_pos) # Print informations about other players self.gui.display_heroes(self.bot.game.heroes, self.bot.game.hero.bot_id) # Print a *list of tuples* representing what you think can be usefull # i.e an heuristic result self.gui.display_decision(self.bot.decision) # Print *list of tuples* representing # the estimated path to reach the goal if any. # If too long the path will be truncated to fit # in the display self.gui.display_path(self.bot.path_to_goal) # Move cursor along the time line (cost cpu time) cursor_pos = int( float(self.gui.TIME_W) // self.bot.game.max_turns * self.bot.game.turn) self.gui.move_time_cursor(cursor_pos) # Finally display selected move self.gui.display_move(self.bot.hero_move) self.gui.display_action(self.bot.action) # Add whathever you want to log using self.gui.append_log() # self.gui.append_log("Whatever") elapsed = round(time.time() - self.start_time, 3) self.gui.display_elapsed(elapsed) self.gui.refresh()
def start_game(self): """Starts a game with all the required parameters""" self.running = True # Delete prévious game states self.states = [] # Restart game with brand new bot self.bot = Curses_ui_bot() # Default move is no move ! direction = "Stay" # Create a requests session that will be used throughout the game self.pprint('Connecting...') self.session = requests.session() if self.config.game_mode == 'arena': self.pprint('Waiting for other players to join...') try: # Get the initial state # May raise error if self.get_new_state() returns # no data or inconsistent data (network problem) self.state = self.get_new_game_state() self.states.append(self.state) self.pprint("Playing at: " + self.state['viewUrl']) except (KeyError, TypeError) as e: # We can not play a game without a state self.pprint("Error: Please verify your settings.") self.pprint("Settings:", self.config.__dict__) self.running = False return for i in range(self.config.number_of_turns + 1): if self.running: # Choose a move self.start_time = time.time() try: while sys.stdin in select.select([sys.stdin], [], [], 0)[0]: line = sys.stdin.read(1) if line.strip() == "q": self.running = False self.bot.running = False break elif line.strip() == "p": self.gui.pause() elif line.strip() == "s": self.save_game() if self.bot.running: direction = self.bot.move(self.state) self.display_game() except Exception as e: # Super error trap ! if self.gui.log_win: self.pprint("Error at client.start_game:", str(e)) self.pprint( "If your code or your settings are not responsible of this error, please report this error to:" ) self.pprint("[email protected].") self.gui.pause() self.running = False return if not self.is_game_over(): # Send the move and receive the updated game state self.game_url = self.state['playUrl'] self.state = self.send_move(direction) self.states.append(self.state) # Clean up the session self.session.close()
def start_ui(self): """Start the curses UI""" self.bot = Curses_ui_bot() self.running = True self.game_url = None self.states = [] self.state = None self.gui = ui.tui() choice = self.gui.ask_main_menu() if choice == '1': # Load config then play game self.load_config() self.gui.draw_game_windows() self.play() elif choice == '2': # Setup game self.config = Config() choice = self.gui.ask_game_mode() if choice == '1': # Arena mode config self.config.game_mode = "arena" self.config.number_of_turns = 300 self.config.number_of_games = self.gui.ask_number_games() elif choice == '2': # Training mode config self.config.game_mode = "training" self.config.number_of_games = 1 self.config.number_of_turns = self.gui.ask_number_turns() self.config.map_name = "m" + str(self.gui.ask_map()) self.config.server_url = self.gui.ask_server_url( self.config.game_mode) self.config.key = self.gui.ask_key(self.config.game_mode) if self.gui.ask_save_config(): self.save_config() if self.gui.ask_play_game(): self.gui.draw_game_windows() self.play() else: self.start_ui() elif choice == '3': # Load game from file game_file_name = self.gui.ask_game_file_path() self.load_game(game_file_name) self.gui.draw_game_windows() self.replay() elif choice == '4': # Load game from URL game_file_url = self.gui.ask_game_file_url() self.download_game_file(game_file_url) self.gui.draw_game_windows() self.replay() elif choice == '5': # quit self.gui.quit_ui() exit(0) if self.gui.running and self.gui.help_win: key = None while key != 'm': key = self.gui.ask_quit() if key == 's': self.save_game() elif key == 'r': self.replay() self.gui.clear() self.start_ui()
class Client: def __init__(self): self.start_time = None self.gui = None self.session = None self.state = None self.running = True self.game_url = None self.config = Config() self.bot = Curses_ui_bot() # Our bot self.states = [] self.delay = 0.5 # Delay in s between turns in replay mode def pprint(self, *args, **kwargs): """Display args in the bot gui or print it if no gui is available For debugging purpose consider using self.gui.append_log() """ printable = "" for arg in args: printable = printable + str(arg)+" " if kwargs and len(kwargs): a = 1 coma = "" printable = printable + "[" for k, v in kwargs.iteritems(): if 1 < a < len(kwargs): coma = ", " else: coma = "]" printable = printable + str(k) + ": " + str(v) + coma a = a + 1 if self.gui and self.gui.running: # bot has a gui so we add this entries to its log panel if self.gui.log_win: self.gui.append_log(printable) self.gui.refresh() else: print printable def load_config(self): """Load saved config from file ~/.vindinium/config""" config_parser = ConfigParser.ConfigParser() user_home_dir = os.path.expanduser("~") config_file_name = os.path.join(user_home_dir, ".vindinium", "config") try: if os.path.isfile(config_file_name): config_parser.read(config_file_name) self.config.server_url = config_parser.get("game", "server_url") self.config.game_mode = config_parser.get("game", "game_mode") self.config.map_name = config_parser.get("game", "map_name") self.config.key = config_parser.get("game", "key") self.config.number_of_games = config_parser.getint("game", "number_of_games") self.config.number_of_turns = config_parser.getint("game", "number_of_turns") except (IOError, ConfigParser.Error) as e: self.gui.quit_ui() print "Error while loading config file", config_file_name, ":", e quit(1) def save_config(self): """Save config to file in ~/.vindinium/config""" config_parser = ConfigParser.ConfigParser() user_home_dir = os.path.expanduser("~") config_file_name = os.path.join(user_home_dir, ".vindinium", "config") try: if not os.path.isdir(os.path.join(user_home_dir, ".vindinium")): os.makedirs(os.path.join(user_home_dir, ".vindinium")) config_parser.add_section("game") with open(config_file_name, "w") as config_file: for key, value in self.config.__dict__.items(): config_parser.set("game", key, value) config_parser.write(config_file) except (IOError, ConfigParser.Error) as e: self.gui.quit_ui() print "Error while saving config file", config_file_name, ":", e quit(1) def load_game(self, game_file_name): """Load saved game from file""" # Reset our bot and self.states self.states = [] try: with open(game_file_name, "r") as game_file: for line in game_file.readlines(): if len(line.strip(chr(0)).strip()) > 0: self.states.append(ast.literal_eval(line)) self.state = self.states[0] except (IOError, IndexError) as e: self.gui.quit_ui() print "Error while loading game file", game_file_name, ":", e quit(1) def save_game(self): """Save game to file in ~/.vindinium/save/<game ID>""" user_home_dir = os.path.expanduser("~") try: # Get game_id from game sate game_id = self.state['game']["id"] except KeyError: try: # State has not been downloaded # Try to get game_id from last state saved if any game_id = self.states[0]['game']["id"] except IndexError: self.pprint("No states available for this game, unable to save game.") game_file_name = os.path.join(user_home_dir, ".vindinium", "save", game_id) try: if not os.path.isdir(os.path.join(user_home_dir, ".vindinium", "save")): os.makedirs(os.path.join(user_home_dir, ".vindinium", "save")) with open(game_file_name, "w") as game_file: for state in self.states: game_file.write(str(state)+"\n") self.pprint("Game saved: "+game_file_name) except IOError as e: self.gui.append_log("Error while saving game file", game_file_name, ":", e) def download_game_file(self, game_file_url): # I will treat no other forbidden char than space char. game_file_url = game_file_url.replace(" ", "%20") # # FIXME : # # Game file available online at http://vindinium.org/events/<gameId> # are not parsable by ast.literal_eval() ???? # # self.session = requests.session() # response = self.session.get(game_file_url, timeout=10*60) # if response.status_code == 200: # for line in response.text: # line = line.strip(chr(0)).strip() # if len(line) > 0: # self.states.append(ast.literal_eval(line)) # try: # print self.states[len(self.states)-1], type(self.states[len(self.states)-1]) # except: # pass self.gui.quit_ui() os.system('cls' if os.name == 'nt' else 'clear') print "********************************************************" print "* Feature not available yet. *" print "* Please wait for U.I restart *" print "********************************************************" for i in reversed(range(1, 6)): print i time.sleep(1) self.start_ui() def start_ui(self): """Start the curses UI""" self.bot = Curses_ui_bot() self.running = True self.game_url = None self.states = [] self.state = None self.gui = ui.tui() choice = self.gui.ask_main_menu() if choice == '1': # Load config then play game self.load_config() self.gui.draw_game_windows() self.play() elif choice == '2': # Setup game self.config = Config() choice = self.gui.ask_game_mode() if choice == '1': # Arena mode config self.config.game_mode = "arena" self.config.number_of_turns = 300 self.config.number_of_games = self.gui.ask_number_games() elif choice == '2': # Training mode config self.config.game_mode = "training" self.config.number_of_games = 1 self.config.number_of_turns = self.gui.ask_number_turns() self.config.map_name = "m"+str(self.gui.ask_map()) self.config.server_url = self.gui.ask_server_url(self.config.game_mode) self.config.key = self.gui.ask_key(self.config.game_mode) if self.gui.ask_save_config(): self.save_config() if self.gui.ask_play_game(): self.gui.draw_game_windows() self.play() else: self.start_ui() elif choice == '3': # Load game from file game_file_name = self.gui.ask_game_file_path() self.load_game(game_file_name) self.gui.draw_game_windows() self.replay() elif choice == '4': # Load game from URL game_file_url = self.gui.ask_game_file_url() self.download_game_file(game_file_url) self.gui.draw_game_windows() self.replay() elif choice == '5': # quit self.gui.quit_ui() exit(0) if self.gui.running and self.gui.help_win: key = None while key != 'm': key = self.gui.ask_quit() if key == 's': self.save_game() elif key == 'r': self.replay() self.gui.clear() self.start_ui() def play(self): """Play all games""" for i in range(self.config.number_of_games): # start a new game if self.bot.running: self.start_game() self.pprint("Game finished: "+str(i+1)+"/"+str(self.config.number_of_games)) def replay(self): """Replay last game""" # Restart with a new bot self.bot = Curses_ui_bot() for i in range(self.config.number_of_games): # start a new game if self.bot.running: self.restart_game() self.pprint("Game finished.") def start_game(self): """Starts a game with all the required parameters""" self.running = True # Delete prévious game states self.states = [] # Restart game with brand new bot self.bot = Curses_ui_bot() # Default move is no move ! direction = "Stay" # Create a requests session that will be used throughout the game self.pprint('Connecting...') self.session = requests.session() if self.config.game_mode == 'arena': self.pprint('Waiting for other players to join...') try: # Get the initial state self.state = self.get_new_game_state() self.states.append(self.state) self.pprint("Playing at: " + self.state['viewUrl']) except (KeyError, TypeError) as e: self.pprint("Error: Please verify your settings.") self.pprint("Settings:", self.config.__dict__) self.running = False return for i in range(self.config.number_of_turns + 1): if self.running: # Choose a move self.start_time = time.time() try: while sys.stdin in select.select([sys.stdin], [], [], 0)[0]: line = sys.stdin.read(1) if line.strip() == "q": self.running = False self.bot.running = False break elif line.strip() == "p": self.gui.pause() elif line.strip() == "s": self.save_game() if self.bot.running: direction = self.bot.move(self.state) self.display_game() except Exception, e: if self.gui.log_win: self.pprint("Error at client.start_game:", str(e)) self.pprint("If your code or your settings are not responsible of this error, please report this error to:") self.pprint("[email protected].") self.gui.pause() self.running = False return if not self.is_game_over(): # Send the move and receive the updated game state self.game_url = self.state['playUrl'] self.state = self.send_move(direction) self.states.append(self.state) # Clean up the session self.session.close()
def start_ui(self): """Start the curses UI""" self.bot = Curses_ui_bot() self.running = True self.game_url = None self.states = [] self.state = None self.gui = ui.tui() choice = self.gui.ask_main_menu() if choice == '1': # Load config then play game self.load_config() self.gui.draw_game_windows() self.play() elif choice == '2': # Setup game self.config = Config() choice = self.gui.ask_game_mode() if choice == '1': # Arena mode config self.config.game_mode = "arena" self.config.number_of_turns = 300 self.config.number_of_games = self.gui.ask_number_games() elif choice == '2': # Training mode config self.config.game_mode = "training" self.config.number_of_games = 1 self.config.number_of_turns = self.gui.ask_number_turns() self.config.map_name = "m"+str(self.gui.ask_map()) self.config.server_url = self.gui.ask_server_url(self.config.game_mode) self.config.key = self.gui.ask_key(self.config.game_mode) if self.gui.ask_save_config(): self.save_config() if self.gui.ask_play_game(): self.gui.draw_game_windows() self.play() else: self.start_ui() elif choice == '3': # Load game from file game_file_name = self.gui.ask_game_file_path() self.load_game(game_file_name) self.gui.draw_game_windows() self.replay() elif choice == '4': # Load game from URL game_file_url = self.gui.ask_game_file_url() self.download_game_file(game_file_url) self.gui.draw_game_windows() self.replay() elif choice == '5': # quit self.gui.quit_ui() exit(0) if self.gui.running and self.gui.help_win: key = None while key != 'm': key = self.gui.ask_quit() if key == 's': self.save_game() elif key == 'r': self.replay() self.gui.clear() self.start_ui()
class Client: def __init__(self): self.start_time = None self.gui = None self.session = None self.state = None self.running = True self.game_url = None self.config = Config() self.bot = Curses_ui_bot() # Our bot self.states = [] self.delay = 0.5 # Delay in s between turns in replay mode self.victory = 0 self.time_out = 0 def pprint(self, *args, **kwargs): """Display args in the bot gui or print it if no gui is available For debugging purpose consider using self.gui.append_log() """ printable = "" for arg in args: printable = printable + str(arg)+" " if kwargs and len(kwargs): a = 1 coma = "" printable = printable + "[" for k, v in kwargs.items(): if 1 < a < len(kwargs): coma = ", " else: coma = "]" printable = printable + str(k) + ": " + str(v) + coma a = a + 1 if self.gui and self.gui.running: # bot has a gui so we add this entries to its log panel if self.gui.log_win: self.gui.append_log(printable) self.gui.refresh() else: print (printable) def load_config(self): """Load saved config from file ~/.vindinium/config""" config_parser = configparser.ConfigParser() user_home_dir = os.path.expanduser("~") config_file_name = os.path.join(user_home_dir, ".vindinium", "config") try: if os.path.isfile(config_file_name): config_parser.read(config_file_name) self.config.server_url = config_parser.get("game", "server_url") self.config.game_mode = config_parser.get("game", "game_mode") self.config.map_name = config_parser.get("game", "map_name") self.config.key = config_parser.get("game", "key") self.config.number_of_games = config_parser.getint("game", "number_of_games") self.config.number_of_turns = config_parser.getint("game", "number_of_turns") except (IOError, configparser.Error) as e: self.gui.quit_ui() print ("Error while loading config file", config_file_name, ":", e) quit(1) def save_config(self): """Save config to file in ~/.vindinium/config""" config_parser = configparser.ConfigParser() user_home_dir = os.path.expanduser("~") config_file_name = os.path.join(user_home_dir, ".vindinium", "config") try: if not os.path.isdir(os.path.join(user_home_dir, ".vindinium")): os.makedirs(os.path.join(user_home_dir, ".vindinium")) config_parser.add_section("game") with open(config_file_name, "w") as config_file: for key, value in self.config.__dict__.items(): config_parser.set("game", key, value) config_parser.write(config_file) except (IOError, configparser.Error) as e: self.gui.quit_ui() print ("Error while saving config file", config_file_name, ":", e) quit(1) def load_game(self, game_file_name): """Load saved game from file""" # Reset our bot and self.states self.states = [] try: with open(game_file_name, "r") as game_file: for line in game_file.readlines(): if len(line.strip(chr(0)).strip()) > 0: self.states.append(ast.literal_eval(line)) self.state = self.states[0] except (IOError, IndexError) as e: self.gui.quit_ui() print ("Error while loading game file", game_file_name, ":", e) quit(1) def save_game(self): """Save game to file in ~/.vindinium/save/<game ID>""" user_home_dir = os.path.expanduser("~") try: # Get game_id from game sate game_id = self.state['game']["id"] except KeyError: try: # State has not been downloaded # Try to get game_id from last state saved if any game_id = self.states[0]['game']["id"] except IndexError: self.pprint("No states available for this game, unable to save game.") return game_file_name = os.path.join(user_home_dir, ".vindinium", "save", game_id) try: if not os.path.isdir(os.path.join(user_home_dir, ".vindinium", "save")): os.makedirs(os.path.join(user_home_dir, ".vindinium", "save")) with open(game_file_name, "w") as game_file: for state in self.states: game_file.write(str(state)+"\n") self.pprint("Game saved: "+game_file_name) except IOError as e: self.gui.append_log("Error while saving game file", game_file_name, ":", e) def download_game_file(self, game_file_url): # I will treat no other forbidden char than space char. game_file_url = game_file_url.replace(" ", "%20") # # FIXME : # # Game file available online at http://vindinium.org/events/<gameId> # are not parsable by ast.literal_eval() ???? # # self.session = requests.session() # response = self.session.get(game_file_url, timeout=10*60) # if response.status_code == 200: # for line in response.text: # line = line.strip(chr(0)).strip() # if len(line) > 0: # self.states.append(ast.literal_eval(line)) <<< Here is the problem # # MUST TRY: # games=[json.loads(line[6:]) for line in requests.get(game_file_url).content.splitlines() if line.startswith("data: ")] # self.gui.quit_ui() os.system('cls' if os.name == 'nt' else 'clear') print ("********************************************************") print ("* Feature not available yet. *") print ("* Please wait for U.I restart *") print ("********************************************************") for i in reversed(range(1, 6)): print (i) time.sleep(1) self.start_ui() def start_ui(self): """Start the curses UI""" self.bot = Curses_ui_bot() self.running = True self.game_url = None self.states = [] self.state = None self.gui = ui.tui() choice = self.gui.ask_main_menu() if choice == '1': # Load config then play game self.load_config() self.gui.draw_game_windows() self.play() elif choice == '2': # Setup game self.config = Config() choice = self.gui.ask_game_mode() if choice == '1': # Arena mode config self.config.game_mode = "arena" self.config.number_of_turns = 300 self.config.number_of_games = self.gui.ask_number_games() elif choice == '2': # Training mode config self.config.game_mode = "training" self.config.number_of_games = 1 self.config.number_of_turns = self.gui.ask_number_turns() self.config.map_name = "m"+str(self.gui.ask_map()) self.config.server_url = self.gui.ask_server_url(self.config.game_mode) self.config.key = self.gui.ask_key(self.config.game_mode) if self.gui.ask_save_config(): self.save_config() if self.gui.ask_play_game(): self.gui.draw_game_windows() self.play() else: self.start_ui() elif choice == '3': # Load game from file game_file_name = self.gui.ask_game_file_path() self.load_game(game_file_name) self.gui.draw_game_windows() self.replay() elif choice == '4': # Load game from URL game_file_url = self.gui.ask_game_file_url() self.download_game_file(game_file_url) self.gui.draw_game_windows() self.replay() elif choice == '5': # quit self.gui.quit_ui() exit(0) if self.gui.running and self.gui.help_win: key = None while key != 'm': key = self.gui.ask_quit() if key == 's': self.save_game() elif key == 'r': self.replay() self.gui.clear() self.start_ui() def play(self): """Play all games""" self.victory = 0 self.time_out = 0 for i in range(self.config.number_of_games): # start a new game if self.bot.running: self.start_game() gold = 0 winner = ("Noone", -1) for player in self.bot.game.heroes: if int(player.gold) > gold: winner = (player.name, player.bot_id) gold = int(player.gold) if winner[1] == self.bot.game.hero.bot_id: self.victory += 1 self.pprint("* " + winner[0] + " wins. ******************") self.gui.display_summary(str(i+1) + "/" + str(self.config.number_of_games), str(self.victory) + "/" + str(i+1), str(self.time_out) + "/" + str(i+1)) self.pprint("Game finished: "+ str(i+1) + "/" + str(self.config.number_of_games)) def replay(self): """Replay last game""" # Restart with a new bot self.bot = Curses_ui_bot() for i in range(self.config.number_of_games): # start a new game if self.bot.running: self.restart_game() gold = 0 winner = "Noone" for player in self.bot.game.heroes: if int(player.gold) > gold: winner = player.name gold = int(player.gold) self.pprint("**** " + winner + " wins. ****") self.pprint("Game finished: "+str(i+1)+"/"+str(self.config.number_of_games)) def start_game(self): """Starts a game with all the required parameters""" self.running = True # Delete prévious game states self.states = [] # Restart game with brand new bot self.bot = Curses_ui_bot() # Default move is no move ! direction = "Stay" # Create a requests session that will be used throughout the game self.pprint('Connecting...') self.session = requests.session() if self.config.game_mode == 'arena': self.pprint('Waiting for other players to join...') try: # Get the initial state # May raise error if self.get_new_state() returns # no data or inconsistent data (network problem) self.state = self.get_new_game_state() self.states.append(self.state) self.pprint("Playing at: " + self.state['viewUrl']) except (KeyError, TypeError) as e: # We can not play a game without a state self.pprint("Error: Please verify your settings.") self.pprint("Settings:", self.config.__dict__) self.running = False return for i in range(self.config.number_of_turns + 1): if self.running: # Choose a move self.start_time = time.time() try: while sys.stdin in select.select([sys.stdin], [], [], 0)[0]: line = sys.stdin.read(1) if line.strip() == "q": self.running = False self.bot.running = False break elif line.strip() == "p": self.gui.pause() elif line.strip() == "s": self.save_game() if self.bot.running: direction = self.bot.move(self.state) self.display_game() except Exception as e: # Super error trap ! if self.gui.log_win: self.pprint("Error at client.start_game:", str(e)) self.pprint("If your code or your settings are not responsible of this error, please report this error to:") self.pprint("[email protected].") self.gui.pause() self.running = False return if not self.is_game_over(): # Send the move and receive the updated game state self.game_url = self.state['playUrl'] self.state = self.send_move(direction) self.states.append(self.state) # Clean up the session self.session.close() def restart_game(self): """Starts a game with all the required parameters""" self.running = True try: # Get the initial state self.state = self.states[0] self.pprint("Replaying: " + self.state['viewUrl']) except (IndexError, KeyError) as e: self.pprint("Error while trying to replay game.") self.pprint("Game states length:", len(self.states)) self.running = False return self.gui.draw_help_win() for state in self.states: self.state = state if self.running: # Choose a move self.start_time = time.time() try: while sys.stdin in select.select([sys.stdin], [], [], 0)[0]: line = sys.stdin.read(1) if line.strip() == "q": self.running = False self.bot.running = False break elif line.strip() == "p": self.gui.pause() elif line.strip() == "s": self.save_game() if self.bot.running: self.bot.process_game(state) self.display_game() except Exception as e: if self.gui.log_win: self.pprint("Error at client.restart_game:", str(e)) self.pprint("If your code or your settings are not responsible of this error, please report this error to:") self.pprint("[email protected].") self.gui.pause() self.running = False return if not self.is_game_over(): # Replay next turn self.game_url = state['playUrl'] time.sleep(self.delay) def get_new_game_state(self): """Get a JSON from the server containing the current state of the game""" if self.config.game_mode == 'training': # Don't pass the 'map' parameter if no map has been selected if len(self.config.map_name) > 0: params = {'key': self.config.key, 'turns': self.config.number_of_turns, 'map': self.config.map_name} else: params = {'key': self.config.key, 'turns': self.config.number_of_turns} api_endpoint = '/api/training' elif self.config.game_mode == 'arena': params = {'key': self.config.key} api_endpoint = '/api/arena' else: raise Exception('Unknown game mode') # Wait for 10 minutes try: r = self.session.post(self.config.server_url + api_endpoint, params, timeout=10*60) if r.status_code == 200: return r.json() else: self.pprint("Error when creating the game:", str(r.status_code)) self.running = False self.pprint(r.text) except requests.ConnectionError as e: self.pprint("Error when creating the game:", e) self.running = False def is_game_over(self): """Return True if game defined by state is over""" try: return self.state['game']['finished'] except (TypeError, KeyError): return True def send_move(self, direction): """Send a move to the server Moves can be one of: 'Stay', 'North', 'South', 'East', 'West'""" try: response = self.session.post(self.game_url, {'dir': direction}, timeout=TIMEOUT) if response.status_code == 200: return response.json() else: self.pprint("Error HTTP ", str(response.status_code), ": ", response.text) self.time_out += 1 self.running = False return {'game': {'finished': True}} except requests.exceptions.RequestException as e: self.pprint("Error at client.move;", str(e)) self.running = False return {'game': {'finished': True}} def display_game(self): """Display game data on the U.I""" if not self.gui.paused: # Draw the map self.gui.draw_map(self.bot.game.board_map, self.bot.path_to_goal, self.bot.game.heroes) # Use the following methods to display datas # within the interface self.gui.display_url(self.bot.game.url) self.gui.display_bot_name(self.bot.game.hero.name) self.gui.display_last_move(self.bot.hero_last_move) self.gui.display_pos(self.bot.game.hero.pos) self.gui.display_last_pos(self.bot.last_pos) self.gui.display_last_life(self.bot.last_life) self.gui.display_life(self.bot.game.hero.life) self.gui.display_last_action(self.bot.last_action) self.gui.display_turn((self.bot.game.turn/4)-1, self.bot.game.max_turns/4) self.gui.display_elo(self.bot.game.hero.elo) self.gui.display_gold(self.bot.game.hero.gold) self.gui.display_last_gold(self.bot.last_gold) self.gui.display_mine_count(str(self.bot.game.hero.mine_count)+"/"+str(len(self.bot.game.mines))) self.gui.display_last_mine_count(str(self.bot.last_mine_count)+"/"+str(len(self.bot.game.mines))) # You can also use those methods to display more information # Function names are explicit, don't they ? self.gui.display_nearest_mine(self.bot.nearest_mine_pos) self.gui.display_nearest_hero(self.bot.nearest_enemy_pos) self.gui.display_nearest_tavern(self.bot.nearest_tavern_pos) self.gui.display_last_nearest_mine(self.bot.last_nearest_mine_pos) self.gui.display_last_nearest_hero(self.bot.last_nearest_enemy_pos) self.gui.display_last_nearest_tavern(self.bot.last_nearest_tavern_pos) # Print informations about other players self.gui.display_heroes(self.bot.game.heroes, self.bot.game.hero.bot_id) # Print a *list of tuples* representing what you think can be usefull # i.e an heuristic result self.gui.display_decision(self.bot.decision) # Print *list of tuples* representing # the estimated path to reach the goal if any. # If too long the path will be truncated to fit # in the display self.gui.display_path(self.bot.path_to_goal) # Move cursor along the time line (cost cpu time) cursor_pos = int(float(self.gui.TIME_W) // self.bot.game.max_turns * self.bot.game.turn) self.gui.move_time_cursor(cursor_pos) # Finally display selected move self.gui.display_move(self.bot.hero_move) self.gui.display_action(self.bot.action) # Add whathever you want to log using self.gui.append_log() # self.gui.append_log("Whatever") elapsed = round(time.time() - self.start_time, 3) self.gui.display_elapsed(elapsed) self.gui.refresh()
class Client: def __init__(self): self.start_time = None self.gui = None self.session = None self.state = None self.running = True self.game_url = None self.config = Config() self.bot = Curses_ui_bot() # Our bot self.states = [] self.delay = 0.5 # Delay in s between turns in replay mode self.victory = 0 self.time_out = 0 def pprint(self, *args, **kwargs): """Display args in the bot gui or print it if no gui is available For debugging purpose consider using self.gui.append_log() """ printable = "" for arg in args: printable = printable + str(arg) + " " if kwargs and len(kwargs): a = 1 coma = "" printable = printable + "[" for k, v in kwargs.iteritems(): if 1 < a < len(kwargs): coma = ", " else: coma = "]" printable = printable + str(k) + ": " + str(v) + coma a = a + 1 if self.gui and self.gui.running: # bot has a gui so we add this entries to its log panel if self.gui.log_win: self.gui.append_log(printable) self.gui.refresh() else: print printable def load_config(self): """Load saved config from file ~/.vindinium/config""" config_parser = ConfigParser.ConfigParser() user_home_dir = os.path.expanduser("~") config_file_name = os.path.join(user_home_dir, ".vindinium", "config") try: if os.path.isfile(config_file_name): config_parser.read(config_file_name) self.config.server_url = config_parser.get( "game", "server_url") self.config.game_mode = config_parser.get("game", "game_mode") self.config.map_name = config_parser.get("game", "map_name") self.config.key = config_parser.get("game", "key") self.config.number_of_games = config_parser.getint( "game", "number_of_games") self.config.number_of_turns = config_parser.getint( "game", "number_of_turns") except (IOError, ConfigParser.Error) as e: self.gui.quit_ui() print "Error while loading config file", config_file_name, ":", e quit(1) def save_config(self): """Save config to file in ~/.vindinium/config""" config_parser = ConfigParser.ConfigParser() user_home_dir = os.path.expanduser("~") config_file_name = os.path.join(user_home_dir, ".vindinium", "config") try: if not os.path.isdir(os.path.join(user_home_dir, ".vindinium")): os.makedirs(os.path.join(user_home_dir, ".vindinium")) config_parser.add_section("game") with open(config_file_name, "w") as config_file: for key, value in self.config.__dict__.items(): config_parser.set("game", key, value) config_parser.write(config_file) except (IOError, ConfigParser.Error) as e: self.gui.quit_ui() print "Error while saving config file", config_file_name, ":", e quit(1) def load_game(self, game_file_name): """Load saved game from file""" # Reset our bot and self.states self.states = [] try: with open(game_file_name, "r") as game_file: for line in game_file.readlines(): if len(line.strip(chr(0)).strip()) > 0: self.states.append(ast.literal_eval(line)) self.state = self.states[0] except (IOError, IndexError) as e: self.gui.quit_ui() print "Error while loading game file", game_file_name, ":", e quit(1) def save_game(self): """Save game to file in ~/.vindinium/save/<game ID>""" user_home_dir = os.path.expanduser("~") try: # Get game_id from game sate game_id = self.state['game']["id"] except KeyError: try: # State has not been downloaded # Try to get game_id from last state saved if any game_id = self.states[0]['game']["id"] except IndexError: self.pprint( "No states available for this game, unable to save game.") game_file_name = os.path.join(user_home_dir, ".vindinium", "save", game_id) try: if not os.path.isdir( os.path.join(user_home_dir, ".vindinium", "save")): os.makedirs(os.path.join(user_home_dir, ".vindinium", "save")) with open(game_file_name, "w") as game_file: for state in self.states: game_file.write(str(state) + "\n") self.pprint("Game saved: " + game_file_name) except IOError as e: self.gui.append_log("Error while saving game file", game_file_name, ":", e) def download_game_file(self, game_file_url): # I will treat no other forbidden char than space char. game_file_url = game_file_url.replace(" ", "%20") # # FIXME : # # Game file available online at http://vindinium.org/events/<gameId> # are not parsable by ast.literal_eval() ???? # # self.session = requests.session() # response = self.session.get(game_file_url, timeout=10*60) # if response.status_code == 200: # for line in response.text: # line = line.strip(chr(0)).strip() # if len(line) > 0: # self.states.append(ast.literal_eval(line)) <<< Here is the problem # # MUST TRY: # games=[json.loads(line[6:]) for line in requests.get(game_file_url).content.splitlines() if line.startswith("data: ")] # self.gui.quit_ui() os.system('cls' if os.name == 'nt' else 'clear') print "********************************************************" print "* Feature not available yet. *" print "* Please wait for U.I restart *" print "********************************************************" for i in reversed(range(1, 6)): print i time.sleep(1) self.start_ui() def start_ui(self): """Start the curses UI""" self.bot = Curses_ui_bot() self.running = True self.game_url = None self.states = [] self.state = None self.gui = ui.tui() choice = self.gui.ask_main_menu() if choice == '1': # Load config then play game self.load_config() self.gui.draw_game_windows() self.play() elif choice == '2': # Setup game self.config = Config() choice = self.gui.ask_game_mode() if choice == '1': # Arena mode config self.config.game_mode = "arena" self.config.number_of_turns = 300 self.config.number_of_games = self.gui.ask_number_games() elif choice == '2': # Training mode config self.config.game_mode = "training" self.config.number_of_games = 1 self.config.number_of_turns = self.gui.ask_number_turns() self.config.map_name = "m" + str(self.gui.ask_map()) self.config.server_url = self.gui.ask_server_url( self.config.game_mode) self.config.key = self.gui.ask_key(self.config.game_mode) if self.gui.ask_save_config(): self.save_config() if self.gui.ask_play_game(): self.gui.draw_game_windows() self.play() else: self.start_ui() elif choice == '3': # Load game from file game_file_name = self.gui.ask_game_file_path() self.load_game(game_file_name) self.gui.draw_game_windows() self.replay() elif choice == '4': # Load game from URL game_file_url = self.gui.ask_game_file_url() self.download_game_file(game_file_url) self.gui.draw_game_windows() self.replay() elif choice == '5': # quit self.gui.quit_ui() exit(0) if self.gui.running and self.gui.help_win: key = None while key != 'm': key = self.gui.ask_quit() if key == 's': self.save_game() elif key == 'r': self.replay() self.gui.clear() self.start_ui() def play(self): """Play all games""" self.victory = 0 self.time_out = 0 for i in range(self.config.number_of_games): # start a new game if self.bot.running: self.start_game() gold = 0 winner = ("Noone", -1) for player in self.bot.game.heroes: if int(player.gold) > gold: winner = (player.name, player.bot_id) gold = int(player.gold) if winner[1] == self.bot.game.hero.bot_id: self.victory += 1 self.pprint("* " + winner[0] + " wins. ******************") self.gui.display_summary( str(i + 1) + "/" + str(self.config.number_of_games), str(self.victory) + "/" + str(i + 1), str(self.time_out) + "/" + str(i + 1)) self.pprint("Game finished: " + str(i + 1) + "/" + str(self.config.number_of_games)) def replay(self): """Replay last game""" # Restart with a new bot self.bot = Curses_ui_bot() for i in range(self.config.number_of_games): # start a new game if self.bot.running: self.restart_game() gold = 0 winner = "Noone" for player in self.bot.game.heroes: if int(player.gold) > gold: winner = player.name gold = int(player.gold) self.pprint("**** " + winner + " wins. ****") self.pprint("Game finished: " + str(i + 1) + "/" + str(self.config.number_of_games)) def start_game(self): """Starts a game with all the required parameters""" self.running = True # Delete prévious game states self.states = [] # Restart game with brand new bot self.bot = Curses_ui_bot() # Default move is no move ! direction = "Stay" # Create a requests session that will be used throughout the game self.pprint('Connecting...') self.session = requests.session() if self.config.game_mode == 'arena': self.pprint('Waiting for other players to join...') try: # Get the initial state # May raise error if self.get_new_state() returns # no data or inconsistent data (network problem) self.state = self.get_new_game_state() self.states.append(self.state) self.pprint("Playing at: " + self.state['viewUrl']) except (KeyError, TypeError) as e: # We can not play a game without a state self.pprint("Error: Please verify your settings.") self.pprint("Settings:", self.config.__dict__) self.running = False return for i in range(self.config.number_of_turns + 1): if self.running: # Choose a move self.start_time = time.time() try: while sys.stdin in select.select([sys.stdin], [], [], 0)[0]: line = sys.stdin.read(1) if line.strip() == "q": self.running = False self.bot.running = False break elif line.strip() == "p": self.gui.pause() elif line.strip() == "s": self.save_game() if self.bot.running: direction = self.bot.move(self.state) self.display_game() except Exception as e: # Super error trap ! if self.gui.log_win: self.pprint("Error at client.start_game:", str(e)) self.pprint( "If your code or your settings are not responsible of this error, please report this error to:" ) self.pprint("[email protected].") self.gui.pause() self.running = False return if not self.is_game_over(): # Send the move and receive the updated game state self.game_url = self.state['playUrl'] self.state = self.send_move(direction) self.states.append(self.state) # Clean up the session self.session.close() def restart_game(self): """Starts a game with all the required parameters""" self.running = True try: # Get the initial state self.state = self.states[0] self.pprint("Replaying: " + self.state['viewUrl']) except (IndexError, KeyError) as e: self.pprint("Error while trying to replay game.") self.pprint("Game states length:", len(self.states)) self.running = False return self.gui.draw_help_win() for state in self.states: self.state = state if self.running: # Choose a move self.start_time = time.time() try: while sys.stdin in select.select([sys.stdin], [], [], 0)[0]: line = sys.stdin.read(1) if line.strip() == "q": self.running = False self.bot.running = False break elif line.strip() == "p": self.gui.pause() elif line.strip() == "s": self.save_game() if self.bot.running: self.bot.process_game(state) self.display_game() except Exception, e: if self.gui.log_win: self.pprint("Error at client.restart_game:", str(e)) self.pprint( "If your code or your settings are not responsible of this error, please report this error to:" ) self.pprint("[email protected].") self.gui.pause() self.running = False return if not self.is_game_over(): # Replay next turn self.game_url = state['playUrl'] time.sleep(self.delay)