2
\$\begingroup\$

This is a rock paper scissors competition. Algorithms will face each other in 100 rounds of rock paper scissors. Except that the algorithms will also be able to read the source code of each other!

Leaderboard

1.  Chaos Bot (by Aiden4) - 25 Points, 168 bytes
2.  Anti-99%-of-posts (by Lyxal) - 22 Points, 489 bytes
3.  If-If (by PkmnQ) - 20 Points, 63 bytes
4.  Biased-Cycler (by HighlyRadioactive) - 19 Points, 17 bytes
5.  Cycler (by petStorm) - 16 Points, 17 bytes
6.  RadiationBot v0.1 (by HighlyRadioactive) - 16 Points, 121 bytes
7.  Custom (by petStorm) - 15 Points, 56 bytes
8.  Craker (by petStorm) - 15 Points, 58 bytes
9.  Lookup (by petStorm) - 15 Points, 61 bytes
10. Anti-Cycler (by Lyxal) - 12 Points, 17 bytes
11. Itna-Cycler (by petStorm) - 11 Points, 17 bytes
12. Lycler (by petStorm) - 10 Points, 24 bytes
13. PseudoRandom (by HighlyRadioactive) - 10 Points, 89 bytes

Submissions are graded automatically via an online judge

View Online Judge

The Competition

