Tepenin Kralı - Spacewar!


64

Eğer hiç Spacewar oynamışsanız ! , eğlenceli bir oyun olduğunu biliyorsun. Bunu yapmadıysanız, şunu bilin: ilk ve en önemli bilgisayar oyunlarından biriydi (ve öyle). Ve hala eğlenceli! Ben büyüdüm klon bu bir görünüşe ve ne yazık ki, sadece Windows vardır. Bu yüzden onu yeniden yarattım!

KotH burada barındırılmaktadır: PPCG - Spacewar! Tepenin Kralı . Oyunun nasıl çalıştığını hissetmek için en az bir botla insan olarak oynamanı tavsiye ediyorum.

Oyun

  • Bir kare 30 milisaniyedir (yani, saniyede yaklaşık 33 kare).
  • Alan 800 piksel genişliğinde ve 600 piksel yüksekliğindedir.
  • Alan toroidaldir, yani alanın dışına hareket eden uzay ve füzelerin karşı tarafta tekrar göründüğü anlamına gelir.
  • İki uzay gemisi var, kırmızı ve mavi.
    • Kırmızı, x = 50 konumunda ve rasgele y, 50 (alan yüksekliği - 50) piksel arasında konumlandırılmıştır.
    • Mavi, x = (alan genişliği - 50) olarak ve rasgele y, 50, (alan yüksekliği - 50) piksel arasında konumlandırılır.
    • Her iki yüz x = (alan genişliği) / 2.
  • Mevcut kontroller:
    • Sola çevirin - kare başına 5 derece saat yönünün tersine.
    • Sağa çevirin - kare başına 5 derece saat yönünde.
    • Ateş füzesi - gemi hızına ek olarak, gemi işaret ettiği yöne ek olarak, kare başına ekstra 10 piksel hareket eder.
    • İtfaiye aracı - uzay gemisinin işaret ettiği yönde her kare için 0,30 piksel ile uzay gemisini hızlandırır.
    • Hyperspace jump - Alandaki bazı rasgele koordinatlara ışınlar,% 25'lik bir patlama şansı. Bu rasgele koordinatlar güneşin üstünde olabilir.
  • Gemiler için maksimum hız, motor gücü altındaki çerçeve başına 15 piksel ve yerçekimi artırıldığında kare başına 40 pikseldir.
    • Çerçeve başına 15 pikselden daha hızlı seyahat ederken, motor itişi yalnızca yön değiştirebilir veya yavaşlayabilir.
  • Füzeler ile ilgili olarak:
    • Füzeler düz bir çizgide ilerliyor.
    • Füzeler 0,1 saniyede maksimum 1 oranında ateşlenebilir.
    • Füzelerin ömrü 2.25 saniyedir.
    • Gemilerin her birinde en fazla 20 füze var.
    • Füzeler dahili olarak partikül parçacıklarıdır.
  • Merkezde, geminiz için son derece tehlikeli olan bir güneş var. En ufak temas ölümcüldür. Bu güneş aynı zamanda füzeleri de yok ediyor.
  • Güneş yerçekimi vardır. Elde edilen ivme 5000 / (mesafe ^ 2) piksel / kare ^ 2'dir, burada mesafe piksel cinsindendir. Uzay gemileri ve füzeler etkilenir.
  • Her iki geminin de üç vuruş bölgesi var: burun, sol kanat ve sağ kanat.
    • Burunda bir vuruş anında ölümdür.
    • Her iki kanattaki vuruş, uzay gemisinin dönüş hızını ve motor ivmesini yarı yarıya azaltır.
    • Her iki kanat da tahrip olursa, uzay gemisi manevra yapamaz ve yalnızca füze ateşleyebilir.
  • Gemiler birbiriyle çarpışabilir.
    • Her iki gemi için bir burun-burun etkisi ölümcüldür.
    • Bir burun kanadı darbesi kanadı yok eder.
    • Kanat kanadı darbesi her iki kanadı da yok eder.
  • Ölü gemiler sağlam ve 1 saniye sonra patlayana kadar donmuş.
  • En az bir gemi öldükten sonra, saha 3 saniye sonra sıfırlanır. O zamana kadar güneş ve kalan füzeler hala tehlikelidir.

Orijinal oyun aynı zamanda ölümcül ve tahrip edilemez asteroitler de içeriyor, ama ben bunları dahil etmeyeceğim.

