In dieser Herausforderung schreiben Sie einen Bot, der das Dilemma des Gefangenen darstellt. Hier ist der Haken: Sie haben keinen Zugriff auf die Geschichte der vorherigen Spiele. Stattdessen haben Sie Zugriff auf den Gegner selbst. In dieser Version erhalten beide Spieler +2 Punkte, wenn beide kooperieren, +1 Punkte, wenn beide defekt sind, und wenn einer kooperiert, aber einer defekt ist, erhält der Defektor +3, während der andere keine Punkte erhält. Jede Einreichung wird zehnmal gegen jede andere Einreichung, einschließlich sich selbst, gespielt. Gewinner ist die Einsendung mit den meisten Gesamtpunkten.
Controller : Sie sollten eine Javascript-Funktion in das Formular schreiben
function submissionName(them) {
/* Your code here */
}
Der Controller verwendet die name
Eigenschaft der Funktion , um die Ergebnisse anzuzeigen. Wenn diese also nicht in diesem Format vorliegen (und stattdessen f = x => ...
oder vorliegen f = function() { ... }
), ist es schwierig, Ihre Punktzahl anzuzeigen, und Sie können nicht auf Ihre eigene Funktion zugreifen.
Die Funktion akzeptiert einen Parameter: them
Dies ist die Funktion des Gegners. Es kann dann diese Funktion aufrufen, um zu sehen, wie die Reaktion des Gegners bestimmte Funktionen als Eingaben erhalten würde. Basierend auf diesen Daten müssen Sie "C" oder "D" für die Zusammenarbeit bzw. den Defekt zurückgeben.
Beispiele (werden konkurrieren):
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'));
}
Der Controller ist hier verfügbar
Regeln :
- Sie können den Code des Gegners selbst nicht sehen. Alle Funktionen werden so umbrochen, dass sie beim
toString()
Aufruf gleich aussehen . Die einzige Möglichkeit, einen Gegner (der Sie selbst sein könnte) zu untersuchen, besteht darin, ihn zu testen. - Ihre Funktion muss nicht deterministisch sein. Sie können den Status nur speichern, indem Sie Eigenschaften für Ihre eigene Funktion festlegen, z
submissionName.state = {};
. Zwischen Spielen (auch zwischen Spielen der gleichen Spieler) wird der Status durch Aufrufen vontoString()
und gelöschteval
. Daher gibt es keine Erinnerung an vorherige Übereinstimmungen. - Die Reihenfolge, in der die Funktion in jeder Übereinstimmung zuerst aufgerufen wird, ist zufällig.
- Wenn Ihr Code einen Fehler auslöst, wird er so behandelt, als hätten Sie zusammengearbeitet, während Ihr Gegner defekt war. Wenn Sie der Erste sind, der rennt, wird der Code des Gegners nicht einmal aufgerufen. Dies geschieht auch dann, wenn der Fehler im Code Ihres Gegners auftritt, während Sie anrufen
them
. Seien Sie vorsichtig bei Stapelüberlauffehlern, insbesondere wenn Ihr Code aufruftthem(wrap(submissionName))
, da diese möglicherweise dasselbe tun. - Sie dürfen nicht auf die Variable
self
oder eine andere Variable zugreifen, die sich zufällig im Gültigkeitsbereich befindet, wenneval
AUSSER der Funktion aufgerufen wirdwrap
. Mit dieser Funktion können Sie den Gegner auf eine Weise anrufen, die nicht davon zu unterscheiden ist, wie der Controller eine Funktion aufruft. Sie können nicht schreibenMath
,window
etc. (Sie Funktionen verwenden können, wie zum BeispielMath.random()
, jedoch). - Sie können möglicherweise nicht auf den Stack-Trace zugreifen, indem Sie eine
Error
oder eine andere Methode erstellen .
Ein Hinweis, der zu lange dauert: Vermeiden Sie es, in a stecken zu bleiben while
Schleife für immer. Die kombinierte Zeit beider Wettkämpfer sollte in einer Runde 1 Sekunde nicht überschreiten. Um dies zu erzwingen, wird eine zufällige Zeitüberschreitung zwischen 1000 ms und 2000 ms gewählt (dies dient dazu, das Spielen zu vermeiden, indem absichtlich eine bekannte Zeitspanne abgewartet wird). Wenn der Worker länger für die Ausführung benötigt, wird ein Fehler ausgegeben. In diesem Fall wird die Fehlerursache wie folgt ermittelt: Die Ausführung wird zu einem beliebigen Zeitpunkt nach 1000 ms unterbrochen, und der Aufrufstapel wird zu diesem Zeitpunkt überprüft. Der zuletzt aufgerufene Konkurrent, der sich derzeit in einer Schleife befindet (oder eine schleifenartige Rekursion in dem Sinne, dass es sich um eine Rekursion handelt, die eingerichtet wurde, um einen Stapelüberlauffehler zu vermeiden), wird dafür verantwortlich gemacht. Wenn derselbe Teilnehmer dafür verantwortlich gemacht wird, dass er mehrmals einen "zu langen" Fehler verursacht hat, wird dieser Teilnehmer disqualifiziert.
them
deterministisch sein / den Regeln folgen? Zum Beispiel function me(them){let log=0;them(x=>{++log;return 'C';})
: return log == 0? 'D': 'C';}
StackOverflow
Fehler und nicht zu einer Endlosschleife führen muss, die niemals beendet wird. Wenn dies zu einem führen könnte StackOverflow
, stellen Sie sicher, dass Sie eine Try-Catch-Anweisung hinzufügen. Für ein Beispiel für eine Rekursion, bei der innerhalb von 1 Sekunde kein Stackoverflow-Fehler auftritt, benötigen Sie weitere undurchsichtige Beispiele wie stackoverflow.com/q/12438786/3371119
them(() => 'C')
würde in einem Fehler nicht zur Folge hat, weil , wenn der Gegner nennt them
, ist es die Anruf () => 'C'
Funktion. Das Einzige, was eingeschlossen werden muss, try-catch
wäre, wenn Sie them
mit einem Parameter einer Funktion aufrufen , die them
mit einem Parameter einer Funktion aufruft, die them
usw. aufruft (unendlich). Zum Beispiel them(t => t(() => 'C'))
würde spielen, was auch immer der Gegner spielen würde, wenn der Gegner dachte, dass er spielt nice
. Es besteht keine Möglichkeit eines stackoverflow
Fehlers.