def main(strategy_type, admin_host, admin_port): if not isinstance(admin_port, int): raise ValueError() if strategy_type == "random": strategy = Strategies.RandomStrategy() elif strategy_type == "look-ahead": try: with open("strategy.config", "r") as f: num_looks_ahead = parse_json( f.read())[0]["value"]["look-ahead"] strategy = Strategies.NLooksAheadStrategy(num_looks_ahead) except FileNotFoundError: print( "strategy.config for look-ahead strategy file not found in directory!" ) sys.exit(1) elif strategy_type == "smart": strategy = Strategies.SmartStrategy() elif strategy_type == "greedy": strategy = Strategies.GreedyStrategy() elif strategy_type == "interactive": strategy = Strategies.InteractiveStrategy() elif strategy_type == "cheating": strategy = Strategies.CheatingStrategy() else: raise ValueError("Unsupported strategy type!") player = SmartPlayer(input("Type your player's name: "), strategy) player_driver = PlayerDriver(player, admin_host, admin_port) player_driver.start_driver()
def start_driver(self): while True: # self.s is the TCP socket connected to the referee data = self.s.recv(1024) if not data: print("Admin terminated connection.") break data = data.strip().decode('utf-8') # print("player driver received: ", data) # debug # print("--------------------------------") # debug json_values = parse_json( data ) # TODO: should only be one element array - what behaviour when not? try: for json_val in json_values: command = json_val["value"] if is_valid_register_command(command): name = self.player.register( ) # should raise error since player is already registered self._send_response(name) elif is_valid_place_command(command): color, board_list = command[1:] placements = self.player.place(board_list, color) self._send_response(placements) elif is_valid_play_command(command): board_list = command[1] plays = self.player.play(board_list) self._send_response(plays) elif is_valid_game_over_command(command): name = command[1] acknowledgement = self.player.notify(name) self._send_response(acknowledgement) else: raise InvalidCommand( "Invalid command passed to Player! Given:".format( command)) # TODO - refactor - making assumption about admin accepting these responses except (InvalidCommand, IllegalPlay) as e: print(e) # debug print( json.dumps( "Santorini is broken! Too many tourists in such a small place..." )) # self._send_response("InvalidCommand") self.s.close() break except ContractViolation as e: # this helps us detect bugs in our implementation print(e) # debug self._send_response("ContractViolation")
def _send_message_and_recv_response(self, message): """ :param any message: an object that can be converted to json via json.dumps() . :return: an object that can be converted to json via json.dumps() :rtype: any """ data = bytes(json.dumps(message) + "\n", "utf-8") self.s.sendall(data) response = str(self.s.recv(1024), "utf-8") # Receive data from the server if not response: raise IllegalResponse("Response was empty!") response = parse_json(response)[0]["value"] return response
raise ValueError() try: # wrapped in try-except to gracefully close the socket if anything unexpected happens. admin.run_tournament() admin.print_rankings() except Exception as e: print(e) admin.s.close() if __name__ == "__main__": try: tournament_type, n = sys.argv[1:] with open("santorini.config") as f: data = parse_json(f.read())[0]["value"] ip, port = data["IP"], data["port"] default_player_path = data["default-player"] DefaultPlayerModule = SourceFileLoader( "DefaultPlayerModule", default_player_path).load_module() DefaultPlayer = DefaultPlayerModule.Player main(tournament_type[1:], int(n), ip, port, DefaultPlayer) except ValueError: print("usage: ./santorini.sh [option] ... [-cup n | -league n]") print("n must be integer >= 0.") sys.exit(1) except AttributeError: print( "Module at path given in santorini.config does not have attribute named 'Player'!"