Kurallar

  • Botunuz JavaScript ile yazılmalıdır.
  • Botunuz kararını yaklaşık 10 milisaniye ile sınırlandırmalıdır. Botunuzdan dolayı sürekli bir gecikme olduğunu fark edersem, diskalifiye edeceğim ve düzeltebilmeniz için size haber vereceğim.
  • Botlar aşağıdakilere erişebilecek:
    • Alan genişliği ve alan yüksekliği
    • Güneş pozisyonu ve yarıçapı
    • Her iki geminin de konumu, dönüşü, hızı, şekli, füze stoğu ve hiper-uzayda durumu
    • Tüm füzelerin konumu ve hızı
  • İstendiğinde, botunuz bir dizeler listesi döndürmelidir.
    • Bu dizeler aşağıdaki biri olmalıdır: turn left, turn right, fire engine, fire missile, hyperspace. Başka bir dize göz ardı edilir.
    • Herhangi bir kopya varsa, yalnızca ilk not alınacaktır.
    • hyperspace tüm diğerlerine göre önceliklidir.
    • turn leftve turn rightaynı zamanda bir etkisi olmayacak.
    • fire engine Geminin sadece burnu varsa veya ölmüşse etkisi olmaz.
    • fire missile Çok yakın zamanda bir füze ateşlendiğinde etkisi olmayacak.
  • Normalden farklı olarak botunuzun diğer botların davranışlarından yararlanmasına izin verilir. Bir meta oyunu teşvik etmek istiyorum.
    • Botlar olmayabilir diğer botlar taklit. (Yani, zihin okuma yok.)
    • Botlar olmayabilir oyun ve fizik kodu tarafından kullanılan herhangi bir değişken olarak ayarlayın. (Yani, hile yapmak yok.)

Bot Uygulama Detayları

Botunuzu, dosya adıyla birlikte otomatik olarak eklenen kendi JavaScript dosyasında depolayacağım bot_<name>.js. Bu yüzden, bununla ya da JavaScript'te bir işlevin isimlendirilmesine müdahale edecek boşluk veya karakter koymayın. Çünkü şu fonksiyonları tanımlamanız gerekir: <name>_setup(team)ve <name>_getActions(gameInfo, botVars). Sayfanın ilerleyen kısımlarında , kodunuzu test etmek için düzenleyebileceğiniz kullanıcıbot için bir yazı var .

<name>_setup(team)

Bu işlev, sürdürmek istediğiniz değişkenleri tanımlamanız içindir. teamya "red"da olacak "blue". Bu işlev bir nesne döndürmelidir. Bunun gibi değişkenleri tanımlayın:

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

Bu varsnesne diğer işleve geçer:

<name>_getActions(gameInfo, botVars)

botVarstarafından döndürülen nesne <name>_setup(team). gameInfoaşağıdaki değişkenleri içeren bir nesnedir:

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

Botunuz bunlara tam erişime sahip. Ben oldukça emin onlara yazıp değil orijinal değişkenleri etkiler, ancak yine de yapmayın ki. Bir rotasyonlar üzerinde not: gemiler işaret gemiye uyum sağlamak istiyoruz aşağıya + y yönünde, yani her şey 90 derece ofset gerekmektedir. Ayrıca, pozitif dönüş saat yönündedir.

Bu işlev botunuzun eylemlerini temsil eden bir dizge listesi döndürmelidir. Örneğin, ["turn right","thrust"]. Bununla ilgili daha fazla ayrıntı Kurallar bölümündedir.

ek detaylar

Ayrıca aşağıdakilerden de yararlanabilirsiniz:

LineIntersection(L1, L2)

L1 ve L2, iki elemanlı dizilerin iki elemanlı dizileridir. Bu L1 := [[x1,y1],[x2,y2]]ve L2 := [[u1,v1],[u2,v2]]. Bu fonksiyon iki satır kesişim hesaplar ve bu döndürür: [[x,y], [a,b]]. [x,y]kesişme noktasının koordinatlarıdır ve kesişme noktasının [a,b]her bir çizgisi boyunca ne kadar uzak olduğunu ifade eden bir oran çiftidir. Olduğu gibi, a = 0.25kesişme noktası yolu dörtte dan anlamına gelir [x1,y1]için [x2,y2]ve aynı şekilde için b. Kesişme yoksa, boş bir dizi döndürülür.

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

