King of the Hill - Spacewar!

64

Jika Anda pernah bermain Spacewar! , Anda tahu itu adalah permainan yang menyenangkan. Jika belum, ketahuilah: ini adalah salah satu game komputer pertama dan terpenting. Dan itu masih menyenangkan! Klon tempat saya dibesarkan adalah yang ini , yang ternyata, dan sayangnya, hanya Windows. Jadi saya membuatnya kembali!

KotH di-host di sini: PPCG - Spacewar! King of the Hill . Saya mendorong Anda untuk bermain sebagai manusia melawan setidaknya satu bot lain untuk merasakan bagaimana permainan bekerja.

Permainan

  • Satu frame adalah 30 milidetik (dengan demikian, sekitar 33 frame per detik).
  • Bidang ini memiliki lebar 800 piksel dan tinggi 600 piksel.
  • Medan tersebut berbentuk toroidal, artinya pesawat ruang angkasa dan rudal yang bergerak di luar medan muncul kembali di sisi yang berlawanan.
  • Ada dua pesawat ruang angkasa, merah dan biru.
    • Merah diposisikan pada x = 50 dan acak y antara 50, (tinggi bidang - 50) piksel.
    • Biru diposisikan pada x = (lebar bidang - 50) dan acak y antara 50, (tinggi bidang - 50) piksel.
    • Kedua muka x = (lebar bidang) / 2.
  • Kontrol yang tersedia adalah:
    • Belok kiri - 5 derajat per frame berlawanan arah jarum jam.
    • Belok kanan - 5 derajat per frame searah jarum jam.
    • Rudal api - bergerak dengan tambahan 10 piksel per bingkai di samping kecepatan kapal, ke arah yang ditunjuk kapal.
    • Mesin pemadam kebakaran - mempercepat pesawat ruang angkasa di 0,30 piksel per frame ke arah yang ditunjuk pesawat ruang angkasa.
    • Hyperspace jump - teleport ke beberapa koordinat acak di lapangan, dengan peluang meledak 25%. Koordinat acak ini mungkin berada di atas matahari.
  • Kecepatan maksimum untuk kapal adalah 15 piksel per frame di bawah tenaga mesin dan 40 piksel per frame saat gravitasi ditingkatkan.
    • Saat bepergian lebih cepat dari 15 piksel per frame, dorongan mesin hanya dapat mengubah arah atau memperlambat.
  • Mengenai rudal:
    • Rudal bepergian dalam garis lurus.
    • Rudal dapat ditembakkan pada kecepatan maksimum 1 per 0,1 detik.
    • Rudal memiliki masa hidup 2,25 detik.
    • Kapal masing-masing memiliki maksimal 20 rudal.
    • Rudal adalah partikel titik internal.
  • Ada matahari di tengah yang sangat berbahaya bagi kapal Anda. The sedikit kontak fatal. Matahari ini juga menghancurkan rudal.
  • Matahari memiliki gravitasi. Akselerasi yang dihasilkan adalah 5000 / (jarak ^ 2) piksel / bingkai ^ 2, di mana jarak berada dalam piksel. Pesawat ruang angkasa dan rudal terpengaruh.
  • Kedua kapal memiliki tiga zona serang: hidung, sayap kiri, dan sayap kanan.
    • Pukulan pada hidung adalah kematian instan.
    • Sebuah pukulan di kedua sayap mengurangi tingkat putaran pesawat ruang angkasa dan akselerasi mesin hingga setengahnya.
    • Jika kedua sayap hancur, pesawat ruang angkasa tidak bisa bermanuver dan hanya bisa menembakkan rudal.
  • Kapal-kapal mungkin saling bertabrakan.
    • Tumbukan hidung-hidung itu fatal bagi kedua kapal.
    • Tabrakan sayap hidung menghancurkan sayap.
    • Tumbukan sayap menghancurkan kedua sayap.
  • Kapal mati padat dan beku sampai meledak 1 detik kemudian.
  • Setelah setidaknya satu kapal mati, lapangan direset 3 detik kemudian. Sampai saat itu, matahari dan rudal yang tersisa masih berbahaya.

Game aslinya juga memiliki asteroid yang mematikan dan tidak bisa dihancurkan, tetapi saya tidak akan memasukkannya.

Aturan

  • Bot Anda harus ditulis dalam JavaScript.
  • Bot Anda harus membatasi keputusannya hingga sekitar 10 milidetik. Jika saya melihat kelambatan yang konsisten karena bot Anda , saya akan mendiskualifikasi dan memberi tahu Anda agar Anda dapat memperbaikinya.
  • Bot akan memiliki akses ke yang berikut:
    • Lebar bidang dan tinggi bidang
    • Posisi dan jari-jari matahari
    • Posisi, rotasi, kecepatan, bentuk, stok rudal, dan status dalam-hyperspace dari kedua kapal
    • Posisi dan kecepatan semua rudal
  • Saat diminta, bot Anda harus mengembalikan daftar string.
    • String ini harus menjadi salah satu dari berikut: turn left, turn right, fire engine, fire missile, hyperspace. String lain akan diabaikan.
    • Jika ada duplikat, hanya yang pertama yang akan dicatat.
    • hyperspace didahulukan dari yang lainnya.
    • turn leftdan turn rightpada saat yang sama tidak akan berpengaruh.
    • fire engine tidak akan berpengaruh jika kapal hanya memiliki hidung atau mati.
    • fire missile tidak akan berpengaruh jika rudal ditembakkan terlalu baru.
  • Dalam perubahan dari biasanya, bot Anda diizinkan untuk mengeksploitasi perilaku bot lain. Saya ingin mendorong metagame.
    • Bot tidak boleh meniru bot lain. (Yaitu, tidak membaca pikiran.)
    • Bot tidak boleh mengatur variabel apa pun yang digunakan oleh game dan kode fisika. (Yaitu, tidak ada kecurangan.)

Detail Implementasi Bot

Saya akan menyimpan bot Anda di file JavaScript sendiri yang disertakan secara otomatis, dengan nama file bot_<name>.js. Jadi jangan letakkan spasi atau karakter apa pun yang akan mengganggu ini atau dengan penamaan fungsi dalam JavaScript. Itu karena Anda harus mendefinisikan fungsi-fungsi berikut: <name>_setup(team)dan <name>_getActions(gameInfo, botVars). Lebih jauh ke bawah halaman, ada textareas untuk userbot , yang dapat Anda edit untuk menguji kode Anda.

<name>_setup(team)

Fungsi ini untuk Anda menentukan variabel apa pun yang ingin Anda pertahankan. teamakan menjadi "red"atau "blue". Fungsi ini harus mengembalikan objek. Definisikan variabel seperti:

var vars = {};
vars['example'] = "example";
return vars;

varsObjek ini akan diteruskan ke fungsi lainnya:

<name>_getActions(gameInfo, botVars)

botVarsadalah objek yang dikembalikan oleh <name>_setup(team). gameInfoadalah objek yang berisi variabel berikut:

redScore
blueScore
timeLeft

fieldWidth
fieldHeight

sun_x
sun_y
sun_r //sun's radius

gravityStrength //acceleration in pixels/frame^2 at 1 pixel away from the sun's center
engineThrust    //acceleration in pixels/frame^2

speedLimit //maximum speed under engine power
maxSpeed   //maximum speed from gravity boosts

red_x
red_y
red_rot          //rotation in degrees
red_xv           //x velocity
red_yv           //y velocity
red_shape        //one of "full ship", "left wing", "right wing", "nose only"
red_missileStock //the number of missiles red has left
red_inHyperspace //true if red is in hyperspace
red_exploded     //until red explodes, it is still solid and hazardous
red_alive
// likewise for blue //

numMissiles
missiles //this is a list of objects, each with the following variables
  x
  y
  xv
  yv

Bot Anda memiliki akses penuh ke ini. Saya cukup yakin bahwa Anda dapat menulis kepada mereka dan tidak mempengaruhi variabel asli, tetapi jangan lakukan itu. Catatan tentang rotasi: kapal menunjuk ke arah + y, ke bawah, jadi apa pun yang ingin Anda selaraskan dengan kapal perlu diimbangi dengan 90 derajat. Juga, rotasi positif searah jarum jam.

Fungsi ini harus mengembalikan daftar string, mewakili tindakan bot Anda. Sebagai contoh ["turn right","thrust"],. Rincian lebih lanjut tentang ini ada di bagian Aturan .

detil tambahan

Anda juga dapat menggunakan yang berikut ini:

LineIntersection(L1, L2)

