Dilema Tahanan dengan akses ke lawan


21

Dalam tantangan ini, Anda akan menulis bot yang memainkan dilema tahanan. Inilah intinya: Anda tidak akan memiliki akses ke sejarah game sebelumnya. Sebaliknya, Anda akan memiliki akses ke lawan itu sendiri. Dalam versi ini, kedua pemain mendapat +2 poin jika mereka berdua bekerja sama, +1 poin jika mereka berdua cacat, dan jika satu bekerja sama tetapi satu cacat, pembelot mendapat +3 sementara yang lain tidak mendapat poin. Setiap pengiriman akan dimainkan melawan setiap pengiriman lainnya, termasuk pengiriman itu sendiri, 10 kali. Pemenangnya adalah pengajuan dengan poin paling total.

Pengontrol : Anda harus menulis fungsi javascript, dalam formulir

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

Pengontrol menggunakan nameproperti fungsi untuk menampilkan hasil, jadi jika tidak dalam format ini (dan sebaliknya f = x => ...atau f = function() { ... }) itu akan sulit untuk melihat skor Anda dan Anda tidak akan dapat mengakses fungsi Anda sendiri.

Fungsi akan menerima satu parameter: themyang merupakan fungsi lawan. Kemudian dapat memanggil fungsi itu untuk melihat apa reaksi lawan akan diberikan fungsi tertentu sebagai input. Berdasarkan data itu, Anda harus mengembalikan 'C' atau 'D' untuk bekerja sama atau cacat masing-masing.

Contoh (akan bersaing):

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

Kontroler tersedia di sini

Aturan :

  • Anda tidak akan dapat melihat kode lawan itu sendiri. Semua fungsi dibungkus sehingga mereka terlihat sama ketika toString()dipanggil. Satu-satunya cara untuk memeriksa lawan (yang bisa menjadi diri sendiri) adalah dengan menguji mereka.
  • Fungsi Anda tidak harus bersifat deterministik. Anda hanya dapat menyimpan status dengan menyetel properti pada fungsi Anda sendiri, seperti submissionName.state = {};. Namun, di antara pertandingan (bahkan di antara pertandingan dari pemain yang sama), status dibersihkan dengan memanggil toString()dan eval. Karena itu, tidak ada memori dari pertandingan sebelumnya.
  • Urutan fungsi yang dipanggil pertama dalam setiap pertandingan secara acak.
  • Jika kode Anda membuat kesalahan, itu akan diperlakukan seolah-olah Anda bekerja sama saat lawan Anda membelot. Jika Anda adalah orang pertama yang menjalankan, kode lawan bahkan tidak akan dipanggil. Ini terjadi bahkan jika kesalahan terjadi pada kode lawan saat Anda menelepon them. Waspadai kesalahan stack overflow, terutama jika kode Anda memanggil them(wrap(submissionName)), karena mereka mungkin melakukan hal yang sama.
  • Anda mungkin tidak mengakses variabel self, atau variabel lain apa pun yang berada dalam lingkup ketika evaldisebut KECUALI fungsi wrap. Fungsi ini memungkinkan Anda untuk memanggil lawan dengan cara yang tidak dapat dibedakan dari cara pengontrol memanggil suatu fungsi. Anda tidak boleh menulis ke Math,, windowdll. (Anda dapat menggunakan fungsi, seperti Math.random(), namun).
  • Anda tidak dapat mengakses jejak tumpukan dengan membuat Erroratau dengan beberapa metode lain.