Bunlar gemilerin çokgenlerinin koordinatları. Geçerli koordinatları almayı kolaylaştırmak için, ayrıca ...

getShipCoords(<color>)

getShipCoords("red")Red'in gemisinin köşelerinin mevcut koordinatlarını ve aynı şekilde ve Mavi'yi döndürür getShipCoords("blue"). Bu koordinatlar şöyle bir listede şunlardır: [[x1,y1],[x2,y2],[x3,y3],...]. Çokgenler örtük olarak kapalıdır, bu nedenle ilk ve son koordinat çiftleri arasında bir çizgi vardır.

Oyun / web sitesi tarafından kullanılan diğer değişkenlere veya işlevlere erişemez veya bunları değiştiremezsiniz. Ve kesinlikle işlevlerinizi aynı şekilde adlandırmayın. Bunun bir sorun olacağını öngörmüyorum, ancak botunuz oyun kodunu kırarsa, bu bir olasılık. Hiçbir kayıt veya istisna yakalama yoktur.

Kazanan

  • Her bot eşleştirmesi, her iki şekilde de en az 10 defa oynanacaktır. (Yani, en az 20 oyun toplam.)
  • Genel olarak en yüksek kazanç / kayıp oranlarına sahip olmayı hedefleyin . Eğer botunuz diğer bir bota karşı çok iyi performans gösteriyorsa, ancak diğer üçüne karşı kaybederse, bu iki kişiye karşı kazanmak ve iki kişiye karşı kaybetmek kadar iyi değildir (genel bir kural olarak).
  • Her bot için, oranlar (+ + 1) / (+ + 1 kazanç), daha sonra bu oranların ortalama ve standart sapmaları hesaplanacaktır. Daha yüksek bir ortalama önceliğe sahip olacak ve araçların birbirinin 1 birimi içinde olması durumunda, düşük varyans önceliğe sahip olacaktır.
  • Puanlama, bugünden itibaren bir hafta içinde veya yeni başvuru yapılmadan üç gün sonra başlayacaktır. Bu yüzden herhangi bir bot çiftini tekrarlamak zorunda kalmam.

Her şeyden önce, eğlenin!


Büyük Afiş (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

Not: Bu, daha fazla oyun çalıştırdıkça değişebilir. Artı, 9-13 arasındaki sıralamada beni rahatsız ediyor, bu yüzden nasıl derecelendirilmeleri gerektiği konusundaki sezgisini daha iyi eşleştirmek için puanlama yöntemini ince ayarlayabilirim.

(Ortalamalar ve standart sapmalar üç ondalık basamağa yuvarlanmıştır. Ayrıca, vurgulanması Hyperzor olan da olmalıdır HYPER.: P)


Herhangi bir skor? ....
ev3 komutanı

Günlük istisnaları yakaladı mı?
TheNumberOne

1
LineIntersectionKesişmeyen bölümlere yapılan çağrıların boş bir dizi döndürdüğünü belirtmelisiniz .
LegionMammal978

1
Galiba yaptım!
ev3 komutanı

3
@ CrazyPython: İlk ikisini temelde bir oyun kopyaladığımı düşünerek itiraz ediyorum, ancak üçüncü tam olarak istediğim şeydi. Teşekkürler! : D
El'endia Starman

Yanıtlar:


12

Helios

Bu bot evrenin merkezi, ya da en azından onun olduğunu düşünüyor. Yaptığı ilk şey büyük bir hatayı düzeltmek ve kendisini koordinat sisteminin merkezine yerleştirmektir. Sonra etrafındaki her şeyi döndürür.

Diğer (sahte) güneşi sevmiyor, bu yüzden ondan uzak durmaya çalışıyor. Ayrıca diğer botlardan hoşlanmıyor, bu yüzden iyi bir çekim pozisyonunda ise, onlara ateş ediyor.

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

1
Sanırım bu şimdiye dek en sevdiğim robotlardan biri. Şaşırtıcı derecede iyi!
El'endia Starman,

@ El'endiaStarman Bot için bazı güncellemeler yaptım.
Sleafar

Güncellemeniz şimdi yayında!
El'endia Starman,

Bu OrbitBot'a karşı çok iyi çalışıyor :)
TheNumberOne

1
@Soaku Bu botla diğerlerinin çoğu arasındaki temel farkın, bu botun atıştan önce rakibini hedef alması olduğunu düşünüyorum.
Sleafar

9

SunAvoider

Bu sadece güneşten uzak durmaya çalışır. O kadar iyi yapıyor ki ... bir ya da her iki kanadı yok edilinceye kadar, o zaman genellikle düşmeden önce sadece bir zaman meselesi.

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

9

EdgeCase

Güneşten uzakta, haritanın kenarına doğru tam hızla uçar! Kendini güneşe dönük bulduğunda, kenara dönmek için kendisini geri çevirirken ateş etmeye başlayacaktır. Ayrıca güneşe çarpmak üzereyken hiperuza girer.

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

Bu bot şimdi yayında! Ayrıca, buna karşı hayatta kalmak şaşırtıcı derecede kolaydı. Muhtemelen diğerleri gibi her yerdeki füzeleri nasıl spam ile karşılamadığı ile ilgili olmalı. : P
El'endia Starman

7

OrbitBot

Şu anda hiçbir hedefleme veya çarpışmadan kaçınma yoktur . Güneşi yörüngeye sokmaya çalışıyor.

Düzenleme: Etki yakın olduğunda şimdi hiper uzaya gider.

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

Botunuz eklendi.
Conor O'Brien,

Güncellemeniz şimdi yayında!
El'endia Starman

5

RighthandedSpasms

İsim oldukça açıklayıcı. turn right0.5 olasılık, fire engine0.5 olasılık ve fire missile0.8 olasılık ile seçer . Şaşırtıcı derecede zor, çünkü esasen tahmin edilemez.

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

5

RandUmmm

Bu meydan okuma rastgele bir bot gerektiriyordu. Golf için bonus puan?

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

Güzel! (. Bu arada, benim bot Değil 13-7 kazandı tarafından keresinde 9-1 kaybetmiş göz önünde bulundurarak bir sürü, ama bu var çok toplamda noktalarının 20 puan 90 saniye içinde.!)
ev3commander

@ BlockCoder1392 bu ise ), bir rastgele bot
Conor O'Brien