L1 dan L2 adalah array dua elemen dari array dua elemen. Yaitu, L1 := [[x1,y1],[x2,y2]]dan L2 := [[u1,v1],[u2,v2]]. Fungsi ini menghitung persimpangan dua garis dan mengembalikan ini: [[x,y], [a,b]]. [x,y]adalah koordinat dari titik persimpangan dan [a,b]merupakan sepasang rasio yang menyatakan seberapa jauh sepanjang setiap garis titik persimpangan. Seperti dalam, a = 0.25akan berarti bahwa titik persimpangan adalah seperempat jalan dari [x1,y1]ke [x2,y2], dan juga untuk b. Jika tidak ada persimpangan, array kosong dikembalikan.

window["shipShapes"]

var shipShapes = {
    'full ship': [[-8,16],[0,-8],[8,16]],
    'left wing': [[-8,16],[0,-8],[4,4],[0,8],[0,16]],
    'right wing':[[-4,4],[0,-8],[8,16],[0,16],[0,8]],
    'nose only': [[-4,4],[0,-8],[4,4],[0,8]]
};

Ini adalah koordinat poligon kapal. Untuk membuat mendapatkan koordinat saat ini lebih mudah, Anda juga dapat menggunakan ...

getShipCoords(<color>)

getShipCoords("red")akan mengembalikan koordinat saat ini dari simpul kapal Merah, dan juga untuk getShipCoords("blue")dan Biru. Koordinat ini berada dalam daftar seperti: [[x1,y1],[x2,y2],[x3,y3],...]. Poligon tertutup secara implisit, jadi ada garis antara pasangan koordinat pertama dan terakhir.

Anda tidak boleh mengakses atau mengubah variabel atau fungsi lain apa pun yang digunakan oleh game / situs web. Dan jelas tidak menyebutkan fungsi Anda sama. Saya tidak melihat bahwa ini akan menjadi masalah, tetapi jika bot Anda melanggar kode permainan, itu satu kemungkinan. Tidak ada penebangan atau penangkapan pengecualian.

Kemenangan

  • Setiap pasangan bot harus dimainkan setidaknya 10 kali, keduanya. (Jadi, setidaknya total 20 pertandingan.)
  • Bertujuan untuk memiliki rasio win / loss tertinggi secara keseluruhan . Jika bot Anda bekerja sangat baik melawan satu bot lainnya, tetapi kalah melawan tiga bot lainnya, itu tidak sebagus menang melawan dua dan kalah melawan dua (seperti aturan umum).
  • Untuk setiap bot, rasio (menang +1) / (kerugian +1) akan dihitung, maka rata-rata dan standar deviasi rasio ini akan dihitung. Rata-rata yang lebih tinggi akan memiliki prioritas, dan dalam hal rata-rata berada dalam 1 unit satu sama lain, varian yang lebih rendah akan memiliki prioritas.
  • Penilaian akan dimulai dalam seminggu dari hari ini atau setelah tiga hari tanpa kiriman baru. Ini jadi saya tidak perlu mengulangi pasangan bot.

Yang terpenting, bersenang-senanglah!


Papan Peringkat (2016-01-08 05:15):

#   Name                       Mean      StdDev
1.  Helios                     13.625    6.852
2.  EdgeCase                    8.335    8.155
3.  OpponentDodger              8.415    8.186
4.  OrbitBot                    5.110    6.294
5.  SunAvoider                  5.276    6.772
6.  DangitBobby                 3.320    4.423
7.  SprayAndPray                3.118    4.642
8.  Engineer                    3.903    6.315
9.  RighthandedSpasms           1.805    2.477
10. AttackAndComeBack           2.521    2.921
11. PanicAttack                 2.622    3.102
12. FullSpeedAhead              2.058    3.295
13. UhhIDKWhatToCallThisBot     2.555    3.406
14. MissilesPlusScore           0.159    0.228
15. Hyper                       0.236    0.332
16. RandUmmm                    0.988    1.329
17. Kamikaze                    0.781    1.793

Catatan: Ini dapat berubah saat saya menjalankan lebih banyak game. Plus, urutan peringkat 9-13 mengganggu saya, jadi saya dapat mengubah metode penilaian agar lebih sesuai dengan intuisi seseorang tentang bagaimana peringkat mereka.

(Berarti dan standar deviasi dibulatkan menjadi tiga angka desimal. Juga, Hyperharus HYPERtapi itu mengacaukan penyorotan.: P)

El'endia Starman
sumber
Ada skor? ....
ev3commander
Apakah itu mencatat pengecualian?
TheNumberOne
1
Anda harus menentukan bahwa memanggil LineIntersectionsegmen yang tidak memotong akan mengembalikan array kosong.
LegionMammal978
1
Saya pikir saya berhasil!
ev3commander
3
@CrazyPython: Saya akan membantah dua yang pertama mengingat pada dasarnya saya menyalin permainan, tetapi yang ketiga persis seperti yang saya inginkan. Terima kasih! : D
El'endia Starman

Jawaban:

12

Helios

Bot ini adalah pusat dari alam semesta, atau setidaknya dia mengira dia. Hal pertama yang ia buat adalah memperbaiki kesalahan besar dan menempatkan dirinya di tengah-tengah sistem koordinat. Lalu dia memutar apa pun di sekitar dirinya.

Dia tidak menyukai matahari (palsu) lainnya, oleh karena itu dia mencoba untuk menjauh darinya. Dia juga tidak suka bot lain, karena itu dia menembak mereka, jika dia dalam posisi menembak yang baik.

function Helios_setup(team) {
    var botVars = {};
    botVars.myPrefix = team + "_";
    botVars.enemyPrefix = team == "red" ? "blue_" : "red_";
    return botVars;
}

