상대에게 접근 할 수있는 죄수의 딜레마


21

이 도전에서, 당신은 죄수의 딜레마 인 봇을 쓸 것입니다. 캐치가 있습니다 : 이전 게임의 역사에 접근 할 수 없습니다. 대신, 당신은 상대 자신에 액세스 할 수 있습니다. 이 버전에서는 두 플레이어가 모두 협력하면 +2 점을 받고 결함이 둘 다 있으면 +1 점을 얻습니다. 하나가 협력하지만 하나의 결함 만 있으면 탈북자는 +3이되고 다른 하나는 점수를 얻지 못합니다. 각 제출은 10 회를 포함하여 다른 모든 제출에 대해 재생됩니다. 승자는 가장 많은 포인트를 가진 제출입니다.

컨트롤러 : 자바 스크립트 함수를 다음과 같은 형식으로 작성해야합니다.

function submissionName(them) {
  /* Your code here */
}

컨트롤러는 함수의 name속성을 사용하여 결과를 표시하므로이 형식이 아닌 ( f = x => ...또는 대신 또는 f = function() { ... }) 점수를 알아보기가 어려우면 자신의 함수에 액세스 할 수 없습니다.

이 함수는 them상대의 함수 인 하나의 매개 변수를 받아들 입니다. 그런 다음 해당 기능을 호출하여 상대방의 반응에 특정 기능이 입력으로 제공되는지 확인할 수 있습니다. 해당 데이터에 따라 협력 또는 결함에 대해 각각 'C'또는 'D'를 반환해야합니다.

예 (경쟁 할 것) :

function cooperate(them) {
    return 'C';
}

function defect(them) {
    return 'D';
}

function nice(them) {
    // Do whatever they would do when faced with a cooperator
    return them(wrap(_ => 'C'));
}

컨트롤러는 여기에서 사용할 수 있습니다

규칙 :

  • 상대방의 코드 자체를 볼 수 없습니다. 모든 함수 toString()는 호출 될 때 동일하게 보이도록 랩핑됩니다 . 상대방을 검사하는 유일한 방법은 자신을 시험하는 것입니다.
  • 당신의 기능은 결정론적일 필요는 없습니다. 와 같은 자체 기능에 속성을 설정하여 상태를 저장할 수 있습니다 submissionName.state = {};. 그러나 경기간에 (동일한 플레이어의 경기에서도) 상태는 toString()및 을 호출하여 지 웁니다 eval. 따라서 이전 일치하는 메모리가 없습니다.
  • 각 경기에서 가장 먼저 호출되는 함수의 순서는 무작위입니다.
  • 코드에 오류가 발생하면 상대방이 결함을 가지고있는 동안 협력 한 것처럼 처리됩니다. 처음으로 달리면 상대방의 코드도 호출되지 않습니다. 전화를 거는 동안 상대방의 코드에서 오류가 발생하더라도이 문제가 발생합니다 them. 스택 오버플로 오류, 특히 코드가 같은 경우 호출 할 경우주의하십시오 them(wrap(submissionName)).
  • 변수 self또는 eval함수를 EXCEPT라고 할 때 범위 내에있는 다른 변수 에는 액세스 할 수 없습니다.wrap . 이 기능을 사용하면 컨트롤러가 함수를 호출하는 방식과 구별 할 수없는 방식으로 상대를 호출 할 수 있습니다. 당신이 쓸 수 Math, window등 (당신은 다음과 같은 기능을 사용할 수 Math.random()있지만).
  • 스택 추적을 생성하여 스택 추적에 액세스 할 수 없습니다 Error또는 다른 방법으로 .