4

Mühendis

Tehlike altındayken hiperuzayı kullanmayı sever. Gerçek güç olduğunu görmek için tarayıcınızın konsolunu açın ve yazın overideHyperspace = 0;. Noktalı virgül unutursanız, Noel için ASI alırsınız.

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

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

Her yöne çılgınca ateş eder. Çok etkili değil!


Bu bot şimdi yayında!
El'endia Starman

3

intihar uçağı

Çok rekabetçi değil ama eğlenceli olacağını düşündüm! Ateş ederken sadece rakibine doğru uçar.

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

Botunuz eklendi!
Conor O'Brien,

OpponentDodger'a karşı korkunç ... PanicAttack ile bağlı ...
no --zɥʇʎԀʎ

2

UhhIDKWhatToCallThisBot

Sadece rastgele şeyler.

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

Kriptik golfluğun nesi var?
noɥʇʎԀʎzɐɹƆ

2

OpponentDodger

ME OPPONENT'DAN ÇIKIŞ OLSUN !!!

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

Bazı kod için user81655 için teşekkürler!


Bu bot şimdi yayında!
El'endia Starman

2

Casus

Hikaye

Bu botun prototipi iki modlu bir bottu: çılgın mod ve normal mod. Çılgın moddayken, sabit sayıda keneler için orada kaldı. Çılgın moda girme konusunda kesin bir olasılık vardı. Aynı zamanda güneşe yakın olduğu zaman da yerini aldı. Çılgın modda diğer botu hedef aldı ve sürekli ateş etti. Normal modda, ateş etmeden diğer bottan uzağa uçtu.

Bu prototipi, düşmanın yeterince yakın olması durumunda ve çılgınca modda olması için çimdikledim. Sonra çılgınca bir fikrim vardı: peki ya sadece çılgın modda kaldıysa? Bazı denemelerden sonra (normal moddayken botu rastgele ateşe verdim), beni her bottan başka Helios dışında yendiğini gördüm. Bu , bu işlemin sonunda, ancak temizlikten önce benim kodum.

Botumun tamamını KotH textarea veya JS güzelleştiricisine yazdım. (Temizlerken Atom editörünü kısaca kullandım - fakat iki satır kod için)

Bot