Catatan untuk waktu yang terlalu lama: harap jangan terjebak dalam a whilelingkaran selamanya. Waktu gabungan kedua pesaing tidak boleh lebih dari 1 detik dalam setiap babak yang diberikan. Untuk menegakkan ini, batas waktu acak antara 1000 ms dan 2000 ms dipilih (ini adalah untuk menghindari permainan dengan sengaja menunggu jumlah waktu yang diketahui), dan jika pekerja membutuhkan waktu lebih lama dari itu untuk mengeksekusi, kesalahan akan terjadi. Jika ini terjadi, penyebab kesalahan akan ditentukan sebagai berikut: eksekusi akan dijeda pada saat acak setelah 1000 ms, dan tumpukan panggilan pada saat itu akan diperiksa. Pesaing yang disebut terakhir yang saat ini berada dalam satu lingkaran (atau rekursi seperti loop, dalam arti bahwa itu adalah rekursi yang diatur untuk menghindari kesalahan stack overflow) akan disalahkan. Jika pesaing yang sama disalahkan karena menyebabkan kesalahan "terlalu lama" beberapa kali, pesaing tersebut akan didiskualifikasi.


Tantangan ini mengingatkan saya pada Lelang Uang Dolar .
Alion

Haruskah fungsi yang digunakan untuk menguji thembersifat deterministik / mengikuti aturan? Sebagai contoh function me(them){let log=0;them(x=>{++log;return 'C';}); return log == 0? 'D': 'C';}
user202729

2
Jika kedua fungsi memanggil mereka (membungkus (sesuatu)), bagaimana Anda bisa mencegah rekursi? Apakah saya melewatkan sesuatu?
Quintec

@ Quintec Anda dapat menggunakan rekursi dan loop. Hanya saja rekursi perlu menghasilkan StackOverflowkesalahan dan bukan loop tak terbatas yang tidak pernah berhenti. Jika itu bisa menghasilkan StackOverflow, pastikan Anda menambahkan pernyataan try-catch. Untuk contoh rekursi yang tidak mencapai kesalahan stackoverflow dalam 1 detik, Anda membutuhkan lebih banyak contoh yang tidak jelas seperti stackoverflow.com/q/12438786/3371119
soktinpk

1
@ Quintec belum tentu. Misalnya, them(() => 'C')tidak akan menghasilkan kesalahan karena ketika lawan memanggil them, ia memanggil () => 'C'fungsi. Satu-satunya hal yang perlu dibungkus try-catchadalah jika Anda memanggil themdengan parameter dari beberapa fungsi yang memanggil themdengan parameter dari beberapa fungsi yang memanggil themdll. (Tanpa batas). Misalnya, them(t => t(() => 'C'))akan memainkan apa pun yang akan dimainkan lawan jika lawan mengira mereka bermain nice. Tidak ada kemungkinan stackoverflowkesalahan.
soktinpk

Jawaban:


14

BoomBot

function boom(them) {
  throw 1;
}

Jika lawan dijalankan terlebih dahulu dan menyebutnya tanpa try..catch, bot ini secara otomatis memenangkan 3 poin. Nol poin dalam hal lain.


Jika lawan dijalankan terlebih dahulu dan tidak memanggil ini, maka itu akan kehilangan 3 poin, kan?
user202729

1
@ user202729 Lebih tepatnya, lawan akan mendapatkan 3 poin. Tidak ada poin kalah di game ini.
Bubbler

10

Archaeopteryx

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';
}
  • Jika lawan bekerja sama cooperate, maka meniru gerakan lawan melawan defect.
  • Lain, jika lawan bekerja sama dengan defectatau dengan nice, maka cacat.
  • Lain, bekerja sama.

Apa yang membuat ini strategi yang bagus? Saya tidak punya ide. Saya membuatnya menggunakan algoritma evolusi, dilatih sebagian pada pengiriman saat ini.

Tiktaalik

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'));
}
  • Jika lawan cacat melawan cooperate, maka balikkan gerakan lawan melawan defect.
  • Lain, jika lawan cacat melawan defect, maka cacat.
  • Lain, meniru gerakan lawan melawan notNice.

