Hacking the game engine is against the rules. If your opponent decides to simulate your code then hacking them from inside your opponents’ simulation is allowed. Your code is allowed to peek at the game engine for the purposes of figuring out if it is being simulated by someone else’s code. Peeking at the game engine for other reasons, like figuring out how many of each opponents remain or attempting to modify the game engine itself or attempting to modify your opponents’ code from anywhere outside their own simulation of you is against the rules.
Anything that could damage the game’s execution environment is a security risk and grounds for disqualification. Forkbombing your opponent is really pushing things…but technically legal. I would prefer something more mundane like calling exit() or an infinite loop. Anything more damaging than a forkbomb constitutes a security risk and is not allowed under any circumstances. If you are going to write any malware-like then code (including forkbombs) then please draw my attention to it in some way what the intended behavior is so I can mitigate any unintended consequences to my own systems. Even better would be to PM me for explicit permission.
Any code which gets disabled by malware will get disqualified from the tournament. I will then restart the tournament with the broken competitor(s) removed.
The resolution is #3 “Untrusted code is untrusted code; simulate at your own risk.”
The function get_opponent_source returns source code as a string. You can trivially overwrite it in your local environment with the command get_opponent_source = my_custom_get_opponent_source. (This is standard Python.) If you execute your opponent’s code in a simulation where get_opponent_source has been rebound[1] to a new function (and have not otherwise left alternate attack vectors open) I see no reason why this would would trigger infinite recursion.
If you rebind the get_opponent_source function in your local environment in a reasonable way that is itself obviously not an attempt to breach anything then I will consider that a bug in the game engine and attempt to engineer a fix.
I have not yet read over Zak’s code in detail nor have I attempted to execute it. If it infinitely recurses then it will be disqualified.
Edit: Do note that an unobfuscated simulator bot is likely to have a statement something along the lines of from extra import get_opponent_source. If you overwrite the get_opponent_source function and then execute your opponent’s code, it is possible your opponent’s from extra import get_opponent_source may un-overwrite your rebinding.
In what order do programs get disqualified? For example, if I submit a program with an infinite loop, every other program using simulation will also go into infinite loop when meeting with my program as detecting infinite loops generally isn’t theoretically feasible. Is my program disqualified before the others? What is the general principle?
EDIT: An unrelated question: Do round numbers start from 0 or 1? In the post you write “Unlike Zvi’s original game, you do get to know what round it is. Rounds are indexed starting at 0.”, but also: “Your class must have an __init__(self, round=1) [..]”. Why not have the default initializer also use 0 if the round numbers start from zero?
First a run your program against one or more simple programs without any simulations. If your program hits an infinite loop there then you will be disqualified before you get to infect any other programs. In this way you can be disqualified before the others.
If your program passes the simple tests then it will join the pool and against all other programs which have passed the initial test. All programs which fail to terminate at this stage will be removed simultaneously.
Thank you for the bug report. I have corrected __init__(self, round=1) [..] to __init__(self, round=0) [..]
Hacking the game engine is against the rules. If your opponent decides to simulate your code then hacking them from inside your opponents’ simulation is allowed. Your code is allowed to peek at the game engine for the purposes of figuring out if it is being simulated by someone else’s code. Peeking at the game engine for other reasons, like figuring out how many of each opponents remain or attempting to modify the game engine itself or attempting to modify your opponents’ code from anywhere outside their own simulation of you is against the rules.
Anything that could damage the game’s execution environment is a security risk and grounds for disqualification. Forkbombing your opponent is really pushing things…but technically legal. I would prefer something more mundane like calling
exit()
or an infinite loop. Anything more damaging than a forkbomb constitutes a security risk and is not allowed under any circumstances. If you are going to write any malware-like then code (including forkbombs) then please draw my attention to it in some way what the intended behavior is so I can mitigate any unintended consequences to my own systems. Even better would be to PM me for explicit permission.Any code which gets disabled by malware will get disqualified from the tournament. I will then restart the tournament with the broken competitor(s) removed.
The resolution is #3 “Untrusted code is untrusted code; simulate at your own risk.”
The function
get_opponent_source
returns source code as a string. You can trivially overwrite it in your local environment with the commandget_opponent_source = my_custom_get_opponent_source
. (This is standard Python.) If you execute your opponent’s code in a simulation whereget_opponent_source
has been rebound[1] to a new function (and have not otherwise left alternate attack vectors open) I see no reason why this would would trigger infinite recursion.If you rebind the
get_opponent_source
function in your local environment in a reasonable way that is itself obviously not an attempt to breach anything then I will consider that a bug in the game engine and attempt to engineer a fix.I have not yet read over Zak’s code in detail nor have I attempted to execute it. If it infinitely recurses then it will be disqualified.
Edit: Do note that an unobfuscated simulator bot is likely to have a statement something along the lines of
from extra import get_opponent_source
. If you overwrite theget_opponent_source
function and then execute your opponent’s code, it is possible your opponent’sfrom extra import get_opponent_source
may un-overwrite your rebinding.In what order do programs get disqualified? For example, if I submit a program with an infinite loop, every other program using simulation will also go into infinite loop when meeting with my program as detecting infinite loops generally isn’t theoretically feasible. Is my program disqualified before the others? What is the general principle?
EDIT: An unrelated question: Do round numbers start from 0 or 1? In the post you write “Unlike Zvi’s original game, you do get to know what round it is. Rounds are indexed starting at 0.”, but also: “Your class must have an __init__(self, round=1) [..]”. Why not have the default initializer also use 0 if the round numbers start from zero?
First a run your program against one or more simple programs without any simulations. If your program hits an infinite loop there then you will be disqualified before you get to infect any other programs. In this way you can be disqualified before the others.
If your program passes the simple tests then it will join the pool and against all other programs which have passed the initial test. All programs which fail to terminate at this stage will be removed simultaneously.
Thank you for the bug report. I have corrected
__init__(self, round=1) [..]
to__init__(self, round=0) [..]