Tim Bukit!

27

Tantangan ini diinspirasi oleh tantangan luar biasa @HelkaHomba Merah vs Biru - Pixel Team Battlebots . Tantangan itu mungkin adalah yang terbaik yang pernah saya lihat di situs ini. Pernah.

Tantangan saya masih jauh berbeda, tetapi @HelkaHomba layak mendapat pujian karena inspirasi.

Ikhtisar

Ini adalah tim tempat tim Anda menang dengan membiarkan semua pemain tetap hidup di tim Anda. Dengan kata lain, kedudukan tim terakhir menang. Pengundian akan dilakukan kembali.

Anda berada di papan tulis. Anda tahu posisi Anda di babak pertama (centang 0). Anda juga tahu siapa yang ada di sekitar Anda:

Kotak merah tunggal dalam kotak 9x9, dikelilingi oleh sel putih.

Dalam hal ini, Anda sendirian (atau begitulah menurut Anda) tanpa ada orang di sekitar Anda. Anda dapat melihat item di sekitarnya dalam argumen pertama ke ontickpenangan Anda . Lebih lanjut tentang API nanti.

Tim Anda

Tim Anda ditentukan oleh ID pengguna Anda. Untuk mengetahuinya, klik pada gambar profil Anda:

Gambar profil saya

Kemudian cari ID pengguna Anda di bilah alamat:

Itu antara / users / dan / yourusername

Jika aneh, Anda berada di tim biru.

Jika bahkan, Anda berada di tim merah.

Sama-sama untuk lingkaran yang digambar tangan.

Nama (bot) Anda

Nama bot Anda dimulai dengan huruf pertama dari tim Anda ("r" atau "b"). Itu harus cocok dengan regex /^(r|b)[A-Za-z_-]$/. Selain itu, Anda dapat memilih nama bot Anda. Tolong jangan gunakan yang sudah ada.

Mulai

Pemain merah akan mulai di dekat bagian atas peta, dan biru akan mulai di dekat bagian bawah. Anda diberi info khusus pada centang pertama (belok) di environmentparameter untuk ontickfungsi. Saya sarankan menyimpannya. Lihat API untuk detailnya.

Sekarang giliranmu

Ubah urutan awalnya secara acak, tetapi kemudian tetap sama.

Putar tindakan

Anda hanya dapat melakukan satu tindakan per giliran.

  • Pindah

    Saat Anda ingin pindah, Anda memanggil this.move(num)API. numadalah sel yang ingin Anda pindahkan:

    0 di kiri atas, 1 di tengah atas, 2 di kanan atas, 3 di kanan tengah, 4 di kiri tengah, 5 di kiri bawah, 6 di tengah bawah, dan 7 di kanan bawah.

    Lokasi relatif dari angka yang dapat Anda pindahkan disimpan dalam konstanta global threeByThree:

[
    [0, 1, 2],
    [3, undefined, 4],
    [5, 6, 7]
]

Jika Anda pindah ke dinding, atau pemain lain, tidak ada yang terjadi.

  • Memutar

    Untuk memutar, Anda menelepon this.rotate(num). Num adalah arah yang ingin Anda putar:

    0 di atas, 1 di kanan, 2 di bawah, dan 3 di kiri

    Rotasi mutlak.

  • Membunuh

    Jika pemain lain (dari tim lain) ada di sel yang Anda hadapi, Anda dapat memanggil this.kill()dan membunuh mereka. Jika tidak ada seorang pun di sana, atau mereka ada di tim Anda, ini tidak melakukan apa-apa. Contoh:

    Angka yang sama seperti di atas, sel 0 berwarna hijau, 1 berwarna biru, 2 berwarna oranye, dan 3 berwarna kuning

    Jika Anda beralih ke 0, Anda dapat membunuh hijau. Jika Anda berubah menjadi 1, Anda dapat membunuh biru. Jika Anda berubah menjadi 2, Anda dapat membunuh oranye. Jika Anda berubah menjadi 3, Anda dapat membunuh kuning.

  • Bom

    Pemboman membunuh semua pemain termasuk Anda dan rekan satu tim di 9 kotak di sekitar Anda. Contoh:

    Ada kotak 9x9 dengan "x" di setiap sel.

    Mengapa Anda ingin melakukan ini? Kamikaze . Jika ada lebih banyak pemain yang tidak ada dalam tim Anda di 9 sel di sekitar Anda, maka ada di tim Anda, Anda mungkin mempertimbangkan untuk melakukan pengeboman. (Saya sarankan Anda memberi tahu teman Anda terlebih dahulu!)

  • Tempatkan ranjau darat

    Ini menciptakan kotak kematian bagi orang lain yang tidak ada di tim Anda. Ketika Anda menempatkan ranjau darat, Anda juga bergerak sehingga Anda tidak menginjaknya. Anda menyebut di this.landMine(num)mana num adalah kotak yang ingin Anda tuju. Contoh:

    Kotak merah tunggal dalam kotak 9x9, dikelilingi oleh sel putih.

    Kemudian Anda menelepon this.landMine(4):

    [Kotak 9x9, dengan "M" merah di tengah dan sel merah di kanan tengah.

    Lihat itu "M"? Itu ranjau darat. Orang lain dapat melihatnya ... untuk saat ini. Siapa pun, bahkan mereka yang tidak di tim Anda, dapat melihat ranjau darat pada kutu yang ditempatkan. Tetapi setelah kutu itu selesai, tidak seorang pun, bahkan Anda tidak dapat melihatnya. Tapi itu akan meledak segera setelah musuh melewatinya. Contoh:

    Dua kisi 9x9, sel biru di tengah kiri di yang pertama, merah "M" di tengah yang pertama, merah "x" di tengah yang kedua, dan panah di antaranya.

    Biru pindah ranjau darat Anda, dan BOOM! Anda baru saja mendapat pembunuhan lain.

    Untuk setiap 2 pembunuhan yang Anda dapatkan (dari pembunuhan langsung atau ranjau darat), Anda mendapatkan 1 ranjau darat tambahan untuk ditempatkan. Anda juga mendapatkan satu di awal.

  • Menggali

    Saat Anda menggali, Anda mencari ranjau darat di area 5x5 yang berpusat di sekitar Anda. Ini tidak menunjukkan tim bot yang menempatkan ranjau darat. (Ingatlah bahwa Anda tidak dapat dibunuh oleh ranjau darat yang ditempatkan oleh seseorang di tim Anda.) Misalnya, jika ini adalah kotak di sekitar Anda:

    Maka nilai kembalinya this.dig()adalah:

[undefined,undefined,undefined,true,undefined,
undefined,undefined,undefined,undefined,undefined,
undefined,undefined,undefined,undefined,
undefined,undefined,true,undefined,undefined,
true,undefined,undefined,undefined,undefined]

Indeks array berasal dari mulai di kiri atas, ke kanan, daripada ke bawah, tidak termasuk Anda:

Total ada 23, dan lokasi relatifnya disimpan dalam konstanta global 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]
]