Strategi lain yang dihasilkan secara evolusioner.


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 cukup sederhana; itu hanya menguji lawannya untuk apa yang akan dilakukannya terhadap program kondisi mapan. Jika bot lebih suka bekerja sama jika mungkin, WWBDB juga akan lebih suka kerja sama (jadi itu akan bekerja sama dengan bot yang bagus). WWBDB sendiri tidak menyukai kerja sama.


5

Periksa status

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

Jika mereka memohon saya, maka mereka mungkin benar-benar mereka. Kami bertindak sebagai pembelot. Jika mereka tidak memohon saya, maka mereka mungkin menjadi tester terbungkus. Kami akan bertindak sebagai lebih baik.


Di atas adalah jawaban asli. Dan mungkin saya harus membuat diri saya bekerja sama untuk mendapatkan lebih banyak poin.

Periksa stateful dengan 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

RandomBot

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

Karena mengapa tidak.


3

Kompleksitas

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

Tes kompleksitas untuk melihat apakah bot bekerja sama atau rusak. Jika ya, itu bekerja sama, tetapi jika tidak, itu cacat. Semua bot saat ini yang menguji lawan mereka menggunakan fungsi sederhana untuk menguji respon, jadi Kompleksitas hanya akan berpura-pura bekerja sama dalam kasus tersebut.


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

Cara saya ingin ini bekerja adalah selalu cacat, kecuali saat bermain melawan diri sendiri. Ia mencoba melakukannya dengan melewati fungsi "tester" yang tidak dibungkus dengan mereka, dan mencoba mendeteksi apakah "mereka" bernama tester. Jika ini bernama tester, ini akan mengubah variabel statis yang diaktifkan menjadi true, lalu kembali bekerja sama. Tapi itu tidak berhasil. Saya tidak terlalu terbiasa dengan javascript, dan saya mungkin akan membuat beberapa perubahan lagi.


ide pintar, tetapi apa yang terjadi ketika bro lain membuat testerfungsi: D
V. Courtois

2

Tidak baik

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

Meniru reaksi lawan terhadap defleksi



2

Akal sehat

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

Penafian: Saya agak tidak tahu javascript.

Jika Anda bisa mendapat untung dari orang yang baik, lakukanlah. Kalau tidak, kembalikan apa yang akan mereka kembalikan jika mereka menghadapi diri mereka sendiri untuk bekerja sama (setidaknya, itulah yang saya pikirkan ).


2

Dan Anda ke mana Anda pergi? (Terinspirasi oleh tegangan dalam buku hutan)

    berfungsi sendiri (mereka) {
      mencoba{
        kembalikan (ini);
      } catch (e) {
        kembali "D";
      }
    }

   fungsi yourself_no_ini (mereka) {
      mencoba{
        kembalikan mereka (yourself_no_this);
      } catch (e) {
        kembali "D";
      }
    }

Ini baru saja menang dalam turnamen yang saya ikuti. Kerja bagus!
MegaTom

Saya hanya memperhatikan bahwa bot ini melanggar aturan. "Anda tidak boleh mengakses variabel diri ..." thissama dengan diri. Saya pikir Anda ingin mengatakannya return them(yourself).
MegaTom

Technicaly ( xkcd.com/1475 );) thisbukan variabel, itu adalah kata kunci, dan dalam konteks fungsi this!=self. selfakan berarti objek jendela dan thisfungsinya sendiri (selalu merujuk pada konteksnya, itulah mengapa ia tidak dianggap sebagai variabel). Itulah sebabnya mengapa var self = this;pada awal banyak contoh kode dapat dianggap menyesatkan. Versi tambahan tanpa "ini"
TS

1
Tidak. thisTidak mengacu pada fungsi. yourselfdan yourself_no_thisjalankan berbeda-beda. thispada dasarnya tidak pernah merujuk pada fungsi dalam javascript. Lihat: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
MegaTom

2

Menghukum Inspektur