Bu bot diğer botlardan ödünç alınmış bir sürü kod içeriyor. Diğer bottan kaçmak yerine diğer bottan kaçmak için kodu Kamikaze'den döndürür ve güneşe yakın olduğunda aşırı boşluk yapmak için EdgeCase'den kod alır.

Bu kemer nemezi Helios. Garip olanı ve uzun bir martini ile sohbet ediyor.

Diğer botlardan kaçar ve% 70'i güneşe yakın olduğunda füze ve hiper uzayları ateşleme şansı verir. Kadar basit. Evet.

Düzenleme: Botumu yeni kodla test ettim ve diğer tüm botlar için başarısız oluyor. Tamir etmeye çalışıyorum. Bunun sadece yeni botum için olduğunu onayladım.

Kod

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

Not: Kodu temizlerken bir şeyler kırmış olabilirim çünkü kodu temizledikten sonra botu test etmedim.

Ayrıca diğer botlarımdan çok daha iyi - aslında Helios (edit) , SetCourseFor30Degrees ve OrbitBot! SunAvoider ile bağları var.

Yan not: Javascriptte korkunçum, nedenini bilmiyorum.


@ El'endiaStarman, lütfen botu duraklatıp canlı hale getirin; Botumu düzeltmem gerekiyor - temizlenmiş sürüm kirli sürümden çok daha kötü.
noɥʇʎԀʎzɐɹƆ

Tamam, tamir edildiğinde bana haber ver.
El'endia Starman,

@ El'endiaStarman Bir şey yaptım ve sonra tekrar çalıştı. Hata ayıklama, biliyorsun! (henüz tamamlanmadı)
noɥʇʎԀʎzɐɹƆ

@ El'endiaStarman ... ve bitti!
noɥʇʎԀʎzɐɹƆ

Bu bot şimdi yayında!
El'endia Starman

1

AttackAndComeBack

Dönme yerine üste gelir ve alttan çıkar (üste döner), çok hızlı bir şekilde ateş eder. Genellikle güneşten kaçınır.

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

Bu bot şimdi yayında!
El'endia Starman

1

Tam gaz ileri

Daima dönmeden hem motorları hem de füzeleri ateşler. Bazen güneşe çarpmadan önce şaşırtıcı derecede uzun sürer.

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

Düşündüğüm kadar kötü değil ...
noɥʇʎԀʎzɐɹƆ

Bu bot şimdi yayında!
El'endia Starman

1

Panik atak

% 50 ateş etme ve% 80 sola dönme şansı var; ama sola dönmezse, sağa döner. Füzelerin tükenmesinden sonra, zaman sonunda güneş yüzünden durmayacak.

EDIT: Düşman hayatta iken ateş etmemek için bir mantık eklendi çünkü kendi füzeleri tarafından öldürülebilirdi.

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

Bu bot şimdi yayında!
El'endia Starman

@ El'endiaStarman Lütfen tekrar güncelleyin
noɥʇʎԀʎzɐɹƆ

Güncellemeniz şimdi yayında!
El'endia Starman

1

DangitBobby

Bobby Hill, başkalarının kendisi hakkında ne düşündüğünü umursamıyor - saha etrafında tembelce sallanmaktan oldukça memnun ve sabırsız bir şekilde "husky" kobra gibi vurmadan önce rakibinin buharının bitmesini bekler.

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

    }
}

“BU PURSE'İM! SENİ BİLMİYORUM!”


Bu bot şimdi yayında!
El'endia Starman

1

Keskin nisanci

Düşmanlarını rahatlatan bir keskin nişancı botu yaratması için biraz tahmin yapıyorum. Benim javascript bir cevaba sığmayacak kadar büyük, bu yüzden burada bir bağlantı, bot_Sniper .


Nihayet bu bot test getirmiştim ve ne yazık ki, gerçekten oyun yavaşlatır. Oldukça dalgalı, bu yüzden kodunuzu daha hızlı hale getirmeniz gerekiyor.
El'endia Starman

Bir dahaki sefere, kodu için tasarlanmış [GitHub Gists] (gist.github.com) gibi bir servise göndermelisiniz.
noɥʇʎԀʎzɐɹƆ

Kodunuzu optimize etmeyi deneyin; Bahse girerim ne kadar uzun olduğunu göz önüne alarak çok iyi bir bot. Bazı değişkenler veya işlevler inling deneyebilirsiniz.
noɥʇʎԀʎzɐɹƆ