function Helios_getActions(gameInfo, botVars) {
    var actions = [];
    var halfPi = Math.PI / 2;
    var engageAngle = Math.PI / 8;

    var field = {};
    field.width = gameInfo.fieldWidth;
    field.height = gameInfo.fieldHeight;
    field.halfWidth = field.width / 2;
    field.halfHeight = field.height / 2;
    field.posOffsetX = field.width * 3 / 2 - gameInfo[botVars.myPrefix + "x"];
    field.posOffsetY = field.height * 3 / 2 - gameInfo[botVars.myPrefix + "y"];
    field.posAngle = (450 - gameInfo[botVars.myPrefix + "rot"]) % 360 * Math.PI / 180;
    field.posSin = Math.sin(-field.posAngle);
    field.posCos = Math.cos(-field.posAngle);
    field.movOffsetXV = -gameInfo[botVars.myPrefix + "xv"];
    field.movOffsetYV = gameInfo[botVars.myPrefix + "yv"];
    field.movAngle = Math.atan2(-field.movOffsetYV, -field.movOffsetXV);
    field.movSin = Math.sin(-field.movAngle);
    field.movCos = Math.cos(-field.movAngle);

    function zeroIfUndefined(v) {
        return v === undefined ? 0 : v;
    }

    function sqr(x) {
        return x * x
    }

    function getEntity(source, prefix) {
        var tmpX = (field.posOffsetX + zeroIfUndefined(source[prefix + "x"])) % field.width - field.halfWidth;
        var tmpY = field.halfHeight - (field.posOffsetY + zeroIfUndefined(source[prefix + "y"])) % field.height;
        var tmpXV = zeroIfUndefined(source[prefix + "xv"]);
        var tmpYV = -zeroIfUndefined(source[prefix + "yv"]);
        var e = {};
        e.posX = tmpX * field.posCos - tmpY * field.posSin;
        e.posY = tmpX * field.posSin + tmpY * field.posCos;
        e.posR = Math.sqrt(sqr(e.posX) + sqr(e.posY));
        e.posPhi = Math.atan2(e.posY, e.posX);
        e.posXV = tmpXV * field.posCos - tmpYV * field.posSin;
        e.posYV = tmpXV * field.posSin + tmpYV * field.posCos;
        e.posV = Math.sqrt(sqr(e.posXV) + sqr(e.posYV));
        e.movX = tmpX * field.movCos - tmpY * field.movSin;
        e.movY = tmpX * field.movSin + tmpY * field.movCos;
        e.movR = Math.sqrt(sqr(e.movX) + sqr(e.movY));
        e.movPhi = Math.atan2(e.movY, e.movX);
        e.movXV = (tmpXV + field.movOffsetXV) * field.movCos - (tmpYV + field.movOffsetYV) * field.movSin;
        e.movYV = (tmpXV + field.movOffsetXV) * field.movSin + (tmpYV + field.movOffsetYV) * field.movCos;
        return e;
    }

    function getShip(prefix) {
        var ship = getEntity(gameInfo, prefix);
        ship.missileStock = gameInfo[prefix + "missileStock"];
        ship.inHyperspace = gameInfo[prefix + "inHyperspace"];
        ship.exploded = gameInfo[prefix + "exploded"];
        ship.alive = gameInfo[prefix + "alive"];
        return ship;
    }

    var myShip = getShip(botVars.myPrefix);
    myShip.movAngle = (field.posAngle - field.movAngle + 3 * Math.PI) % (2 * Math.PI) - Math.PI;
    var enemyShip = getShip(botVars.enemyPrefix);
    var sun = getEntity(gameInfo, "sun_");

    enemyShip.intersectionLine = [[enemyShip.movX - enemyShip.movXV * 30, enemyShip.movY - enemyShip.movYV * 30],
            [enemyShip.movX + enemyShip.movXV * 30, enemyShip.movY + enemyShip.movYV * 30]];

    var intersection = LineIntersection([[0, 0], [Math.cos(myShip.movAngle) * 10 * 30, Math.sin(myShip.movAngle) * 10 * 30]],
            enemyShip.intersectionLine);
    if (intersection.length == 2) {
        myShip.intersection = Math.abs(intersection[1][0] / 2 + 0.5 - intersection[1][1]);
    }
    intersection = LineIntersection([[0, 0], [Math.cos(myShip.movAngle - 0.001) * 10 * 30, Math.sin(myShip.movAngle - 0.001) * 10 * 30]],
            enemyShip.intersectionLine);
    if (intersection.length == 2) {
        myShip.intersectionLeft = Math.abs(intersection[1][0] / 2 + 0.5 - intersection[1][1]);
    }
    intersection = LineIntersection([[0, 0], [Math.cos(myShip.movAngle + 0.001) * 10 * 30, Math.sin(myShip.movAngle + 0.001) * 10 * 30]],
            enemyShip.intersectionLine);
    if (intersection.length == 2) {
        myShip.intersectionRight = Math.abs(intersection[1][0] / 2 + 0.5 - intersection[1][1]);
    }

    function danger() {
        var tmp1 = sqr(sun.movXV) + sqr(sun.movYV);
        var tmp2 = tmp1 == 0 ? 0 : Math.max(0, Math.min(1, ((-sun.movX) * sun.movXV + (-sun.movY) * sun.movYV) / tmp1));
        var dis = Math.sqrt(sqr(sun.movX + tmp2 * sun.movXV) + sqr(sun.movY + tmp2 * sun.movYV));
        if (dis < 30) {
            return true;
        }
        var shipLine1 = [[-16, 8], [-16, -8]];
        var shipLine2 = [[-16, 8], [8, 0]];
        var shipLine3 = [[-16, -8], [8, 0]];
        if (gameInfo.missiles !== undefined) {
            for (var i = 0; i < gameInfo.missiles.length; i++) {
                var missile = getEntity(gameInfo.missiles[i], "");
                var missileLine = [[missile.movX + missile.movXV * 0.5, missile.movY + missile.movYV * 0.5],
                        [missile.movX + missile.movXV * 3, missile.movY + missile.movYV * 3]];
                if (LineIntersection(shipLine1, missileLine).length == 2 ||
                        LineIntersection(shipLine2, missileLine).length == 2 ||
                        LineIntersection(shipLine3, missileLine).length == 2) {
                  return true;
                }
            }
        }
        return false;
    }

    function fire() {
        return enemyShip.alive && !enemyShip.inHyperspace && myShip.intersection !== undefined &&
            myShip.intersection < 0.1 + myShip.missileStock / 200;
    }

    function evadeSun() {
        if ((sun.movPhi >= 0 && myShip.movAngle < 0) || (sun.movPhi <= 0 && myShip.movAngle > 0)) {
            actions.push("fire engine");
        }
        if (sun.movPhi > 0) {
            if (Math.abs(myShip.movAngle) < halfPi) {
                actions.push("turn right");
            } else {
                actions.push("turn left");
            }
        } else {
            if (Math.abs(myShip.movAngle) < halfPi) {
                actions.push("turn left");
            } else {
                actions.push("turn right");
            }
        }
    }

    function aim() {
        if (myShip.intersection !== undefined && myShip.intersectionLeft !== undefined && myShip.intersectionLeft < myShip.intersection) {
            actions.push("turn left");
        } else if (myShip.intersection !== undefined && myShip.intersectionRight !== undefined && myShip.intersectionRight < myShip.intersection) {
            actions.push("turn right");
        } else {
            if (enemyShip.posPhi > 0) {
                actions.push("turn left");
            } else {
                actions.push("turn right");
            }
        }
        if (myShip.posV < 2 || (enemyShip.alive && (enemyShip.movXV >= 0 || myShip.missileStock == 0))) {
            actions.push("fire engine");
        }
    }

    function brake() {
        if (myShip.movAngle > 0) {
            actions.push("turn left");
        } else {
            actions.push("turn right");
        }
        if (Math.abs(myShip.movAngle) > Math.PI * 3 / 4) {
            actions.push("fire engine");
        }
    }

    function engage() {
        if (enemyShip.missileStock > 0) {
            if ((enemyShip.posPhi > 0 && enemyShip.posPhi < engageAngle) || enemyShip.posPhi < -engageAngle) {
                actions.push("turn right");
            } else {
                actions.push("turn left");
            }
        } else {
            if (enemyShip.posPhi > 0) {
                actions.push("turn left");
            } else {
                actions.push("turn right");
            }
        }
        actions.push("fire engine");
    }

    if (myShip.alive && !myShip.inHyperspace) {
        if (danger()) {
            actions.push("hyperspace");
        }
        if (fire()) {
            actions.push("fire missile");
        }
        if (enemyShip.exploded || enemyShip.inHyperspace || sun.movR < 150 || (sun.movR < 300 && Math.abs(sun.movPhi) < Math.PI)) {
            evadeSun();
        } else if (enemyShip.posR < 300 || myShip.intersection !== undefined) {
            aim();
        } else if (myShip.posV > 10) {
            brake();
        } else {
            engage();
        }
    }

    return actions;
}
Sleafar
sumber
1
Saya pikir ini adalah salah satu bot favorit saya sejauh ini. Sangat bagus!
El'endia Starman
@ El'endiaStarman Saya membuat beberapa pembaruan pada bot.
Sleafar
Pembaruan Anda sekarang aktif!
El'endia Starman
Ini bekerja sangat baik terhadap OrbitBot :)
TheNumberOne
1
@ Soaku Saya pikir perbedaan utama antara bot ini dan sebagian besar yang lain adalah, bahwa bot ini bertujuan pada lawannya sebelum menembak.
Sleafar
9

SunAvoider

Yang ini hanya berusaha menjauhi matahari. Ia melakukannya dengan cukup baik ... sampai ia menghancurkan satu atau kedua sayap, maka biasanya hanya masalah waktu sebelum jatuh.

function SunAvoider_setup(team) {
    var botVars = {};

    botVars["color"] = team;

    return botVars;
}

function SunAvoider_getActions(gameInfo, botVars) {
    var actions = [];

    if (gameInfo[botVars["color"]+"_alive"]) {
        var shipx = gameInfo[botVars["color"]+"_x"];
        var shipy = gameInfo[botVars["color"]+"_y"];
        var sunx = gameInfo["sun_x"];
        var suny = gameInfo["sun_y"];
        var dx = shipx - sunx;
        var dy = shipy - suny;
        var dis = Math.sqrt(dx*dx+dy*dy);
        var fireEngineChance = (dis-100)/(gameInfo["fieldHeight"]/2);

        if (Math.random() > fireEngineChance){ actions.push("fire engine") }

        var ang1 = gameInfo[botVars["color"]+"_rot"]+90;
        var ang2 = Math.degrees( Math.atan2(dy, dx) );
        var angDiff = ang2 - ang1;
        if (angDiff < -180) { //http://stackoverflow.com/a/7869457/1473772
            angDiff += 360;
        } else if (angDiff > 180) {
            angDiff -= 360;
        }

        if (angDiff >= 0) {
            actions.push("turn left");
        } else if (angDiff < 0) {
            actions.push("turn right");
        }
    }

    return actions;
}
El'endia Starman
sumber
9

EdgeCase

Terbang dengan kecepatan penuh dari matahari ke tepi peta! Ketika menemukan dirinya menunjuk ke arah matahari, ia akan mulai menembak sambil memalingkan diri untuk kembali ke tepi. Ini juga memasuki hyperspace ketika hendak menabrak matahari.

function EdgeCase_setup(team) {
  var botVars = {};
  botVars["color"] = team;
  return botVars;
}