Perhatikan bahwa penggalian mengungkapkan ranjau yang ditempatkan pada kutu sebelumnya, tidak seperti aroundMe.

Komunikasi

Ketika Anda ingin berbicara dengan seseorang, Anda menelepon this.sendMessage(recipients, team, data). Data dapat berupa apa pun yang Anda inginkan, dan Anda dapat mengirimkannya kepada siapa pun yang Anda inginkan, bahkan pemain di tim lain. Ini dapat digunakan untuk mengelabui bot yang tidak terprogram, tetapi semua pemain dapat melihat siapa yang mengirim pesan dan siapa tim mereka.

Contoh:

Kirim sesuatu ke bot bernama "redisbest":

this.sendMessage("redisbest", undefined, "Hi!");

Kirim sesuatu ke bot bernama "redisbest" dan "blueiscool":

this.sendMessage(["redisbest", "blueiscool"], undefined, {hello: "there"});

Kirim sesuatu ke seluruh tim merah

this.sendMessage(undefined, "red", {hello: "red"});

Kirim sesuatu ke semua orang

this.sendMessage(undefined, "*", {hello: "everyone"});

Kirim sesuatu ke seluruh tim merah dan bot bernama "blueiscool":

this.sendMessage("blueiscool", "red", {hello: "bots"});

API

Kode Anda harus terdiri dari satu panggilan ke createBotfungsi. Tidak ada lagi. Kode sampel:

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

(Anda bebas menyalin-menempelkan ini. Cukup modifikasi untuk tim Anda, dll.)

Metode

  • ontick(environment)

    Disebut kapan giliran Anda. Harus mengembalikan Promiseyang menyelesaikan dalam 1 detik atau kurang atau itu akan diabaikan. Ini untuk alasan kinerja dan memiliki efek samping yang bagus karena tidak memiliki tab hang.

    this (ketika dalam ontick)

    • landMines Berapa banyak ranjau darat yang tersisa. Semakin banyak pembunuhan yang Anda miliki, semakin banyak ranjau darat yang Anda dapatkan. Untuk setiap 2 bot yang Anda bunuh, Anda mendapatkan 1 ranjau darat lagi. Anda juga mendapatkan 1 untuk memulai.
    • direction Arah yang Anda hadapi.
    • storage Penyimpanan yang tetap ada di antara panggilan ke onTickdan onMessage. Objek kosong di awal. Ubah untuk tujuan apa pun, tetapi pastikan array atau objek selalu untuk memastikannya tetap benar.
    • move(num) Pindah ke posisi yang ditentukan. Tidak melakukan apa pun jika tidak valid. Lihat detail di atas.
    • rotate(num) Putar ke posisi yang ditentukan. Tidak melakukan apa pun jika tidak valid. Lihat detail di atas.
    • kill() Membunuh pemain yang Anda hadapi, jika ada dan tidak ada di tim Anda. Lihat detail di atas.
    • bomb() Membunuh siapa pun di 9 kotak di sekitar Anda, termasuk diri Anda.
    • landMine(num) Tempatkan ranjau darat di tempat Anda berada, dan kemudian pindah ke posisi yang ditentukan. Tidak melakukan apa pun jika tidak valid numatau Anda tidak memiliki yang tersisa. Lihat detail di atas.
    • dig() baru! Mengembalikan serangkaian info tentang ranjau darat di area 5x5 yang berpusat di sekitar Anda. Lihat detail di atas.
    • sendMessage(recipients, team, data) recipientsdapat berupa bot tunggal (string), array bot, atau undefined/ null. Ini adalah siapa yang ingin Anda kirimi pesan. teamadalah serangkaian tim yang ingin Anda kirimi pesan. Gunakan "*"untuk mengirim pesan ke semua orang. dataadalah segala sesuatu yang dapat diteruskan ke fungsi JS. Itu dikirim ke penerima. Jika itu adalah objek atau array, itu dilewatkan dengan referensi , sehingga Anda dan penerima dapat menyimpannya ke mereka storagedan setiap modifikasi pada objek mempengaruhi salinan bot keduanya. Perhatikan bahwa penerima yang berada di salah satu daftar bots, bot yang tepat yang ditetapkan dalam string, atau bot di tim Anda tentukan, maka akan mendapatkan pesan.

