相手にアクセスできる囚人のジレンマ


21

この課題では、囚人のジレンマを演じるボットを作成します。キャッチは次のとおりです。以前のゲームの履歴にアクセスすることはできません。代わりに、相手自身にアクセスできます。このバージョンでは、両方のプレイヤーが協力すると+2ポイントを獲得し、両方がディフェクトすると+1ポイントを獲得します。各サブミッションは、それ自体を含む他のすべてのサブミッションに対して10回プレイされます。勝者は、合計ポイントが最も多い提出物です。

コントローラー:JavaScript関数を次の形式で作成する必要があります

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

コントローラーは関数のnameプロパティを使用して結果を表示します。したがって、この形式ではない場合(f = x => ...または代わりにまたはf = function() { ... })、スコアを確認することは難しく、独自の関数にアクセスすることはできません。

この関数は、1つのパラメーターを受け入れます。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関数を除いて呼び出されたときにスコープ内にある他の変数にはアクセスできませんwrap。この関数を使用すると、コントローラーが関数を呼び出す方法と見分けがつかない方法で相手を呼び出すことができます。自分の書き込み権限のないかもしれないMathwindowなど(次のような機能を使用することができるMath.random()が、)。
  • Errorまたはその他の方法でスタックトレースにアクセスすることはできません。

時間がかかりすぎることに注意してください。 while永遠にループします。両方の競技者の合計時間は、どのラウンドでも1秒を超えてはなりません。これを強制するために、1000ミリ秒から2000ミリ秒の間のランダムタイムアウトが選択されます(これは、既知の時間を意図的に待機することによりゲームを回避するためです)。これが発生した場合、エラーの原因は次のように判断されます。実行は1000ミリ秒後のランダムな瞬間に一時停止され、その瞬間の呼び出しスタックが検査されます。現在ループになっている(または、スタックオーバーフローエラーを回避するために設定された再帰であるという意味でのループのような再帰)、最近呼び出された競合他社が非難されます。同じ競合他社が「時間がかかりすぎる」エラーを数回引き起こしたと非難された場合、その競合他社は失格となります。


この挑戦は私にダラービルオークションを思い出させます。
アリオン

テストthemに使用される関数は確定的であるか、ルールに従っている必要がありますか?たとえば、function me(them){let log=0;them(x=>{++log;return 'C';}); return log == 0? 'D': 'C';}
user202729

2
両方の関数がそれらを呼び出す場合(wrap(something))、どのように再帰を防ぐことができますか?何か不足していますか?
クインテック

@Quintecでは、再帰とループを使用できます。再帰はStackOverflowエラーを発生させる必要があるだけであり、終了しない無限ループではありません。結果がになる可能性があるStackOverflow場合は、try-catchステートメントを追加してください。1秒以内にstackoverflowエラーに達しない再帰の例については、stackoverflow.com
q / 12438786/3371119

1
@Quintecは必ずしもそうではありません。たとえばthem(() => 'C')、相手がthemを呼び出すと() => 'C'関数が呼び出されるため、エラーは発生しません。ラップする必要があるのは、(無限に)などを呼び出す関数のパラメーターで呼び出す関数のパラメーターでtry-catch呼び出す場合だけです。たとえば、対戦相手がプレイしていると思った場合に対戦相手がプレイするものは何でもプレイします。エラーの可能性はありません。themthemthemthem(t => t(() => 'C'))nicestackoverflow
soktinpk

回答:


14

BoomBot

function boom(them) {
  throw 1;
}

対戦相手が最初に実行され、これをなしtry..catchで呼び出す場合、このボットは自動的に3ポイントを獲得します。その他の場合はゼロポイント。


対戦相手が最初に実行され、これを呼び出さない場合、3ポイントを失いますよね?
user202729

1
@ user202729より正確には、相手は3ポイントを獲得します。このゲームには負け点はありません。
バブラー

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;
}

それらが私を呼び出す場合、それらはおそらく本当にそれらです。私たちは脱走者として行動します。それらが私を呼び出さない場合、おそらくラップされたテスターに​​なります。私たちはより良く行動するでしょう。


上記が元の答えです。そして多分、もっとポイントを稼ぐために協力するべきです。

セルフコープでステートフルをチェック

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

RandomBot

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";
}

ボットがCooperateであるかDefectであるかを確認するための複雑性テスト。もしそうなら、それは協力しますが、そうでなければ、欠陥があります。対戦相手をテストする現在のすべてのボットは、単純な関数を使用して応答をテストするため、これらの場合、ComplexityはCooperateのふりをします。


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に変更してから、協力を返します。しかし、それは機能しません。私はjavascriptにあまり詳しくないので、おそらくさらに変更を加えます。


賢いアイデアですが、別の仲間がtester関数を作成するとどうなりますか:D
V.クルトワ

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';
  }
}

免責事項:私はJavaScriptを知らない。

いい人から利益を得ることができるなら、それをしてください。そうでなければ、彼らが協力することに直面した場合、彼らが返すであろうものを返します(少なくとも、それは私がそうすることだと思います)。


2

そして、あなたはどこに行きたいですか?(ジャングルの本の意志に触発された)

    自分で機能する(それら){
      試す{
        それらを返す(これ);
      } catch(e){
        return "D";
      }
    }

   関数myself_no_this(them){
      試す{
        それらを返す(yourself_no_this);
      } catch(e){
        return "D";
      }
    }

これは私が走ったトーナメントで勝ったばかりです。よくやった!
メガトム

このボットがルールに違反していることに気づきました。「変数self ...にアクセスすることはできません」thisはselfと同じです。あなたが言いたかったと思いますreturn them(yourself)
メガトム

技術(xkcd.com/1475);)thisは変数ではなく、キーワードであり、関数のコンテキストで使用されますthis!=selfselfは、ウィンドウオブジェクトとthis関数自体を意味します(常にそれが存在するコンテキストを参照するため、変数とは見なされません)。そのため var self = this;、多くのコード例の冒頭にあると誤解を招く可能性があります。「this」なしのバージョンを追加
-TS

1
いいえthis、機能を参照していません。yourselfそして、yourself_no_this実行が異なっ異なります。this基本的にjavascriptの関数を参照することはありません。参照: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

変更したトーナメントコードは次のとおり
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

TrickyBot

予測不能になるようにしてください

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)
アンデルスカセオルグ

独自の自己適用を検討しましたが、大丈夫だと思いました。私はそれが本当に今を願っています。
クリスチャンシーバーズ

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.クルトワ

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

彼は私が思ったほど悪くはありませんでした。
2回目の試行では、a背後に、再び260再び、3位になったonlyTrustYourselfし、defect再び。最終的には一貫しているかもしれません:)

PS:ゴルフはあまり得意ではないので、何よりもジョークに向いています。ここでは、変数名、関数名を短縮し、できるだけ多くの空白を削除しました。


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.