function EdgeCase_getActions(gameInfo, botVars) {
  var actions = [];

  // Get our ship's position
  var rotation, x, y, opponentAlive;
  if(botVars.color == "red") {
    rotation = gameInfo.red_rot;
    x = gameInfo.red_x;
    y = gameInfo.red_y;
    opponentAlive = gameInfo.blue_alive;
  }
  else if(botVars.color == "blue") {
    rotation = gameInfo.blue_rot;
    x = gameInfo.blue_x;
    y = gameInfo.blue_y;
    opponentAlive = gameInfo.red_alive;
  }

  // Calculate our rotation compared to the sun in degrees
  var sunX = gameInfo.sun_x,
      sunY = gameInfo.sun_y,
      angle = Math.atan2(sunY - y, sunX - x) * 180 / Math.PI,
      rotationToSun = (rotation - angle + 360) % 360;

  // Check if we need to hyperspace to avoid the sun
  var rX = x - sunX,
      rY = y - sunY,
      distanceFromSun = Math.sqrt(rX * rX + rY * rY) - gameInfo.sun_r;
  if(distanceFromSun < 30) actions.push("hyperspace");
  else {

    // Turn away from the sun
    if(rotationToSun > 90 && rotationToSun < 270) {
      actions.push("turn right");
    }
    else actions.push("turn left");

    // Fire engines if we're pointing away from the sun
    if(rotationToSun > 180) {
      actions.push("fire engine");
    }

    // If we shoot while our opponent's dead we can only kill ourself
    else if(opponentAlive) actions.push("fire missile");
  }

  return actions;
}
pengguna81655
sumber
Bot ini sekarang hidup! Juga, yang satu ini ternyata mudah untuk bertahan hidup. Mungkin ada hubungannya dengan bagaimana tidak ada rudal spam di mana-mana seperti yang lainnya. : P
El'endia Starman
7

OrbitBot

Saat ini tidak memiliki penargetan atau penghindaran tabrakan . Ia mencoba mengorbit matahari.

Sunting: Sekarang masuk ke hyperspace ketika dampak sudah dekat.

function OrbitBot_setup(team) {
  var botVars = {};

  botVars.color = team;
  return botVars;
}


function OrbitBot_getActions(gameInfo, botVars) {
  var actions = [];

  function getVar(name) {
    return gameInfo[botVars.color + "_" + name];
  }

  function getEnemyVar(name) {
    var eColor;
    if (botVars.color == 'blue') {
        eColor = 'red';
    } else {
        eColor = 'blue';
    }
    return gameInfo[eColor + "_" + name];
  }

  function distance(x1, y1, x2, y2) {
    return Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
  }

  function toroidDistance(x1, y1, x2, y2) {
    dx = Math.abs(x1 - x2);
        while (dx > gameInfo.fieldWidth) {
        dx -= gameInfo.fieldWidth;
    }
    dx = Math.min(dx, gameInfo.fieldWidth - dx);
    dy = Math.abs(y1 - y2);
        while (dx > gameInfo.fieldHeight) {
        dx -= gameInfo.fieldHeight;
    }
    dy = Math.min(dy, gameInfo.fieldHeight - dy);
    return Math.sqrt(dx*dx+dy*dy);
  }

  function angleDistance(theta1, theta2) {
    var d = theta1 - theta2;
    while (d < 0 || d > Math.PI) {
      if (d < 0) {
        d += Math.PI * 2;
      }
      if (d > Math.PI * 2) {
        d -= Math.PI * 2;
      } else if (d > Math.PI) {
        d = Math.PI * 2 - d;
      }
    }
    return d;
  }

  function toRad(degrees) {
    return degrees / 180 * Math.PI;
  }

  function cap(x, y, limit) {
    var r = x*x+y*y;
    if (r < limit * limit) {
        r = Math.sqrt(r);
        x = x * r / limit;
      y = y * r / limit;
    }
    return [x,y];
  }

  var shape = getVar('shape');

  if (shape != 'nose only') {
    var broken = shape != 'full ship';
    var sunX = gameInfo.sun_x,
      sunY = gameInfo.sun_y,
      sunG = gameInfo.gravityStrength;

    function desirability(x, y, vx, vy) {     //Borrowed from a useless bot.
      var lowest = distance(x, y, sunX, sunY) - 5;
      var missiles = gameInfo.missiles;
      for (var i = 0; i < missiles.length; i++) {
        var mx = missiles[i].x + missiles[i].xv / 2;
        var my = missiles[i].y + missiles[i].yv / 2;
        lowest = Math.min(lowest, toroidDistance(x, y, mx, my) - distance(0, 0, missiles[i].xv, missiles[i].yv));
      }
      return lowest - 16;
    }

    var x = getVar("x"),
      y = getVar("y"),
      vx = getVar("xv"),
      vy = getVar("yv");

    function desirabilityByAcceleration(ax, ay) {//Borrowed from a useless bot.
        var x1 = x,
            y1 = y,
          vx1 = vx,
          vy1 = vy;
      var speed = distance(0,0,vx1,vy1);
      var limit = Math.max(gameInfo.speedLimit, speed);

      vx1 += ax;
      vy1 += ay;
      var temp = cap(vx1, vy1, limit);
      vx1 = temp[0];
      vy1 = temp[1];


      var dx = x1 - sunX;
      var dy = y1 - sunY;
      var dis = Math.sqrt(dx*dx+dy*dy);
      if (dis > 5){
        var force = sunG / (dis * dis);
      } else {
        var force = sunG /5;
      }
      vx1 -= force*dx/dis;
      vy1 -= force*dy/dis;

      var temp = cap(vx1, vy1, 40);
      vx1 = temp[0];
      vy1 = temp[1];

      x1 += vx1;
      y1 += vy1;

      return desirability(x1, y1, vx1, vy1);
    }

    var r = distance(sunX, sunY, x, y);
    var theta = Math.atan((y - sunY) / (x - sunX));

    var sunA = sunG/r/r,
            sunAx = -Math.cos(theta) * sunA,
        sunAy = -Math.sin(theta) * sunA;

    var dv = Math.sqrt(sunG / r);
    var dvx = -dv * Math.sin(theta);
    var dvy = dv * Math.cos(theta);
    if (distance(-dvx, -dvy, vx, vy) < distance(dvx, dvy, vx, vy)) {
      dvx = -dvx;
      dvy = -dvy;
    }

    var dax = dvx - vx;
    var day = dvy - vy;

    var dAngle = Math.atan(day / dax);
    if (dax < 0) {
        dAngle += Math.PI;
    }
    var cAngle = toRad(getVar('rot') - 90);
    var dLeft = angleDistance(cAngle - toRad(broken ? 2.5 : 5), dAngle);
    var dRight = angleDistance(cAngle + toRad(broken ? 2.5 : 5), dAngle);
    var dNeither = angleDistance(cAngle, dAngle);
    if (dLeft < dRight && dLeft < dNeither) {
      actions.push('turn left');
    } else if (dRight < dLeft && dRight < dNeither) {
      actions.push('turn right');
    }

    var cax = Math.cos(cAngle) * (broken ? .15 : .3);
    var cay = Math.sin(cAngle) * (broken ? .15 : .3);

    var ax = 0;
    var ay = 0;

    if (distance(cax, cay, dax, day) < distance(0, 0, dax, day)) {
      actions.push('fire engine');
      ax = cax;
      ay = cay;
    }

    if (desirabilityByAcceleration(ax, ay) <= 16) {
        actions.push('hyperspace');
    }

  }

  return actions;
}
TheNumberOne
sumber
Bot Anda telah ditambahkan.
Conor O'Brien
Pembaruan Anda sekarang aktif!
El'endia Starman
5

Kejang Tangan Kanan

Namanya cukup deskriptif. Memilih turn rightdengan 0,5 probabilitas, fire enginedengan 0,5 probabilitas, dan fire missiledengan probabilitas 0,8. Sangat sulit, terutama karena itu benar-benar tidak dapat diprediksi.

function RighthandedSpasms_setup(team) {
    var botVars = {};

    botVars["color"] = team;

    return botVars;
}

function RighthandedSpasms_getActions(gameInfo, botVars) {
    var actions = [];

    if (gameInfo[botVars["color"]+"_alive"]) {
        if (Math.random() > 0.5) { actions.push("turn right") }
        if (Math.random() > 0.5) { actions.push("fire engine") }
        if (Math.random() > 0.8) { actions.push("fire missile") }
    }

    return actions;
}
El'endia Starman
sumber
5

Randummm

Tantangan ini membutuhkan bot acak. Poin bonus untuk golfiness?