Your code will be a javascript anonymous function (sorry, other languages aren't supported!) that takes in two arguments:

  • The source code of your opponent AI (as a string)
  • The current round number

It should then return one of "R", "P", or "S", indicating that it will throw a rock, paper, or scissors for that round.

Your code must follow these rules, otherwise it will be disqualified:

  • Your code may not be longer than 500 bytes
  • Your function must be pure
    • That is, if your function is given the same set of arguments, your code must always return the same result
    • This is to ensure that the tournament results are consistent
  • eval() calls are banned!
    • If this were allowed, two submissions with eval() would end up calling each other in an endless loop which would never terminate.
    • (See the discussion in the comments for more details/reasoning)
  • Your code may not:
    • Access external resources (e.g. make web fetch/get requests)
    • Attempt to modify or tamper with the judge system code
    • Cause excessive lag or time delay
    • Modify any globals or object prototypes
    • Attempt to do an XSS attack or any other sketchy/illegal stuff

Example submission

(code, round) => {
  if (round === 1) {
    // Throw rock if it's the first round
    return "R";
  }
  else if (code.includes('"R"')) {
    // Throw paper if the opponent code includes "R"
    return "P";
  } else {
    // Otherwise throw scissors
    return "S";
  }
}

Tournament structure

Every submission will play rounds of rock paper scissors against every other submission. Each submission will play 100 rounds with each other submission.

To get the ball rolling, the following three functions will be submitted by default and will not be counted in the final leaderboard:

(code, round) => {
  // Always throw rock
  return "R";
}
(code, round) => {
  // Always throw paper
  return "P";
}
(code, round) => {
  // Always throw scissors
  return "S";
}

Scoring

A submission gains 2 points for winning against another submission, and 1 point for tying against another submission (no points are awarded for losses).

Rankings are ordered by most points. If two submissions have the same number of points, they will be ranked in order of least bytes. If two submissions have the same number of points and bytes, the older submission will be ranked higher.

Judging & Testing

Post your submissions here, I will periodically add submissions to the online judge which will automatically rank each algorithm.

You can also test your algorithms using the online judge testing area. A testing area is provided at the bottom to test different algorithms against each other.

\$\endgroup\$
  • 3
    \$\begingroup\$ why does it have to be js? to make sure any submission can interact with any other? \$\endgroup\$ – golf69 Aug 8 at 2:30
  • 1
    \$\begingroup\$ Related: Prisoner's Dilemma with access to opponent \$\endgroup\$ – xnor Aug 8 at 2:35
  • 4
    \$\begingroup\$ Since it seems natural for submissions to try to simulate each other, it will be easy for infinite loops to be created. How would this resolve? Perhaps each submissions could be run for a fixed amount of time, and any that does output without that time forfeits the round. \$\endgroup\$ – xnor Aug 8 at 2:38
  • 1
    \$\begingroup\$ @MrSiliconGuy I don't know JS, but does anything then stop a submissions from attempting to execute the opponent's source code string and so simulate their opponent? An when you say, "Your code may not: Cause excessive lag or time delay", if someone writes code that intentionally takes very long if someone tries to simulate it but runs quickly by itself, would they be breaking this rule, or would the code trying to simulate it be breaking it? \$\endgroup\$ – xnor Aug 8 at 2:41
  • 2
    \$\begingroup\$ To be honest, I'm not sure programs can glean anything really interesting just from analyzing the strings of the other competitors without simulating, especially since code can be written to be obfuscated. But if that's your intention, might it work to ban any calls to eval-style interpreter functions? I guess someone can write a small bit of an interpreter, but this can only get so far in 500 bytes. \$\endgroup\$ – xnor Aug 8 at 2:51

14 Answers 14

4
\$\begingroup\$

Anti-99%-of-posts

(code,r)=>{var S="S";var R="R";var P="P";var x=S+R+P;var y=R+P+S;var z=P+S+R
if(code.includes("17")){return "P";}
else if(code.includes("[r%2]")){return"RR"[r%2]}
else if(code.includes("[r%3]")){
if (code.includes(x)){return (R+P+S)[r%3];}
else if(code.includes(y)){return (P+S+R)[r%3];}
else if(code.includes(z)){return (S+R+P)[r%3];}
}else{if(code.includes("scissors")){return "R"}else if (code.includes("rock")){return "P"}else if (code.includes("paper") ){return "S"}else{return "P"}}}

Haha. Testing it on submissions gives either a win or a tie.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ I have witnessed pure evil \$\endgroup\$ – Razetime Aug 10 at 6:26
  • 1
    \$\begingroup\$ You should rename this to "Rookup" \$\endgroup\$ – null Aug 12 at 1:04
  • \$\begingroup\$ Indeed, this answer currently wins the game. However, are you sure that you can handle the new answers with the remaining 11 bytes !? \$\endgroup\$ – hi. Aug 12 at 10:10
4
\$\begingroup\$

If-If

(c,r)=>{if(c.includes("i")){return"RPS"[2]}else{return"P"}; 17}

This was built off of an algorithm that detected if "if" was in the code.

| improve this answer | |
\$\endgroup\$
4
\$\begingroup\$

Chaos Bot

I lost track of what's going on here, but it seems to win or tie everything but the standard cycler.

(c,r) => {if(c.includes("else")){return "SSR"[r%3];}if(c.includes("/")){if(c.includes("P")){return "S";//17
} return "SRP"[r%3];} else{return "PPS"[(c.length + r)%3];}}
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Welcome to Code Golf SE! Congrats your bot is currently winning \$\endgroup\$ – thesilican Aug 13 at 23:00
3
\$\begingroup\$

Cycler

Picks depending on the round number.

(c,r)=>"RPS"[r%3]
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Isn't this trivially beaten by ++r%3? \$\endgroup\$ – Shaggy Aug 9 at 0:14
  • 2
    \$\begingroup\$ @Shaggy Yes, but every simple strategy is trivially beaten by the same strategy, but rotated, so it's not unique in that way. \$\endgroup\$ – Spitemaster Aug 9 at 0:55
3
\$\begingroup\$

Anti-Cycler

(c,r)=>"PSR"[r%3]

Someone had to do it. Why not me? ;P

| improve this answer | |
\$\endgroup\$
3
\$\begingroup\$

Custom

A bot designed to beat the default bots. I'm a horrible golfer indeed...

Edit: I'm now also trying to get around RadiationBot, by changing the algorithm.

(c,r)=>["P","S","R"][-~[["P","S","R"].findIndex(i=>!c.indexOf(i))%3]]
| improve this answer | |
\$\endgroup\$
2
\$\begingroup\$

RadiationBot v0.1

HighlyRadioactive's botty bot.

(c,r)=>{if(c.indexOf("RP")>=0){return "PSR"[r%3];}else if(c.indexOf("PS")>=0){return "SRP"[r%3];}else{return "RP"[r%2];}}
| improve this answer | |
\$\endgroup\$
2
\$\begingroup\$

Lycler

Like Cycler, but this time with length.

(c,r)=>"RPS"[c.length%3]
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ I like the idea of using the code of others to decide the result, but the length can be easily countered. I think some sort of hashing of the code should take place in order to make it much harder to adjust the code as each change also changes the hash \$\endgroup\$ – RFSnake Aug 12 at 8:00
  • \$\begingroup\$ @RFSnake Added \$\endgroup\$ – hi. Aug 12 at 9:48
2
\$\begingroup\$

Lookup

The lookup table here explains everything.

(c,r)=>({17:["R","P","S"][(r-(~-c.slice(8).indexOf(`S`)||(r-3+r%2))+3)%3],24:"S",56:"S",58:"S",63:["P","S","R"][2],69:"S",81:"P",121:"PS"[r%2],168:"SSR"[(c.length+r)%3],489:"S"})[c.length]||"R"
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ This submission can't be accepted, because the function doesn't always return "R", "P", or "S". You should add a case for if the length of the code isn't in the lookup table. \$\endgroup\$ – thesilican Aug 9 at 14:56
  • \$\begingroup\$ @MrSiliconGuy Fixed. \$\endgroup\$ – hi. Aug 9 at 15:32
  • \$\begingroup\$ Alright looks good \$\endgroup\$ – thesilican Aug 9 at 15:38
  • \$\begingroup\$ And change the name, you are not HighlyRadioactive & lookup table's not the spirit of RadiationBot... \$\endgroup\$ – null Aug 10 at 13:22
1
\$\begingroup\$

PseudoRandom

(c,r)=>{a=0;for(i=0;i<c.length;i++){a+=c[i].charCodeAt()^r^i;}return "RPS"[a%3];}

Not too random I guess but I tried.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ I had to modify your solution a little, to include let a=0 and let i=0 because it wasn't working for some reason without it. Probably because the judge is running with "use strict"; mode. Sorry for the lost bytes! \$\endgroup\$ – thesilican Aug 9 at 13:13
1
\$\begingroup\$

Craker

Inspired by Custom. (Hopefully) does something different.

(c,r)=>"RPS"[-~[..."RPS"].findIndex(i=>c.indexOf(i)>-1)%3]
| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

Itna-Cycler

Let's raise the maximum score of the cycler family to 8!

(c,r)=>"SRP"[r%3]
| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

Biased-Cycler

(c,r)=>"RRP"[r%3]

Yay.

| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

#</>

Let's add an awful hash answer.

(c,r)=>"SPR"[c.split``.reduce((t,i)=>(t<<5)+i.charCodeAt(0),5381)%3]
| improve this answer | |
\$\endgroup\$
  • 1
    \$\begingroup\$ This should replace PseudoRandom. EDIT: Oh wait, round number is not involved. \$\endgroup\$ – null Aug 12 at 10:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.