environment

Pada centang pertama

  • x: Posisi x pemain Anda
  • y: Posisi-Y pemain Anda
  • gridWidth: Lebar kotak (dalam sel)
  • gridHeight: Tinggi kotak (dalam sel)

    Pada semua kutu

  • aroundMe: Array pemain dan ranjau darat. Para pemain adalah benda yang terlihat seperti {name: "bot name", team: "bot team"}, dan ranjau darat {team: "team of bot who placed mine"}. Indeks array:

    0 di kiri atas, 1 di tengah atas, 2 di kanan atas, 3 di kanan tengah, 4 di kiri tengah, 5 di kiri bawah, 6 di tengah bawah, dan 7 di kanan bawah.

    Perhatikan bahwa ranjau darat yang ditempatkan pada kutu selain yang sekarang tidak akan ditampilkan.

    aroundMe contoh:

    Katakanlah ini adalah kisi (Anda merah):

    Kotak 9x9, dengan biru muda di kiri atas, "M" abu-abu di kanan atas, merah di tengah, kuning di kiri tengah, dan merah "M" di kiri bawah.

    Anda aroundMeakan terlihat seperti ini:

[
    {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.
]

Indeks array dijelaskan di sini:

0 di kiri atas, 1 di tengah atas, 2 di kanan atas, 3 di kanan tengah, 4 di kiri tengah, 5 di kiri bawah, 6 di tengah bawah, dan 7 di kanan bawah.

Bot Anda secara efektif melihat ini:

Kotak biru muda di kiri atas dengan angka hitam 0 di dalamnya, kotak kuning di tepi kiri dengan angka hitam 4 di dalamnya, dan "M" merah di kiri bawah dengan 5 hitam di atasnya.

  • onmessage(data, fromBot, fromTeam)

    this (ketika di onmessage)

    • sendMessage(recipients, team, data) Fungsi pengiriman pesan standar.
    • storage Penyimpanan standar.

    dataData yang dikirim dari pengirim. fromPlayerPemain dari mana pesan itu dikirim. fromTeamTim dari mana pesan itu dikirim.

  • onkill()

    this (ketika di onkill)

    • sendMessage(recipients, team, data) Fungsi pengiriman pesan standar.

Susunan global yang nyaman (konstan):

threeByThree:

[
    [0, 1, 2],
    [3, undefined, 4],
    [5, 6, 7]
]

Berguna untuk meneruskan data ke fungsi pemindahan serta menafsirkan aroundMe. Lihat di atas.

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]
]

Berguna untuk this.dig()fungsi dalam ontickpenangan.

Cobalah!

Pengontrol akan dijalankan dari mesin saya di localhost untuk alasan kinerja, tetapi Anda dapat menggunakan CodePen untuk menguji bot Anda.

Perhatikan bahwa Anda harus menempelkan kode Anda di konsol dan tekan Entersebelum Anda mengklik jalankan. Anda dapat menempelkan bot sebanyak yang diinginkan. "Bot uji" adalah contoh yang bisa Anda uji. Jika Anda bisa mengalahkan atau mengikat semuanya, Anda memiliki setidaknya bot yang layak.

Pengajuan

Aturan

Aturan (diberlakukan oleh pengontrol)

  • ontickKode utama Anda tidak boleh lebih dari 1 detik. Kami tidak ingin putaran untuk selamanya. Jika kode Anda membutuhkan> 1 detik, itu akan dihentikan.
  • Jika Anda mencoba melakukan lebih dari 1 tindakan per giliran, atau melakukan tindakan yang tidak valid (mis. this.move(-1)Atau pindah ke dinding), itu akan diabaikan.
  • Lebih banyak akan datang segera ...

Aturan (diberlakukan oleh saya, dapat menghasilkan DQ)

  • Jangan menulis variabel global ( membaca baik-baik saja ).
  • Kode Anda harus bekerja di Nodejs (jika pengontrol porting ke Nodejs), jadi JSON.parse(...)baik-baik saja, tetapi alert()tidak.
  • Anda tidak diizinkan untuk memanggil createBotatau mengganggu pengontrol dengan cara apa pun .
  • Jangan gunakan kode orang lain tanpa izin dan perubahan signifikan. Tidak ada salinan.
  • Tolong, tidak ada celah!
  • Lebih banyak akan datang segera ...

Bot saya

Inilah beberapa bot:

