Wyzwanie to zostało zainspirowane doskonałym wyzwaniem @HelkaHomba Red vs. Blue - Pixel Team Battlebots . To wyzwanie było prawdopodobnie najlepszym, jakie widziałem na tej stronie. Zawsze.
Moje wyzwanie jest wciąż inne, ale @HelkaHomba zasługuje na uznanie za inspirację.
Przegląd
To drużynowy król wzgórza, w którym Twoja drużyna wygrywa, utrzymując przy życiu wszystkich graczy. Innymi słowy, ostatnia drużyna stojąca wygrywa. Losowania zostaną ponownie wykonane.
Jesteś na tablicy. Znasz swoją pozycję w pierwszej rundzie (zaznacz 0). Wiesz także, kto jest w pobliżu:
W takim przypadku jesteś zupełnie sam (a przynajmniej tak ci się wydaje) bez nikogo w pobliżu. Możesz zobaczyć otaczające elementy w pierwszym argumencie do twojego ontick
handlera. Więcej o API później.
Twój zespół
Twój zespół jest określany na podstawie identyfikatora użytkownika. Aby się tego dowiedzieć, kliknij swoje zdjęcie profilowe:
Następnie znajdź swój identyfikator użytkownika w pasku adresu:
Jeśli to dziwne, jesteś w niebieskiej drużynie.
Jeśli jest parzysty, jesteś w czerwonej drużynie.
Zapraszamy do ręcznie narysowanych kół.
Twoje imię (bota)
Nazwa twojego bota zaczyna się od pierwszej litery twojego zespołu („r” lub „b”). Musi pasować do wyrażenia regularnego /^(r|b)[A-Za-z_-]$/
. Poza tym możesz wybrać nazwę bota. Nie używaj już istniejącego.
Startowy
Czerwoni gracze zaczną się u góry mapy, a niebieski zaczną u dołu. Otrzymasz specjalne informacje o pierwszym tiku (skręcie) w environment
parametrze ontick
funkcji. Polecam to przechowywać. Szczegółowe informacje można znaleźć w interfejsie API.
Na twoją kolej
Kolejność tur jest początkowo losowa, ale potem pozostaje taka sama.
Włącz akcje
Możesz wykonać tylko jedną akcję na turę.
Ruszaj się
Gdy chcesz się przenieść, wywołujesz
this.move(num)
interfejs API.num
to komórka, do której chcesz przenieść:Względne lokalizacje liczb, do których można się przenieść, są przechowywane w stałej globalnej
threeByThree
:
[
[0, 1, 2],
[3, undefined, 4],
[5, 6, 7]
]
Jeśli wejdziesz do ściany lub innego gracza, nic się nie stanie.
Obracać się
Aby obrócić, dzwonisz
this.rotate(num)
. Num to kierunek, który chcesz obrócić:Rotacja jest absolutna.
Zabić
Jeśli inny gracz (z innej drużyny) znajduje się w komórce, w której stoisz, możesz do niego zadzwonić
this.kill()
i zabić. Jeśli nikogo tam nie ma lub są w twoim zespole, to nic nie robi. Przykład:Jeśli się odwrócisz
0
, możesz zabić zielonego. Jeśli zmienisz na 1, możesz zabić niebieski. Jeśli zmienisz na 2, możesz zabić pomarańczę. Jeśli zmienisz na 3, możesz zabić żółty.Bomba
Bombardowanie zabija wszystkich graczy, w tym ciebie i członków drużyny na 9 polach wokół ciebie. Przykład:
Dlaczego miałbyś to robić? Kamikadze . Jeśli w 9 komórkach wokół ciebie jest więcej graczy, którzy nie są w twojej drużynie, to w twojej drużynie jest więcej graczy , możesz rozważyć zbombardowanie. (Radzę najpierw powiadomić swoich towarzyszy!)
Umieść minę
To tworzy kwadrat śmierci dla osób spoza zespołu. Kiedy umieszczasz minę, również się poruszasz, aby na nią nie nadepnąć. Nazywasz
this.landMine(num)
gdzie num jest kwadratem chcesz się udać. Przykład:Następnie dzwonisz
this.landMine(4)
:Widzisz to „M”? To mina. Inni to widzą ... na razie. Każdy, nawet nie należący do twojego zespołu, może zobaczyć minę na kleszczu, który jest umieszczony. Ale po tym kleszczu już nie ma, nikt, nawet ty go nie widzisz. Ale eksploduje, gdy tylko nadejdzie wróg. Przykład:
Niebieski porusza się po twojej minie i BOOM! Właśnie dostałeś kolejnego zabójstwa.
Za każde 2 zabójstwa, które otrzymujesz (z bezpośredniego zabijania lub min), dostajesz 1 dodatkową minę na miejsce. Dostajesz też jeden na początku.
Kopać
Podczas kopania szukasz min przeciwpiechotnych w obszarze 5 x 5, który jest wokół ciebie. Nie pokazuje to zespołu bota, który umieścił minę. (Pamiętaj, że nie możesz zostać zabity przez minę lądową umieszczoną przez kogoś w twojej drużynie). Na przykład, jeśli była to siatka wokół ciebie:
Wtedy zwracana wartość
this.dig()
to:
[undefined,undefined,undefined,true,undefined,
undefined,undefined,undefined,undefined,undefined,
undefined,undefined,undefined,undefined,
undefined,undefined,true,undefined,undefined,
true,undefined,undefined,undefined,undefined]
Indeksy tablic zaczynają się od lewego górnego rogu, w prawo, niż w dół, nie obejmując ciebie:
W sumie jest ich 23, a ich względne lokalizacje są przechowywane w stałej globalnej fiveByFive
:
[
[0, 1, 2, 3, 4],
[5, 6, 7, 8, 9],
[10, 11, undefined, 12, 13],
[14, 15, 16, 17, 18],
[19, 20, 21, 22, 23]
]
Zauważ, że wykop odsłania miny umieszczone na poprzednich kleszczach, w przeciwieństwie do aroundMe
.
Komunikacja
Kiedy chcesz z kimś porozmawiać, dzwonisz this.sendMessage(recipients, team, data)
. Dane mogą być dowolne i możesz je wysłać do dowolnej osoby, nawet graczy z innych drużyn. Można to wykorzystać do oszukiwania źle zaprogramowanych botów, ale wszyscy gracze mogą zobaczyć, kto wysłał wiadomość i do kogo należą.
Przykład:
Wyślij coś do bota o nazwie „redisbest”:
this.sendMessage("redisbest", undefined, "Hi!");
Wyślij coś do bota o nazwie „redisbest” i „blueiscool”:
this.sendMessage(["redisbest", "blueiscool"], undefined, {hello: "there"});
Wyślij coś do całej czerwonej drużyny
this.sendMessage(undefined, "red", {hello: "red"});
Wyślij coś każdemu
this.sendMessage(undefined, "*", {hello: "everyone"});
Wyślij coś do całego czerwonego zespołu i bota o nazwie „blueiscool”:
this.sendMessage("blueiscool", "red", {hello: "bots"});
API
Kod powinien składać się z jednego połączenia do createBot
funkcji. Nic więcej. Przykładowy kod:
createBot({
ontick: function(environment) {
return new Promise((resolve, reject)=>{
this.move(0);//example
resolve();//please call this when you are done
});
},
onmessage: function(data, from, fromBot) {
console.log("onMessage: " + this.name + " from " + this.team + " got message ", data, " from " + from + ", on team " + fromTeam);
this.sendMessage(["bot", "otherbot"], "team", "some data");
},
team: "red",//your team
name: "rmyteamname",//team name must begin with the first letter of your team's name
onkill: function(){
//say goodbye
}
});
(Możesz to skopiować i wkleić. Po prostu zmodyfikuj dla swojego zespołu itp.)
Metody
ontick(environment)
Wywoływany, kiedy jest twoja kolej. Musi zwrócić a,
Promise
które rozwiązuje się w ciągu 1 sekundy lub krócej, albo zostanie zignorowane. Jest to spowodowane wydajnością i ma fajny efekt uboczny polegający na tym, że karta się nie zawiesiła.this
(w trybie ontick)landMines
Ile min min pozostało. Im więcej zabijasz, tym więcej masz min lądowych. Za każde 2 roboty, które zabijesz, zyskujesz 1 dodatkową minę lądową. Dostajesz także 1, aby rozpocząć.direction
Kierunek, w którym patrzysz.storage
Pamięć, która utrzymuje się między połączeniami doonTick
ionMessage
. Pusty obiekt na początku. Modyfikuj w dowolnym celu, ale upewnij się, że jest to tablica lub obiekt zawsze, aby upewnić się, że nadal działa poprawnie.move(num)
Przejdź do określonej pozycji. Nie robi nic, jeśli jest nieprawidłowy. Szczegóły powyżej.rotate(num)
Obróć do określonej pozycji. Nie robi nic, jeśli jest nieprawidłowy. Szczegóły powyżej.kill()
Zabija gracza, z którym się mierzysz, jeśli istnieje i nie należy do twojej drużyny. Szczegóły powyżej.bomb()
Zabija każdego na 9 polach wokół ciebie, w tym ciebie.landMine(num)
Umieszcza minę, gdzie jesteś, a następnie przesuwa się na określoną pozycję. Nie robi nic, jeśli jest nieważnynum
lub nie masz go już. Szczegóły powyżej.dig()
Nowy! Zwraca tablicę informacji o minach w obszarze 5x5, który jest wokół ciebie. Szczegóły powyżej.sendMessage(recipients, team, data)
recipients
może być pojedynczym botem (ciągiem), tablicą bota lubundefined
/null
. To do kogo chcesz wysłać wiadomość.team
to ciąg zespołu, który chcesz wysłać wiadomość. Służy"*"
do wysyłania wiadomości do wszystkich.data
to wszystko, co można przekazać do funkcji JS. Jest wysyłany do odbiorców. Jeśli jest to obiekt lub tablica, jest przekazywany przez referencję , więc ty i odbiorca (-ci) możecie zapisać to na sobie,storage
a wszelkie modyfikacje obiektu wpływają na kopie obu botów. Zauważ, że odbiorcy, którzy znajdują się na liście botów, dokładnego bota określonego w ciągu lub bota w podanym zespole, otrzymają wiadomość.
environment
Na pierwszym tyknięciu
x
: Pozycja x twojego graczay
: Pozycja y twojego graczagridWidth
: Szerokość siatki (w komórkach)gridHeight
: Wysokość siatki (w komórkach)Na wszystkich kleszczach
aroundMe
: Tablica graczy i min. Gracze to obiekty, które wyglądają podobnie jak{name: "bot name", team: "bot team"}
miny{team: "team of bot who placed mine"}
. Indeksy tablicy:Pamiętaj, że miny umieszczone na kleszczu innym niż bieżący nie zostaną pokazane.
aroundMe
przykład:Powiedzmy, że to jest siatka (jesteś czerwony):
Twój
aroundMe
będzie wyglądał następująco:
[
{name: "bexamplebluebot", team: "blue"},
undefined,//sparse array, nothing in index 1
undefined,//there is technically a landmine here, but it wasn't placed this tick, so it is not shown
undefined,//nothing in 3
{name: "yexampleyellowbot", team: "yellow"},
{team: "red"},//this is a landmine, you can tell is not a bot because it has no name. mines have the team name of the player they were placed by. This mine was placed this tick, otherwise you couldn't see it
//nothing else after index 5, so the array's length is 5.
]
Indeksy tablicy są wyjaśnione tutaj:
Twój bot skutecznie widzi to:
onmessage(data, fromBot, fromTeam)
this
(w wiadomości)sendMessage(recipients, team, data)
Standardowa funkcja wysyłania wiadomości.storage
Standardowe przechowywanie.
data
Dane wysłane od nadawcy.fromPlayer
Gracz, z którego wiadomość została wysłana.fromTeam
Zespół, z którego wysłano wiadomość.onkill()
this
(gdy onkill)sendMessage(recipients, team, data)
Standardowa funkcja wysyłania wiadomości.
Wygodne (stałe) tablice globalne:
threeByThree
:
[
[0, 1, 2],
[3, undefined, 4],
[5, 6, 7]
]
Przydatny do przekazywania danych do funkcji przenoszenia oraz tłumaczenia aroundMe
. Patrz wyżej.
fiveByFive
:
[
[0, 1, 2, 3, 4],
[5, 6, 7, 8, 9],
[10, 11, undefined, 12, 13],
[14, 15, 16, 17, 18],
[19, 20, 21, 22, 23]
]
Przydatne dla this.dig()
funkcji w ontick
przewodnika.
Wypróbuj to!
Kontroler będzie uruchamiany z mojego komputera na hoście lokalnym ze względu na wydajność, ale możesz użyć CodePen do przetestowania swojego bota.
Pamiętaj, że musisz wkleić kod w konsoli i nacisnąć Enter
przed kliknięciem przycisku Uruchom. Możesz wkleić tyle botów, ile chcesz. „Boty testowe” są przykładami do przetestowania. Jeśli potrafisz je wszystkie pokonać lub związać, masz przynajmniej przyzwoitego bota.
Zgłoszenia
Zasady
Zasady (egzekwowane przez kontrolera)
- Twój główny
ontick
kod nie może zająć więcej niż 1 sekundę. Nie chcemy, aby rundy trwały wiecznie. Jeśli Twój kod zajmie> 1 sekundę, zostanie zatrzymany. - Jeśli spróbujesz wykonać więcej niż 1 akcję na turę lub wykonasz nieprawidłową akcję (np.
this.move(-1)
Lub przejście do ściany), zostanie to zignorowane. - Więcej może wkrótce ...
Reguły (egzekwowane przeze mnie mogą powodować DQ)
- Nie pisz zmiennych globalnych ( czytanie jest w porządku ).
- Twój kod musi działać w Nodejs (w przypadku, gdy kontroler jest przeniesiony do Nodejs), więc
JSON.parse(...)
jest w porządku, alealert()
nie jest. - Nie możesz
createBot
w żaden sposób dzwonić lub ingerować w kontroler . - Nie używaj cudzego kodu bez pozwolenia i znaczących zmian. Bez kopiowania.
- Proszę, żadnych luk!
- Więcej może wkrótce ...
Moje boty
Oto niektóre boty:
Ten bot losowo wybiera akcję. Cóż, jest ważony losowo, ale wciąż dość losowo. Jeśli możesz zabić tego bota (w końcu sam się zabije, to się nie liczy), to masz przynajmniej przyzwoitego bota. Opublikuj i zobacz, co się stanie!
Moje boty mają nazwę zaczynającą się od „x” i zespół „none”. Zapraszamy do korzystania z niektórych tego kodu, ale proszę zrobić przynajmniej kilka modyfikacji. Jeśli nie będziesz miał najmniejszych kłopotów z poprawieniem numeru, nie wygrasz.
Formatowanie zgłoszenia
Proszę użyć tego formatu:
# rmyamazingbot
createBot({
ontick: function(environment) {
return new Promise((resolve, reject)=>{
this.move(0);//example
resolve();//please call this when you are done
});
},
onmessage: function(data, fromTeam, fromBot) {
console.log("onMessage: " + this.name + " from " + this.team + " got message ", data, " from " + from + ", on team " + fromTeam);
this.sendMessage(["bot", "otherbot"], "team", "some data");
},
team: "red",//your team
name: "rmyteamname",//team name must begin with the first letter of your team's name
onkill: function(){
//say goodbye
}
});
Long, but cool explanation...
Prośby o nowe funkcje, błędy, pytania itp.?
Komentarz poniżej! Sprawdź, czy jest już z tym komentarz. Jeśli już istnieje, oceń go.
Chcesz porozmawiać ze swoim zespołem?
Korzystaj z pokojów czatowych w kolorze czerwonym i niebieskim .
Język
Obecnie obsługiwany jest tylko JS i coś, co kompiluje się do JS, ale jeśli znasz sposób, aby inne języki współpracowały z Nodejsem, chętnie przeniesie kontroler do Nodejsa.
Uwagi końcowe
Pomysły na strategię
Pomóż swojemu zespołowi! Stworzenie bota, który ma pomóc innym botom i współpracować ze sobą. Ta strategia działała dobrze dla Red vs. Blue - Pixel Team Battlebots
Osoby poszukujące przedstawicieli
Przyjmuję najwyższą głosowaną odpowiedź na zwycięską drużynę. Należy pamiętać, że wcześniejsze odpowiedzi zwykle zdobywają więcej głosów, ale ich słabości są bardziej prawdopodobne do znalezienia i wykorzystania.
Ponadto, jeśli odpowiesz wkrótce, możesz otrzymać nagrodę +100.