diff --git a/klient/client.py b/klient/client.py index 3a1ed40..65bbba2 100644 --- a/klient/client.py +++ b/klient/client.py @@ -13,13 +13,14 @@ from typing import List, Optional, Tuple parser = argparse.ArgumentParser() parser.add_argument("--token", type=str, required=True, help="API token.") -parser.add_argument("--program", type=str, required=True, help="Program to run.") parser.add_argument("--server", type=str, default="http://localhost:5000", help="Server address.") parser.add_argument("--game", type=str, default="main", help="'main' or 'test_#'.") -parser.add_argument("--copy", default=False, action="store_true", help="Save a copy of the program to ensure the same code is used all the time.") -parser.add_argument("--log-level", type=str, default="warning", choices=["error", "warning", "info"]) +parser.add_argument("--command", type=str, nargs="+", default=["python3", "%"], help="Command to execute as strategy code. Use '%' for program.") +parser.add_argument("--program", type=str, default=None, help="Program to substitute to command.") +parser.add_argument("--copy", default=False, action="store_true", + help="Save a copy of the program to ensure the same code is used all the time.") +parser.add_argument("--log-level", type=str, default="info", choices=["error", "warning", "info"]) parser.add_argument("--save-state", type=str, default=None, help="Save state to this file.") -# parser.add_argument("program", nargs=argparse.REMAINDER, help="Program to run.") TIME_BEFORE_RETRY = 2.0 @@ -29,12 +30,10 @@ logger = logging.getLogger("client") def main(args: argparse.Namespace) -> None: logger.setLevel(args.log_level.upper()) - program = args.program - if args.copy: - program = tempfile.mktemp() - shutil.copyfile(args.program, program) - program = "./" + program min_round = 0 + program = None + if args.save_state is None: + program = get_command(args) while True: state = get_state(min_round, args) @@ -60,12 +59,28 @@ def main(args: argparse.Namespace) -> None: send_turn(turn, round, args) +def get_command(args) -> List[str]: + if args.program is None: + logger.error("Program not specified.") + sys.exit(1) + + program = args.program + if args.copy: + program = tempfile.mktemp() + shutil.copyfile(args.program, program) + + command: List[str] = [] + for arg in args.command: + command.append(arg.replace("%", program)) + return command + + def run_subprocess( - program: str, state_json: str, timeout: Optional[float] + command: List[str], state_json: str, timeout: Optional[float] ) -> Optional[str]: """Run user program and return its output.""" - proc = Popen([program], encoding="utf-8", + proc = Popen(command, encoding="utf-8", stdin=PIPE, stdout=PIPE, stderr=PIPE) try: stdout, stderr = proc.communicate(input=state_json, timeout=timeout)