From c43a57bb1afa5188b91e0e866ccf63262e004e6e Mon Sep 17 00:00:00 2001 From: AlexHell Date: Fri, 2 Aug 2019 01:33:13 +0300 Subject: [PATCH 1/2] =?UTF-8?q?=D1=80=D0=B0=D1=81=D1=87=D0=B5=D1=82=20?= =?UTF-8?q?=D0=B2=D1=80=D0=B5=D0=BC=D0=B5=D0=BD=D0=B8=20=D0=B8=20=D0=B2?= =?UTF-8?q?=D1=8B=D0=B4=D0=B0=D1=87=D0=B0=20'time=5Fleft'=20=D0=B2=20FileC?= =?UTF-8?q?lient,=20=D1=80=D0=B5=D1=84=D0=B0=D0=BA=D1=82=D0=BE=D1=80=D0=B8?= =?UTF-8?q?=D0=BD=D0=B3=20(TcpClient=20=D0=B8=20FileClient=20=D0=BE=D1=82?= =?UTF-8?q?=20=D0=B1=D0=B0=D0=B7=D0=BE=D0=B2=D0=BE=D0=B3=D0=BE=20=D0=BA?= =?UTF-8?q?=D0=BB=D0=B0=D1=81=D1=81=D0=B0)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- paperio/local_runner/clients.py | 77 +++++++++++++++++++++------------ 1 file changed, 50 insertions(+), 27 deletions(-) diff --git a/paperio/local_runner/clients.py b/paperio/local_runner/clients.py index 27e6622..fe0643d 100644 --- a/paperio/local_runner/clients.py +++ b/paperio/local_runner/clients.py @@ -147,13 +147,41 @@ def send_message(self, t, d): pass -class TcpClient(Client): - EXECUTION_LIMIT = datetime.timedelta(seconds=MAX_EXECUTION_TIME) +class BasicProxyClient(Client): + REQUEST_LIMIT = datetime.timedelta(seconds=REQUEST_MAX_TIME) + TOTAL_LIMIT = datetime.timedelta(seconds=MAX_EXECUTION_TIME) + + def __init__(self): + self.execution_time = datetime.timedelta() + self.started_measure_time = None + + def prepare_message_bytes(self, t, d): + msg = { + 'type': t, + 'params': d, + 'time_left': round((self.TOTAL_LIMIT - self.execution_time).total_seconds() * 1000) + } + return '{}\n'.format(json.dumps(msg)).encode() + + def begin_measure_time(self): + self.started_measure_time = datetime.datetime.now() + + def end_measure_time(self): + request_time = (datetime.datetime.now() - self.started_measure_time) + if request_time > self.REQUEST_LIMIT: + raise Exception('request timeout error') + + self.execution_time += request_time + if self.execution_time > self.TOTAL_LIMIT: + raise Exception('sum timeout error') + + +class TcpClient(BasicProxyClient): def __init__(self, reader, writer): + super(TcpClient, self).__init__() self.reader = reader self.writer = writer - self.execution_time = datetime.timedelta() self.solution_id = None def save_log_to_disk(self, log, path): @@ -178,31 +206,25 @@ async def set_solution_id(self): return bool(self.solution_id) def send_message(self, t, d): - msg = { - 'type': t, - 'params': d, - 'time_left': round((self.EXECUTION_LIMIT-self.execution_time).total_seconds()*1000) - } - msg_bytes = '{}\n'.format(json.dumps(msg)).encode() + msg_bytes = self.prepare_message_bytes(t, d) self.writer.write(msg_bytes) async def get_command(self): try: - before = datetime.datetime.now() + self.begin_measure_time() + # z = await asyncio.wait_for(self.reader.readline(), timeout=REQUEST_MAX_TIME) if not z: raise ConnectionError('Connection closed') - self.execution_time += (datetime.datetime.now() - before) - if self.execution_time > self.EXECUTION_LIMIT: - raise Exception('sum timeout error') + # + self.end_measure_time() except asyncio.TimeoutError: raise asyncio.TimeoutError('read timeout error') + try: - z = json.loads(z.decode()) + return json.loads(z.decode()) except ValueError: - z = {'debug': 'cant pars json'} - - return z + return {'debug': 'cant pars json'} def close(self): self.writer.close() @@ -211,8 +233,10 @@ def get_solution_id(self): return self.solution_id -class FileClient(Client): +class FileClient(BasicProxyClient): + def __init__(self, path_to_script, path_to_log=None): + super(FileClient, self).__init__() self.process = Popen(path_to_script, stdout=PIPE, stdin=PIPE) self.last_message = None if path_to_log is None: @@ -223,20 +247,19 @@ def __init__(self, path_to_script, path_to_log=None): self.path_to_log = path_to_log def send_message(self, t, d): - msg = { - 'type': t, - 'params': d - } - msg_bytes = '{}\n'.format(json.dumps(msg)).encode() - + msg_bytes = self.prepare_message_bytes(t, d) self.process.stdin.write(msg_bytes) self.process.stdin.flush() async def get_command(self): try: - line = self.process.stdout.readline().decode('utf-8') - state = json.loads(line) - return state + self.begin_measure_time() + # + z = self.process.stdout.readline().decode('utf-8') + # + self.end_measure_time() + + return json.loads(z) except Exception as e: return {'debug': str(e)} From 6118a9bcdc8646e0e268a84a9d2decf9d5e6139e Mon Sep 17 00:00:00 2001 From: AlexHell Date: Fri, 2 Aug 2019 18:29:13 +0300 Subject: [PATCH 2/2] =?UTF-8?q?=D1=84=D0=BB=D0=B0=D0=B3=20'--ai-timeout'?= =?UTF-8?q?=20(=D0=BF=D0=BE=20=D1=83=D0=BC=D0=BE=D0=BB=D1=87=D0=B0=D0=BD?= =?UTF-8?q?=D0=B8=D1=8E=20'off')=20=D0=B4=D0=BB=D1=8F=20FileClient;=20?= =?UTF-8?q?=D0=B2=20scene.py=20=D0=BD=D0=B0=D0=B4=D0=BF=D0=B8=D1=81=D1=8C?= =?UTF-8?q?=20'END=20TICK'=20=D0=B2=D0=BC=D0=B5=D1=81=D1=82=D0=BE=20'TIMEO?= =?UTF-8?q?UT'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- paperio/local_runner/clients.py | 9 ++++++--- paperio/local_runner/game_objects/scene.py | 2 +- paperio/local_runner/localrunner.py | 5 +++-- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/paperio/local_runner/clients.py b/paperio/local_runner/clients.py index fe0643d..34a6026 100644 --- a/paperio/local_runner/clients.py +++ b/paperio/local_runner/clients.py @@ -235,10 +235,11 @@ def get_solution_id(self): class FileClient(BasicProxyClient): - def __init__(self, path_to_script, path_to_log=None): + def __init__(self, path_to_script, path_to_log=None, check_ai_timeout=False): super(FileClient, self).__init__() self.process = Popen(path_to_script, stdout=PIPE, stdin=PIPE) self.last_message = None + self.check_ai_timeout = check_ai_timeout if path_to_log is None: base_dir = os.getcwd() now = datetime.datetime.now().strftime('%Y_%m_%d-%H-%M-%S.log.gz') @@ -253,11 +254,13 @@ def send_message(self, t, d): async def get_command(self): try: - self.begin_measure_time() + if self.check_ai_timeout: + self.begin_measure_time() # z = self.process.stdout.readline().decode('utf-8') # - self.end_measure_time() + if self.check_ai_timeout: + self.end_measure_time() return json.loads(z) except Exception as e: diff --git a/paperio/local_runner/game_objects/scene.py b/paperio/local_runner/game_objects/scene.py index a5a1c7a..d527a87 100644 --- a/paperio/local_runner/game_objects/scene.py +++ b/paperio/local_runner/game_objects/scene.py @@ -79,7 +79,7 @@ def reset_leaderboard(self): self.leaderboard_rows_count = 0 def show_game_over(self, timeout=False): - self.game_over_label.text = 'TIMEOUT' if timeout else 'GAME OVER' + self.game_over_label.text = 'END TICK' if timeout else 'GAME OVER' self.game_over_label.draw() def draw_grid(self): diff --git a/paperio/local_runner/localrunner.py b/paperio/local_runner/localrunner.py index 49ab49c..f2a16cc 100755 --- a/paperio/local_runner/localrunner.py +++ b/paperio/local_runner/localrunner.py @@ -25,7 +25,8 @@ help='Path to executable with strategy for player {}'.format(i)) parser.add_argument('--p{}l'.format(i), type=str, nargs='?', help='Path to log for player {}'.format(i)) -parser.add_argument('-t', '--timeout', type=str, nargs='?', help='off/on timeout', default='on') +parser.add_argument('-t', '--timeout', type=str, nargs='?', help='off/on tick limit per game', default='on') +parser.add_argument('--ai-timeout', type=str, nargs='?', help='off/on AI execution time limit', default='off') parser.add_argument('-s', '--scale', type=int, nargs='?', help='window scale (%%)', default=100) parser.add_argument('--replay', help='Replay visio.gz') parser.add_argument('--no-gui', help='Disable default gui', action='store_true') @@ -149,7 +150,7 @@ def get_solution_id(self): elif arg == 'simple_bot': client = SimplePythonClient() else: - client = FileClient(arg.split(), getattr(args, 'p{}l'.format(i))) + client = FileClient(arg.split(), getattr(args, 'p{}l'.format(i)), args.ai_timeout == 'on') clients.append(client)