function RandUmmm_setup(t){
    function P(n,t,r,o,e,f,g){for(o=[e=1<<(f=n.length)];e;)for(t=e.toString(2),r=g=t.length,o[--e]=[];r;)~-t[--r]||o[e].push(n[r+f-g]);return o}var q=P(["fire missile","turn right","fire engine","turn left"]);q.pop();
    return {color:t,m:function(){return q[Math.random()*q.length|0]}};
}

function RandUmmm_getActions(g,b){
    return b.m();
}
Conor O'Brien
sumber
Keren! (By the way, bot saya menang 13-7 Tidak. Oleh banyak, mengingat saya kehilangan 9-1 kali, tapi itu banyak poin total 20 poin dalam 90 detik.!)
ev3commander
@ BlockCoder1392 itu adalah bot acak;)
Conor O'Brien
4

Insinyur

Suka menggunakan hyperspace saat dalam bahaya. Untuk melihat itu kekuatan sebenarnya, buka konsol dan ketik browser Anda overideHyperspace = 0;. Jika Anda lupa titik koma, Anda akan mendapatkan ASI untuk Natal.

function Engineer_setup(t){
    return{c:t,C:"red0blue".split(0)[+(t=="red")]};
}

function Engineer_getActions(gameInfo,botVars){
    var actions = [];

    function d(x1,y1,x2,y2){return Math.sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2))}
    function hS(g){return d(g.sun_x,g.sun_y,g[botVars.c+"_x"],g[botVars.c+"_y"])<50}
    function enemyDist(g){return d(g[botVars.c+"_x"],g[botVars.c+"_y"],g[botVars.C+"_x"],g[botVars.C+"_y"]);}

    function hSm(g){
        // get closest missile
        var r = (g.missiles||[{x:10000,y:10000}]).reduce(function(p,c){return Math.min(d(c.x,c.y,g[botVars.c+"_x"],g[botVars.c+"_y"]),p)},Infinity);
        return r<18;
    }
    function dF(g){
        var a = Math.degrees(Math.atan2(g[botVars.C+"_y"]-g[botVars.c+"_y"],g[botVars.C+"_x"]-g[botVars.c+"_x"]));
        var tP = (g[botVars.c+"_rot"]+360-a)%360;
        return [a,tP];
    }
    function lOr(g){
        var tP = dF(g)[1];
        return 90<tP&&tP<270?"turn left":"turn right";
    }
    function thrust(g){
        return Math.abs(dF(g)-g[botVars.c+"_rot"]);
    }

    // are we too close to the sun or a missile?
    if(hS(gameInfo)||hSm(gameInfo))actions.push("hyperspace");

    // should we fire?
    if(enemyDist(gameInfo)<200)actions.push("fire missile");

    // direction function
    actions.push(lOr(gameInfo,botVars));

    if(Math.random()<.7)actions.push("fire engine");
    return actions;
}
Conor O'Brien
sumber
3

SprayAndPray

function SprayAndPray_setup(team) {
    var botVars = {};
    botVars["color"] = team;
    return botVars;
}

function SprayAndPray_getActions(gameInfo, botVars) {
    var actions = [];

    if (gameInfo[botVars["color"]+"_alive"]) {
        actions.push("turn left");
        if (Math.random() > 0.5) { actions.push("fire engine")};
       actions.push("fire missile");
    }

    return actions;
}

Kebakaran liar ke segala arah. Ini tidak terlalu efektif!

Jack Brounstein
sumber
Bot ini sekarang hidup!
El'endia Starman
3

Kamikaze

Tidak terlalu kompetitif tetapi saya pikir itu akan menyenangkan! Hanya terbang lurus ke arah lawan saat menembak.

function Kamikaze_setup(team) {
  var botVars = {};
  botVars["color"] = team;
  return botVars;
}

function Kamikaze_getActions(gameInfo, botVars) {
  var actions = [];

  // Get our ship's position
  var us, them, red = {
        rotation: gameInfo.red_rot,
        x: gameInfo.red_x,
        y: gameInfo.red_y,
        alive: gameInfo.blue_alive
      },
      blue = {
        rotation: gameInfo.blue_rot,
        x: gameInfo.blue_x,
        y: gameInfo.blue_y,
        alive: gameInfo.blue_alive
      };
  if(botVars.color == "red") {
    us = red;
    them = blue;
  }
  else if(botVars.color == "blue") {
    us = blue;
    them = red;
  }

  // Turn towards our opponent's position
  var angle = Math.degrees(Math.atan2(them.y - us.y, them.x- us.x)),
      rotationToOpponent = (us.rotation - angle + 360) % 360;
  if(rotationToOpponent > 90 && rotationToOpponent < 270) {
    actions.push("turn left");
  }
  else actions.push("turn right");

  actions.push("fire missile", "fire engine");

  return actions;
}
pengguna81655
sumber
Bot Anda telah ditambahkan!
Conor O'Brien
Mengerikan melawan OpponentDodger ... Terikat dengan PanicAttack ...
no 26zɐɹƆ
2

UhhIDKWhatToCallThisBot

Hanya barang acak.

function UhhIDKWhatToCallThisBot_setup(team) {
var botVars = {};
 botVars['t'] = 0;
botVars["color"] = team;
     return botVars;

}

function UhhIDKWhatToCallThisBot_getActions(gameInfo, botVars) {
    var actions = [];
    //when i need it: "turn left",
    //Use missiles sparingly!
    var WCID = [
    "fire engine",
     "turn right",
    "fire engine",
    "fire missile",
    "turn right",
    "fire engine"]

    if (gameInfo[botVars["color"]+"_alive"]) {
        botVars['t']++;
        actions.push(WCID[botVars[t]%(WCID.length)]);
    }
     return actions;
}
ev3commander
sumber
ada apa dengan golfiness samar?
noɥʇʎԀʎzɐɹƆ
2

OpponentDodger

MENDAPATKAN JAUH DARI SAYA OPPONENT !!!

function OpponentDodger_setup(t){b={};b["c"]=t;b['o']=(t=="red")?"blue":"red";return b;}function OpponentDodger_getActions(g,b){a=[];o=b["c"];j={r:g[o+"_rot"],x:g[o+"_x"],y:g[o+"_y"]};o=b["o"];p={r:g[o+"_rot"],x:g[o+"_x"],y:g[o+"_y"]};l=Math.degrees(Math.atan2(p.y-j.y,p.x-j.x)),x=(j.r-l+360)%360;if(x > 90 && x < 270)a.push("turn right");else a.push("turn left");a.push("fire engine");return a;}  

Terima kasih kepada user81655 untuk beberapa kode!

ev3commander
sumber
Bot ini sekarang hidup!
El'endia Starman
2

Mengintai

Cerita

Prototipe bot ini adalah bot yang memiliki dua mode: mode gila dan mode normal. Ketika berada dalam mode gila, ia tetap di sana untuk jumlah kutu yang konstan. Ada kemungkinan contant memasuki mode gila. Itu juga hyperspaced ketika dekat dengan matahari. Dalam mode gila, itu ditujukan ke bot lain dan menembak secara konstan. Dalam mode normal, ia terbang menjauh dari bot lain, tidak menembak.

Saya men-tweak prototipe itu sehingga akan berada dalam mode gila jika dan hanya jika musuh cukup dekat. Lalu saya punya ide gila: bagaimana jika itu hanya tinggal dalam mode gila? Setelah beberapa percobaan (saya menambahkan membuat bot menyala secara acak ketika itu dalam mode normal) Saya menemukan saya bot baru mengalahkan setiap bot tetapi Helios. Ini adalah kode saya di akhir proses ini, tetapi sebelum membersihkan.

Saya menulis seluruh bot saya di textarea KotH atau beautifier JS. (Saya sempat menggunakan editor Atom saat membersihkan - tetapi untuk seperti dua baris kode)

Bot

Bot ini mengandung banyak kode yang dipinjam dari bot lain. Itu membalik kode dari Kamikaze untuk melarikan diri dari bot lain alih-alih berlari ke bot lain dan dibutuhkan kode dari EdgeCase untuk hyperspacing ketika dekat dengan matahari.

Musuh bebuyutannya adalah Helios. Itu yang aneh dan obrolan panjang dengan martini.

Itu lari dari bot lain dengan peluang 70% menembakkan rudal dan hyperspaces ketika dekat dengan matahari. Sesimpel itu. Ya.

Sunting: Saya menguji bot saya dengan kode baru dan gagal untuk setiap bot lainnya. Saya sedang berusaha memperbaikinya. Saya baru saja mengkonfirmasi ini hanya untuk bot baru saya.

Kode

function Spy_setup(team) {
  // Typical setup. Nothing to see here. ;)
  var botVars = {};
  botVars["color"] = team;
  return botVars;
}


