What do you mean by information restrictions? What exactly is restricted? If I were to use some side-channel to determine that I was being simulated by an opponent and forkbomb if so, would I be eliminated for hacking? Would they be eliminated for overusing compute? (after all, it wasn’t my code per say that forkbombed, but their code simulating my code) Would I be eliminated for being a dick? (Which would be self-evident, at any rate)
You say in another comment, “Simulator bots are legal for programmers to write provided they never crash, slow the game to a crawl, etc. Any bot (even a non-simulator) that does will be disqualified.” I’m just concerned about the edge case where someone writes the troll code described above, and suddenly every person who submitted a simulator bot (i.e. Zak M. Davis) gets DQ’d. The rules as written suggest that such a bot (presuming it does not preserve information across rounds) would be perfectly legal and it’s Zak’s own fault for executing untrusted code, but that seems to effectively prohibit simulators as there’s an infinite plurality of side-channels through which to do this.
A few possible resolutions would be:
Whoever wrote the code that contains the instructions to forkbomb is at fault. Essentially, don’t be a dick.
Any information not explicitly given is forbidden. Essentially, you don’t know if you’re being simulated, and you’re not allowed to find out.
Untrusted code is untrusted code; simulate at your own risk. Essentially, if Zak executes my forkbomb, that’s his problem. (Well, your problem as well to fix it, but his fault.)
Resolution 2 seems the most reasonable to me, but if you choose it I humbly request a way to locally overwrite get_opponent_source so you simulate your opponent’s response without risking infinite recursion. (Such an overwrite is probably standard python, but being ignorant of your implementation I’d be concerned about screwing something up and not being able to detect the mistake in testing)
EDIT: Upon further consideration it seems inevitable that Zak will get DQ’d for infinite recursion. So I must be missing something.
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) [..]
What do you mean by information restrictions? What exactly is restricted? If I were to use some side-channel to determine that I was being simulated by an opponent and forkbomb if so, would I be eliminated for hacking? Would they be eliminated for overusing compute? (after all, it wasn’t my code per say that forkbombed, but their code simulating my code) Would I be eliminated for being a dick? (Which would be self-evident, at any rate)
You say in another comment, “Simulator bots are legal for programmers to write provided they never crash, slow the game to a crawl, etc. Any bot (even a non-simulator) that does will be disqualified.” I’m just concerned about the edge case where someone writes the troll code described above, and suddenly every person who submitted a simulator bot (i.e. Zak M. Davis) gets DQ’d. The rules as written suggest that such a bot (presuming it does not preserve information across rounds) would be perfectly legal and it’s Zak’s own fault for executing untrusted code, but that seems to effectively prohibit simulators as there’s an infinite plurality of side-channels through which to do this.
A few possible resolutions would be:
Whoever wrote the code that contains the instructions to forkbomb is at fault. Essentially, don’t be a dick.
Any information not explicitly given is forbidden. Essentially, you don’t know if you’re being simulated, and you’re not allowed to find out.
Untrusted code is untrusted code; simulate at your own risk. Essentially, if Zak executes my forkbomb, that’s his problem. (Well, your problem as well to fix it, but his fault.)
Resolution 2 seems the most reasonable to me, but if you choose it I humbly request a way to locally overwrite get_opponent_source so you simulate your opponent’s response without risking infinite recursion. (Such an overwrite is probably standard python, but being ignorant of your implementation I’d be concerned about screwing something up and not being able to detect the mistake in testing)
EDIT: Upon further consideration it seems inevitable that Zak will get DQ’d for infinite recursion. So I must be missing something.
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) [..]