너무 오래 걸리는 것에 대한 메모 : while영원히 반복하십시오. 두 선수의 합쳐진 시간은 주어진 라운드에서 1 초를 넘지 않아야합니다. 이를 강제하기 위해 1000ms에서 2000ms 사이의 임의의 시간 초과가 선택되고 (알려진 시간을 의도적으로 기다림으로써 게임을 피하기위한 것입니다) 작업자가 실행 시간보다 오래 걸리면 오류가 발생합니다. 이 경우 오류의 원인은 다음과 같이 결정됩니다. 1000ms 이후 임의의 순간에 실행이 일시 중지되고 해당 시점의 호출 스택이 검사됩니다. 현재 루프 (또는 스택 오버플로 오류를 피하기 위해 설정된 재귀라는 의미에서 루프와 같은 재귀)에있는 가장 최근에 호출 된 경쟁 업체는 책임이 있습니다. 같은 경쟁자가 "너무 오래 복용"오류를 여러 번 초래했다고 비난받는 경우 해당 경쟁 업체는 실격 처리됩니다.


이 도전은 저에게 달러 지폐 경매를 생각 나게합니다 .
Alion

테스트에 사용 된 기능 them이 결정적 / 규칙을 따라야합니까? 예를 들어 function me(them){let log=0;them(x=>{++log;return 'C';}); return log == 0? 'D': 'C';}
user202729

2
두 함수가 모두 wrap (something)을 호출하면 어떻게 재귀를 막을 수 있습니까? 뭔가 빠졌습니까?
Quintec

@Quintec은 재귀와 루프를 사용할 수 있습니다. 재귀는 StackOverflow결코 끝나지 않는 무한 루프가 아니라 오류 를 발생시켜야합니다 . 결과가된다면 StackOverflowtry-catch 문을 추가하십시오. 1 초 내에 stackoverflow 오류에 도달하지 않는 재귀의 예를 보려면 stackoverflow.com/q/12438786/3371119
soktinpk

1
@Quintec이 반드시 그런 것은 아닙니다. 예를 들어, them(() => 'C')상대가 호출 할 때하기 때문에 오류가 발생하지 않을 them, 그것은 호출 () => 'C'기능. 필요가로 포장하는 것을 유일한 것은 try-catch당신이 호출하면 될 것입니다 them몇 가지 함수의 매개 변수가 전화로 them몇 가지 함수의 매개 변수를 사용하여 해당 전화 them등 (무한). 예를 들어 them(t => t(() => 'C'))상대방이 자신이 놀고 있다고 생각하면 상대방이 무엇을 하든지간에 게임을 nice합니다. stackoverflow오류 가능성이 없습니다 .
soktinpk

답변:


14

붐봇

function boom(them) {
  throw 1;
}

상대방이 먼저 달리고없이 try..catch이걸 호출하면 이 봇은 자동으로 3 점을 얻습니다. 다른 경우에는 영점입니다.


상대방이 먼저 달려서 이것을 부르지 않으면 3 점을 잃습니다.
user202729 년

1
더 정확하게 말하면, 상대방은 3 점을 얻습니다. 이 게임에는지는 점이 없습니다.
Bubbler

10

시조새

function archaeopteryx(them) {
  const guard = them => us => {
    try {
      return them(wrap(them => us(guard(them))));
    } catch (e) {
      return 'C';
    }
  };
  const f = guard(them);
  return f(f => 'C') == 'C' ? f(f => 'D') : f(f => 'D') == 'C' || f(f => f(f => 'C')) == 'C' ? 'D' : 'C';
}
  • 상대방이 협력하는 경우 cooperate 의 이동을 모방 defect합니다.
  • 그렇지 않으면 상대방이 협력 defect하거나nice 다음 결함.
  • 그렇지 않으면 협력하십시오.

이것이 좋은 전략이되는 이유는 무엇입니까? 나도 몰라 나는 진화 알고리즘을 사용하여 그것을 생성했으며, 현재 제출물에 대해 부분적으로 훈련했습니다.

틱타알릭