function Spy_getActions(gameInfo, botVars) {
    var actions = [];
    var us, them, red = {
            rotation: gameInfo.red_rot,
            x: gameInfo.red_x,
            y: gameInfo.red_y,
            alive: gameInfo.blue_alive
        },
        blue = {
            rotation: gameInfo.blue_rot,
            x: gameInfo.blue_x,
            y: gameInfo.blue_y,
            alive: gameInfo.blue_alive
        };
    if (botVars.color == "red") {
        us = red;
        them = blue;
    } else if (botVars.color == "blue") {
        us = blue;
        them = red;
    }

    function distance(x1, y1, x2, y2) {
        return Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
    }

    // Get our ship's position
    var rotation, x, y, opponentAlive;
    if (botVars.color == "red") {
        rotation = gameInfo.red_rot;
        x = gameInfo.red_x;
        y = gameInfo.red_y;
        opponentAlive = gameInfo.blue_alive;
    } else if (botVars.color == "blue") {
        rotation = gameInfo.blue_rot;
        x = gameInfo.blue_x;
        y = gameInfo.blue_y;
        opponentAlive = gameInfo.red_alive;
    }

    // Calculate our rotation compared to the sun in degrees
    var sunX = gameInfo.sun_x,
        sunY = gameInfo.sun_y,
        angle = Math.atan2(sunY - y, sunX - x) * 180 / Math.PI,
        rotationToSun = (rotation - angle + 360) % 360;

    // Check if we need to hyperspace to avoid the sun
    var rX = x - sunX,
        rY = y - sunY,
        distanceFromSun = Math.sqrt(rX * rX + rY * rY) - gameInfo.sun_r;
    if (distanceFromSun < 30) {
        actions.push("hyperspace");
        console.log("Command Module is Hyperspacing.")
    }
    if (gameInfo[botVars["color"] + "_alive"]) {
        var angle = Math.degrees(Math.atan2(them.y - us.y, them.x - us.x)),
            rotationToOpponent = (us.rotation - angle + 360) % 360;
        if (rotationToOpponent > 90 && rotationToOpponent < 270) {
            actions.push("turn right");
        } else {
            actions.push("turn left");
        };
        actions.push("fire engine");
        if (Math.random() > 0.3) {
            actions.push("fire missile")
        }

    }
    return actions;
}

Misc

Catatan: Saya mungkin telah memecahkan sesuatu ketika membersihkan kode karena saya tidak menguji bot setelah membersihkan kode.

Ini juga jauh lebih baik daripada semua bot saya yang lain - itu benar-benar mengalahkan bot lain kecuali untuk Helios (sunting) , SetCourseFor30Degrees, dan OrbitBot! Itu terkait dengan SunAvoider.

Catatan: Saya mengerikan di javascript, tidak tahu mengapa.

noɥʇʎԀʎzɐɹƆ
sumber
@ El'endiaStarman harap menempatkan bot langsung pada jeda; Saya perlu memperbaiki bot saya - versi yang dibersihkan jauh lebih buruk daripada versi yang tidak bersih.
noɥʇʎԀʎzɐɹƆ
Baiklah, beri tahu saya kalau sudah diperbaiki.
El'endia Starman
@ El'endiaStarman Saya melakukan sesuatu dan kemudian berhasil lagi. Debugging, Anda tahu! (belum selesai)
noɥʇʎԀʎzɐɹƆ
@ El'endiaStarman ... dan selesai!
noɥʇʎԀʎzɐɹƆ
Bot ini sekarang hidup!
El'endia Starman
1

AttackAndComeBack

Alih-alih berputar-putar, ia muncul di atas dan keluar di bawah (kembali di atas), menembak dengan sangat cepat. Umumnya menghindari sinar matahari.

function AttackAndComeBack_setup(team) {
    var botVars = {};
    botVars["color"] = team;
    return botVars;
}

function AttackAndComeBack_getActions(gameInfo, botVars) {
    var actions = [];
    actions.push("fire missile");
    if (Math.random()>0.4){actions.push("turn right");}
    else {actions.push("turn left");}
    actions.push("fire engine");
    return actions;
}
noɥʇʎԀʎzɐɹƆ
sumber
Bot ini sekarang hidup!
El'endia Starman
1

FullSpeedAhead

Selalu menembakkan mesin dan misil tanpa berbelok. Terkadang berlangsung sangat lama sebelum menabrak matahari.

function FullSpeedAhead_setup(team){
    return {color: team};
}

function FullSpeedAhead_getActions(gameInfo, botVars){
    var actions = [];

    if (gameInfo[botVars["color"]+"_alive"]) {
        actions.push("fire engine");
        actions.push("fire missile");
    }
    return actions;
}
Tomulainen
sumber
Tidak seburuk yang saya kira ...
noɐɹƆzɐɹƆ
Bot ini sekarang hidup!
El'endia Starman
1

Serangan panik

Memiliki peluang 50% untuk menembak, dan peluang 80% untuk berbelok ke kiri; tetapi jika tidak belok kiri, itu akan belok kanan. Setelah kehabisan rudal, waktu pada akhirnya akan membuatnya berhenti karena matahari.

EDIT: Menambahkan beberapa logika untuk tidak menembak ketika musuh masih hidup karena bisa terbunuh oleh misilnya sendiri.

function PanicAttack_setup(team) {
    var botVars = {};
    botVars["color"] = team;
    return botVars;
}

function PanicAttack_getActions(gameInfo, botVars) {
    var actions = [];
    actions.push("fire engine");
    if(botVars.color == "red") {
        var opponentAlive = gameInfo.blue_alive;
    }
    else if(botVars.color == "blue") {
        var opponentAlive = gameInfo.red_alive;
    }

    if ((Math.random()>0.5)&&opponentAlive) {
        actions.push("fire missile");
    }

    if (Math.random()>0.2) {
        actions.push("turn left");
    } else {
        actions.push("turn right");
    }

    return actions;
}
noɥʇʎԀʎzɐɹƆ
sumber
Bot ini sekarang hidup!
El'endia Starman
@ El'endiaStarman Harap perbarui lagi
noɥʇʎԀʎzɐɹƆ
Pembaruan Anda sekarang aktif!
El'endia Starman
1

DangitBobby

Bobby Hill tidak peduli apa yang dipikirkan orang lain tentang dia - dia cukup puas untuk berayun malas di sekitar lapangan dan dengan sabar menunggu lawannya kehabisan tenaga sebelum menyerang seperti kobra "husky".

function DangitBobby_setup(team) {
    var botVars = {};
    botVars["color"] = team;
    if (team == 'red'){
        botVars['them'] = "blue";
    }
    else{
        botVars['them'] = 'red';
    }
    return botVars;
}

function DangitBobby_getActions(gameInfo, botVars) {
    var actions = [];
    if (gameInfo[botVars["color"]+"_alive"]) {
        actions.push('turn right');
        actions.push('fire engine');
        if (gameInfo[botVars['them']+'_missileStock'] == 0){
                actions.push('fire missile');
        }

    }
}

"ITULAH PURSE SAYA! AKU TIDAK TAHU KAMU!"

john dikeman
sumber
Bot ini sekarang hidup!
El'endia Starman
1

Penembak jitu

Saya telah bermain dengan prediksi sebentar untuk membuat bot sniper yang menembak musuh-musuhnya. Javascript saya terlalu besar untuk ditampung dalam jawaban jadi di sini ada tautan, bot_Sniper .

Jake Ellenberg
sumber
Akhirnya sempat menguji bot ini, dan sayangnya, itu benar - benar memperlambat permainan. Ini cukup berombak, jadi Anda perlu membuat kode Anda lebih cepat.
El'endia Starman
Lain kali, Anda harus mempostingnya di layanan seperti [GitHub Gists] (gist.github.com) yang dirancang untuk kode.
noɥʇʎԀʎzɐɹƆ
Coba optimalkan kode Anda; Saya yakin itu bot yang sangat bagus mengingat berapa lama itu. Anda dapat mencoba memasukkan beberapa variabel atau fungsi.
noɥʇʎԀʎzɐɹƆ
Anda juga memiliki beberapa kode duplikat - saya pikir Anda akan mendapatkan banyak hal dari memposting bot Anda ke ulasan kode , pada pertukaran stack.
noɥʇʎԀʎzɐɹƆ
Anda juga bisa mendefinisikan fungsi yang Anda letakkan di Actions () di lingkup luar, jadi interpreter tidak harus mem-reparse setiap kali Anda menjalankan Actions (). Anda juga harus mencoba membuat profil kode Anda untuk mempercepatnya.
noɥʇʎԀʎzɐɹƆ
1