Bot ini secara acak memilih tindakan. Yah, ini acak, tetapi masih cukup acak. Jika Anda dapat membunuh bot ini (itu akhirnya akan membunuh dirinya sendiri, itu tidak masuk hitungan), daripada setidaknya Anda memiliki bot yang layak. Posting dan lihat apa yang terjadi!

Bot saya memiliki nama yang dimulai dengan "x" dan tim "tidak ada". Anda dipersilakan untuk menggunakan beberapa kode ini, tetapi harap lakukan setidaknya beberapa modifikasi. Jika Anda tidak dapat diganggu untuk setidaknya men-tweak nomor, Anda tidak akan menang.

Memformat kiriman Anda

Silakan gunakan format ini:

# 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...

Permintaan fitur, bug, pertanyaan, dll?

Komentar dibawah! Silakan periksa untuk melihat apakah sudah ada komentar dengan itu. Jika sudah ada, upvote.

Ingin berbicara dengan tim Anda?

Gunakan ruang obrolan untuk merah dan biru .

Bahasa

Saat ini, hanya JS dan sesuatu yang mengkompilasi ke JS yang didukung, tetapi jika Anda mengetahui cara agar bahasa lain dapat bekerja dengan Nodejs, saya akan dengan senang hati mengirim port controller ke Nodejs.

Catatan akhir

Gagasan strategi

Bantu tim Anda! Membuat bot yang dirancang untuk membantu bot lain dan bekerja bersama. Strategi ini berhasil dengan baik untuk Merah dan Biru - Pixel Team Battlebots

Pencari perwakilan

Saya akan menerima jawaban dengan suara terbanyak di tim pemenang. Perlu diingat bahwa jawaban sebelumnya cenderung mendapatkan lebih banyak suara, tetapi kelemahan mereka lebih cenderung ditemukan dan dieksploitasi.

Juga, jika Anda segera menjawab, Anda mungkin mendapatkan hadiah +100.

programmer5000
sumber
1
Komentar bukan untuk diskusi panjang; percakapan ini telah dipindahkan ke obrolan .
Dennis
Bolehkah saya menghasilkan lebih dari satu bot? (maaf, saya tahu pembicaraan telah dipindahkan, saya hanya mengobrol jadi ya)
Matthew Roh
@SIGSEGV ya, tetapi orang lain harus mempostingnya. Anda dapat memposting satu bot dan memberikan kode lainnya kepada seseorang di tim Anda, tetapi Anda tidak dapat memposting dua kali.
programmer5000
Tentang penentuan posisi, di mana sel [0, 0] yang diindeks, apakah itu sel kiri atas? Juga, apakah olahpesan mengkonsumsi tindakan Anda (per giliran)? Terima kasih.
Thrax
@Thrax ya, dan tidak. Anda bahkan dapat mengirim pesan sebagai tanggapan terhadap pesan.
programmer5000

Jawaban:

7

xscared (tidak bersaing)

createBot({
    ontick: function(environment) {
        var reverse = [0, 1, 2, 3, 4, 5, 6, 7].reverse();
        return new Promise((resolve, reject)=>{
            (this.aroundMe || []).forEach((item,idx)=>{
                this.move(reverse[idx]);
                return resolve();
            });
            this.move(~~(Math.random() * 8));
            return resolve();
        });
    },
    onmessage: function() {
    },
    team: "none",
    name: "xscared",
    onkill: function(){
    }
});

Sangat takut pada orang. Pergi dari orang pertama (atau ranjau darat) yang dilihatnya. Kalau tidak, itu bergerak secara acak. Perhatikan bahwa ini tidak bersaing, hanya sebuah contoh. Cobalah untuk mengalahkannya!

programmer5000
sumber
6

cadangan, bot biru

Seperti yang diperingatkan dalam obrolan, saya tidak pernah menulis apa pun dalam javascript dalam hidup saya, jadi jika Anda menemukan kesalahan, tolong beritahu saya! (Terima kasih kepada @ programmer5000 karena telah membantu saya)
Konsep bot ini adalah bot ini berkomunikasi dengan bot lain dari tim yang sama dan mengirimkan posisinya beserta peta ranjau yang ditemukannya. Ia mencoba untuk bergabung dengan bot biru terdekat (jika seseorang mengirim data posisinya [diberikan sebagai array [x, y]]), dan tetap di dekatnya (dengan membelakanginya sebanyak mungkin), membunuh mendekati bot merah atau melihat maju untuk tambang.

