I don’t know quine at all and can’t easily understand exactly what all these guys are doing but:
This is obviously NOT a stable metagame; in both senses.
If we ran this tournament again the random-bots would get utterly destroyed (since it’s very easy/fast to check for them and defect).
If we ran this tournament with multiple rounds, where successful strategies survive and unsuccessful die, and there was even one defect-against-randombot code in the mix, it will win if it doesn’t die early.
My guess-happy summary of what happened is this: The core problem is very hard, so most people instead did something simple, often very simple (cooperate bot, defect bot, random bot—which won!) with a small number of people trying for real. The people trying for real, however, spent all their energy planning for other people trying for real and trying to fool them, rather than trying to act correctly against all the super-simple programs, because if you put in that much work you think other people will mostly put in at least some work (R has an entire long blog post of metagame and strategic analysis which is COMPLETELY wrong in exactly this way, in real life I do this a lot). That, combined with programming errors since the task involved was actually hard, prevented them from winning.
The lesson here, I think, is more about how people react to such tournaments than it is about the actual problem at hand; if anyone had assumed their opponents would either be simple or hopelessly complex, they could have written a program that defects against programs that don’t look at their code or otherwise are clearly safe defections, does something hard to exploit against everyone else that likely is somewhat random, and win easily.
Your summary seems pretty accurate. I don’t think there were many programming errors outside of P’s meltdown, though. Also, as has been touched upon elsewhere in these comments, some of the failures to maximally exploit simple bots were necessary side effects of the attempts to trick complex bots, not just failures to anticipate there being a significant number of simple bots at all. (Sort of a quantitative instead of qualitative prediction mistake—we just thought there’d be more complex bots than simple bots).
One clue towards the general simplicity of the field is the generally atrocious formatting (e.g. close-parens on their own lines)--not many people seem to have had too much experience with Lisp, let alone Lisp projects as complex as this game can get. That’s a shame, but it’s not like any non-Lisp languages are remotely suitable for the kind of source analysis we all wanted to see in this game.
If the tournament were run a second time, my expectation would be that such programs would abound (since writing “if they showed signs of life randomly do something but usually defect, else cooperate” is pretty easy), there’d still be a bunch of simple guys running around, there’d be a small number of people trying to play higher-level exploit games that would have better code than last time, and you’d likely see a level-2 bot (one that beats the obvious level-1 bot that wins the first tournament) come out ahead.
for reference, here’s what I was “planning”-I was all too aware i didn’t have time to learn a new language to actually implement it in. a pity i didn’t think to post this before the tournament results, even if it’s just pseudocode...
run(me,opponent){ //start point
notethetime()
if(me=opponent){return C}
defectbot[]=a list of primitive defectbots with a junk string value added
run5times and record results:(run(opponnent, (opponent, defectbot[i])
{
if (opponent cooperated sometimes){ if(isooponentclearlymimicbot(ooponent)){cooperate()}else{defect()}}//mimic bot is assumed to be simple and easy to identify as such, but I’m not exactly sure how i’d test this.
checktime()//if the opponent takes way too long to run against a short defect bot with barely any baggage, it’s going to have trouble with you. Defect for both your sakes.
if(opponent cooperates allways){if(opponentisclearly cooperate-bot){do I cooperate with C-bots in the hopes of cooperating with those who cooperate with C-bots or do I take advantage of the schmuck?}//a decision i really never made...
mimicbot=”....”
result=(opponent,mimicbot)
if(opponent defected{defect()}
checktime(){}//but this time, cooperate if things are taking dangerously long-MAYBE. it’s somewhat reasonable for an opponent to take a while against a mimicbot, especially if opponent is mimicbot with small epsilon. .
psychbot1.0=(”....”+mimicbot+”...”); /psychbot 1.0 sends you against mimic bot, and then does what you do. only, I get to see the final result. record(run( opponent,psychbot1.0))
checktime();-possibly in a seperate thread. depends on how quickly this whole thing goes. psychbot 1.1=”...+defectbot”. result=run(opponent, psychbot1.1); psychbot 1.1 also checks you against defect bot, like the main program. the purpose, if used, is to avoid cooperating with programs that defect on finding a “D”
if(result=C){return C;} else{return D}.
}
I find cooperation with cooperation-bot utterly insane in context; I would have predicted less than three, but a good chance of at least one. In the real world problem, or a tournament with a lot of rounds, it’s potentially worth saying that since C-bots will die off quickly (although, if enough people cooperate with them, maybe they won’t) they’re effectively unlikely enough that you can safely use your response to them as signaling for other programs, but if that’s true, then your opponent should presumably know that and throw non-trivial cases at you instead.
yeah...but I was more concerned about various TrollBots-including but not limited to HashBot, Randombot, DitherBot, cooperate-IFF you are a defect bot or cooperate bot, antimimicbot...and I considered “cooperates with C-Bot” to be extremely useless as a source of information given the unusual demographics of LessWrong while drawing up my plans.
I don’t know quine at all and can’t easily understand exactly what all these guys are doing but:
This is obviously NOT a stable metagame; in both senses.
If we ran this tournament again the random-bots would get utterly destroyed (since it’s very easy/fast to check for them and defect). If we ran this tournament with multiple rounds, where successful strategies survive and unsuccessful die, and there was even one defect-against-randombot code in the mix, it will win if it doesn’t die early.
My guess-happy summary of what happened is this: The core problem is very hard, so most people instead did something simple, often very simple (cooperate bot, defect bot, random bot—which won!) with a small number of people trying for real. The people trying for real, however, spent all their energy planning for other people trying for real and trying to fool them, rather than trying to act correctly against all the super-simple programs, because if you put in that much work you think other people will mostly put in at least some work (R has an entire long blog post of metagame and strategic analysis which is COMPLETELY wrong in exactly this way, in real life I do this a lot). That, combined with programming errors since the task involved was actually hard, prevented them from winning.
The lesson here, I think, is more about how people react to such tournaments than it is about the actual problem at hand; if anyone had assumed their opponents would either be simple or hopelessly complex, they could have written a program that defects against programs that don’t look at their code or otherwise are clearly safe defections, does something hard to exploit against everyone else that likely is somewhat random, and win easily.
Your summary seems pretty accurate. I don’t think there were many programming errors outside of P’s meltdown, though. Also, as has been touched upon elsewhere in these comments, some of the failures to maximally exploit simple bots were necessary side effects of the attempts to trick complex bots, not just failures to anticipate there being a significant number of simple bots at all. (Sort of a quantitative instead of qualitative prediction mistake—we just thought there’d be more complex bots than simple bots).
One clue towards the general simplicity of the field is the generally atrocious formatting (e.g. close-parens on their own lines)--not many people seem to have had too much experience with Lisp, let alone Lisp projects as complex as this game can get. That’s a shame, but it’s not like any non-Lisp languages are remotely suitable for the kind of source analysis we all wanted to see in this game.
If the tournament were run a second time, my expectation would be that such programs would abound (since writing “if they showed signs of life randomly do something but usually defect, else cooperate” is pretty easy), there’d still be a bunch of simple guys running around, there’d be a small number of people trying to play higher-level exploit games that would have better code than last time, and you’d likely see a level-2 bot (one that beats the obvious level-1 bot that wins the first tournament) come out ahead.
for reference, here’s what I was “planning”-I was all too aware i didn’t have time to learn a new language to actually implement it in. a pity i didn’t think to post this before the tournament results, even if it’s just pseudocode...
run(me,opponent){ //start point notethetime() if(me=opponent){return C} defectbot[]=a list of primitive defectbots with a junk string value added run5times and record results:(run(opponnent, (opponent, defectbot[i]) { if (opponent cooperated sometimes){ if(isooponentclearlymimicbot(ooponent)){cooperate()}else{defect()}}//mimic bot is assumed to be simple and easy to identify as such, but I’m not exactly sure how i’d test this. checktime()//if the opponent takes way too long to run against a short defect bot with barely any baggage, it’s going to have trouble with you. Defect for both your sakes.
if(opponent cooperates allways){if(opponentisclearly cooperate-bot){do I cooperate with C-bots in the hopes of cooperating with those who cooperate with C-bots or do I take advantage of the schmuck?}//a decision i really never made...
mimicbot=”....” result=(opponent,mimicbot) if(opponent defected{defect()} checktime(){}//but this time, cooperate if things are taking dangerously long-MAYBE. it’s somewhat reasonable for an opponent to take a while against a mimicbot, especially if opponent is mimicbot with small epsilon. .
psychbot1.0=(”....”+mimicbot+”...”); /psychbot 1.0 sends you against mimic bot, and then does what you do. only, I get to see the final result.
record(run( opponent,psychbot1.0))
checktime();-possibly in a seperate thread. depends on how quickly this whole thing goes.
psychbot 1.1=”...+defectbot”.
result=run(opponent, psychbot1.1); psychbot 1.1 also checks you against defect bot, like the main program. the purpose, if used, is to avoid cooperating with programs that defect on finding a “D” if(result=C){return C;} else{return D}. }
}
Yeah. pseudocode. for java, not lisp.
edit: clarified a few things in the intro.
I find cooperation with cooperation-bot utterly insane in context; I would have predicted less than three, but a good chance of at least one. In the real world problem, or a tournament with a lot of rounds, it’s potentially worth saying that since C-bots will die off quickly (although, if enough people cooperate with them, maybe they won’t) they’re effectively unlikely enough that you can safely use your response to them as signaling for other programs, but if that’s true, then your opponent should presumably know that and throw non-trivial cases at you instead.
yeah...but I was more concerned about various TrollBots-including but not limited to HashBot, Randombot, DitherBot, cooperate-IFF you are a defect bot or cooperate bot, antimimicbot...and I considered “cooperates with C-Bot” to be extremely useless as a source of information given the unusual demographics of LessWrong while drawing up my plans.