SmartArrow

Seperti Arrow, tapi pintar

function SmartArrow_setup(team) {
    var botVars = {};
    botVars['mpref'] = team + '_';
    botVars['epref'] = team == 'red' ? 'blue_' : 'red_';
    botVars['ecolor'] = team == 'red' ? 'blue' : 'red';
    return botVars;
}

function SmartArrow_getActions(gameInfo, botVars) {
    var actions = [];
    var x = gameInfo[botVars['mpref'] + 'x'],
        y = gameInfo[botVars['mpref'] + 'y'],
        rot = gameInfo[botVars['mpref'] + 'rot']; // SmartArrow position and rotation
    var ex = gameInfo[botVars['epref'] + 'x'],
        ey = gameInfo[botVars['epref'] + 'y']; // Enemy position
    var sunx = gameInfo.sun_x,
        suny = gameInfo.sun_y; // Sun position
    var Dsunx = Math.abs(x - sunx),
        Dsuny = Math.abs(y - suny); // Sun position delta
    var dex = Math.abs(x - ex),
        dey = Math.abs(y - ey); // Enemy position delta
    var sangle = Math.degrees(Math.atan2(suny - y, sunx - x)),
        snrot = (rot - sangle + 360) % 360;
    if (Dsunx < 40 && Dsuny < 40) // If SmartArrow is too close from sun, hyperspace !
        return ['hyperspace'];
    var missiles = gameInfo.missiles;
    for (var i = 0; i < missiles.length; i++) { // Avoid all these silly missiles
        var dx = Math.abs(x - missiles[i].x),
            dy = Math.abs(y - missiles[i].y);
        if (dx < 10 && dy < 10)
            return ['hyperspace'];
    }
    if (gameInfo[botVars['epref'] + 'alive']) { // If his enemy is alive, SmartArrow try to kill him (logic)
        var angle = Math.degrees(Math.atan2(ey - y, ex - x)),
            nrot = (rot - angle + 360) % 360;
        if (nrot > 90 && nrot < 270)
            actions.push('turn left');
        else
            actions.push('turn right');
        if (nrot > 80 && nrot < 100
         && Math.random() > 0.5) actions.push('fire missile'); // If SmartArrow is in a good spot, shot this silly oponnent
        if (Math.random() > 0.5) actions.push('fire engine');
    }
    else { // Simply (try to) act like SunAvoider if his enemy is dead
        if (snrot > 90 && snrot < 270)
            actions.push('turn right');
        else
            actions.push('turn left');
        if (Dsunx < 300 && Dsuny < 300)
            actions.push('fire engine');
        if (dex < 40 && dey < 40)
            actions.push('hyperspace'); // Dying on the corpse of his opponent is dumb.
    }
    return actions;
}
TuxCrafting
sumber
Bot ini sekarang hidup!
El'endia Starman
1

Kamikaze-

Juga tidak dirancang agar kompetitif. Hanya untuk bersenang-senang. Ini hyperspaces ketika dekat dengan matahari dan mengejar pemain tanpa menembakkan peluru. Sangat menyenangkan untuk menonton bot ini mengejar versi Spy tanpa senjata, tetapi sayangnya Anda tidak dapat memiliki lebih dari satu userbot.

El'endia: pernah mempertimbangkan untuk menambahkan lebih dari satu userbot;)

function KamikazePlus_setup(team) {
  // Typical setup. Nothing to see here. ;)
  var botVars = {};
  botVars["color"] = team;
  return botVars;
}


function KamikazePlus_getActions(gameInfo, botVars) {
    var actions = [];
    var us, them, red = {
            rotation: gameInfo.red_rot,
            x: gameInfo.red_x,
            y: gameInfo.red_y,
            alive: gameInfo.blue_alive
        },
        blue = {
            rotation: gameInfo.blue_rot,
            x: gameInfo.blue_x,
            y: gameInfo.blue_y,
            alive: gameInfo.blue_alive
        };
    if (botVars.color == "red") {
        us = red;
        them = blue;
    } else if (botVars.color == "blue") {
        us = blue;
        them = red;
    }

    function distance(x1, y1, x2, y2) {
        return Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
    }

    // Get our ship's position
    var rotation, x, y, opponentAlive;
    if (botVars.color == "red") {
        rotation = gameInfo.red_rot;
        x = gameInfo.red_x;
        y = gameInfo.red_y;
        opponentAlive = gameInfo.blue_alive;
    } else if (botVars.color == "blue") {
        rotation = gameInfo.blue_rot;
        x = gameInfo.blue_x;
        y = gameInfo.blue_y;
        opponentAlive = gameInfo.red_alive;
    }

    // Calculate our rotation compared to the sun in degrees
    var sunX = gameInfo.sun_x,
        sunY = gameInfo.sun_y,
        angle = Math.atan2(sunY - y, sunX - x) * 180 / Math.PI,
        rotationToSun = (rotation - angle + 360) % 360;

    // Check if we need to hyperspace to avoid the sun
    var rX = x - sunX,
        rY = y - sunY,
        distanceFromSun = Math.sqrt(rX * rX + rY * rY) - gameInfo.sun_r;
    if (distanceFromSun < 30) {
        actions.push("hyperspace");
        console.log("Command Module is Hyperspacing.")
    }
    if (gameInfo[botVars["color"] + "_alive"]) {
        var angle = Math.degrees(Math.atan2(them.y - us.y, them.x - us.x)),
            rotationToOpponent = (us.rotation - angle + 360) % 360;
        if (rotationToOpponent > 90 && rotationToOpponent < 270) {
            actions.push("turn left");
        } else {
            actions.push("turn right");
        };
        actions.push("fire engine");
    }
    return actions;
}

Hanya mengambil kode Kamikaze + dan menyingkirkan bagian penembakan rudal.

noɥʇʎԀʎzɐɹƆ
sumber
Saya mungkin tidak akan menambahkan bot ini karena kami sudah memiliki satu bot Kamikaze lainnya , dan saya lebih suka tidak memiliki tiga bot kamikaze. Selain itu, ini lebih sepele daripada dua lainnya.
El'endia Starman
@ El'endiaStarman maka saya meminta beberapa userbot - bidang kode yang kedua dapat menjadi default tersembunyi yang dapat diperluas
noɥʇʎԀʎzɐɹƆ
0

MissilesPlusScore

Beberapa ide aneh yang saya kemukakan mengambil nilai absolut dari selisih skor dan menggunakan daftar gerakan secara acak berdasarkan cara permainan. Ini bekerja dengan baik melawan bot dengan strategi tetapi gagal melawan badai rudal. Juga pertamaku .

function MissilesPlusScore__setup(team) {
var botVars = {};
botVars["color"] = team;
return botVars;
}
function MissilesPlusScore_getActions(gameInfo, botVars) {
var actions = [];
var moves=["fire missile","hyperspace","turn right","turn left","fire engine","fire missile","turn right","hyperspace","turn left","fire missile","hyperspace","turn right","turn left","hyperspace","fire engine","fire missile","turn right","turn left","hyperspace","fire missile","turn right","turn left","fire engine","hyperspace","fire missile","turn right","turn left","hyperspace"];
if(gameInfo[botVars["color"]+"_alive"]){
var num=gameInfo["redScore"]-gameInfo["blueScore"];
if(num<0){num=num*-1;}
if(num===0){actions.push(moves[Math.round(Math.random()*4)]);}
else{
actions.push(moves[num+gameInfo["numMissiles"]]);
}
}
    return actions;
}

HIPER

HYPERSPACE IS COOL !!!!!!!!!!!!!!!!

function HYPER_setup(team){var botVars={};botVars["color"]=team;return botVars}function HYPER_getActions(gameInfo,botVars){var actions=[];if(gameInfo[botVars["color"]+"_alive"]){actions.push(["fire engine","fire missile","hyperspace"][Math.round(Math.random()*2)])};return actions}

Pengaruh Koordinat

Didasarkan pada Koordinat, secara mengejutkan efektif:

function CoordinateInfluence_setup(team) {
var botVars = {};
botVars["color"] = team;
return botVars;
}
function CoordinateInfluence_getActions(gameInfo, botVars) {
var actions = [];
if (gameInfo[botVars["color"]+"_alive"]) {
if(gameInfo["blue_x"]>gameInfo["red_x"]){
if(gameInfo["blue_y"]<gameInfo["red_y"]){actions.push("turn right");}
else{actions.push("fire engine");}
}
else if(gameInfo["blue_y"]<gameInfo["red_y"]){
if(gameInfo["blue_x"]>gameInfo["red_x"]){actions.push("turn left");}
else{actions.push("fire missile");}
}
else{actions.push("hyperspace");}
}
return actions;
}
Pengguna Generik
sumber
Kedua bot ini hidup.
El'endia Starman
Anda harus memposting beberapa jawaban sebagai gantinya.
noɥʇʎԀʎzɐɹƆ
Jika Anda pernah menambahkan bot lain, harap ping saya agar saya tahu Anda melakukannya. Bot ketiga Anda sekarang hidup.
El'endia Starman
0