createBot({
    team: 'blue',
    name: 'backup',
    ontick: function(environment) {
        return new Promise((resolve, reject) => {
            //if (typeof this.x != "undefined") this.storage['position'] = [this.x, this.y];
            if (typeof environment.x != "undefined") this.storage['position'] = [environment.x, environment.y]; //Modified according to @WasteD
            if (typeof this.storage['map'] == "undefined") { //Create empty map
                var map = [[]];
                //for(i=0;i<this.gridHeight;i++) map[i]=[];
                for(i=0;i<environment.gridHeight;i++) map[i]=[]; //Modified according to @WasteD
                this.storage['map'] = map;
            }
            var blue = []
            var red = []
            var x = this.storage['position'][0];
            var y = this.storage['position'][1];
            var dx = [-1, 0, 1, -1, 0, 1, -1, 0, 1]
            var dy = [1, 1, 1, 0, 0, 0, -1, -1, -1]
            (this.aroundMe || []).forEach((item, idx) => { // Update map and list positions of surrounding blues and reds
                if (item && item.team == 'red' && typeof item.name != "undefined") red += idx;
                if (item && item.team == 'red' && typeof item.name == "undefined") this.storage['map'][x+dx[idx]][y+dy[idx]] = 'M';
                if (item && item.team == 'blue' && typeof item.name != "undefined") blue += idx;
            });
            this.sendMessage(undefined, "blue", {"position": this.storage['position'], 'map': this.storage['map']}); //Send to buddies my position and the map
            if (red.indexOf([1, 4, 6, 3][this.direction]) > -1) this.kill() ; //If red guy is in front of
            else if (red.indexOf([1,4,6,3]) > -1) this.rotate(red.indexOf([1,4,6,3])); //If red guy is next but not in front of
            else if (blue.indexOf(3) > -1){ //If blue buddy on the left
                if (blue.indexOf(4) > -1){ //If another one is on the right
                    if (blue.indexOf(1) > -1 && this.direction != 2) this.rotate(2); //...and a third one at the top
                    else var digging = this.dig();
                    }
                else if (this.direction != 1) this.rotate(1);
                else var digging = this.dig();
            }
            else if (blue.indexOf(1) > -1){
                if (blue.indexOf(6) > -1 && this.direction != 3) this.rotate(3);
                else if (this.direction != 2) this.rotate(2);
                else var digging = this.dig();
            }
            else if (blue.indexOf(4) > -1){
                if (this.direction != 3) this.rotate(3);
                else var digging = this.dig();
            }
            else if (blue.indexOf(6) > -1 && this.direction != 0) this.rotate(0);
            else if (blue.indexOf([0,2]) > -1){ //If no blue next to me but one in diagonal, move next
                this.move(1);
                this.storage['position'][1] = y+1; //Update position
            }
            else if (blue.indexOf([5,7]) > -1){
                this.move(6);
                this.storage['position'][1] = y-1;
            }
            else if (typeof this.storage['other_blue'] != "undefined"){ //Check if buddies said where they were, try to go near the closest one
                var dmin = 99999;
                var pos = []
                (this.storage['other_blue'] || {}).forEach((item, idx) => {
                    var d = Math.sqrt(Math.pow(item['position'][0]-x,2) + Math.pow(item['position'][1]-y,2));
                    if (d < dmin){
                        dmin = d;
                        pos = item['position'];
                        }
                });
                if (pos[0]-x > 0){
                    this.move(4);
                    this.storage['position'][0] = x+1
                }
                else if (pos[0] < 0){
                    this.move(3);
                    this.storage['position'][0] = x-1
                }
                else if (pos[1] > 0){
                    this.move(1);
                    this.storage['position'][1] = y+1
                }
                else{
                    this.move(6);
                    this.storage['position'][1] = y-1
                }
            }
            else var digging = this.dig();
            if (typeof digging != "undefined"){ //Check out surroundings if dig() was played and update the map accordingly
                var dx2 = [-2,-1,0,1,2,-2,-1,0,1,2,-2,-1,0,1,2,-2,-1,0,1,2,-2,-1,0,1,2];
                var dy2 = [2,2,2,2,2,1,1,1,1,1,0,0,0,0,0,-1,-1,-1,-1,-1,-2,-2,-2,-2,-2];
                (digging || []).forEach((item, idx) => {
                    //if (item && item.team == 'red' && typeof item.name == "undefined") this.storage['map'][x+dx2[idx]][y+dy2[idx]] = 'M';
                    if (item) this.storage['map'][x+dx2[idx]][y+dy2[idx]] = 'M'; //previously misread what dig() returned
                });
            }
            resolve();
        });
    },
    onmessage: function(data, fromTeam, fromBot) {
        if (typeof data['position'] != "undefined" && fromTeam == 'blue') { //If position sent by a blue bot
            if (typeof this.storage['other_blue'] == "undefined") this.storage['other_blue'] = [];
            for (i in this.storage['other_blue']){
                var found = false;
                if ('name' in i){
                    if (i['name'] == fromBot){
                        i['position'] = data['position'];
                        found = true; //Update if position already known from previous ticks
                        }
                }
            }
            if (!found) this.storage['other_blue'] += {'position':data['position'], 'name':fromBot}; //Add position if previously unknown
            this.sendMessage(fromBot, undefined, "roger.");
        }
    },
    onkill: function() {this.sendMessage(undefined, "blue", {"position": this.storage['position'], 'map': this.storage['map']});}
});
plannapus
sumber
Hei Anda peduli apakah saya juga memasukkan ini tetapi (dengan nama yang berbeda) Saya juga pada biru
Christopher
@Christopher Tidak, saya tidak keberatan, tapi itu akan sedikit lebih menarik bagi Anda dan tim jika Anda membuat satu setidaknya sedikit berbeda (setidaknya untuk melengkapi 2 bot yang sudah ada).
plannapus
Akan melakukan itu. Saya akan mengubahnya
Christopher
Jika saya mencoba menjalankan bot Anda dalam codepen itu tidak bekerja karena Anda menggunakan this.xdan sebagainya tetapi apakah ini salah environment.xatau saya salah?
WasteD
@WasteD seperti yang saya katakan saya tidak tahu Javascript sama sekali, jadi itu mungkin. Tetapi jika itu masalahnya maka saya kira itu juga harus environment.gridHeightdan environment.aroundMe? Dalam hal ini maka bot lain tidak akan berfungsi karena mereka gunakan this.aroundMe.
plannapus
5

