W tym wyzwaniu napiszesz bota, który gra dylemat więźnia. Oto haczyk: nie będziesz mieć dostępu do historii poprzednich gier. Zamiast tego będziesz miał dostęp do samego przeciwnika. W tej wersji obaj gracze otrzymują +2 punkty, jeśli obaj ze sobą współpracują, +1 punkty, jeśli obaj wadą, a jeśli jeden współpracuje z jedną wadą, dezerter otrzymuje +3, a drugi nie otrzymuje punktów. Każde zgłoszenie będzie odtwarzane 10 razy względem każdego innego zgłoszenia, w tym samego siebie. Zwycięzcą jest zgłoszenie z największą liczbą punktów.
Kontroler : Powinieneś napisać funkcję javascript w formie
function submissionName(them) {
/* Your code here */
}
Kontroler używa właściwości funkcji name
do wyświetlania wyników, więc jeśli nie jest ona w tym formacie (a zamiast niej f = x => ...
lub f = function() { ... }
), trudno będzie zobaczyć wynik i nie będzie można uzyskać dostępu do własnej funkcji.
Funkcja zaakceptuje jeden parametr: them
funkcję przeciwnika. Może wtedy wywołać tę funkcję, aby zobaczyć, jaka reakcja przeciwnika otrzyma określone funkcje jako dane wejściowe. Na podstawie tych danych musisz zwrócić „C” lub „D” odpowiednio dla współpracy lub usterki.
Przykłady (będą konkurować):
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 jest dostępny tutaj
Zasady :
- Nie będziesz w stanie zobaczyć samego kodu przeciwnika. Wszystkie funkcje są opakowane, aby wyglądały tak samo, gdy
toString()
są wywoływane. Jedynym sposobem na zbadanie przeciwnika (który może być sobą) jest przetestowanie go. - Twoja funkcja nie musi być deterministyczna. Możesz zapisać stan tylko poprzez ustawienie właściwości dla własnej funkcji, takiej jak
submissionName.state = {};
. Jednak między meczami (nawet między meczami tych samych graczy) stan jest kasowany przez wywołanietoString()
ieval
. Dlatego nie ma pamięci o poprzednich meczach. - Kolejność wywoływania funkcji w pierwszym dopasowaniu jest losowa.
- Jeśli Twój kod zgłasza błąd, będzie traktowany tak, jakbyś współpracował, podczas gdy twój przeciwnik jest wadliwy. Jeśli pierwszy biegniesz, kod przeciwnika nawet nie zostanie wywołany. Dzieje się tak nawet wtedy, gdy błąd pojawia się w kodzie przeciwnika podczas twojego sprawdzania
them
. Uważaj na błędy przepełnienia stosu, szczególnie w przypadku wywołań koduthem(wrap(submissionName))
, ponieważ mogą one zrobić to samo. - Nie możesz uzyskać dostępu do zmiennej
self
ani żadnej innej zmiennej, która jest objęta zakresem, gdyeval
jest nazywana Z WYJĄTKIEM funkcjiwrap
. Ta funkcja pozwala na wołanie przeciwnika w sposób nie do odróżnienia od sposobu, w jaki kontroler wywołuje funkcję. Nie możesz pisaćMath
,window
itd (można użyć funkcji, takich jakMath.random()
, jednak). - Nie można uzyskać dostępu do śledzenia stosu, tworząc metodę
Error
lub inną metodą.
Uwaga dotycząca zbyt długiego czasu: unikaj utknięcia w while
pętla na zawsze. Łączny czas obu zawodników nie powinien przekraczać 1 sekundy w danej rundzie. Aby to wymusić, wybierany jest losowy limit czasu między 1000 ms a 2000 ms (ma to na celu uniknięcie gry przez celowe oczekiwanie znanej ilości czasu), a jeśli proces roboczy trwa dłużej, zostanie zgłoszony błąd. Jeśli tak się stanie, przyczyna błędu zostanie określona w następujący sposób: wykonanie zostanie wstrzymane w losowym momencie po 1000 ms, a stos wywołań w tym momencie zostanie sprawdzony. Oskarżony zostanie ostatnio nazywany konkurent, który jest obecnie w pętli (lub rekurencji podobnej do pętli, w tym sensie, że jest to rekurencja skonfigurowana w celu uniknięcia błędu przepełnienia stosu). Jeśli winny jest ten sam zawodnik za kilkakrotne spowodowanie błędu „zbyt długiego”, zostanie on zdyskwalifikowany.
them
musi być deterministyczna / przestrzegać reguł? Na przykład function me(them){let log=0;them(x=>{++log;return 'C';})
; return log == 0? 'D': 'C';}
StackOverflow
błędem, a nie nieskończoną pętlą, która nigdy się nie kończy. Jeśli może to spowodować StackOverflow
, upewnij się, że dodałeś instrukcję try-catch. Na przykład rekurencji, która nie osiągnie błędu
them(() => 'C')
nie spowodowałoby to błędu, ponieważ gdy przeciwnik dzwoni them
, wywołuje () => 'C'
funkcję. Jedyną rzeczą, którą należy zapakować, try-catch
byłoby wywołanie them
z parametrem jakiejś funkcji, która wywołuje się them
z parametrem funkcji wywołującej them
itp. (Nieskończenie). Na przykład, them(t => t(() => 'C'))
zagrałby wszystko , co grałby przeciwnik, gdyby przeciwnik myślał, że gra nice
. Nie ma możliwości stackoverflow
błędu.