SetCourseFor30Degrees

Tidak tahu mengapa kapten sangat bersikeras mengatur kapal pada jalur 30 derajat, tapi hei, sebagai panji rendah, siapa yang akan Anda pertanyakan? Setidaknya Anda telah diberi izin untuk menghindari matahari! Dan Anda diizinkan untuk menembakkan rudal ... hanya tidak diizinkan untuk mengarahkan mereka ...

function SetCourseFor30Degrees_setup(team) 
{
  var botVars = {};
  botVars["color"] = team;
  return botVars;
}


function SetCourseFor30Degrees_getActions(gameInfo, botVars)
{
var actions = [];
var ang1 = gameInfo[botVars["color"]+"_rot"]+0;
var fireChance=0.95;
// sun avoidance
   var x = gameInfo[botVars["color"]+"_x"];
   var y = gameInfo[botVars["color"]+"_y"];
   var sunX = gameInfo["sun_x"]+0;
   var sunY = gameInfo["sun_y"]+0;
  var dx = sunX- x;
   var dy = sunY - y;
var shortRangeAvoidanceDistance = (dx * dx + dy * dy ) ;

 x = gameInfo[botVars["color"]+"_x"]+gameInfo[botVars["color"]+"_xv"]*10;
 y = gameInfo[botVars["color"]+"_y"]+gameInfo[botVars["color"]+"_yv"]*10;
 dx = sunX- x;
 dy = sunY - y;

var longRangeAvoidanceDistance = (dx * dx + dy * dy ) ;


var vel = Math.sqrt(gameInfo[botVars["color"]+"_xv"]*gameInfo[botVars["color"]+"_xv"]+
gameInfo[botVars["color"]+"_yv"]*gameInfo[botVars["color"]+"_yv"]);

var close=vel*1.5;

if (shortRangeAvoidanceDistance <= close* close)
{
  actions.push("hyperspace");
}
else
{
   if (longRangeAvoidanceDistance <= 200*200)
   {

     x = x+Math.cos((ang1-5)*Math.PI/180)*vel ;
     y = y+Math.sin((ang1-5)*Math.PI/180)*vel ;
     dx = sunX- x;
     dy = sunY - y;
     if (( dx * dx + dy * dy ) > longRangeAvoidanceDistance  )
     {
       actions.push("turn right")
     }
     else
     {
        actions.push("turn left")
     }
  }
  else
  {
    var course = botVars["color"]=="red"?30:-30;
    if (ang1>course ) {actions.push("turn left")}
    if (ang1<course ) {actions.push("turn right")}
  }
  if (Math.random() > fireChance){ actions.push("fire missile") }
  actions.push("fire engine")
}
return actions;
}
Moogie
sumber
Bot ini sekarang hidup!
El'endia Starman
0

Panah

Cukup kejar musuhnya, hyperspace ketika dia dalam bahaya dan menganggur ketika musuhnya sudah mati.

function Arrow_setup(team) {
    var botVars = {};
    botVars['mpref'] = team + '_';
    botVars['epref'] = team == 'red' ? 'blue_' : 'red_';
    return botVars;
}

function Arrow_getActions(gameInfo, botVars) {
    var actions = [];
    var x = gameInfo[botVars['mpref'] + 'x'],
        y = gameInfo[botVars['mpref'] + 'y'],
        rot = gameInfo[botVars['mpref'] + 'rot']; // My position and rotation
    var ex = gameInfo[botVars['epref'] + 'x'],
        ey = gameInfo[botVars['epref'] + 'y']; // Enemy position
    var Dsunx = Math.abs(x - gameInfo.sun_x);
    var Dsuny = Math.abs(y - gameInfo.sun_y);
    if (Dsunx < 30 && Dsuny < 30) // If Arrow is too close from sun, hyperspace !
        return ['hyperspace'];
    var missiles = gameInfo.missiles;
    for (var i = 0; i < missiles.length; i++) {
        var dx = Math.abs(x - missiles[i].x);
        var dy = Math.abs(y - missiles[i].y);
        if (dx < 10 && dy < 10)
            return ['hyperspace'];
    }
    if (gameInfo[botVars['epref'] + 'alive']) {
        var angle = Math.degrees(Math.atan2(ey - y, ex - x)),
            nrot = (rot - angle + 360) % 360;
        if (nrot > 90 && nrot < 270)
            actions.push('turn left');
        else
            actions.push('turn right');
        if (Math.random() > 0.5) actions.push('fire missile');
    }
    if (Math.random() > 0.5) actions.push('fire engine');
    return actions;
}
TuxCrafting
sumber
Bot ini sekarang hidup!
El'endia Starman
@ El'endiaStarman Saya telah memperbarui bot
TuxCrafting
Pembaruan sekarang hidup! Tapi tidak banyak. : P
El'endia Starman
0

Kamikaze +

Tidak dirancang untuk kompetitif. Hanya untuk bersenang-senang. Secara teknis, itu kebalikan dari Spy: mengejar pemain, hyperspace ketika dekat dengan matahari, menembakkan rudal 70% dari waktu. Saya agak hanya ingin melihat KamikazePlus mengejar Mata-Mata dan Mata-Mata melarikan diri seperti orang gila.

function KamikazePlus_setup(team) {
  // Typical setup. Nothing to see here. ;)
  var botVars = {};
  botVars["color"] = team;
  return botVars;
}


function KamikazePlus_getActions(gameInfo, botVars) {
    var actions = [];
    var us, them, red = {
            rotation: gameInfo.red_rot,
            x: gameInfo.red_x,
            y: gameInfo.red_y,
            alive: gameInfo.blue_alive
        },
        blue = {
            rotation: gameInfo.blue_rot,
            x: gameInfo.blue_x,
            y: gameInfo.blue_y,
            alive: gameInfo.blue_alive
        };
    if (botVars.color == "red") {
        us = red;
        them = blue;
    } else if (botVars.color == "blue") {
        us = blue;
        them = red;
    }

    function distance(x1, y1, x2, y2) {
        return Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
    }

    // Get our ship's position
    var rotation, x, y, opponentAlive;
    if (botVars.color == "red") {
        rotation = gameInfo.red_rot;
        x = gameInfo.red_x;
        y = gameInfo.red_y;
        opponentAlive = gameInfo.blue_alive;
    } else if (botVars.color == "blue") {
        rotation = gameInfo.blue_rot;
        x = gameInfo.blue_x;
        y = gameInfo.blue_y;
        opponentAlive = gameInfo.red_alive;
    }

    // Calculate our rotation compared to the sun in degrees
    var sunX = gameInfo.sun_x,
        sunY = gameInfo.sun_y,
        angle = Math.atan2(sunY - y, sunX - x) * 180 / Math.PI,
        rotationToSun = (rotation - angle + 360) % 360;

    // Check if we need to hyperspace to avoid the sun
    var rX = x - sunX,
        rY = y - sunY,
        distanceFromSun = Math.sqrt(rX * rX + rY * rY) - gameInfo.sun_r;
    if (distanceFromSun < 30) {
        actions.push("hyperspace");
        console.log("Command Module is Hyperspacing.")
    }
    if (gameInfo[botVars["color"] + "_alive"]) {
        var angle = Math.degrees(Math.atan2(them.y - us.y, them.x - us.x)),
            rotationToOpponent = (us.rotation - angle + 360) % 360;
        if (rotationToOpponent > 90 && rotationToOpponent < 270) {
            actions.push("turn left");
        } else {
            actions.push("turn right");
        };
        actions.push("fire engine");
        if (Math.random() > 0.3) {
            actions.push("fire missile")
        }

    }
    return actions;
}

Pada dasarnya hanya mengambil kode mata-mata dan membalik "kiri" dan "kanan".

noɥʇʎԀʎzɐɹƆ
sumber
Bot ini sekarang hidup! Dan ya, sangat menyenangkan untuk menonton KamikazePlus mengejar Spy. : P
El'endia Starman
@ El'endiaStarman Saya merasa senang menyaksikan KamikazePlus bertarung tanpa peluru dan overideHyperspace = 0;; mereka hanya hilang ketika mereka mencoba untuk pergi satu sama lain.
noɥʇʎԀʎzɐɹƆ