Biru, biru, duniaku biru

createBot({
    team: 'blue',
    name: 'blue-blue-my-world-is-blue',
    ontick: function(environment) {
        return new Promise((resolve, reject) => {
            var red = 0;
            // See who's around me
            (this.aroundMe || []).forEach((item, idx) => {
                if (item && item.team == 'red') red++;
            });
            // If surrounded, take one for the team
            if (red >= 6) this.bomb();
            else {
                // Translate direction into position
                var kill = [1, 4, 6, 3][this.direction];
                // Random values
                var move = Math.floor(Math.random() * 8);
                var nsew = Math.floor(Math.random() * 4);
                // Lay a landmine if possible
                if (this.landMines) this.landMine(move);
                // Kill if someone is in the way
                else if (this.aroundMe && this.aroundMe[kill] && this.aroundMe[kill].team == 'red' && this.aroundMe[kill].name) this.kill();
                else {
                    // Move somewhere if already in the requested direction
                    if (nsew == this.direction) this.move(move);
                    // Otherwise just rotate to the requested direction
                    else this.rotate(nsew);
                }
            }
            resolve();
        });
    },
    onmessage: function(data, from, fromBot) {},
    onkill: function() {}
});

Sebagian besar acak, tetapi akan meledak jika dikelilingi, dan lebih suka memeriksa sekitar dan membunuh saat bergerak.


sumber
Pintar! Bagus
programmer5000
3
Yo dengarkan, ini cerita, tentang seorang lelaki kecil yang tinggal di dunia biru.
Matius Roh
3

Bomber santai

Bot ini mencari tempat dengan setidaknya 1 sel bebas di setiap sisi lalu menanam ranjau. Itu berkemah di atasnya sampai musuh mendekat. Ketika seseorang mendekat, dia akan melangkah bolak-balik di tambang untuk memberi umpan bot lain di atasnya. Dia juga akan memutar dan membunuh jika perlu. Ketika dia tidak memiliki ranjau yang tersisa, dia akan mencari perlindungan di sudut kiri atas dengan punggung ke dinding dan membalas jika dia terancam.

Tidak ada permainan khusus di sini, selain dari menyiarkan posisinya ke timnya dengan selfkata kunci.