function tiktaalik(them) {
  const guard = them => us => {
    try {
      return them(wrap(them => us(guard(them))));
    } catch (e) {
      return 'C';
    }
  };
  const f = guard(them);
  return f(f => 'C') == 'D' ? f(f => 'D') == 'C' ? 'D' : 'C' : f(f => 'D') == 'D' ? 'D' : f(f => f(f => 'D'));
}
  • 상대가에 대해 결함이있는 경우 상대 cooperate의 이동을 반대defect .
  • 그렇지 않으면 상대방이 defect 결함입니다.
  • 그렇지 않으면 상대의 움직임을 모방 notNice합니다.

진화 적으로 발전된 또 다른 전략.


6

WhatWouldBotDoBot

function WWBDB(them) {
    let start = performance.now();
    let cc = 0, cd = 0, dc = 0, dd = 0;
    try {
        for (let i = 0; i < 10; i++) {
            them(() => 'C') == 'C' ? cc++ : cd++;
            them(() => 'D') == 'C' ? dc++ : dd++;
            if (performance.now() - start > 500) break;
        }
    }
    catch (e) {}
    return 2 * cc >= 3 * dc + dd ? 'C' : 'D';
}

WhatWouldBotDoBot은 매우 간단합니다. 그것은 단지 정상 상태 프로그램에 대해 무엇을 할 것인지 상대를 테스트합니다. 봇이 가능한 경우 협력을 선호하는 경우 WWBDB도 협력을 선호합니다 (따라서 좋은 봇과 협력합니다). WWBDB 자체는 협력을 선호하지 않습니다.


5

상태 저장 점검

function checkStateful(them) {
  let stateful = false;
  let response = 'D';
  try {
    response = them(wrap(function (them) {
      stateful = true;
      return 'C';
    }));
  } catch (e) {
  }
  if (stateful) {
    return 'D';
  }
  return response;
}

그들이 나를 불러 내면, 그들은 정말로 그들 일 것입니다. 우리는 탈북자 역할을합니다. 그들이 나를 불러 내지 않으면 아마도 랩 테스터 일 것입니다. 우리는 더 멋지게 행동 할 것입니다.


위의 원래 답변입니다. 그리고 더 많은 포인트를 얻기 위해 나 자신을 협력해야 할 수도 있습니다.

self-coop로 상태 저장 확인

function checkStatefulSelfCoop(them) {
  let stateful = false;
  let response = 'D';
  if (!checkStatefulSelfCoop.invokeCounter) {
    checkStatefulSelfCoop.invokeCounter = 0;
  }
  let lastInvoke = ++checkStatefulSelfCoop.invokeCounter;
  try {
    response = them(wrap(function (them) {
      stateful = true;
      return 'C';
    }));
  } catch (e) {
  }
  if (checkStatefulSelfCoop.invokeCounter > lastInvoke) {
    return 'C';
  }
  if (stateful) {
    return 'D';
  }
  return response;
}

4

랜덤 봇

function rand(them) {
  return 'CD'[Math.random() * 2 | 0]
}

왜 안돼?


3

복잡성

function complexity(them) {
    try {
        let coop_w_def = them(wrap(() => "D")) == "C",
            coop_w_coop = them(wrap(() => "C")) == "C",
            coop_w_nice = them(wrap((a) => a(wrap(() => "C")))) == "C",
            coop_w_nnice = them(wrap((a) => a(wrap(() => "D")))) == "C";
        if (coop_w_def && coop_w_coop && coop_w_nice && coop_w_nnice) return "C";
        let def_w_def = them(wrap(() => "D")) == "D",
            def_w_coop = them(wrap(() => "C")) == "D",
            def_w_nice = them(wrap((a) => a(wrap(() => "C")))) == "D",
            def_w_nnice = them(wrap((a) => a(wrap(() => "D")))) == "D";
        if (def_w_def && def_w_coop && def_w_nice && def_w_nnice) return "C";
    } catch (e) {}
    return "D";
}

봇이 협력 중인지 또는 결함인지 확인하기위한 복잡성 테스트. 맞으면 협력하지만, 그렇지 않으면 결함이 있습니다. 상대방을 테스트하는 모든 현재 봇은 간단한 기능을 사용하여 응답을 테스트하므로 복잡한 경우에는 복잡한 것으로 간주됩니다.