Ayrıca bazı kodlarınız da var - bence botunuzu kod incelemesine göndermekle yığın alışverişinde kullanmaktan kazanacağınız bir sürü şey var .
noɥʇʎԀʎzɐɹƆ

Actions () 'a koyduğunuz işlevleri dış kapsamda da tanımlayabilirsiniz, böylece tercümanın, her bir Action () işlemini her çalıştırdığınızda yeniden doldurması gerekmez. Ayrıca, hızlandırmak için kodunuzu profillemeyi denemelisiniz.
noɥʇʎԀʎzɐɹƆ

1

SmartArrow

Ok gibi, ama akıllı

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

Bu bot şimdi yayında!
El'endia Starman

1

Kamikaze-

Ayrıca rekabetçi olacak şekilde tasarlanmamıştır. Sadece eğlence için. Güneşe yakın olduğunda hızlanır ve mermiyi ateşlemeden oynatıcıyı kovalar. Bu botun Spy'ın silahsız versiyonunu takip etmesini izlemek eğlenceli, ama maalesef birden fazla userbot'a sahip olamazsınız.

El'endia: hiç birden fazla userbot eklemeyi düşünmedim;)

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

Sadece Kamikaze + 'nın kodunu aldı ve füze ateşleme kısmından kurtuldum.


Muhtemelen bir tane daha Kamikaze botumuz olduğu için bu botu eklemeyeceğim ve üç kamikaze botu istemedim. Ayrıca, bu diğer ikisinden daha önemsiz.
El'endia Starman

@ El'endiaStarman sonra birden fazla kullanıcı botu rica ediyorum - ikincisinin kod alanı varsayılan olarak genişletilebilir bir gizli olabilir
noɥʇʎԀʎzɐɹƆ

0

MissilesPlusScore

Karşılaştığım tuhaf bir fikir, puanların farkının mutlak değerini alır ve oyun şeklini temel alarak rastgele bir hareket listesi kullanır. Stratejisi olan botlara karşı iyi çalışır ancak füze fırtınalarına karşı başarısız olur. Ayrıca ilk .

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

AŞIRI

HİPERSPLE SERBİR !!!!!!!!!!!!!!!!!

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}

CoordinateInfluence

Koordinatlara dayanarak, şaşırtıcı derecede etkili:

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

Bu botların ikisi de canlı.
El'endia Starman

Bunun yerine birden fazla cevap göndermelisiniz.
noɥʇʎԀʎzɐɹƆ

Başka bir bot eklersen, lütfen bana ping at, böylece yaptığını biliyorum. Üçüncü botun şimdi canlı.
El'endia Starman

0

SetCourseFor30Degrees

Kaptanın neden gemiyi 30 derecelik bir rotaya yerleştirmekte bu kadar ısrarcı olduğu konusunda hiçbir fikrim yok, ama hey, alçakgönüllü olarak, kimi sorgulayacaksın? En azından güneşten korunma izniniz var! Ve füzeleri ateşlemene izin verilir ... onları hedeflemene izin verilmez ...

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

Bu bot şimdi yayında!
El'endia Starman

0

Ok

Düşmanının peşindeyken düşmanı, hiperuzayı tehlikedeyken ve boşta iken peşinde koş.

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

Bu bot şimdi yayında!
El'endia Starman

@ El'endiaStarman Botu güncelleştirdim
TuxCrafting

Güncelleme şimdi yayında! Çok değil ama. : P
El'endia Starman

0

Kamikaze +

Rekabetçi olacak şekilde tasarlanmamıştır. Sadece eğlence için. Teknik olarak, Casus'un tam tersini yapıyor: oyuncuları kovala, güneşe yakınyken hiper uzayı kovala,% 70 oranında füze ateşle. Ben sadece KamikazePlus’ı Spy ve Spy’ı bir deli gibi kaçarken kovalarken görmek istiyorum.

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

Temelde sadece Spy'ın kodunu aldı ve "sol" ve "sağ" çevirdi.


Bu bot şimdi yayında! Ve evet, KamikazePlus Chase Spy'ı izlemek eğlenceli. : P
El'endia Starman

@ El'endiaStarman KamikazePlus'un mermi olmadan kendisiyle dövüşmesini izlemek eğlenceli overideHyperspace = 0;; Birbirlerine gitmeye çalıştıklarında sadece kaybolmaya devam ediyorlar.
noɥʇʎԀʎzɐɹƆ
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.