createBot({
    team: 'red',
    name: 'relaxed-bomber',
    ontick: function(environment) {
        return new Promise((resolve, reject) => {
            if (typeof this.storage['dropped'] == "undefined") {
                this.storage['dropped'] = false;
                this.storage['covered'] = false;
                this.storage['baited'] = false;
            }
            if (typeof environment.x != "undefined" && typeof environment.y != "undefined") {
                this.storage['pos'] = [environment.x, environment.y];
            }
            if (typeof environment.gridWidth != "undefined" && typeof environment.gridHeight != "undefined") {
                this.storage['grid'] = [environment.gridWidth, environment.gridHeight];
            }
            var x = this.storage['pos'][0];
            var y = this.storage['pos'][1];
            var x0 = this.storage['grid'][0];
            var y0 = this.storage['grid'][1];
            var source = [1, 4, 6, 3];
            var dest = [6, 3, 1, 4];
            var rot = [0, 1, 2, 3];
            var movex = [-1, 0, 1, -1, 1, -1, 0, 1];
            var movey = [-1, -1, -1, 0, 0, 1, 1, 1];
            var action = false;
            if (this.landMines > 0) { 
                var move = [false, false, false, false];
                var moveIndex = -1;
                if (x <= 0) { move[1] = true; }
                if (x >= x0 - 1) { move[3] = true; }
                if (y <= 0) { move[2] = true; }
                if (y >= y0 - 1) { move[0] = true; }    
                if (move[0] && !move[1] && !move[2] && move[3]) { moveIndex = 0; }
                if (move[0] && !move[1] && !move[2] && !move[3]) { moveIndex = 1; }
                if (move[0] && move[1] && !move[2] && !move[3]) { moveIndex = 2; }
                if (!move[0] && !move[1] && !move[2] && move[3]) { moveIndex = 3; }
                if (!move[0] && move[1] && !move[2] && !move[3]) { moveIndex = 4; }
                if (!move[0] && !move[1] && move[2] && move[3]) { moveIndex = 5; }
                if (!move[0] && !move[1] && move[2] && !move[3]) { moveIndex = 6; }
                if (!move[0] && move[1] && move[2] && !move[3]) { moveIndex = 7; }  
                if (moveIndex >= 0) {
                    this.storage['pos'] = [ x + movex[moveIndex], y + movey[moveIndex]];
                    this.move(moveIndex);
                } else {
                    this.storage['dropped'] = true;
                    this.storage['covered'] = false;
                    this.landMine(1);
                }
            } else {
                if (this.storage['dropped']) {
                    this.storage['dropped'] = false;
                    this.storage['covered'] = true;
                    this.storage['pos'] = [ x + movex[6], y + movey[6]];
                    this.move(6);
                } else if (this.storage['covered']) {
                    for (var i = 0; i < source.length; i++) {
                        if (typeof environment.aroundMe[source[i]] != "undefined" && typeof environment.aroundMe[source[i]].team != "undefined" && environment.aroundMe[source[i]].team == "blue" && typeof environment.aroundMe[source[i]].name != "undefined") {
                            this.storage['covered'] = false;
                            this.storage['baited'] = true;
                            this.storage['mine'] = this.storage['pos'].slice();
                            this.storage['reverse'] = source[dest[i]];
                            this.storage['pos'] = [ x + movex[dest[i]], y + movey[dest[i]]];
                            this.move(dest[i]);
                            action = true;
                        }
                    }
                    if (!action) {
                        this.dig();
                    }
                } else if (this.storage['baited']) {
                    for (var i = 0; i < source.length; i++) {
                        if (typeof environment.aroundMe[source[i]] != "undefined" && typeof environment.aroundMe[source[i]].team != "undefined" && environment.aroundMe[source[i]].team == "blue" && typeof environment.aroundMe[source[i]].name != "undefined") {
                            if (this.direction == rot[source[i]]) {
                                this.kill();
                                this.storage['baited'] = false;
                                action = true;
                            } else {
                                this.rotate(rot[source[i]]);
                                action = true;
                            }
                        }
                    }
                    if (!action) {
                        if (this.storage['mine'][0] == this.storage['pos'][0] && this.storage['mine'][1] == this.storage['pos'][1]) {
                            this.storage['pos'] = [ x + movex[this.storage['reverse']], y + movey[this.storage['reverse']]];
                            this.move(this.storage['reverse']);
                            this.storage['reverse'] = source[this.storage['reverse']];
                        } else {
                            this.storage['pos'] = [ x + movex[this.storage['reverse']], y + movey[this.storage['reverse']]];
                            this.move(this.storage['reverse']);
                            this.storage['reverse'] = dest[this.storage['reverse']];
                        }
                    }
                } else {
                    for (var i = 0; i < source.length; i++) {
                        if (typeof environment.aroundMe[source[i]] != "undefined" && typeof environment.aroundMe[source[i]].team != "undefined" && environment.aroundMe[source[i]].team == "blue" && typeof environment.aroundMe[source[i]].name != "undefined") {
                            if (this.direction == rot[source[i]]) {
                                this.kill();
                                this.storage['baited'] = false;
                                action = true;
                            } else {
                                this.rotate(rot[source[i]]);
                                action = true;
                            }
                        }
                    }
                    if (!action) {
                        if (x > 0 && y > 0) {
                            this.storage['pos'] = [ x + movex[0], y + movey[0]];
                            this.move(0);
                        } else if (x > 0 && y == 0) {
                            this.storage['pos'] = [ x + movex[3], y + movey[3]];
                            this.move(3);
                        } else if (x == 0 && y > 0) {
                            this.storage['pos'] = [ x + movex[1], y + movey[1]];
                            this.move(1);
                        } else {
                            this.rotate(1);
                        }
                    }
                }
            }
            this.sendMessage(undefined, "red", {'self': this.storage['pos'] });
            resolve();
        });
    },
    onmessage: function(data, fromTeam, fromBot) {},
    onkill: function() {}
});
Thrax
sumber
Anda berada di tim apa?
programmer5000
@ programmer5000 Karena nama bot harus dimulai dengan huruf tim, saya kira saya Tim Merah :)
Thrax
Bot yang bagus! Saya sarankan Anda brodcast apa yang ada di sekitar Anda ke tim Anda juga.
programmer5000
1

Cadangkan 1 bot biru lainnya (lupa melakukannya sebelumnya)