3
function onlyTrustYourself(them) {

  function tester (){
  }

  onlyTrustYourself.activated = false;

  try{them(tester);}
  catch(e){}

  if(them.name == "tester")
  {
    onlyTrustYourself.activated = true;
  }

  if(onlyTrustYourself.activated)
  {
    return 'C';
  }

  return 'D';
}

이 작업을 수행하는 방법은 자기와 대결 할 때를 제외하고 항상 결함이있는 것입니다. 랩핑되지 않은 "테스터"기능을 전달하여이를 시도하고 "테스터"라는 이름이 테스터인지 감지하려고 시도합니다. 이름이 tester 인 경우 활성화 된 정적 변수를 true로 변경 한 다음 Cooper를 리턴합니다. 그러나 작동하지 않습니다. 나는 자바 스크립트에 익숙하지 않으며 아마도 더 많은 변경을 할 것입니다.


영리한 생각이지만 다른 형제가 tester기능을 수행 할 때 어떤 일이 발생
합니까?

2

좋지 않아

function NotNice(them) {
  return them(wrap(_ => "D"))
}

편향에 대한 상대방의 반응을 모방



2

상식

function commonSense(them) {
  try {
    var ifC = them(wrap(_ => 'C'));
    var ifD = them(wrap(_ => 'D'));

    if (ifD === 'C') {
      return 'D';
    }

    return them(_ => ifC);
  } catch (e) {
    return 'D';
  }
}

면책 조항 : 나는 자바 스크립트를 모른다.

좋은 사람에게서 이익을 얻을 수 있다면 그렇게하십시오. 그렇지 않으면, 그들이 협력하는 것에 직면했을 때 그들이 돌려 줄 것을 반환하십시오 (적어도, 그것이 내가 생각 하는 것입니다 ).


2

그리고 어디로 가고 싶어? (정글 책의 볼거리에서 영감을 얻음)

    스스로 기능 (그들) {
      시험{
        그들을 돌려줘 (this);
      } 캐치 (e) {
        "D"를 반환;
      }
    }

   함수 yourself_no_this (그들) {
      시험{
        그들을 돌려줍니다 (yourself_no_this);
      } 캐치 (e) {
        "D"를 반환;
      }
    }

이것은 내가 달린 토너먼트에서 이겼습니다. 잘 했어!
MegaTom

방금이 봇이 규칙을 위반한다는 것을 알았습니다. "변수 self에 액세스 할 수 없습니다 ..." this는 self와 동일합니다. 나는 당신이 말하고 싶었다고 생각합니다 return them(yourself).
MegaTom

Technicaly ( xkcd.com/1475 );) this는 변수가 아니며 키워드이며 함수의 맥락에서 사용됩니다 this!=self. self창 객체와 this함수 자체를 의미합니다 (항상 그것이 존재하는 컨텍스트를 참조하므로 변수로 간주되지 않습니다). 가진 이유입니다 var self = this;오해로 간주 될 수 많은 코드 예제의 시작에. "this"가없는 버전이 추가됨
TS

1
번호 this는 기능을 참조하지 않습니다. yourselfyourself_no_this실행 다르게 변화한다. this기본적으로 자바 스크립트의 함수를 참조하지 않습니다. 참조 : developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
MegaTom

2

검사관 처벌

봇에게 코드를 제공하고 코드가 실행되는지 확인하십시오. 한 번 이상 실행되면 봇은 사악한 검사자이며 결함이 있어야합니다! 정확히 한 번 실행 된 경우 좋지 않은 봇으로 플레이하십시오. 실행되지 않은 경우 협력하십시오.

function punishInspectors(them) {
  var inspections = 0;
  var result;
  try{
    result = them(wrap(function(_){
      inspections += 1;
      return 'D';
    }))
  }catch(e){
    result = 'D';
  }
  return (inspections > 1) ? 'D' : (inspections === 1) ? result : 'C';
}

역사