Berikan bot beberapa kode dan lihat apakah itu menjalankannya. Jika dijalankan lebih dari sekali, bot adalah inspektur jahat, dan kita harus membelot! Jika dijalankan tepat satu kali, mainkan bot tidak bagus. Jika tidak pernah berjalan, bekerja sama.

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

Sejarah

Apa yang bot terakhir yang saya lihat lakukan vs lawan ini?

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

Hasil untuk turnamen 10.000 putaran:

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

Kode turnamen saya yang dimodifikasi adalah di: jsfiddle.net/eyqL4a8d/2
MegaTom

2

Mal mencoba menentukan apakah itu di dalam simulasi atau tidak. Jika demikian, ia mengasumsikan pada akhirnya akan melewati kode asli untuk them, dan mencoba berbagai strategi untuk meyakinkan mereka untuk bekerja sama.
Jika tidak tahu pasti, ia memeriksa apakah dapat cacat secara gratis, atau jika tidak, mencoba menyalin apa yang themakan dilakukan ketika diberi kooperator.

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

Cobalah untuk tidak dapat diprediksi

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

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

  return 'C';
}

1

diri sendiri

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

Tidak yakin apakah itu masuk akal, tetapi tampaknya menarik! Lakukan untuk Anda seperti yang Anda lakukan untuk diri sendiri, ulangi untuk menangkap keacakan. Jika itu tidak berhasil, bersikaplah baik.

Belum teruji, dan kode javascript pertama saya, dan lebih kompleks dari yang saya harapkan.


Ini akan mendiskualifikasi dirinya sendiri karena selfapply(selfapply)panggilan selfapply(selfapply)!
Anders Kaseorg

Saya memang mempertimbangkan aplikasi sendiri, tetapi saya pikir itu akan baik-baik saja. Saya harap itu benar-benar sekarang.
Christian Sievers

1

RandomAlternate

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

Jadi saya belajar cara menggunakan properti untuk keadaan ...


1

Bot Pembunuhan # 1

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

Menyebabkan loop tak terbatas di mana lebih mungkin bahwa lawan akan disalahkan.


1

Bot Aturan Platinum

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

Aturan Platinum menyatakan "Perlakukan orang lain dengan cara yang mereka inginkan." Bot saya mengakomodasi itu. Apa pun yang akan mereka lakukan untuk diri mereka sendiri, yang kita asumsikan adalah bagaimana mereka ingin diperlakukan, kita lakukan untuk mereka. Jika mereka melakukan kesalahan, kami menganggap mereka ingin bekerja sama.


Ini benar-benar akan berlangsung selamanya jika dipanggil melawan dirinya sendiri
mackycheese21

maka bukankah itu crash (stack overflow) dan bekerja sama dengan dirinya sendiri? @ mackycheese21
V. Courtois

1

TheGolfedOne (nama fungsi:) a, 63 byte

Kode golf sulit dibaca. Karena itu, themakan pecah.
Saya tidak sepenuhnya memahami mekanisme di bawah KotH ini, tapi saya kira jika lawan tidak memiliki kewarganegaraan, saya hanya perlu mematahkannya saat saya membelot.

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

Hasil pertandingan pertamanya (saya tidak repot menggunakan semua bot, maaf)

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

Dia tidak melakukan hal yang buruk seperti yang saya pikirkan, tempat ketiga (di antara mereka) pertama kali mencoba.
Percobaan kedua,a mendapat 260 lagi, ke-3 lagi, di belakang onlyTrustYourselfdan defectlagi. Mungkin akan konsisten pada akhirnya :)

PS: Saya tidak begitu baik dalam bermain golf sehingga lebih untuk lelucon daripada apa pun. Di sini saya hanya memperpendek nama variabel, nama fungsi, dan menghapus spasi sebanyak mungkin.


0

Karma

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

Jika lawan mau bekerja sama dengan kami, maka kami akan bekerja sama. Jika mereka mencoba untuk membelot ketika kita bekerja sama, kita juga akan membelot.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.