createBot({
    team: 'blue',
    name: 'backup1',
    ontick: function(environment) {
        return new Promise((resolve, reject) => {
            //if (typeof this.x != "undefined") this.storage['position'] = [this.x, this.y];
            if (typeof environment.x != "undefined") this.storage['position'] = [environment.x, environment.y]; //Modified according to @WasteD
            if (typeof this.storage['map'] == "undefined") { //Create empty map
                var map = [[]];
                //for(i=0;i<this.gridHeight;i++) map[i]=[];
                for(i=0;i<environment.gridHeight;i++) map[i]=[]; //Modified according to @WasteD
                this.storage['map'] = map;
            }
            var blue = []
            var red = []
            var x = this.storage['position'][0];
            var y = this.storage['position'][1];
            var dx = [-1, 0, 1, -1, 0, 1, -1, 0, 1]
            var dy = [1, 1, 1, 0, 0, 0, -1, -1, -1]
            (this.aroundMe || []).forEach((item, idx) => { // Update map and list positions of surrounding blues and reds
                if (item && item.team == 'red' && typeof item.name != "undefined") red += idx;
                if (item && item.team == 'red' && typeof item.name == "undefined") this.storage['map'][x+dx[idx]][y+dy[idx]] = 'M';
                if (item && item.team == 'blue' && typeof item.name != "undefined") blue += idx;
            });
            this.sendMessage(undefined, "blue", {"position": this.storage['position'], 'map': this.storage['map']}); //Send to buddies my position and the map
            if (red.indexOf([1, 4, 6, 3][this.direction]) > -1) this.kill() ; //If red guy is in front of
            else if (red.indexOf([1,4,6,3]) > -1) this.rotate(red.indexOf([1,4,6,3])); //If red guy is next but not in front of
            else if (blue.indexOf(3) > -1){ //If blue buddy on the left
                if (blue.indexOf(4) > -1){ //If another one is on the right
                    if (blue.indexOf(1) > -1 && this.direction != 2) this.rotate(2); //...and a third one at the top
                    else var digging = this.dig();
                    }
                else if (this.direction != 1) this.rotate(1);
                else var digging = this.dig();
            }
            else if (blue.indexOf(1) > -1){
                if (blue.indexOf(6) > -1 && this.direction != 3) this.rotate(3);
                else if (this.direction != 2) this.rotate(2);
                else var digging = this.dig();
            }
            else if (blue.indexOf(4) > -1){
                if (this.direction != 3) this.rotate(3);
                else var digging = this.dig();
            }
            else if (blue.indexOf(6) > -1 && this.direction != 0) this.rotate(0);
            else if (blue.indexOf([0,2]) > -1){ //If no blue next to me but one in diagonal, move next
                this.move(1);
                this.storage['position'][1] = y+1; //Update position
            }
            else if (blue.indexOf([5,7]) > -1){
                this.move(6);
                this.storage['position'][1] = y-1;
            }
            else if (typeof this.storage['other_blue'] != "undefined"){ //Check if buddies said where they were, try to go near the closest one
                var dmin = 99999;
                var pos = []
                (this.storage['other_blue'] || {}).forEach((item, idx) => {
                    var d = Math.sqrt(Math.pow(item['position'][0]-x,2) + Math.pow(item['position'][1]-y,2));
                    if (d < dmin){
                        dmin = d;
                        pos = item['position'];
                        }
                });
                if (pos[0]-x > 0){
                    this.move(4);
                    this.storage['position'][0] = x+1
                }
                else if (pos[0] < 0){
                    this.move(3);
                    this.storage['position'][0] = x-1
                }
                else if (pos[1] > 0){
                    this.move(1);
                    this.storage['position'][1] = y+1
                }
                else{
                    this.move(6);
                    this.storage['position'][1] = y-1
                }
            }
            else var digging = this.dig();
            if (typeof digging != "undefined"){ //Check out surroundings if dig() was played and update the map accordingly
                var dx2 = [-2,-1,0,1,2,-2,-1,0,1,2,-2,-1,0,1,2,-2,-1,0,1,2,-2,-1,0,1,2];
                var dy2 = [2,2,2,2,2,1,1,1,1,1,0,0,0,0,0,-1,-1,-1,-1,-1,-2,-2,-2,-2,-2];
                (digging || []).forEach((item, idx) => {
                    //if (item && item.team == 'red' && typeof item.name == "undefined") this.storage['map'][x+dx2[idx]][y+dy2[idx]] = 'M';
                    if (item) this.storage['map'][x+dx2[idx]][y+dy2[idx]] = 'M'; //previously misread what dig() returned
                });
            }
            resolve();
        });
    },
    onmessage: function(data, fromTeam, fromBot) {
        if (typeof data['position'] != "undefined" && fromTeam == 'blue') { //If position sent by a blue bot
            if (typeof this.storage['other_blue'] == "undefined") this.storage['other_blue'] = [];
            for (i in this.storage['other_blue']){
                var found = false;
                if ('name' in i){
                    if (i['name'] == fromBot){
                        i['position'] = data['position'];
                        found = true; //Update if position already known from previous ticks
                        }
                }
            }
            if (!found) this.storage['other_blue'] += {'position':data['position'], 'name':fromBot}; //Add position if previously unknown
            this.sendMessage(fromBot, undefined, "roger.");
        }
    },
    onkill: function() {this.sendMessage(undefined, "blue", {"position": this.storage['position'], 'map': this.storage['map']});}
});
Christopher
sumber
1

Petarung Biru

createBot({
  team: "blue",
  name: "blue-fighter",
  ontick: function(environment) {
    return new Promise((resolve, reject)=>{
      let map = environment.aroundMe;
      let sides = [1, 4, 6, 3];
      let facing = sides[this.direction];
      let isTeam = (team,a) => a && a.team === team;
      let isRed = (a)=>isTeam("red",a);
      let isBlue = (a)=>isTeam("blue",a);
      let randomSquare = ()=>Math.floor(Math.random()*8);
      let redNum = map.filter(isRed).length;
      let blueNum =  map.filter(isBlue).length;
      if(redNum > blueNum && redNum > 2){
        this.bomb();
      }else if(isRed(map[facing])){
        this.kill();
      }else if(sides.includes(map.findIndex(isRed))){
        this.rotate(sides.indexOf(map.findIndex(isRed)));
      }else if(Math.random() < 0.5 && this.landMines > 0){
        this.landMine(randomSquare());
      }else{            
        this.move(randomSquare());
      }
      resolve();
    });
  },
  onmessage: function(data, from, fromBot) {},
  onkill: function(){}
});

Petarung biru bergerak dan ranjau secara acak dan berputar ke arah pemain merah. Jika blok di sekelilingnya lebih merah daripada biru, itu bom. Jika berhadapan dengan pemain merah, ia akan membunuhnya.

SuperStormer
sumber