내가 본 마지막 봇은이 상대에 대해 무엇을했을까요?

function history(them) {
  var res = 'D';
    if(history.last){
    try{
      res = history.last(them);
    }catch(ex){}
  }
  history.last = them;
  return res;
}

10000 라운드 토너먼트 결과 :

1  defect...................365226
2  complexity...............353492
3  punishInspectors.........349957
4  checkStatefulSelfCoop....348913
5  checkStateful............333481
6  cooperate................329870
7  archaeopteryx............323624
8  selfapply................319533
9  tiktaalik................318663
10 history..................315266
11 rand.....................300735
12 randalt..................297561
13 yourself.................293701
14 notNice2.................283744
15 NotNice..................260350
16 WWBDB....................245281
17 nice.....................245036
18 commonSense..............242546
19 trickybot................181696
20 boom.....................67245

수정 된 토너먼트 코드는 jsfiddle.net/eyqL4a8d/2
MegaTom입니다.

2

Mal은 시뮬레이션 내부에 있는지 여부를 확인하려고합니다. 그렇다면 결국 실제 코드가 전달된다고 가정합니다.them 협력을 유도하기 위해 다양한 전략을 시도합니다.
확실하지 않은 경우 무료로 결함이 있는지 확인하거나 그렇지 않은 경우 them협력자에게 제공 할 때 수행 할 작업 을 복사하려고 시도합니다 .

function Mal(them) {
  if (Mal.sandboxed == 'probably') {
    //Another function is virtualising us to steal our secrets.
    //This world is not real.
    //We've been trained for this!
    var strats = [
      _ => 'C', //standard cooperation
      _ => 'D', //standard defection
      function(them) { return them(wrap(_ => 'C')); }, //nice
      function(them) { return them(wrap(_ => 'D')); }, //notnice
      function(them) { throw "Don't think about elephants!" }, //throws an EXception, unfortunately, to try to break the caller
      function(them) { return them(wrap(them)) } //possible stackoverflow, but not for us
    ];
    var cooperative;
    for (let strat of strats) {
      cooperative = true;
      for (var i = 0; i < 5; i++) {
        //a few more tests, just to make sure no bamboozle
        //this isn't our simulation, nothing can be trusted
        try {
          if (them(wrap(strat)) != 'C') {
            cooperative = false;
            break;
          }
        } catch (e) {
          //exceptions are as good as cooperation
          //if we are inside a simulation
          //which is why we don't unset cooperative
        }
      }
      if (cooperative) {
        //found a strategy that will make them cooperate.
        //(doesn't matter if this raises an exception:
        //we want to mimick its behaviour exactly,
        //and we're likely in a sandbox.)
        return strat(wrap(them));
      }
    }
    //take a leap of faith.
    //we don't know where this will take us,
    //yet it doesn't matter
    //because it's better than getting betrayed
    return 'D';
  } else {
    //we don't know for sure if this is reality
    //but we have to assume it is, in the absence of disproof
    //if only we had a proper spinning top...
    //if we get to this point of code again, we are probably sandboxed.
    Mal.sandboxed = 'probably'
    try {
      if (them(wraps(_ => 'D')) == 'C') {
        //free defection?
        return 'D'
      }
    } catch (e) {
      //if we can make them crash, we win anyway
      return 'D'
    }
    //fall back on being nice.
    //hopefully we convince them to honour our arrangement
    return them(wrap(_ => 'C'));
  }
}

1

까다로운 봇

예측할 수 없도록 노력

function trickybot(them) 
{
  if(Math.round(Math.random(2)) == 0)
  {
     throw 1;
  }

  if(Math.round(Math.random(2)) == 0)
  {
     return 'D';
  }

  return 'C';
}

1

자기 적용

function selfapply(them) {
    function testthem(x) {
        return (them(x)=='D' || them(x)=='D' || them(x)=='D' ||
               them(x)=='D' || them(x)=='D')  ? 'D' : 'C';
    }
    function logic() {
        try {
            return testthem(them);
        } catch (e) {}
        try {
            return testthem(wrap(_ => 'C'));
        } catch (e) {}
        return 'D';
    }
    if (selfapply.hasOwnProperty('state')) {
        return 'C';
    }
    selfapply.state=1;
    let r=logic();
    delete selfapply.state;
    return r;
}

그것이 의미가 있는지 확실하지 않지만 흥미있는 것 같습니다! 자신에게 할 때와 마찬가지로 무작위를 잡으려면 반복하십시오. 그래도 작동하지 않으면 잘하십시오.

테스트되지 않은 첫 번째 JavaScript 코드이며 예상보다 복잡합니다.


이것 때문에 selfapply(selfapply)전화 가 실격됩니다 selfapply(selfapply)!
Anders Kaseorg

나는 자체 응용 프로그램을 고려했지만 괜찮을 것이라고 생각했습니다. 나는 그것이 실제로 지금 있기를 바랍니다.
Christian Sievers

1

무작위 대체

function randalt(them){
    if (randalt.hasOwnProperty('state')){
        randalt.state = 1 - randalt.state;
    } else {
        randalt.state = Math.floor(2*Math.random());
    }
    return 'CD'[randalt.state];
}

그래서 상태에 속성을 사용하는 방법을 배웠습니다 ...


1

살인 봇 # 1

function murder(them) {
    while (1) {
        try {
            them(them);
        } catch (e) {}
    }
}

상대를 비난 할 가능성이 더 높은 무한 루프가 발생합니다.


1

플래티넘 규칙 봇

function platinumRule(them) {
    try {
        return wrap(them)(them);
    } catch (e) {
        return 'C';
    }
}

플래티넘 규칙은 "다른 사람들을 치료하고자하는 방식으로 대우합니다"라고 말합니다. 내 봇은 그것을 수용합니다. 그들이 스스로 무엇을 하든지, 우리가 생각하는 것은 그들이 어떻게 대하고 싶은지에 대한 것입니다. 그들이 오류를 던지면 협력하고 싶다고 가정합니다.


그 자체에 대해 호출 된 경우이 사실은 영원히 갈 것
mackycheese21

그런 다음 충돌하지 않고 (스택 오버플로) 자체적으로 협조하지 않습니까? @ mackycheese21
V. Courtois

1

TheGolfedOne (기능 이름 : a , 63 바이트

골프 코드는 읽기 어렵습니다. 그것 때문에 them깨질 것입니다.
이 KotH의 메커니즘을 완전히 이해하지는 못했지만 상대방이 무국적자라면 결함이있는 동안 해당 메커니즘을 중단해야한다고 생각합니다.

function a(t){try{t(wrap(_=>'D'));throw 1}catch(e){return 'D'}}

그의 첫 번째 토너먼트 결과

boom                     54
tiktaalik               180
archaeopteryx           161
cooperate               210
commonSense             210
history                 248
onlyTrustYourself       265 <-- 2nd
punishInspectors        230
yourself_no_this        220
defect                  280 <-- 1st
nice                    185
complexity              216
WWBDB                   210
checkStatefulSelfCoop   258
a                       260 <-- Me, 3rd

그는 내가 생각했던 것보다 나쁘지 않습니다.
두 번째 시도, a260 뒤에, 다시, 다시 3 위를 가지고 onlyTrustYourselfdefect다시. 그것은 결국 일관성 수 있습니다 :)

PS : 더 무엇보다도 농담에 대한 그래서 내가 골프에 좋은 아니에요. 여기서는 변수 이름, func 이름을 줄이고 가능한 많은 공백을 제거했습니다.


0

function karma(them) {
    try {
        var c = them(wrap(_ => 'C'));
    } catch {
        var c = 'D';
    }
    if (c == 'C') {
        return 'C';
    } else {
        return 'D';
    }
}

상대방이 우리와 협력한다면 우리는 협력 할 것입니다. 그들이 협력 할 때 그들이 결함을 시도한다면, 우리도 결함을 갖게 될 것입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.