Altın Toplayıcı KoTH


48

Not: Topluluğun favorisi için anket yakında yayınlanacak

Bu KoTH'de amaç, yaşayan en son bot olmak. Madeni paralar rastgele bölgelere yerleştirilir ve botunuz önce paraları almalıdır. Bir bot başka bir botla karşılaşırsa, daha fazla jetonlu bot kazanır ve diğer bot ölür. Daha fazla detay aşağıda.

Para türleri

Altın ve gümüş olmak üzere 2 tür sikke olacaktır. Altın, botun gücüne 5 jeton, gümüş ise 2 ekler. Bir jeton toplandıktan sonra, tahtadaki başka bir noktaya başka bir jeton konur. Herhangi bir zamanda, arenada bir altın sikke ve dört gümüş sikke vardır.

Bot çarpışmaları

Aynı yerde kalmaya çalışan iki bot durumunda, daha fazla paraya sahip olan kalacak, daha azına sahip olan ... kalacak. Kazanan bot rakip paraların % 85'ini kazanacak (Yuvarlanmış). Bağlanırlarsa ikisi de ölür. Üç ya da daha fazla aynı alanı işgal etmeye çalışırsa, en güçlü olan kazanır ve diğer tüm botların paralarının% 85'ini alır. En güçlü botun bir kravat olması durumunda, tüm botlar uzaya girmeye çalışan ölür.

Arena

Arenanın yan uzunluğu ile hesaplanır 4 + botCount. Oyunun başında botlar yerleştirilirken rastgele yerler seçilir. Sistem aynı alanda veya yan yana hiçbir botun başlamamasını sağlar. Madeni paralar, her bir botta merkezlenmiş 3 x 3 kare hariç, rasgele üretilir. Arenanın dışında bir bot bulunursa, anında ölür. Arena sol üst köşede (0,0) veya Kuzeybatı'dan başlar ve bir botun konumu her zaman bir tamsayıdır.

Senin bot

Botunuz, dizileri, tam sayıları, dizeleri ve işlevleri olan herhangi bir nesne yönelimli dilde bir işlev olmalıdır. Tüm gönderilerin işleri kolaylaştırmak için Javascript'e dönüştürüleceğini unutmayın. Hareketler arasında bilgi depolamak için, botNotes.storeData(key, value)ve tuşlarını kullanın botNotes.getData(key, value). Ve parametrelerinde sağlananlar dışında hiçbir şekilde veri depolayamaz veya erişemezsiniz botNotes. Sen, çağrıldığında, bir dize döndüren bir işlev oluşturmalısınız north, east, south, west, veya none. İşlev için 3 argüman olacaktır:

  • Dört tamsayılar ile bir nesne ( locationX, locationY, coins, arenaLength), mevcut konumunuz, senin paralar, ve arena uzunluğu

  • Diğer botların X ve Y koordinatlarına sahip çok boyutlu bir dizi ve madeni para sayımı,[[0,5,4],[4,7,1],[7,4,12]]

  • Madeni para konumları listelenen bir dizi (Altın her zaman öncedir)

Bu tepe mücadelesinin kralı, Standart Loopholes yasaktır. Her seferinde bir "Hareket" izin verdiğinde işleviniz binlerce kez çalıştırılacak. Oyun 20.000 hamleyi aşarsa , en çok para kazandıran bot kazanır. Bu rastgele kaldırmak için 8.000 kez yapılacaktır.

Sohbet odası: https://chat.stackexchange.com/rooms/81347/gold-collectors-koth

Ödüller:

Birincilik: 100 puan ödül
Topluluk Favori: 15 puan kabul edilen cevap

Kazananlar:

Birincisi: TBTPTGCBCBA
İkincilik: Büyük Kral Küçük Tepesi
Üçüncülük: Potansiyel Olarak Muzaffer
Dördüncü Sıra: Kibar Yakın Görülen Sarhoş Bot
Beşinci Yer: Güvenlik Madeni Para


6
"Tüm gönderilerin işleri kolaylaştırmak için Javascript'e dönüştürüleceğini unutmayın." Bunun nasıl çalışması gerekiyor? Dönüşüm yapıyor musunuz?
Laikoni

21
Sadece tek bir dile izin veren, özellikle de JavaScript kadar yaygın olan bir koth ile ilgili yanlış bir şey yoktur. Belirsizce JavaScript'e (dönüştürerek) cevapları vermek yerine (muhtemelen kendiniz ve elinizle), mücadeleyi yalnızca JS ile sınırlandırmanız gerekir. Ne de olsa geçmişte bol miktarda Java ve yalnızca Python desteği vardı.
Skidsdev

2
Konum yerine ivmeyi kontrol ettiğiniz bir sürüm oldukça iyi olurdu.
akozi

12
Herkese: Çok fazla yorum zaten var. Örneğin "1, güzel bot" olarak yararsız bir yorum bırakmayın ve 's gereksiz eğer yorumlarınızı silin . Tipik bir soru-cevap sitesi değiliz ama kimse yüzlerce komut okumayı sevmiyor.
user202729

5
(Kendi soruma göre): Sohbetteki NP'ye göre, ikincisi: tüm botlar hareket eder, sonra tüm çatışmalar çözülür, sonra tüm para toplamaları meydana gelir, sonra tüm yeni paralar yerleştirilir.
BradC,

Yanıtlar:


26

BaitBot - JavaScript Node.JS

Asla yakalayamıyorsan niçin kovalamaktan ya da koşmaktan rahatsız ol? Bunun yerine, BaitBot en yakın madeni parayı bulur ve daha zayıf bir botun ona yaklaşmasını bekler. İkisi de bitişik olduklarında, baitBot zayıf botun da olacağını varsayarak paraya gider. Eğer baitBot bekliyorsa ve daha güçlü bir bot yaklaşıyorsa, parayı ve skedad'ları alır. Beni dene!

function baitBot(me, others, coins) {
  let directions = ['none','east','south','west','north']
  function distanceTo(a) {
    return (Math.abs(a[0] - me.locationX) + Math.abs(a[1] - me.locationY))
  }
  function distanceBetween(a, b){
    return (Math.abs(a[0] - b[0]) + Math.abs(a[1] - b[1]))
  }
  function adjacentDir(a) {
    //0 = no, 1,2,3,4 = ESWN
    if(distanceTo(a) == 1) {
      if(a[0] > me.locationX){ return 1}
      else if(a[0] < me.locationX) {return 3}
      else if(a[1] > me.locationY) {return 2}
      else{ return 4}
    }
    else {return 0}
  }
  function edibility(a) {
    return me.coins - a[2]
  }

  //Find nearest coin and get next to it
  let closestCoin = coins.sort((a,b) => distanceTo(a) - distanceTo(b))[0]
  if(distanceTo(closestCoin) > 1) {
    if(closestCoin[0] > me.locationX){ return 'east'}
    else if(closestCoin[0] < me.locationX){ return 'west'}
    else if(closestCoin[1] < me.locationY){ return 'north'}
    else if(closestCoin[1] > me.locationY){ return 'south'}
  }

  //If we're next to a coin and there's a threat close, just grab it
  let nearestThreat = others.filter(a => edibility(a) < 0).sort((a,b) => distanceBetween(a, closestCoin) - distanceBetween(b, closestCoin))[0]
  if(nearestThreat && distanceBetween(nearestThreat, closestCoin) <= 2) {
    return directions[adjacentDir(closestCoin)]
  }



  //Otherwise, wait until there's a target also next to the coin. If none are close, just take it
  let targets = others.filter(a => edibility(a) > 0 && distanceBetween(closestCoin, a) <= 3)
  targets.sort((a,b) => distanceBetween(a, closestCoin) - distanceBetween(b, closestCoin))
  if(targets.length > 0 && distanceBetween(targets[0], closestCoin) > 1){
    return directions[0]
  }
  return directions[adjacentDir(closestCoin)]

}

1
Ha, bu güzel bir fikir, hoşuma gitti.
Sundar

Bu yaklaşım oldukça hayır ... serin olduğu çok serin
Redwolf Programları

1
BaitBot nearestThreat && distanceTo(nearestThreat)sadece yerine ihtiyacı var distanceTo(nearestThreat). Hiçbir tehdit olmadığında başarısız olur.
Redwolf Programları

1
Evet, nearestThreatolan undefinedbütün diğer botlar seninkinden daha fazla puan varsa.
Gece 2

1
[10] Bot Bait Bot tired of this world, and jumped off its edgeOlay
günlüğümdeki

17

Potansiyel Olarak Muzaffer | JavaScript

Bu bot için tercih edilen renk #1600a6.

function (me, others, coins)
{
    let huntingTimer = botNotes.getData("huntingTimer");
    let huntedIndex = botNotes.getData("huntedIndex");
    if(!huntingTimer)
    huntingTimer = 0;
    else if(huntingTimer >0)
    huntingTimer--;
    else if(huntingTimer == -1)
    huntingTimer = Math.ceil(20*(1+Math.log2(me.coins/25)));
    else
    huntingTimer++;

    function distanceFromMe(X, Y) { return Math.abs(me.locationX - X) + Math.abs(me.locationY - Y); }

    function U(x, y)
    {
    function distance(X, Y) { return Math.abs(X-x) + Math.abs(Y-y); }
    function gravitation(k, X, Y) { return - k / ( distance(X, Y) + .2 ); }
    function exponential(k, q, X, Y) { return - 5*k * Math.exp(- q * distance(X,Y)); }

    // No going away from the arena.
    if(!((0 <= x) && (x < me.arenaLength) && (0 <= y) && (y < me.arenaLength)))
    {
        return Infinity;
    }

    let reachability = [1, 1, 1, 1, 1];
    let distances = coins.map(c => distanceFromMe(c[0], c[1]));
    for(let i = 0; i < others.length; i++)
    {
        for(let coin = 0; coin < 5; coin++)
            reachability[coin] += (Math.abs(others[i][0] - coins[coin][0]) + Math.abs(others[i][1] - coins[coin][1])) < distances[coin];
    }

    let potential = gravitation(40, coins[0][0], coins[0][1]) / (reachability[0]); // Gold

    // Silver
    for(let i = 1; i < 5; i++)
    {
        potential += gravitation(10, coins[i][0], coins[i][1]) / (reachability[i]);
    }

    others.sort((a, b) => b[2] - a[2]);

    // Other bots
    for(let i = 0; i < others.length; i++)
    {
        if(
            ((Math.abs(me.locationX - others[i][0]) + Math.abs(me.locationY - others[i][1])) < 3) &&
            (huntingTimer == 0) &&
            (me.coins > 25) && 
            (me.coins < (others[0][2]*.9)) &&
            (others[i][2] < me.coins-5) && (others[i][2] >= 10)
        )
        {
            huntingTimer = -10;
            huntedIndex = i;
        }

        if((huntingTimer < 0) && (huntedIndex == i))
           potential += exponential(30, 1, others[i][0], others[i][1]);

        if(others[i][2] >= me.coins)
        {
        // Otherwise, they could eat us, and we will avoid them.
        potential += exponential(-1400, 3, others[i][0], others[i][1]);
        }
    }

    return potential;
    }

    // All possible squares we can move to, with their names.
    let movements = [
    [ "north", U(me.locationX, me.locationY - 1)],
    [ "south", U(me.locationX, me.locationY + 1)],
    [ "east", U(me.locationX + 1, me.locationY)],
    [ "west", U(me.locationX - 1, me.locationY)],
    [ "none", U(me.locationX, me.locationY)]
    ];

    botNotes.storeData("huntingTimer", huntingTimer);
    botNotes.storeData("huntedIndex", huntedIndex);

    // Sort them according to the potential U and go wherever the potential is lowest.
    movements.sort((a, b) => a[1] - b[1]);
    return movements[0][0];
}

(Özensiz biçimlendirme için özür dilerim, bu sitenin 4 boşluk girintisi, sekmeleri kullanma alışkanlığımla iyi gitmiyor.)

Kaba açıklama

Formüllerin açıklamasını güncelleme girişiminde istifa ediyorum. Katsayılar sürekli değişiyor ve açıklamayı güncel tutmak biraz zor. Bu yüzden genel prensibi açıklayacağım.

Her jeton ve her bot bazı potansiyeli olan bir kuvvet alanı oluşturur. Sadece her şeyden potansiyelleri topladım ve bot daha sonra potansiyelin en düşük olduğu yere gidiyor. (Açıkçası bu fikir fizikten çalındı.)

İki çeşit potansiyel kullanıyorum. Birincisi, U = - k ile sözde yerçekimidir (herhangi bir aralıkta hareket eden). Kişareti bu seçimi ile, potansiyel çekici, alanın bir "kuvvet" olduğunu ve. Buradakir(ve başka her yer) taksik metrikteki uzaklıktır,r = | x₁ - x₂ | + | y₁ - y₂ | .

U=kr+1511+n.

Kullandığım = 40 k altın para ve için k = 10 gümüş para için. n , madeni paraya bizden daha yakın olan botların sayısıdır. Aksi takdirde, diğer botları kesinlikle görmezden geliyoruz (daha güçlü bir botun önüne geçersek kaçarız, ama o kadar). Altın paralara değerlerinden daha fazla değer veriyorum çünkü aksi halde öncelikle altından sonra giden botlar beni yendi.

İkinci potansiyel, üssel olarak çürüyen bir potansiyeldir (bu sadece çok küçük mesafelerde etkili bir şekilde hareket eder). Bu, özellikle daha güçlü botlar olmak üzere diğeri tarafından üretilir.

Bunlar olan bir alan üretir . Bu kuvvet 0-1 aralığında oldukça kuvvetlidir, ancak daha büyük mesafelerde neredeyse hiçbir şeye düşmez. (Mesafe + 1, kuvveti 1/20 olarak kesmek anlamına gelir.)

U=5×1400e3r.

Genel olarak diğer botlara kasten saldırmazız (elbette yolumuza girerlerse ve üzerlerine basarsak, bu onların suçu), ama bunu yapma olasılığı var. Bazı zor şartlar yerine getirilirse, tek bir bot üzerinde odaklanarak avcılık moduna girebiliriz . Avcılık moduna girmek için:

  1. En az 25 tane bozuk paramız olmalı. (Önce biraz para almamız gerekiyor.)
  2. En fazla (jetonumuz - 5) jetonu ve en az 10 jetonu olmalıdır. (Bir jeton kapan ve aniden daha güçlü olan birini avlamak istemiyoruz ve sıfır jetonlu botların peşinde olmak istemiyoruz.)
  3. Mevcut lider botun gerisinde kalmalı, sikkelerinin en az 1 / 10'u kadar. (Bir şeyi avladığınız için şanslı olmanız gerekir, bu yüzden sadece şansımızı denemek için iyi bir pozisyon vermenize gerek yoktur.)
  4. Bir avlanma süresinin üzerinde olmamalıyız (aşağıya bakınız).

Bütün bunlar tatmin edilirse, avlanma modu etkinleştirilir. Sonraki 10 turda, avlanan bot sadece potansiyelini yayar . Bu 10 tur geçtikten sonra, avlanma bekleme süresine gireriz; bu sırada tekrar avlanma moduna giremeyebiliriz. (Bu, diğer tüm paraları kaparken, bir botu sonsuz ve meyvesizce kovalamamızı engeller.) Avlanma süresi 25 jetonumuz olduğunda 20 turdur ve her iki katına çıkacak başına 20 jeton artar. (Başka bir deyişle, bekleme süresi

U=150er.
20(1 + log2(c / 25)).) (Son maçta, tüm toplanabilen botların büyük olasılıkla ölü olduklarından ve bu nedenle herhangi bir avın büyük olasılıkla boşuna olacağından kullanıyoruz. Bu nedenle, boşa harcanan zamanı sınırlamak istiyoruz. Oyun yeme her şeyi değiştirebilir, bu yüzden imkanı koruruz.)

Son olarak, tüm arena botun kaçmasını engelleyen sonsuz bir potansiyel kuyusuna yerleştirilir.


Sanırım bu bot benim de ağırlıklı hareketimi yeniyor.
08

@ fəˈnɛtɪk - Öyle mi: :). Bunun diğer botlarla başa çıkabileceğini düşünüyorum. (Ayrıca bitişik bir karede bulunan bir madeni para ile "kör" değildir.) Ama kesinlikle + 1 verdim çünkü bu fikrin büyük bir hayranıyım.
Ramillies

Buna en az eylem ilkesini uygular mısınız?
Beta Çürüğü

@ BetaDecay: Çok korkmuyorum, matematik, bunun gibi ayrık problemlere iyi cevap vermiyor. Sürekli durumda bile önemsiz olmayacaktır (sabit hız büyüklüğü nedeniyle), ancak bazı kutupsal koordinatlar büyüden sonra yapılabilir.
Ramillies,

4
Bu havalı. Riskin monoton bir şekilde mesafe ile ilişkili olduğundan emin değilim, sanırım 2 boşluk uzakta bir komşudan daha fazla ölüm tehlikesi var, çünkü ikinci durumda birinizin çarpışma için sabit kalması gerekiyor.
Cain

16

İlk Gen Öğrenme Algoritması | JavaScript (Node.js)

function run() {
	return ['north','east','south','west'][(Math.random()*4)|0];
}

Çevrimiçi deneyin!

Bir oyun oynamayı öğrenen öğrenme algoritmalarının zaman çizelgelerini hiç gördünüz mü? İlk birkaç nesilde sıklıkla rastgele hareket ederler ...


LOL ... Hala işe yarayabilir!
Redwolf Programları

2
Çoğu öğrenme algoritması, ilk birkaç tekrarlama için tam anlamıyla rastgele çalışır, sadece rastgele değil.
f Augnɛtɪk

Bil bakalım ne oldu? Bu bot ortalamada tur başına yaklaşık 0.22 jeton aldı!
Redwolf Programları

16

Büyük Kral Küçük Tepe | JavaScript

function BigKingLittleHill(me, enemies, coins) {

	
	// Is a move safe to execute?
	function isItSafe(x){
			let loc = [x[0] + me.locationX,x[1] + me.locationY];
			return loc[0] >= 0 && loc[0] < me.arenaLength
			&& loc[1] >= 0 && loc[1] < me.arenaLength
			&& enemies
					.filter(enemy => me.coins <= enemy[2])
					.filter(enemy => getDist(enemy,loc) == 1).length === 0;
	}

	
	// Dumb conversion of relative coord to direction string
	function coordToString(coord){
		if (coord[0] == 0 && coord[1] == 0) return 'none';
		if (Math.abs(coord[0]) > Math.abs(coord[1]))
			return coord[0] < 0 ? 'west' : 'east';
		return coord[1] < 0 ? 'north' : 'south';
	}
	
	
	// Calculate a square's zone of control
	function getZOC(x) {
		let n = 0;
		for(let i = 0; i < me.arenaLength;i++){
			for(let j = 0; j < me.arenaLength;j++){
				if (doesAControlB(x, [i,j])) n++;
			}
		}
		return n;
	}
	
	function doesAControlB(a, b) {
		return getEnemyDist(b) > getDist(a, b);
	}
  
	// Distance to nearest enemy
	function getEnemyDist(x) {
			return enemies.filter(enemy => enemy[2] >= me.coins/50).map(enemy => getWeightedDist(enemy, x)).reduce((accumulator, current) => Math.min(accumulator, current));
	}
  
	// Weights distance by whether enemy is weaker or stronger
	function getWeightedDist(enemy, pos) {
		return getDist(enemy, pos) + (enemy[2] < me.coins ? 1 : 0);
	}
  
	function getDist(a, b){
		return (Math.abs(a[0] - b[0]) + Math.abs(a[1] - b[1]))
	}
	
	//check whether there are coins in our Zone of Control, if yes move towards the closest one
	let loc = [me.locationX,me.locationY];
	let sortedCoins = coins.sort((a,b) => getDist(loc,a) - getDist(loc,b));
	for (let coin of sortedCoins) {
		if (doesAControlB(loc,coin)){
			return coordToString([coin[0] - loc[0],coin[1] - loc[1]]);
		}
	}
	
	//sort moves by how they increase our Zone of Control
	northZOC = [[0,-1], getZOC([loc[0],loc[1]-1])];
	southZOC = [[0,1], getZOC([loc[0],loc[1]+1])];
	westZOC = [[-1,0], getZOC([loc[0]-1,loc[1]])];
	eastZOC = [[1,0], getZOC([loc[0]+1,loc[1]])];
	noneZOC = [[0,0], getZOC([loc[0],loc[1]])];
	let moves = [northZOC,southZOC,westZOC,eastZOC,noneZOC].sort((a,b) => b[1] - a[1]);
	
	//check whether these moves are safe and make the highest priority safe move
	for (let move of moves) {
		if (isItSafe(move[0])) { 
			return coordToString(move[0]);
		}
	}
	//no moves are safe (uh oh!), return the highest priority
	return coordToString(moves[0][0])
}

Çevrimiçi deneyin!

Big King Little Hill “kontrol bölgelerine” dayanarak kararlar alıyor. Sadece kendi kontrol bölgesinde bulunan ve başka herhangi bir botun alabilmesi için madeni paraya erişebileceği madeni paraların peşinde koşacaktır. Kontrol bölgesinde bozuk para olmadığında, kontrol bölgesinin boyutunu maksimize etmek için hareket eder. Büyük Kral Küçük Tepe, olası 5 hareketinin her birinin kontrol bölgesini hesaplar ve kendi kontrol bölgesinin boyutunu maksimize eden hareketleri tercih eder. Bu şekilde, Büyük Kral Küçük Tepesi nihayetinde yerel bir maksimum (küçük tepeye) kontrole ulaşır ve kendi bölgesinde bir madeni para oluşmasını bekler. Ek olarak, Big King Little Hill, alternatif olmadıkça ölümüne neden olabilecek herhangi bir hareketi reddetti.

Büyük Kral Küçük Tepesi karamsardır (gerçekçiliğin ismini tercih eder) çünkü alması kesin olmayan herhangi bir madeni paraya itiraz etmek zahmetine girmez. Ayrıca, herhangi bir anlamda zayıf botlar peşinde koşmadığından pasifisttir (eğer bir şekilde karşılaşırlarsa birine basabilir). Son olarak, Büyük Kral Küçük Tepesi, mecbur olmadığı sürece, herhangi bir ödül için kendi hayatını tehlikeye atmayacak bir korkaktır.


1
PPCG'ye Hoşgeldiniz! Bu çok iyi bir bot = D
Luis felipe De jesus Munoz

Bu bir bot için düşündüğüm şeydi. Aferin.
Jo.

10

Emanet para | JavaScript

SafetyCoin=(myself,others,coins)=>{
  x=myself.locationX;
  y=myself.locationY;
  power=myself.coins;
  arenaSize=myself.arenaLength;
  dist=0;
  optimalCoin=7;
  optimalDist=11*arenaSize;
  for(i=0;i<coins.length;i++){
    enemyDist=3*arenaSize;
    dist=Math.abs(x-coins[i][0])+Math.abs(y-coins[i][1])
    for(j=0;j<others.length;j++){
      if(i==0){
        if(others[j][2]+5>=power){
          enemyDist=Math.min(enemyDist,Math.abs(others[j][0]-coins[i][0])+Math.abs(others[j][1]-coins[i][1]))
        }
      }
      else{
        if(others[j][2]+2>=power){
          enemyDist=Math.min(enemyDist,Math.abs(others[j][0]-coins[i][0])+Math.abs(others[j][1]-coins[i][1]))
        }
      }

    }
    if(enemyDist>dist){
      if(i==0){
        if(dist/5<optimalDist){
          optimalDist=dist/5;
          optimalCoin=i;
        }
      }
      else{
        if(dist/2<optimalDist){
          optimalDist=dist/2;
          optimalCoin=i;
        }
      }
    }
  }
  if(optimalCoin==7){
    safeDir=15;
    if(x==0){safeDir-=8;}
    if(x==arenaSize-1){safeDir-=2;}
    if(y==0){safeDir-=1;}
    if(y==arenaSize-1){safeDir-=4;}
    for(i=0;i<others.length;i++){
      if(others[i][2]>=power){
        if(Math.abs(x-others[i][0])+Math.abs(y-others[i][1])==2){
          if(x-others[i][0]>0){safeDir-=8;}
          if(x-others[i][0]<0){safeDir-=2;}
          if(y-others[i][1]>0){safeDir-=1;}
          if(y-others[i][1]<0){safeDir-=4;}
        }
      }
    }
    directions=["north","east","south","west"];
    if(safeDir!=0){
      tmp="";
      tmp+="0".repeat(Math.max(Math.sqrt(arenaSize)/2|0,y-(arenaSize/2|0)));
      tmp+="2".repeat(Math.max(Math.sqrt(arenaSize)/2|0,(arenaSize/2|0)-y));
      tmp+="1".repeat(Math.max(Math.sqrt(arenaSize)/2|0,(arenaSize/2|0)-x));
      tmp+="3".repeat(Math.max(Math.sqrt(arenaSize)/2|0,x-(arenaSize/2|0)));
      rnd=tmp[Math.random()*tmp.length|0];
      while(!(2**rnd&safeDir)){rnd=tmp[Math.random()*tmp.length|0];}
      return directions[rnd];
    }
    return "none";//the only safe move is not to play :P
  }
  distX=coins[optimalCoin][0]-x;
  distY=coins[optimalCoin][1]-y;
  if(Math.abs(distX)>Math.abs(distY)){
    if(distX>0){return "east";}
    else{return "west";}
  }
  else{
    if(distY>0){return "south";}
    else{return "north";}
  }
}

Bu bot, aynı anda veya başka bir bottan sonra ulaşamayacağından ötürü ölemediği ağırlıklı değerli bir madeni paraya (değer / mesafe) doğru yönelir. Bu özelliğe sahip geçerli bir jeton yoksa, botun rasgele güvenli bir yöne hareket ettiği yere oturur (güvenlik, bir bot kendine doğru hareket ederse, emniyet jetonunun çarpışmayacağı anlamına gelir. Bu, botun başka bir botla yer değiştirmesine izin verir. hemen yanında), arena merkezine doğru ağırlıklı.


1
Huh, bu aslında kazanabilir. Her ne kadar, çok sayıda bot var
Redwolf Programları

Bu yöntem daha fazla sorun yaşayacak, eşit olmayan bir şekilde daha yüksek veya eşit değere sahip düşman botları yerleştirilecektir.
08

1
Muhtemelen hepsi kendilerine en yakın madalyonun / altın madalyonun üzerinde bir çizgi yapacaktır.
Redwolf Programları,

Sadece başlangıçta biraz para kazanmayı başarırsa iyi olur.
08

Ve bu çoğunlukla şanstır, çünkü madeni paraların ürettiği yer rastgele belirlenir
Redwolf Programları

10

Oyunu Dikkatle Oynanan Bot Agresif Olabilir | JavaScript

Tercih edilen renk: #F24100

Not: Bu bot birincilik kazanmasına rağmen, sonunda "Feodal Asil" ile bir araya gelip onu daha fazla para kazanmak için yemekten kaynaklanıyor. Aksi halde bu bot 3'üncü olurdu. Bireysel olarak daha güçlü olan botlarla ilgileniyorsanız, Potansiyel Olarak Muzaffer ve Büyük Kral Küçük Tepeye gidin .

function (me, monsters, coins) {
    var i, monstersCount = monsters.length, phaseSize = Math.round((me.arenaLength - 4) / 4),
        center = (me.arenaLength - 1) / 2, centerSize = me.arenaLength / 4,
        centerMin = center - centerSize, centerMax = center + centerSize, centerMonsters = 0, centerMonstersAvg = null,
        end = 2e4, apocalypse = end - ((me.arenaLength * 2) + 20), mode = null;

    var getDistance = function (x1, y1, x2, y2) {
        return (Math.abs(x1 - x2) + Math.abs(y1 - y2)) + 1;
    };

    var isAtCenter = function (x, y) {
        return (x > centerMin && x < centerMax && y > centerMin && y < centerMax);
    };

    var round = botNotes.getData('round');
    if (round === null || !round) round = 0;
    round++;
    botNotes.storeData('round', round);

    var isApocalypse = (round >= apocalypse && round <= end);
    if (isApocalypse) {
        mode = botNotes.getData('mode');
        if (mode === null || !mode) mode = 1;
    }

    for (i = 0; i < monstersCount; i++) if (isAtCenter(monsters[i][0], monsters[i][1])) centerMonsters++;

    var lc = botNotes.getData('lc');
    if (lc === null || !lc) lc = [];
    if (lc.length >= 20) lc.shift();
    lc.push(centerMonsters);
    botNotes.storeData('lc', lc);

    if (lc.length >= 20) {
        centerMonstersAvg = 0;
        for (i = 0; i < lc.length; i++) centerMonstersAvg += lc[i];
        centerMonstersAvg = centerMonstersAvg / lc.length;
    }

    var getScore = function (x, y) {
        var score = 0, i, chaseFactor = 0.75, coinFactor = 1;

        if (monstersCount < phaseSize) {
            chaseFactor = 0;
            coinFactor = 0.25;
        } else if (monstersCount < phaseSize * 2) {
            chaseFactor = 0;
            coinFactor = 0.5;
        } else if (monstersCount < phaseSize * 3) {
            chaseFactor = 0.5;
            coinFactor = 0.75;
        }

        if (isApocalypse) {
            if (mode === 1) {
                var centerDistance = getDistance(x, y, center, center);
                if (centerDistance <= 3) {
                    mode = 2;
                } else {
                    score += 5000 / (centerDistance / 10);
                }
            }
            if (mode === 2) chaseFactor = 1000;
        }

        for (i = 0; i < monstersCount; i++) {
            var monsterCoins = monsters[i][2], monsterDistance = getDistance(x, y, monsters[i][0], monsters[i][1]);
            if (me.coins > monsterCoins && monsterDistance <= 3) {
                score += (Math.min(5, monsterCoins) * chaseFactor) / monsterDistance;
            } else if (me.coins <= monsterCoins && monsterDistance <= 3) {
                score -= (monsterDistance === 3 ? 50 : 10000);
            }
        }

        for (i = 0; i < coins.length; i++) {
            var coinDistance = getDistance(x, y, coins[i][0], coins[i][1]),
                coinDistanceCenter = getDistance(center, center, coins[i][0], coins[i][1]),
                coinValue = (i === 0 ? 250 : 100), coinCloserMonsters = 0;

            for (var j = 0; j < monstersCount; j++) {
                var coinMonsterDistance = getDistance(monsters[j][0], monsters[j][1], coins[i][0], coins[i][1]);
                monsterCoins = monsters[j][2];

                if (
                    (coinMonsterDistance < coinDistance && monsterCoins >= me.coins / 2) ||
                    (coinMonsterDistance <= coinDistance && monsterCoins >= me.coins)
                ) {
                    coinCloserMonsters++;
                }
            }

            var coinMonsterFactor = (100 - ((100 / monstersCount) * coinCloserMonsters)) / 100;
            if (coinMonsterFactor < 1) coinMonsterFactor *= coinFactor;
            if (coinMonsterFactor >= 1) coinMonsterFactor *= 15;
            score += ((coinValue * coinMonsterFactor) / coinDistance) + (centerMonstersAvg === null || centerMonstersAvg > 1.75 ? -1 * (50 / coinDistanceCenter) : 200 / coinDistanceCenter);
        }

        return score + Math.random();
    };

    var possibleMoves = [{x: 0, y: 0, c: 'none'}];
    if (me.locationX > 0) possibleMoves.push({x: -1, y: 0, c: 'west'});
    if (me.locationY > 0) possibleMoves.push({x: -0, y: -1, c: 'north'});
    if (me.locationX < me.arenaLength - 1) possibleMoves.push({x: 1, y: 0, c: 'east'});
    if (me.locationY < me.arenaLength - 1) possibleMoves.push({x: 0, y: 1, c: 'south'});

    var topCommand, topScore = null;
    for (i = 0; i < possibleMoves.length; i++) {
        var score = getScore(me.locationX + possibleMoves[i].x, me.locationY + possibleMoves[i].y);
        if (topScore === null || score > topScore) {
            topScore = score;
            topCommand = possibleMoves[i].c;
        }
    }

    if (isApocalypse) botNotes.storeData('mode', mode);

    return topCommand;
}

Bu bot (aka "TBTPTGCBCBA"), her olası hamle için bir puan oluşturarak mümkün olan en iyi kararı vermeye çalışır ve her bir tur için daha yüksek skorlu hamleyi seçer.

Puanlama sistemi, mücadelenin başlamasından bu yana gelişen birçok ayrıntıya sahiptir. Genel olarak şöyle tarif edilebilirler:

  • Madeni paralar olası bir harekete ne kadar yakınsa, o kadar fazla puan alır. Bir madalyonun başka olası yarışmacıları yoksa, skor daha da artar. Bir madalyonun başka olası yarışmacıları varsa, skor daha düşük olur.
  • Başka bir bot olası bir harekete yakınsa ve oyunun aşamasına bağlı olarak daha az bozuk para varsa, bu hamle için daha fazla puan anlamına gelebilir. Bu yüzden "TBTPTGCBCBA" nın her oyunda diğer botlardan birkaçını yemesi rahattır.
  • Başka bir bot, eşit veya daha fazla puanla muhtemel bir hamleye yakınsa, o hamle ölümden kaçınılması için yeterli negatif puan alır. Elbette tüm olası hareketlerin kötü olduğu ve ölümden kaçınamadığı bazı durumlar olabilir, ancak bu çok nadirdir.
  • Tahtanın ortasındaki bot sayısının son 20 tur boyunca izlenmesi için bir mekanizma var. Ortalama yeterince düşükse, ortadaki tüm paralara doğru hareket daha fazla puan alır ve ortalamanın yüksek olması durumunda ortadaki tüm paralara doğru daha düşük puan alırsınız. Bu mekanizma "Feodal Asil" ile çatışmaları önlemeye izin verir. "Feodal Asil" her zaman ortada olduğu için (kovalanmadıkça), ortadaki ortalama bot sayısı artar ve orta alanın dışında daha iyi bir seçenek varsa, "TBTPTGCBCBA" ortadan kaçınmayı anlar. Eğer "Feodal Asil" ölürse, ortalama düşer ve "TBTPTGCBCBA" ortayı kullanabileceğini anlar.
  • Oyunun evresine göre dinamik olarak değişen bazı faktörler vardır (hayatta kalan robotların sayısından tespit edilir), bu faktörler yukarıdakilerin her birindeki skorlamayı etkiler.
  • Bu botun özel bir yeteneği var. Zamanla "Feodal Asil" in bencilliğinden ve köylülerin ezilmesinden bıktı. Doğru anda, tatsız Feodalizm sistemine son verecek. Başarılı bir girişim sadece yoksul köylülere yardım etmekle kalmaz, aynı zamanda "Feodal Asil" den alınan madeni paralar nedeniyle daha yüksek bir kazanma şansı sağlar.

Bu çok daha fazla ... zeki diğerlerinden daha görünüyor
Redwolf Program


9

Anti-Kapitalist | JavaScript

Madeni paraların peşinden gitmeye teşviki yok, ancak aynı parayla en zengin iki bot arasında tam olarak kendisini bulmaya çalışır, umarız onu avlarlar ve sonunda aynı anda yakalarlar, öldüğünde iki kapitalisti alırlar. . Aktif olarak jeton almaya direnmez, bu yüzden daha sulu bir hedef haline gelebilir.

function antiCapitalist(me, capitalists, coins){

    function acquireTargets(capitalists){
        capitalists.sort((a, b) => a[2] < b[2]);
        let previousCapitalist;
        for(let i in capitalists){
            let capitalist = capitalists[i];

            if(capitalist[2] === 0){
                return false;
            }
            if(previousCapitalist && capitalist[2] === previousCapitalist[2]){
                return [previousCapitalist, capitalist];
            }

            previousCapitalist = capitalist;
        }

        return false;
    }

    function move(){
        const targets = acquireTargets(capitalists);
        if(!targets){
            return 'none';
        }

        const coordinates = [Math.floor((targets[0][0] + targets[1][0]) / 2), Math.floor((targets[0][1] + targets[1][1]) / 2)];
        if(me.locationX !== coordinates[0]){
            return me.locationX < coordinates[0] ? 'east' : 'west';
        }
        else if(me.locationX !== coordinates[1]){
            return me.locationY < coordinates[1] ? 'south' : 'north';
        }
        else {
            return 'none';
        }
    }

    return move();
}

9

GUT, JavaScript

function gut(me, others, coins) {
    // Prepare values for the calculation
    var x = me.locationX;
    var y = me.locationY;
    var cMe = me.coins+1;
    var arenaLen = me.arenaLength;

    var objects = [];

    // Add bots to objects
    for (var i = 0; i < others.length; i++) {
        objects.push([others[i][0],others[i][1],others[i][2]/cMe]);
    }

    // Add coins to objects
    for (var j = 0; j < coins.length; j++) {
        var coinVal = 0;

        if (j == 0) {
            // Gold has a higher coin value
            coinVal = -10;
        } else {
            // Silver has a lower coin value
            coinVal = -5;
        }

        objects.push([coins[j][0],coins[j][1],coinVal/cMe]);
    }

    // Perform the calculation
    // x acceleration
    var x_acceleration = 0;

    for (var k=0; k < objects.length; k++) {
        var kval = objects[k][2];
        var xval = objects[k][0];

        x_acceleration += 200*kval/cMe*(x-xval)*Math.exp(Math.pow(kval,2)-50*Math.pow(x-xval,2));
    }

    // y acceleration
    var y_acceleration = 0;

    for (var l=0; l < objects.length; l++) {
        var kval = objects[l][2];
        var yval = objects[l][1];

        y_acceleration += 200*kval/cMe*(y-yval)*Math.exp(Math.pow(kval,2)-50*Math.pow(y-yval,2));
    }

    // Compare the values
    if (Math.abs(y_acceleration)>Math.abs(x_acceleration)) {
        if (y_acceleration < 0) {
            // Don't fall off the edge
            if (y>0) {
                return "north";
            } else {
                return "none";
            }
        } else {
            if (y<arenaLen-1) {
                return "south";
            } else {
                return "none";
            }
        }
    } else if (Math.abs(y_acceleration)<Math.abs(x_acceleration)) {
        if (x_acceleration < 0) {
            if (x>0) {
                return "west";
            } else {
                return "none";
            }
        } else {
            if (x<arenaLen-1) {
                return "east";
            } else {
                return "none";
            }
        }
    } else {
        return "none";
    }
}

Potansiyel Olarak Muzaffer ile iki alanımız var: bot alanı ve jeton alanı. Ancak, doğa o kadar karmaşık değil. Büyük Birleşik Teoriyi üretmek için iki alanı birleştirme zamanı .

Öncelikle, alanın potansiyelinin ne olduğunu bulmamız gerekiyor. Kendi botumuzun alanı hiçbir şekilde etkilemediğini varsayarsak, şunu yazabiliriz:

V=nkn(ekn2100(xxn)2+ekn2100(yyn)2)

kn(xn,yn) her bir nesnenin koordinatları vardır.

Nesnenin göreceli özelliği şöyle hesaplanır:

k=cobjectcme

ccme=cself+1cself

Bu sadece Modifiye Betanian Dynamics'in (MOBD) bu düzeltme bölümünü diyelim .

Kinetik enerjiyi şu şekilde de bulabiliriz:

T=12cme(x˙2+y˙2)

Şimdi eylemi hesaplayabiliriz:

Action=ab(TV)dt=ab(12cme(x˙2+y˙2)nkn(ekn2100(xxn)2+ekn2100(yyn)2))dt

Ve böylece bot-jetonlu bot alanındaki Lagrangian:

L=12cme(x˙2+y˙2)nkn(ekn2100(xxn)2+ekn2100(yyn)2)

Şimdi Euler-Lagrange denklemlerini çözmemiz gerekiyor:

ddtLx˙=Lx

ve:

ddtLy˙=Ly

Yani:

ddtLx˙=ddt[cmex˙]=cmex¨

Lx=n200kn(xxn)ekn2100(xxn)2

x¨=n200kncme(xxn)ekn2100(xxn)2

Ve ayrıca:

ddtLy˙=ddt[cmey˙]=cmey¨

Ly=n200kn(yyn)ekn2100(yyn)2

y¨=n200kncme(yyn)ekn2100(yyn)2

Şimdi daha ileri gitmemize gerek yok: Sadece genel ivmenin yönüne bakıyoruz:

output={northif y¨<0 and |y¨|>|x¨|southif y¨>0 and |y¨|>|x¨|westif x¨<0 and |x¨|>|y¨|eastif x¨>0 and |x¨|>|y¨|noneif |y¨|=|x¨|

Ve aynen böyle, paraları ve botları birleştirdik. Nobel Ödülüm nerede?


5
Nobel Ödülün postayla kayboldu ama onun yerine Emmy Ödülü verebiliriz
Redwolf Programları

1
Görünüşe göre fizik bu mücadelede popüler olmaya başlıyor. :-D. Ve tabii ki ne kadar iyi olacağını merak ediyorum.
Ramillies

1
(Bu arada, Euler-Lagrange denklemleriyle olan güçlüğü kurtarabilirdiniz, çünkü F = c_me a = - grad U:
Ramillies,

@Ramillies Meh, bu şekilde yapmak daha eğlenceliydi: D
Beta Decay,

1
K = jetonunu kullanmak istediğinize emin misiniz? Madeni paralarla başlamıyorsunuz ... ve her yerde NaN ile, kazanamayacaksınız.
Ramillies,

8

Goldilocks, JavaScript (Node.js)

function goldilocks(me, others, coins) {
  let target = coins[0]; // Gold
  let x = target[0] - me.locationX;
  let y = target[1] - me.locationY;

  mymove = 'none'
  if (Math.abs(x) <= Math.abs(y) && x != 0)
    mymove = x < 0 ? 'west' : 'east'
  else if (y != 0)
    mymove = y < 0 ? 'north' : 'south'

  return mymove
}

Çevrimiçi deneyin!

Sadece altın sikkenin yerine kilitlenir ve her seferinde ona doğru hareket eder. (Bu kullanılan orijinal kod için @ Mayube’un 'B33-L1N3' botu sayesinde, neredeyse hiçbiri kalmadı.)


Bu oldukça hoş, basit bir bot. Bunu sevdim.
Redwolf Programları

2
Bu arada, bu botu kontrol
cihazım

8

Üçüncü Gen Öğrenme Algoritması | JavaScript (Node.js)

function run(me) {
	options = [];
	if (me.locationX > 0) options.push('west');
	if (me.locationY > 0) options.push('north');
	if (me.locationX < me.arenaLength) options.push('east');
	if (me.locationY < me.arenaLength) options.push('south');

	return options[Math.floor(Math.random() * options.length)];
}

Çevrimiçi deneyin!

Birkaç nesilden sonra, bu bot arenayı terk etmenin kötü olduğunu öğrendi


Oh iyi. Buna "Doğal Seleksiyon"
dendiğini

5
İkinci gen nerede
Luis Felipe De Jesus Munoz

11
@LuisfelipeDejesusMunoz Arenadan ayrıldı.
Jo.

Bu denetleyicide hata ayıklamak için iyi bir bot
Redwolf Programları

3
Oh, bu arada, arena 0'dan başlıyor, öyle olmalı arenaLength - 1. Bu, botunuzu birkaç defa adil bir şekilde öldürdü
Redwolf Programları

7

B33-L1N3 | JavaScript (Node.js)

function(me, others, coins) {
	// Do nothing if there aren't any coins
	if (coins.length == 0) return 'none';
	// Sort by distance using Pythagoras' Theorem
	coins = coins.sort((a, b) => (a[0] ** 2 + a[1] ** 2) - (b[0] ** 2 + b[1] ** 2));
	// Closest coin
	let target = coins[0];
	let x = target[0];
	let y = target[1];

	// Util function for movement
	function move(pos, type) {
		let moveTypes = { X: ['east', 'west'], Y: ['south', 'north'] };
		if (pos > me['location'+type]) return moveTypes[type][0];
		else return moveTypes[type][1];
	}

	// Move the shortest distance first
	if (x < y && x != me.locationX) return move(x, 'X');
	else if (y != me.locationY) return move(y, 'Y');
}

Çevrimiçi deneyin!

Yapar En yakın para için beeline


Oh, B33-L1N3'ün bir çeşit model numarası olduğunu düşünmüştüm
Redwolf Programları

İsim için +1
Cain

let coins = ...Uncaught SyntaxError: Identifier 'coins' has already been declared
Gece2


5

Sınırda Yaşamak, JavaScript

function LivinOnTheEdge (myself, others, coins) {
  x = myself.locationX;
  y = myself.locationY;
  xymax = myself.arenaLength - 1;
  if (x < xymax && y == 0) {
      return 'east';
    } else if (y < xymax && x == xymax) {
      return 'south';
    } else if (x > 0 && y == xymax) {
      return 'west';
  } else {
    return 'north';
  }
}

Bu arenada kenarının olması tehlikeli bir yer olduğunu duydu. Hiçbir korku bilmeden, yorulmadan tahtayı saat yönünde çevirir, sadece sınırın arkasında bekleyen kesin ölümden birkaç santim uzaktadır, başka hiçbir botun sınırın çevresine bu kadar yakın hareket etmeye cesaret edemez.


1
1 jetonu olan bir bot daha yaratıldıysa ve sınırı ters yöne yönlendirdiyseniz, bu iyi
olmazdı

8
Sınır kontrolü şakası yapardım, ama bunu @BetaDecay
Redwolf Programlarına

5

Damacy, JavaScript (Node.js)

function damacy(me, others, coin) {
  let xdist = t => Math.abs(t[0] - me.locationX)
  let ydist = t => Math.abs(t[1] - me.locationY)
  function distanceCompare(a, b, aWt, bWt) {
    aWt = aWt || 1
    bWt = bWt || 1
    return (xdist(a) + ydist(a)) / aWt - (xdist(b) + ydist(b)) / bWt
  }
  function hasThreat(loc) {
    let threat = others.filter(b => b[0] == loc[0] && b[1] == loc[1] && b[2] >= me.coins)
    return (threat.length > 0)
  }
  function inArena(loc) {  // probably unnecessary for this bot
    return loc[0] >= 0 && loc[1] >= 0 && loc[0] < me.arenaLength && loc[1] < me.arenaLength
  }
  function sortedCoins() {
    coinsWithValues = coin.map((coords, i) => coords.concat((i == 0) ? 5 : 2))
    coinsWithValues.sort((a, b) => distanceCompare(a, b, a[2], b[2]))
    return coinsWithValues.map(c => c.slice(0, 2))
  }
  othersPrev = botNotes.getData('kata_others_pos')
  botNotes.storeData('kata_others_pos', others)
  if (othersPrev) {

    for(let i = 0; i < others.length; i++) {
      let bot = others[i]

      let matchingBots = othersPrev.filter(function (b) {
        let diff = Math.abs(b[0] - bot[0]) + Math.abs(b[1] - bot[1])
        if (diff >= 2)
          return false // bot can't have jumped
        return [0, 2, 5].includes(bot[2] - b[2])
      })

      if (matchingBots.length > 0) {
        let botPrev = matchingBots.shift()
        // remove matched bot so it doesn't get matched again later
        othersPrev = othersPrev.filter(b => b[0] != botPrev[0] || b[1] != botPrev[1])
        bot[0] = Math.min(Math.max(bot[0] + bot[0] - botPrev[0], 0), me.arenaLength-1)
        bot[1] = Math.min(Math.max(bot[1] + bot[1] - botPrev[1], 0), me.arenaLength-1)
      }
    }
  }

  let eatables = others.filter(b => b[2] < me.coins && b[2] > 0)
  let targets
  if (eatables.length > 0) {
    targets = eatables.sort(distanceCompare)
  }
  else {
    targets = sortedCoins()
  }

  let done, newLoc, dir
  while (!done && targets.length > 0) {
    t = targets.shift()
    if ((xdist(t) <= ydist(t) || ydist(t) == 0) && xdist(t) != 0) {
      let xmove = Math.sign(t[0] - me.locationX)
      dir = xmove < 0 ? 'west' : 'east'
      newLoc = [me.locationX + xmove, me.locationY]
      if (!hasThreat(newLoc) && inArena(newLoc))
        done = 1
    }

    if (!done) {
      let ymove = Math.sign(t[1] - me.locationY)
      dir = ['north', 'none', 'south'][ymove + 1]
      newLoc = [me.locationX, me.locationY + ymove]
      if (!hasThreat(newLoc) && inArena(newLoc))
        done = 1
    }
  }

  if (!done)
    dir = 'none'


  return dir
}

Çevrimiçi deneyin!

Bugün için son bir katamari tabanlı bot, bu sefer biraz hafıza ile. @BetaDecay sayesinde ad önerisi için - kesinlikle benden daha eğlenceli bir ad simplePredictorKatamari.

Botların son sıralarda nasıl hareket ettiklerini anlamaya çalışır ve buna göre, bu dönüşün sonunda nereye hareket etmeye çalışacaklarını tahmin eder (aynı yönde hareket etmeye devam ettiklerini varsayarsak).

(@ Fəˈnɛtɪk sayesinde, botNotes uygulamasında yanlış işlev adını çağırdığımı fark ettiğiniz için ve temel kodda bir hata olduğunu fark ettiğim için @ OM @ öğesine teşekkür ederiz.)


Bu muhtemelen şu anda başkalarını sadece şanslı olmanın dışında yakalayabilen tek kişi.
Cain

Botnot'ların settata değil "storedata" olması gerekmiyor mu?
f Augnɛtɪk

@ fəˈnɛtɪk Bakın, zaten bir hataya ihtiyacı var! :) Teşekkürler, şimdi düzeltildi.
Sundar

aWt = 1Paramlarda yerini almalı aWtve aWt = aWt || 1altına koymalısınız (Aynı ile bWt). Bu hataları önler.
Redwolf Programları

5

Proton | JavaScript

Proton=(myself,others,coins)=>{
  x=myself.locationX;
  y=myself.locationY;
  power=myself.coins;
  arenaSize=myself.arenaLength;
  forceX=0;
  forceY=0;
  prevState=botNotes.getData("proton_velocity");
  if(prevState){
    velocity=prevState[0];
    direction=prevState[1];
  }
  else{
    velocity=0;
    direction=0;
  }
  for(i=0;i<coins.length;i++){
    if(Math.abs(x-coins[i][0])+Math.abs(y-coins[i][1])==1){
      velocity=0;
      direction=0;
      botNotes.storeData("proton_velocity",[velocity,direction]);
      if(x-coins[i][0]==1){return "west";}
      if(coins[i][0]-x==1){return "east";}
      if(y-coins[i][1]==1){return "north";}
      if(coins[i][1]-y==1){return "south";}
    }
    else{
      dist=Math.sqrt(Math.pow(x-coins[i][0],2)+Math.pow(y-coins[i][1],2));
      if(i==0){
        forceX+=(x-coins[i][0])*5/Math.pow(dist,3);
        forceY+=(y-coins[i][1])*5/Math.pow(dist,3);
      }
      else{
        forceX+=(x-coins[i][0])*2/Math.pow(dist,3);
        forceY+=(y-coins[i][1])*2/Math.pow(dist,3);
      }
    }
  }
  for(i=0;i<others.length;i++){
    if(Math.abs(x-others[i][0])+Math.abs(y-others[i][1])==1&&power>others[i][2]){
      velocity=0;
      direction=0;
      botNotes.storeData("proton_velocity",[velocity,direction]);
      if(x-others[i][0]==1){return "west";}
      if(others[i][0]-x==1){return "east";}
      if(y-others[i][1]==1){return "north";}
      if(others[i][1]-y==1){return "south";}
    }
    else{
      dist=Math.sqrt(Math.pow(x-others[i][0],2)+Math.pow(y-others[i][1],2));
      forceX+=(x-others[i][0])*others[i][2]/Math.pow(dist,3);
      forceY+=(y-others[i][1])*others[i][2]/Math.pow(dist,3);
    }
  }
  vX=velocity*Math.cos(direction)+10*forceX/Math.max(1,power);
  vY=velocity*Math.sin(direction)+10*forceY/Math.max(1,power);
  velocity=Math.sqrt(vX*vX+vY*vY);
  if(velocity==0){return "none"}
  retval="none";
  if(Math.abs(vX)>Math.abs(vY)){
    if(vX>0){
      if(x<arenaSize-1){retval="east";}
      else{vX=-vX;retval="west";}
    }
    else{
      if(x>0){retval="west";}
      else{vX=-vX;retval="east";}
    }
  }
  else{
    if(vY>0){
      if(y<arenaSize-1){retval="south";}
      else{vY=-vY;retval="north";}
    }
    else{
      if(y>0){retval="north";}
      else{vY=-vY;retval="south";}
    }
  }
  direction=Math.atan2(-vY,vX);
  botNotes.storeData("proton_velocity",[velocity,direction]);
  return retval;
}

Tüm madeni paralar (diğer botlar tarafından tutulanlar dahil) Protonbot'a itici bir güç yayar. Bu kuvvete dayanarak, hız kurar ve duvarlardan zıplar (bir sınıra çarptıktan hemen sonra döner). Eğer tüketebileceği bir botun veya madalyonun yanında biterse, Güçlü nükleer kuvvet devralır ve tüketmek için hareket eder, öyle olunca tüm hızları düşürür.


Hazine avcılığına uygulanan nükleer fizik mi? Bu, her gün Bilim Kanalı'nı yener!
Redwolf Programları,

Sen değiştirmeniz gerekiyor sinile Math.sin, cosbirlikte Math.cos, vb
Redwolf Programları

4

Kör Değil | JavaScript (Node.js)

Önemli Not: Bu yaklaşım tamamen benim değildir ve benzer bir soruya cevaplanmıştır. . Bu cevabı da oyladığınızdan emin olun.

Hiç A * yol bulma algoritmasını duydunuz mu? işte burada. Bir noktadan daha az değerli madeni paraya kadar en iyi yolu yaratır (herkes en değerli olanı, hiç kimse daha azına gitmez) ve başka bir kullanıcıyla çarpışmamaya çalışır.

Parametreleri aşağıdaki gibi bekler:

AI({locationX: 3, locationY: 1, arenaLength: [5,5]}, [[2,1],[2,2], ...],[[1,2],[3,1], ...])

Belki başka botlara avcılık yapan birini yaparım.


function AI(me, others, coins){
    var h = (a,b) => Math.abs(a[0] -b[0]) + Math.abs(a[1] -b[1])
    var s = JSON.stringify;
    var p = JSON.parse;
    var walls = others.slice(0,2).map(s);
    var start = [me.locationX, me.locationY];
    var goal = coins.pop();
    var is_closed = {};
    is_closed[s(start)] = 0;
    var open = [s(start)];
    var came_from = {};
    var gs = {};
    gs[s(start)] = 0;
    var fs = {};
    fs[s(start)] = h(start, goal);
    var cur;
    while (open.length) {
        var best;
        var bestf = Infinity;
        for (var i = 0; i < open.length; ++i) {
            if (fs[open[i]] < bestf) {
                bestf = fs[open[i]];
                best = i;
            }
        }
        cur = p(open.splice(best, 1)[0]);
        is_closed[s(cur)] = 1;
        if (s(cur) == s(goal)) break;
        for (var d of [[0, 1], [0, -1], [1, 0], [-1, 0]]) {
            var next = [cur[0] + d[0], cur[1] + d[1]];
            if (next[0] < 0 || next[0] >= me.arenaLength[0] ||
                next[1] < 0 || next[1] >= me.arenaLength[1]) {
                continue;
            }
            if (is_closed[s(next)]) continue;
            if (open.indexOf(s(next)) == -1) open.push(s(next));
            var is_wall = walls.indexOf(s(next)) > -1;
            var g = gs[s(cur)] + 1 + 10000 * is_wall;
            if (gs[s(next)] != undefined && g > gs[s(next)]) continue;
            came_from[s(next)] = cur;
            gs[s(next)] = g;
            fs[s(next)] = g + h(next, goal);
        }
    }
    var path = [cur];
    while (came_from[s(cur)] != undefined) {
        cur = came_from[s(cur)];
        path.push(cur);
    }
    var c = path[path.length - 1];
    var n = path[path.length - 2];
    if(n){
        if (n[0] < c[0]) {
            return "west";
        } else if (n[0] > c[0]) {
            return "east";
        } else if (n[1] < c[1]) {
            return "north";
        } else {
            return "south";
        }
    }else{
        return "none";
    }
}

1
Vay ... zaten bir yol bulma algoritması? Sadece 3 saat oldu!
Redwolf Programları,

@RedwolfPrograms Dediğim gibi, başka bir benzer meydan okumadan kopyalanır. Sadece buna adapte olmak gerekiyordu.
Luis felipe De jesus Munoz

Algoritmalarim, hangi sikkelerin gideceği en güvenli olanı seçiyor.
08

4

Korkak | Python 2

import random

def move(me, others, coins):
    target = (me.locationX, me.locationY)

    # Identify the dangerous opponents.
    threats = [i for i, value in enumerate(others[2]) if value >= me.coins]

    # If no one scary is nearby, find a nearby coin.
    safe = True
    for x, y in self.coins:
        distance = abs(me.locationX - x) + abs(me.locationY - y)
        safe = True
        for i in threats:
            if abs(others[0][i] - x) + abs(others[1][i] - y) <= distance:
                safe = False
                break

        if safe:
            target = (x, y)
            break

    # Otherwise, just try not to die.
    if not safe:
        certain = []
        possible = []
        for x, y in [
            (me.locationX, me.locationY),
            (me.locationX + 1, me.locationY),
            (me.locationX - 1, me.locationY),
            (me.locationX, me.locationY + 1),
            (me.locationX, me.locationY - 1),
        ]:
            # Don't jump off the board.
            if x < 0 or y < 0 or x == me.arenaLength or y == me.arenaLength:
                continue

            # Check if we can get away safely.
            for i in threats:
                if abs(others[0][i] - x) + abs(others[1][i] - y) <= 1:
                    break
            else:
                certain.append((x, y))

            # Check if we can take a spot someone is leaving.
            for i in threats:
                if others[0][i] = x and others[1][i] == y:
                    for i in threats:
                        if abs(others[0][i] - x) + abs(others[1][i] - y) == 1:
                            break
                    else:
                        possible.append((x, y))

        if certain:
            target = random.choice(certain)
        elif possible:
            target = random.choice(possible)
        # Otherwise, we're doomed, so stay still and pray.

    directions = []
    x, y = target
    if x < me.locationX:
        directions.append('west')
    if x > me.locationX:
        directions.append('east')
    if y < me.locationY:
        directions.append('north')
    if y > me.locationY:
        directions.append('south')
    if not directions:
        directions.append('none')

    return random.choice(directions)

Mümkünse daha fazla paraya sahip botlardan kaçının. Aksi takdirde, etrafta yatan parayı al.


Bu kazanma şansına sahip en temel bot
Redwolf Programlar

4

Vahşi Kaz Chase Bot, Javascript

Diğer botlardan kaçmak için gerçekten iyi, ancak para almakta çok kötü bir bot.


Algoritma:

  1. Bitişik bot yoksa, hiçbiri döndür
  2. Aksi takdirde:
    1. Hiçbirini rastgele bir şansla 1/500 şansla geri döndürün (bu, çıkmazları önlemeye yöneliktir).
    2. Hangi alanlara taşınmanın güvenli olduğunu belirleyin (yani arenada ve başka bir bot tarafından işgal edilmemiş)
    3. Birini rastgele döndür

Kod:

function wildGooseChase(me, others, coins){
    x = me.locationX;
    y = me.locationY;

    dirs = {};
    dirs[(x+1)+" "+y] = "east";
    dirs[(x-1)+" "+y] = "west";
    dirs[x+" "+(y+1)] = "south";
    dirs[x+" "+(y-1)] = "north";

    mov = {};
    mov["east"] = [x+1,y];
    mov["west"] = [x-1,y];
    mov["north"] = [x,y-1];
    mov["south"] = [x,y+1]; 

    possibleDirs = ["east","west","north","south"];

    for (i = 0; i < others.length; i++){
        if (others[i][0]+" "+others[i][1] in dirs){
            possibleDirs.splice(possibleDirs.indexOf(dirs[others[i][0]+" "+others[i][1]]),1);
        }
    }

    if (possibleDirs.length == 4 || Math.floor(Math.random() * 500) == 0){
        return "none"
    }

    for (i = 0; i < possibleDirs.length; i++){
        if (mov[possibleDirs[i]][0] == me.arenaLength || mov[possibleDirs[i]][0] < 0 
        || mov[possibleDirs[i]][1] == me.arenaLength || mov[possibleDirs[i]][1] < 0){
            var index = possibleDirs.indexOf(possibleDirs[i]);
            if (index != -1) {
                possibleDirs.splice(index, 1);
                i--;
            }
        }
    }

    if (possibleDirs.length == 0){
         return "none";
    }

    return possibleDirs[Math.floor(Math.random() * possibleDirs.length)];
}

Çevrimiçi Deneyin!

Redwolf Programlarına Not:

Bu botun çok uzun mermilere neden olma potansiyeli var. Çürükleri önlemek için bazı özgürlükler aldım, ancak gerçekten etkili olup olmadıklarını sınamadım. Bu bot test sırasında sorun çıkarsa, lütfen diskalifiye etmekten çekinmeyin.


Not için teşekkürler. Uzman bir
kaçakçı

Bunu severim. Av robotları için yem gibi bir şey
Beta Çürüğü

4

KatamariWithValues, JavaScript (Node.js) ,

function katamariWithValues(me, others, coin) {
  let xdist = t => Math.abs(t[0] - me.locationX)
  let ydist = t => Math.abs(t[1] - me.locationY)
  function distanceCompare(a, b, aWt = 1, bWt = 1) {
    return (xdist(a) + ydist(a)) / aWt - (xdist(b) + ydist(b)) / bWt
  }
  function hasThreat(loc) {
    let threat = others.filter(b => b[0] == loc[0] && b[1] == loc[1] && b[2] >= me.coins)
    return (threat.length > 0)
  }
  function inArena(loc) {  // probably unnecessary for this bot
    return loc[0] >= 0 && loc[1] >= 0 && loc[0] < me.arenaLength && loc[1] < me.arenaLength
  }
  function sortedCoins() {
    coinsWithValues = coin.map((coords, i) => coords.concat((i == 0) ? 5 : 2))
    coinsWithValues.sort((a, b) => distanceCompare(a, b, a[2], b[2]))
    return coinsWithValues.map(c => c.slice(0, 2))
  }

  let eatables = others.filter(b => b[2] < me.coins && b[2] > 0)
  let targets
  if (eatables.length > 0) {
    targets = eatables.sort(distanceCompare)
  }
  else {
    targets = sortedCoins()
  }

  let done, newLoc, dir
  while (!done && targets.length > 0) {
    t = targets.shift()
    if ((xdist(t) <= ydist(t) || ydist(t) == 0) && xdist(t) != 0) {
      let xmove = Math.sign(t[0] - me.locationX)
      dir = xmove < 0 ? 'west' : 'east'
      newLoc = [me.locationX + xmove, me.locationY]
      if (!hasThreat(newLoc) && inArena(newLoc))
        done = 1
    }

    if (!done) {
      let ymove = Math.sign(t[1] - me.locationY)
      dir = ['north', 'none', 'south'][ymove + 1]
      newLoc = [me.locationX, me.locationY + ymove]
      if (!hasThreat(newLoc) && inArena(newLoc))
        done = 1
    }
  }

  if (!done)
    dir = 'none'

  return dir
}

Çevrimiçi deneyin!

(Bunun temel kodundaki bir hatayı işaret ettiği için @ OMᗺ'ya teşekkürler.)

Kendinden daha az para ile botları "yiyerek" büyümeye çalışır. Bu mümkün değilse (böyle bir bot bulunmuyorsa), en yakın bozuk parayı arar.

Bu versiyonun küçük tweaksları (a) 'nın altın sikkelere göre gümüş sikkelere göre daha fazla tercih edilmesini sağlar - daha uzak bir altın madeni para aramanın botun ömrüne malolarak bitmesi veya aptalın altının peşinden koşmasına neden olma riski (b) 0 jeton - peşinde koşmaya gerek yok.


Bir akıllı avcı ... iyi, o da iyi!
Redwolf Programları,

@RedwolfPrograms Öyle umalım! :)
sundar

Bu Damacy adını vermeliydim;)
Beta Decay

1
@ BetaDecay İstek verildi.
Sundar

4

Kibar yakın görüşlü sarhoş bot | JavaScript

function politeNearSightedDrunkBot(me, others, coins) {
  let directions = ['none','east','south','west','north']
  let drunkennessCoefficient = .2
  let nearSightedness = me.arenaLength - others.length + 2
  //drawCircle(me.locationX, me.locationY, nearSightedness*squareSize)

  function randomInt(a) {
    return Math.floor(Math.random() * a);
  }
  function getRandomDirection() {
    return ['east', 'west', 'north', 'south'][randomInt(4)]
  }

  function distanceTo(a) {
    return (Math.abs(a[0] - me.locationX) + Math.abs(a[1] - me.locationY))
  }
  function distanceBetween(a, b){
    return (Math.abs(a[0] - b[0]) + Math.abs(a[1] - b[1]))
  }
  function isTargetSafe(a) {
    for (let i = 0; i < others.length; i++) {
      if (others[i][2] >= me.coins && distanceBetween(a, others[i]) <= distanceTo(a)) {
        return false //unnecessary loop, but I don't want to split out into a function
      }
    }
    return true
  }
  function amISafe() {
    for (let i = 0; i < others.length; i++) {
      if (others[i][2] >= me.coins && distanceTo(others[i]) == 1) {
        /*let num = botNotes.getData('turnsSpentAdjacentToEnemy')
        if (!num) {
          console.log('politeNearSightedDrunkBot: Woops!')
          botNotes.storeData('turnsSpentAdjacentToEnemy', 1)
        } else if (num == 1) {
          console.log('politeNearSightedDrunkBot: \'Scuse me...')
          botNotes.storeData('turnsSpentAdjacentToEnemy', 2)
        } else if (num == 2) {
          console.log('politeNearSightedDrunkBot: D\'ye mind?')
          botNotes.storeData('turnsSpentAdjacentToEnemy', 3)
        } else if (num == 3) {
          console.log('politeNearSightedDrunkBot: Bugger off!')
        }*/
        return false
      }
    }
    return true
  }
  function getSafeDirections() {
    let candidates = {'none': true, 'east': true, 'south': true, 'west': true, 'north': true}
    if (me.locationY == 0) {
      candidates['north'] = false
    } else if (me.locationY == me.arenaLength - 1) {
      candidates['south'] = false
    }
    if (me.locationX == 0) {
      candidates['west'] = false
    } else if (me.locationX == me.arenaLength - 1) {
      candidates['east'] = false
    }
    if (!amISafe()) {
      candidates['none'] = false
    }/* else {
      botNotes.storeData('turnsSpentAdjacentToEnemy', 0)
    }*/
    if (candidates['north'] && !isTargetSafe([me.locationX, me.locationY-1])) {
      candidates['north'] = false
    }
    if (candidates['south'] && !isTargetSafe([me.locationX, me.locationY+1])) {
      candidates['south'] = false
    }
    if (candidates['west'] && !isTargetSafe([me.locationX-1, me.locationY])) {
      candidates['west'] = false
    }
    if (candidates['east'] && !isTargetSafe([me.locationX+1, me.locationY])) {
      candidates['east'] = false
    }
    if (candidates['none']) {
    }
    return candidates
  }
  function getSafeCoins() {
    let safestCoins = []
    let coinSizes = [5, 2, 2, 2, 2]
    for (let i = 0; i < coins.length; i++) {
      let distanceToThisCoin = distanceTo(coins[i])
      if (distanceToThisCoin < nearSightedness && isTargetSafe(coins[i])) {
        safestCoins.push([coins[i][0], coins[i][1], coinSizes[i], distanceToThisCoin])
        //alert('Coin at (' + coins[i][0] + ', ' + coins[i][1] + ') is safe!')
      }
    }
    if (safestCoins.length == 0) {
      //alert('No safe coins!')
    }
    return safestCoins
  }

  function getAdditiveBestDirectionToTargets(targets) {
    let candidates = {'east': 0, 'south': 0, 'west': 0, 'north': 0}
    for (let i = 0; i < targets.length; i++) {
      if (targets[i][0] < me.locationX) { 
        candidates['west'] = candidates['west'] + targets[i][2]/targets[i][3]
      } else if (targets[i][0] > me.locationX) {
        candidates['east'] = candidates['east'] + targets[i][2]/targets[i][3]
      }
      if (targets[i][1] > me.locationY) { 
        candidates['south'] = candidates['south'] + targets[i][2]/targets[i][3]
      } else if (targets[i][1] < me.locationY) {
        candidates['north'] = candidates['north'] + targets[i][2]/targets[i][3]
      }
    }
    for (let key in candidates) {
      //alert(key + ': ' + candidates[key])
    }
    return candidates
  }

    let targetCoins = getSafeCoins()
    let safeDirections = getSafeDirections()
    let chosenDir = null
    if (targetCoins.length > 0) {
      //alert('Coins found! Exactly ' + targetCoins.length)
      let weightedDirections = getAdditiveBestDirectionToTargets(targetCoins)
      let bestOptionWeight = 0
      let choices = []
      for (let key in safeDirections) {
        if (safeDirections[key] && key != 'none') {
          if (weightedDirections[key] == bestOptionWeight) {
            choices.push(key)
          } else if (weightedDirections[key] > bestOptionWeight) {
            choices = [key]
            bestOptionWeight = weightedDirections[key]
          }
        }
      }
      if (choices.length > 0) {
        //alert('Picking from choices, ' + choices.length + ' options and best weight is ' + bestOptionWeight)
        chosenDir = choices[randomInt(choices.length)]
      } else {
        //alert('No safe choices!')
      }
    } else {
      let lastDir = botNotes.getData('direction') || 'none'
      if (safeDirections[lastDir] && Math.random() >= drunkennessCoefficient) {
        chosenDir = lastDir
      }
    }

    if (!chosenDir) {
      //alert('indecisive!')
      let choices = []
      for (key in safeDirections) {
        if (safeDirections[key]) {
          choices.push(key)
        }
      }
      if (choices.length > 0) {
        chosenDir = choices[randomInt(choices.length)]
      } else {
        chosenDir = getRandomDirection()
      }
    }

    botNotes.storeData('direction', chosenDir)
    //alert('Moving ' + chosenDir)
    return chosenDir
}

Yakındaki paraları almak için etrafta dolaşıyor, ancak rastgele her seferinde yönleri değiştiriyor. Kimseye çarpmaktan kaçınmak için elinden geleni yapar, ama ağırlaştığında ... kavga eder. Rekabet devam ettikçe ayılma eğilimindedir.

Bazı hata ayıklama gerekebilir, denetleyici tamamen tamamlandığında üzerinde çalışacağım.


3
Hmm, çıtayı yükseltir, sonra ona sarhoş olur
Redwolf Programları

4

Ağırlıklı Hareket | JavaScript

WeightedMotion=(myself,others,coins)=>{
  x=myself.locationX;
  y=myself.locationY;
  power=myself.coins;
  arenaSize=myself.arenaLength;
  dirX=0;
  dirY=0;
  for(i=0;i<coins.length;i++){
    if(i==0){
      dirX+=5/(x-coins[i][0]);
      dirY+=5/(y-coins[i][1]);
    }
    else{
      dirX+=2/(x-coins[i][0]);
      dirY+=2/(y-coins[i][1]);
    }
  }
  for(i=0; i<others.length;i++){
    dirX+=(power-others[i][2])/(2*(x-others[i][0]));
    dirY+=(power-others[i][2])/(2*(y-others[i][1]));
  }
  if(Math.abs(dirX)>Math.abs(dirY)){
    if(dirX>0){
      if(x>0){return "west";}
      else{
        if(dirY>0){if(y>0)return "north";}
        else if(dirY<0){if(y<arenaSize-1)return "south";}
      }
    }
    else if(x<arenaSize-1){return "east";}
    else{
      if(dirY>0){if(y>0)return "north";}
      else if(dirY<0){if(y<arenaSize-1)return "south";}
    }
  }
  else{
    if(dirY>0){
      if(y>0){return "north";}
      else{
        if(dirX>0){if(x>0)return "west";}
        else if(dirX<0){if(x<arenaSize-1)return "east";}
      }
    }
    else if(y<arenaSize-1){return "south";}
    else{
      if(dirX>0){if(x>0)return "west";}
      else if(dirX<0){if(x<arenaSize-1){return "east";}
    }
  }
  return "none";
}

Tahtanın kenarından kaçmaktan kaçınırken, en yüksek değeri atadığı yönde hareket eder.

Değer şu şekilde hesaplanır:

  • Para = madalyonun gücü / paraya olan uzaklık
  • Bot = Botların gücündeki fark / 2 * bot ile mesafe

1
Bu oldukça harika bir bot gibi görünüyor. Bot çalışan ustaydı eğer gerçek bir kayıp olacağından, yön kontrol etmeyi unutmayın uzakta sikke (den:
Redwolf Programları

Eh, hala. İyi olmalıyım değil mi?
Redwolf Programları,

Tamam, yayınla! Şu anda büyük miktarlarda bulunan daha küçük ve daha hızlı botları telafi edecek.
Redwolf Programları,

for(i=0;i<6;i++){toplamda 5 altın, 1 altın ve 4 gümüş bulunmaktadır.
Döngünüz 0'dan

3

Blindy | JavaScript (Node.js)

Bu kesinlikle kazanmayacak ama en azından katıl. İlk önce KoH mücadelesinde deneyin. Paraları sıralar ve en yakınına gider. Oyuncu aramıyor, o yüzden başka biri ile çarpışması umrunda değil.

function(myself, others, coins){
    mx = myself.locationX
    my = myself.locationY
    l="west"
    r="east"
    u="north"
    d="south"
    n="none"

    if(coins.length == 0)
        return n

    var closestCoin = coins.sort(a=>Math.sqrt(Math.pow(mx-a[0],2) + Math.pow(my-a[1],2))).pop()
    cx = closestCoin[0]
    cy = closestCoin[1]

    return mx>cx?l:mx<cx?r:my>cy?u:my<cy?d:n
}

Hmm, işe yarayabilir, çünkü diğer botlar öncelikle altını arayacak, potansiyel olarak gümüşü kavga etmeden almaya bırakacaklar
Redwolf Programları

3

Feodal Asil | JavaScript

Tercih edilen renk: #268299

function (noble, peasants, coins) {
    var center = (noble.arenaLength - 1) / 2, centerSize = noble.arenaLength / 4, peasantsCount = peasants.length,
        centerMin = center - centerSize, centerMax = center + centerSize, apocalypse = 2e4 - ((noble.arenaLength * 2) + 20), inDanger = false;

    var round = botNotes.getData('round');
    if (round === null || !round) round = 0;
    round++;
    botNotes.storeData('round', round);

    var getDistance = function (x1, y1, x2, y2) {
        return (Math.abs(x1 - x2) + Math.abs(y1 - y2)) + 1;
    };

    var isAtCenter = function (x, y) {
        return (x > centerMin && x < centerMax && y > centerMin && y < centerMax);
    };

    var getScore = function (x, y) {
        var score = 0, i, centerFactor = 10;

        for (i = 0; i < peasantsCount; i++) {
            var peasantCoins = peasants[i][2], peasantDistance = getDistance(x, y, peasants[i][0], peasants[i][1]);

            if (noble.coins > peasantCoins && isAtCenter(x, y)) {
                score += Math.min(100, peasantCoins) / peasantDistance;
            } else if (noble.coins <= peasantCoins && peasantDistance <= 3) {
                score -= (peasantDistance === 3 ? 50 : 2000);
                inDanger = true;
            }
        }

        for (i = 0; i < coins.length; i++) {
            if (isAtCenter(coins[i][0], coins[i][1])) {
                var coinDistance = getDistance(x, y, coins[i][0], coins[i][1]),
                    coinValue = (i === 0 ? 500 : 200),
                    coinCloserPeasants = 1;

                for (var j = 0; j < peasantsCount; j++) {
                    var coinPeasantDistance = getDistance(peasants[j][0], peasants[j][1], coins[i][0], coins[i][1]);
                    if (coinPeasantDistance <= coinDistance && peasants[j][2] >= noble.coins) coinCloserPeasants++;
                }

                score += (coinValue / coinCloserPeasants) / (coinDistance / 3);
            }
        }

        if (round >= apocalypse) centerFactor = 1000;
        score -= getDistance(x, y, center, center) * centerFactor;

        return score;
    };

    var possibleMoves = [{x: 0, y: 0, c: 'none'}];
    if (noble.locationX > 0) possibleMoves.push({x: -1, y: 0, c: 'west'});
    if (noble.locationY > 0) possibleMoves.push({x: -0, y: -1, c: 'north'});
    if (noble.locationX < noble.arenaLength - 1) possibleMoves.push({x: 1, y: 0, c: 'east'});
    if (noble.locationY < noble.arenaLength - 1) possibleMoves.push({x: 0, y: 1, c: 'south'});

    var topCommand, topScore = null;
    for (var i = 0; i < possibleMoves.length; i++) {
        var score = getScore(noble.locationX + possibleMoves[i].x, noble.locationY + possibleMoves[i].y);
        if (topScore === null || score > topScore) {
            topScore = score;
            topCommand = possibleMoves[i].c;
        }
    }

    if (round >= apocalypse) {
        var dg = botNotes.getData('dg');
        if (dg === null || !dg) dg = [];
        if (dg.length >= 20) dg.shift();
        dg.push(inDanger);
        botNotes.storeData('dg', dg);
        if (dg.length >= 20) {
            var itsTime = true;
            for (i = 0; i < dg.length; i++) if (!dg[i]) itsTime = false;
            if (itsTime) return 'none';
        }
    }

    return topCommand;
}

Bu feodal asil, tarlanın merkezinde kalır ve kendi sarayı olarak kabul eder. Merkezdeki her şeyi kendisi için toplar, ancak uzaktaki çiftliklerdeki her şey ona köylüler tarafından getirilmelidir. Elbette, öfkeli bir köylü sarayda görünürse, soylu, hayatını kurtarmak için kaçabilir, ama en kısa sürede güvende olur!

Zaman geçtikçe köylüler daha da güçleniyor. Profesyonel savaşçılar ve güçlü kahramanlar köylülükten yükselmeye başlar. Soyluların gücü bozulmaya devam ediyor. Servetini ve Feodalizm sistemini olabildiğince bir arada tutmaya çalışıyor. Ama nihayet, inancını kabul etmesi, insanların artık Feodalizm istemediklerini kabul etmesi gerekiyor. Bugün feodal asillerin her şeyden vazgeçtiği, güçlü köylülerden kaçmadığı ve biri tarafından öldürülmediği gün.


2

Kuantum Gnat Bot | JavaScript

function quantumGnatBot(me, others, coins) {
  let quantumCoefficient = .2
  let turn = botNotes.getData('turn')
  botNotes.storeData('turn', turn+1)
  botNotes.storeData('test', [2, 5, 7])
  botNotes.getData('test')
  let dG = {'none': [0, 0, -2, -2], 'east': [1, 0, me.arenaLength-1, -2], 'south': [0, 1, -2, me.arenaLength-1], 'west': [-1, 0, 0, -2], 'north': [0, -1, -2, 0]}

  function randomInt(a) {
    return Math.floor(Math.random() * a);
  }
  function getRandomDirection() {
    return ['east', 'west', 'north', 'south'][randomInt(4)]
  }
  function distanceBetween(a, b){
    return (Math.abs(a[0] - b[0]) + Math.abs(a[1] - b[1]))
  }
  function isTargetSafe(a) {
    for (let i = 0; i < others.length; i++) {
      if (others[i][2] >= me.coins && distanceBetween(a, others[i]) <= 1) {
        return false
      }
    }
    return true
  }
  function isEnemySquare(a) {
    for (let i = 0; i < others.length; i++) {
      if (distanceBetween(a, others[i]) == 0) {
        return true
      }
    }
    return false
  }
  function getSafeDirections() {
    let candidates = {'none': true, 'east': true, 'south': true, 'west': true, 'north': true}
    for (let key in dG) {
      if (me.locationX == dG[key][2] || me.locationY == dG[key][3] || !isTargetSafe([me.locationX+dG[key][0], me.locationY+dG[key][1]])) {
        candidates[key] = false
      }
    }
    //alert('Safe: ' + candidates['north'] + ', ' + candidates['east'] + ', ' + candidates['south'] + ', ' + candidates['west'])
    return candidates
  }
  function getThreatDirections() {
    let candidates = {'none': false, 'east': false, 'south': false, 'west': false, 'north': false}
    for (let key in dG) {
      if (isEnemySquare([me.locationX+dG[key][0], me.locationY+dG[key][1]])) {
        candidates[key] = true
      }
    }
    return candidates
  }
  function getTargetDirections() {
    let targetBot = null
    let candidates = {'none': false, 'east': false, 'south': false, 'west': false, 'north': false}
    for (let i = 0; i < others.length; i++) {
      if (distanceBetween([me.locationX, me.locationY], others[i]) > 2 && (!targetBot || targetBot[2] < others[i][2])) {
        targetBot = others[i]
      }
    }
    if (targetBot[0] < me.locationX) {
      candidates['west'] = true
    } else if (targetBot[0] > me.locationX) {
      candidates['east'] = true
    }
    if (targetBot[1] > me.locationY) {
      candidates['south'] = true
    } else if (targetBot[1] < me.locationY) {
      candidates['north'] = true
    } 
    //alert('Chasing ' + targetBot[0] + ', ' + targetBot[1] + ' (' + targetBot[2] + ')')
    //alert('Path: ' + candidates['north'] + ', ' + candidates['east'] + ', ' + candidates['south'] + ', ' + candidates['west'])
    return candidates
  }

  let safeDirections = getSafeDirections()
  let threatDirections = getThreatDirections()
  let targetDirections = getTargetDirections()
  let chosenDir = null
  let choices = []
  for (key in safeDirections) {
    if (safeDirections[key] && targetDirections[key]) {
      choices.push(key)
    }
  }
  if (choices.length == 0) {
    //alert('Best options are blocked...')
    for (key in safeDirections) {
      if (safeDirections[key]) {
        choices.push(key)
      }
    }
  }
  for (key in threatDirections) {
    if (threatDirections[key] && Math.random() < quantumCoefficient) {
      //alert('Chance for quantum swap!')
      choices.push(key)
    }
  }
  if (choices.length > 0) {
    chosenDir = choices[randomInt(choices.length)]
  } else {
    //alert('No options? Guess we spin the wheel.')
    chosenDir = getRandomDirection()
  }

  return chosenDir
}

Bu sinir bozucu bot, en güçlü botun etrafında dolanmadan dolaşmaya çalışıyor ve onu avlamaya çalışanlar arasında aşama aşama şansı var. En güçlü iki botu birbirine yaklaştırmaya meyillidir ...;)


Uygun bir hedef bulamazsa getTargetDirections(), ilginç şeyler olmaya başlar. ( undefined has no property 0Hata nedeniyle her şeyi parçalamak gibi .)
Ramillies

2

Emekli ICE Ajansı, JavaScript

Tercih edilen renk: indianred

function(me, others, coins) {
    me.arenaLength = me.arenaLength - 1;
    // Calculate the average coin value of bots
    var avg = 2;

    for (var i = 0; i < others.length; i++) {
    avg += others[i][2];
    }

    avg /= others.length;

    // Find nearest coins
    var min = [];
    var min_distance = 100000
    for (var j = 0; j < coins.length; j++) {
    var distance = Math.sqrt(Math.pow(me.locationX - coins[j][0],2) + Math.pow(me.locationY - coins[j][1],2));
    if (distance < min_distance) {
        min_distance = distance;
        min = coins[j];
    }
    }

    if (me.coins <= avg || min_distance < 5) {
    // If own coinage is lower than the average or a coin is very close, find some coins

    // Move straight to the nearest coin
    if (me.locationY != min[1]) {
        if (me.locationY - min[1] > 0) {
        return "north";
        } else {
        return "south";
        }
    } else {
        if (me.locationX - min[0] > 0) {
        return "west";
        } else {
        return "east";
        }
    }
    } else {
        // You have enough money to eat most bots
        // Find the weakest bot
        var weakling = [];
        var weakling_money = 1000000;

        for (var k = 0; k < others.length; k++) {
            if (others[k][2] < weakling_money) {
                weakling_money = others[k][2];
                weakling = others[k];
            }
        }

        // Move to the weakest bot
        if (me.locationY != weakling[1]) {
            if (me.locationY - weakling[1] > 0) {
                return "north";
            } else {
                return "south";
            }
        } else {
            if (me.locationX - weakling[0] > 0) {
                return "west";
            } else {
                return "east";
            }
        }
    }
}

Şimdi emekli, bu ICE ajanı insanlık konusunda acı. Sonuç olarak, Emekli ICE en düşük botu hedeflerken, jeton değerini ortalamanın üzerinde tutarken (ICE politikasına göre).


2

Açgözlü-Pursuit | Haskell

Tercih edilen renk: #62bda4

import Data.List

f x y c _ bs _
  | [bx,by,_]:_ <- sortByDist x y $ filter ((c>).last) bs = toDir (bx-x,by-y)
f x y _ _ _ cs
  | [cx,cy,_]:_ <- sortByDist x y cs = toDir (cx-x,cy-y)
f _ _ _ _ _ _ = "none"


sortByDist x y = sortOn (\[bx,by,_]-> abs (bx-x) + abs (by-y))

toDir (dx,dy)
  | dx > 0 = "east"
  | dx < 0 = "west"
  | dy > 0 = "south"
  | dy < 0 = "north"
  | otherwise = "none"

Çevrimiçi deneyin! *

Oldukça basit bir strateji, ilk kararı alır:

  • daha az bozuk para olan botlar varsa: en yakını seç ve ona doğru hareket et
  • madeni para varsa: en yakını seç ve ona doğru hareket et
  • varsayılan: kal

Bot, diğer botları veya madeni paraları yakalamaya çalışabilecek potansiyel olarak daha güçlü botlara bakmadan yakalamaya çalışır.

* JavaScript'i gerçekten bilmiyorum ama google'da olan şeyi yaptım (yanlış olabilir): Çevrimiçi deneyin!


6
Haskell'i nasıl js'ye çevireceğini merak ediyorum
Luis felipe De jesus Munoz

3
@ LouisfelipeDejesusMunoz: Evet ben de. Ama neyse ki, çok karmaşık bir kod değil.
ბიმო

@ LouisfelipeDejesusMunoz Sadece ayrıştırma ile Node.JS ve process.open(veya child_process.spawnveya benzerlerini) kullanın.
user202729

@LuisfelipeDejesusMunoz: Çevirmeye çalıştım ve bir link ekledim, fakat JavaScript yazarken kendimi güvende hissetmiyorum, bu yüzden buggy olabilir.
48'te

4
@LuisfelipeDejesusMunoz Eğer bu 10.000 hat AI öğrenme programı olsaydı bir şey olurdu, ama bunu yönetebileceğimi düşünüyorum (:
Redwolf Programları

1

Para Mıknatısı | JavaScript

CoinMagnet=(myself,others,coins)=>{
  x=myself.locationX;
  y=myself.locationY;
  power=myself.coins;
  arenaSize=myself.arenaLength;
  dirX=0;
  dirY=0;
  for(i=0;i<coins.length;i++){
    if(i==0){
      dirX+=(coins[i][0]-x)*3
      dirY+=(coins[i][1]-y)*3
    }
    dirX+=(coins[i][0]-x)*2
    dirY+=(coins[i][1]-y)*2
  }
  for(i=0;i<others.length;i++){
    dirX+=Math.ceil(0.85*others[i][2])*(others[i][0]-x)
    dirX+=Math.ceil(0.85*others[i][2])*(others[i][1]-y)
  }
  if(Math.abs(dirX)>Math.abs(dirY)){
    if(dirX>0){return "east";}
    else{return "west";}
  }
  else if(dirY!=0){
    if(dirY>0){return "south";}
    else{return "north";}
  }
  return "none";
}

Bu bot oldukça aptal, en çok kazanılan paralar yönünde gidiyor. Bu, diğer botların kendisinden daha yüksek güce sahip olması nedeniyle alamayacağınız paraları içerir.


1

BUZ Ajan | JavaScript

function(me, others, coins) {
    me.arenaLength = me.arenaLength - 1;
    // Calculate the average coin value of bots
    var avg = 2;

    for (var i = 0; i < others.length; i++) {
        avg += others[i][2];
    }

    avg /= others.length;

    // Find nearest coins
    var min = [];
    var min_distance = 100000
    for (var j = 0; j < coins.length; j++) {
        var distance = Math.sqrt(Math.pow(me.locationX - coins[j][0],2) + Math.pow(me.locationY - coins[j][1],2));
        if (distance < min_distance) {
            min_distance = distance;
            min = coins[j];
        }
    }

    if (me.coins <= avg || min_distance < 5) {
        // If own coinage is lower than the average or a coin is very close, find some coins

        // Move straight to the nearest coin
        if (me.locationY != min[1]) {
            if (me.locationY - min[1] > 0) {
                return "north";
            } else {
                return "south";
            }
        } else {
            if (me.locationX - min[0] > 0) {
                return "west";
            } else {
                return "east";
            }
        }
    } else {
        // You have enough money to eat most bots
        // Check if already on border
        if (me.locationX == 0 || me.locationX == me.arenaLength || me.locationY == 0 || me.locationY == me.arenaLength) {
            // Move anticlockwise around the border
            if (me.locationX == 0 && me.locationY != 0 && me.locationY != me.arenaLength) {
                return "south";
            }
            if (me.locationX == 0 && me.locationY == 0) {
                return "south";
            }

            if (me.locationY == me.arenaLength && me.locationX != 0 && me.locationX != me.arenaLength) {
                return "east";
            }
            if (me.locationX == 0 && me.locationY == me.arenaLength) {
                return "east";
            }

            if (me.locationX == me.arenaLength && me.locationY != 0 && me.locationY != me.arenaLength) {
                return "north";
            }
            if (me.locationX == me.arenaLength && me.locationY == me.arenaLength) {
                return "north";
            }

            if (me.locationY == 0 && me.locationX != 0 && me.locationX != me.arenaLength) {
                return "west";
            }
            if (me.locationX == me.arenaLength && me.locationY == 0) {
                return "west";
            }
        } else {
            // Find the nearest border and move to it
            if (me.locationX <= me.arenaLength - me.locationX) {
                // Move to left border
                return "west";
            } else {
                // Move to right border
                return "east";
            }
        }
    }
}

Devriye gezilmiyorsa sınırın amacı ne? ICE sınırın etrafında saat yönünün tersine hareket ederek yoluna sapan botları toplar.

Bunu yapmadan önce, önce diğer botları yiyebilmesi gerekiyor. Bu nedenle ICE, sikkelerini tüm botların ortalamasının üzerinde tutar.

Çocukları ebeveynlerinden çalma garantisi ™


Bu kadar alakalı olmasaydı daha komik olurdu
Don Thousand

1

X Noktayı İşaretler | JavaScript

function(me, others, coins){
    if (me.locationY != 0) {
        // If not on X axis
        if (others.every(other => other[1]==me.locationY-1)) {
            // If any in my way
            if (!others.every(other => other[0]==me.locationX-1)) {
                if (me.locationX != 0) {
                    // If no one to my left and not on edge of board
                    return "west"
                } else {
                    return "none"
                }
            } else if (!others.some(other => other[0]==me.locationX+1)) {
                if (me.locationX != me.arenaLength-1) {
                    // If no one to my right and not on edge of board
                    return "east"
                } else {
                    return "none"
                }
            } else {
                // I'm surrounded
                return "none"
            }
        } else {
            // No one in my way
            return "north"
        }
    } else {
        // If on the x axis
        if (!others.some(other => Math.abs(other[0]-me.locationX)==1 && other[1] == me.locationY)) {
            // If no one next to me
            move = ["east","west"][Math.floor(Math.random()*2)]

            // Prevent from falling off the board
            if (move == "east" && me.locationX == me.arenaLength-1) {
                return "west"
            } else if (move == "west" && me.locationX == 0) {
                return "east"
            } else {
                return move
            }
        } else {
            // I'm surrounded
            return "none"
        }
    }
}

X noktayı işaretler, bu yüzden tüm altın x ekseninde olmalı, değil mi? Botum y = 0 çizgisi için bir çizgi çiziyor, sonra orada kalıyor, rastgele hareket ediyor.


Huh, gerçekten ilginç bir yöntem
Redwolf Programları


1
Olduğu göz önüne alındığında The arena starts at (0,0) in the upper left corner, size taşımak istediğiniz emin misiniz southalmak için y=0?
AdmBorkBork,

@AdmBorkBork Teşekkürler, bu kötü olabilirdi
Beta Decay

1

Firebird

    function(me,others,coins) {
        var x = me.locationX;
        var y = me.locationY;
        var safe = [true, true, true, true];
        var threats = [];
        var targets = [];
        var opps = [];

        var meTo = (loc) => (Math.abs(x - loc[0]) + Math.abs(y - loc[1]));
        var inSquare = (loc, r) => (Math.abs(loc[0] - x) <= r && Math.abs(loc[1] - y) <= r);
        var distance = (from, loc) => (Math.abs(from[0] - loc[0]) + Math.abs(from[1] - loc[1]));
        var attackRange = (from, check, r) => {
            for (var i = 0; i < check.length; i++) {
                if (distance(check[i], from) == (r || 1)) {
                    return true;
                }
            }
            return false;
        };
        var dirStr = (dir) => (['north','east','south','west'][dir]);

        var i, n, o, p;
        for (i = 0; i < others.length; i++) {
            o = others[i];
            if (o[2] >= me.coins) {
                threats.push(o);
            } else {
                targets.push([o[0], o[1], Math.floor(o[2] * 0.55)]);
            }
        }
        for (i = 1; i < 5; i++) {
            targets.push([coins[i][0], coins[i][1], 2]);
        }
        targets.push([coins[0][0], coins[0][1], 5]);
        if (y === 0 || attackRange([x, y - 1], threats)) {
            safe[0] = false;
        }
        if (x == me.arenaLength - 1 || attackRange([x + 1, y], threats)) {
            safe[1] = false;
        }
        if (y == me.arenaLength - 1 || attackRange([x, y + 1], threats)) {
            safe[2] = false;
        }
        if (x === 0 || attackRange([x - 1, y], threats)) {
            safe[3] = false;
        }
        if (safe.includes(false)) {
            if (!(safe[0]) && safe[2]) {
               opps.push(2);
            }
            if (!(safe[1]) && safe[3]) {
                opps.push(3);
            }
            if (!(safe[2]) && safe[0]) {
                opps.push(0);
            }
            if (!(safe[3]) && safe[1]) {
                opps.push(1);
            }
        } else {
            targets.sort((a,b)=>(meTo(a) - meTo(b)));
            o = targets[0];
            if (o[0] == x) {
                if (o[1] < y) {
                    return 'north';
                } else {
                    return 'south';
                }
            } else if (o[1] == y) {
                if (o[0] < x) {
                    return 'west';
                } else {
                    return 'east';
                }
            } else if (Math.abs(o[0] - x) < Math.abs(o[1] - y)) {
                if (o[1] < y) {
                    return 'north';
                } else {
                    return 'south';
                }
            } else if (Math.abs(o[0] - x) > Math.abs(o[1] - y)) {
                if (o[0] < x) {
                    return 'west';
                } else {
                    return 'east';
                }
            }
        }
        console.log(safe[opps[0]]);
        var lx, ly;
        for (i = 0; i < opps.length; i++) {
            if (opps[i] === 0) {
                lx = x;
                ly = y - 1;
            }
            if (opps[i] == 1) {
                lx = x + 1;
                ly = y;
            }
            if (opps[i] == 2) {
                lx = x;
                ly = y + 1;
            }
            if (opps[i] == 3) {
                lx = x - 1;
                ly = y;
            }
            if (attackRange([lx, ly], targets, 0)) {
                return dirStr(opps[i]);
            }
        }
        return dirStr(opps[0]);
    }

Daha önce olduğundan daha ölümcül olmak için tamamen yenilendi:


2
Bir botun mutlak kaybeden
Redwolf Programları

Onları hedef almıyor, onlardan kaçıyor
Redwolf Programları

Üzgünüm, yanlış anladım
Beta Çürüğü 22

1

A-Yolu-y | JavaScript

Bu bot için tercih edilen renk #0077b3.

 run: function (me, others, coins)
{
    var X_INDEX = 0;
    var Y_INDEX = 1;
    var COIN_INDEX = 2;

    var GOLD_POINTS = 5;
    var SILVER_POINTS = 2;

    var NORTH = 0;
    var SOUTH = 1;
    var WEST = 2;
    var EAST = 3;
    var IDLE = 4;
    var MOVE_COMMANDS_COUNT = IDLE+1;

    var MAP_TYPE_BLANK = 0;
    var MAP_TYPE_BOT = 1;
    var MAP_TYPE_GOLD_COIN = 2;
    var MAP_TYPE_SILVER_COIN = 3;

    var MIDGAME_THRESHOLD = 25;

    var PATH_FINDING_MAX_STEPS = 10000;
    var offsets = [[0,-1],[1,0],[0,1],[-1,0]];

function randInt(min,max)
    {
        return  Math.floor(Math.random() * ((max - min) + 1)) + min;
    }


    /**
     * Find a path using a*, returns the direction to take from the starting position coupled with a metric describing the cost of the path
     */
function pathFind(startX,startY,targetX,targetY,map,mapSize)
    {
        var i;
        var j;

        // shuffleIndecies to make path selection slightly random
        var indecies = [0,1,2,3];
        var shuffleIndecies = new Array(4);
        for (j=0;j<4;j++)
        {
            var randomIndex = randInt(0,3-j);
            shuffleIndecies[j] = indecies[randomIndex];
            indecies[randomIndex] = indecies[0];
            var lastElementIndex = 4-j-1;
            indecies[0] = indecies[lastElementIndex];
        }

        // A*
        if (!(startX===targetX && startY===targetY))
        {

            var tileX = new Array(PATH_FINDING_MAX_STEPS);
            var tileY = new Array(PATH_FINDING_MAX_STEPS);
             var fscore = new Array(PATH_FINDING_MAX_STEPS);
             var gscore = new Array(PATH_FINDING_MAX_STEPS);
             var openList = new Array(PATH_FINDING_MAX_STEPS);
             var tileParent = new Array(PATH_FINDING_MAX_STEPS);
             var tileIsClosed = new Array(mapSize);

             for (i = 0;i<PATH_FINDING_MAX_STEPS;i++)
             {
                 tileX[i]=0;
                 tileY[i]=0;
                 fscore[i]=0;
                 gscore[i]=0;
                 openList[i]=0;
                 tileParent[i]=0;
             }


             for (i = 0;i<mapSize;i++)
             {
                 var newArray = new Array(mapSize);
                 tileIsClosed[i] = newArray;
                 for (j = 0;j<mapSize;j++)
                 {
                     tileIsClosed[i][j] = 0;
                 }
             }

             var currentIndex = -1;     

            var openListSize=1;
            var tileId=1;

            tileX[0]=targetX;
            tileY[0]=targetY;
            fscore[0]=1;
            gscore[0]=map[targetX][targetY].negativeWeight;



            do
            {
              var currentBestIndex=-1;
              var currentBestScore=2147483647;
              //  Look for the lowest F cost square on the open list
              for (var ii=0;ii<openListSize;ii++)
              {
                if (fscore[openList[ii]]<currentBestScore)
                {
                  currentBestScore=fscore[openList[ii]];
                  currentBestIndex=ii;
                }
              }
              if (currentBestIndex===-1)
              {
                break;
              }
              currentIndex=openList[currentBestIndex];
              var currentTileX=tileX[currentIndex];
              var currentTileY=tileY[currentIndex];

              // found path
              if (startX===currentTileX && startY===currentTileY)
              {
                break;
              }

              // if not in closed list
              if (tileIsClosed[currentTileX][currentTileY]===0)
              {
                    // Switch it to the closed list.
                    tileIsClosed[currentTileX][currentTileY]=1;
                    // remove from openlist
                    openList[currentBestIndex]=openList[--openListSize];   

                    // add neighbours to the open list if necessary
                    for (j=0;j<4;j++)
                    {
                        i = shuffleIndecies[j];

                        var surroundingCurrentTileX=currentTileX+offsets[i][0];
                        var surroundingCurrentTileY=currentTileY+offsets[i][1];
                        if (surroundingCurrentTileX>=0 && surroundingCurrentTileX<mapSize &&
                            surroundingCurrentTileY>=0 && surroundingCurrentTileY<mapSize )
                        {
                          tileX[tileId]=surroundingCurrentTileX;
                          tileY[tileId]=surroundingCurrentTileY;

                          var surroundingCurrentGscore=gscore[currentIndex] + map[surroundingCurrentTileX][surroundingCurrentTileY].negativeWeight;
                          gscore[tileId]=surroundingCurrentGscore;
                          fscore[tileId]=surroundingCurrentGscore+Math.abs( surroundingCurrentTileX-startX)+Math.abs( surroundingCurrentTileY-startY);
                          tileParent[tileId]=currentIndex;
                          openList[openListSize++]=tileId++;
                        }
                    }
              }
              else
              {
              // remove from openlist
              openList[currentBestIndex]=openList[--openListSize];    
              }
            } while(true);

            if (tileX[tileParent[currentIndex]]<startX) return {moveDirection:WEST, pathLength:currentIndex, pathScore:gscore[currentIndex]+currentIndex/4};
            else if (tileX[tileParent[currentIndex]]>startX) return {moveDirection:EAST, pathLength:currentIndex, pathScore:gscore[currentIndex]+currentIndex/4};
            else if (tileY[tileParent[currentIndex]]<startY) return {moveDirection:NORTH, pathLength:currentIndex, pathScore:gscore[currentIndex]+currentIndex/4};
            else if (tileY[tileParent[currentIndex]]>startY) return {moveDirection:SOUTH, pathLength:currentIndex, pathScore:gscore[currentIndex]+currentIndex/4};
        }
        console.log("Path finding failed");
        return {moveDirection:IDLE, pathLength:0, pathScore:2147483647};
     }

function process(info,bots,coins)
    {
        var i;
        var j;
        var k;
        var x;
        var y;

        // initialise map
        var mapSize = info.arenaLength;
        var map = new Array(mapSize);
        for (i = 0;i < info.arenaLength;i++)
        {
            var newArray = new Array(info.arenaLength);
            map[i] =  newArray;
            for (j = 0;j < mapSize;j++)
            {
                map[i][j] = {type:MAP_TYPE_BLANK, coins: 0 , negativeWeight:i===0||i===mapSize-1||j===0||j===mapSize-1?3:1};
            }
        }

        // populate map with bots
        for (i = 0 ; i<bots.length;i++)
        {
            map[bots[i][X_INDEX]][bots[i][Y_INDEX]].type = MAP_TYPE_BOT;
            map[bots[i][X_INDEX]][bots[i][Y_INDEX]].coins = bots[i][COIN_INDEX];

            for (j=-1;j<2;j++)
            {
                x = bots[i][X_INDEX] + j;
                if (x>=0 && x < mapSize)
                {
                    for(k=-1;k<2;k++)
                    {
                        if (Math.abs((k+j)%2) === 1)
                        {
                            y = bots[i][Y_INDEX] + k;
                            if (y>=0 && y< mapSize )
                            {
                                // are we adjacent the bot or potentially will be?
                                if (Math.abs(info.locationX-x)<=1 && Math.abs(info.locationY-y)<=1)
                                {
                                    // make the cell significantly less attractive when the bot is stronger than us, or
                                    // make the cell slightly more attactive when the bot is weaker than us, or
                                    // not change if the bot has no coins
                                    map[x][y].negativeWeight+= bots[i][COIN_INDEX] >= info.coins?100000:(bots[i][COIN_INDEX]===0?0:-1);
                                }
                                // another bot is not a direct threat/target
                                else
                                {
                                    // make the cell moderately less attractive when the bot is stronger than us, or
                                    // make the cell slightly more attactive when the bot is weaker than us, or
                                    // not change if the bot has no coins
                                    map[x][y].negativeWeight+= bots[i][COIN_INDEX] >= info.coins?3:(bots[i][COIN_INDEX]===0?0:-1);
                                }
                            }
                        }
                    }
                }
            }
        }

        // populate map with coins
        for (i = 0 ; i<coins.length;i++)
        {
            map[coins[i][X_INDEX]][coins[i][Y_INDEX]].type = i === 0?MAP_TYPE_GOLD_COIN:MAP_TYPE_SILVER_COIN;
            map[coins[i][X_INDEX]][coins[i][Y_INDEX]].coins = i === 0?GOLD_POINTS:SILVER_POINTS;

            // check to see whether bots are adjacent to the coin
            for (j=-1;j<2;j++)
            {
                x = coins[i][X_INDEX] + j;
                if (x>=0 && x < mapSize)
                {
                    for(k=-1;k<2;k++)
                    {
                        if ((k+j)%2 === 1)
                        {
                            y = coins[i][Y_INDEX] + k;
                            if (y>=0 && y< mapSize )
                            {
                                if (map[x][y].type === MAP_TYPE_BOT)
                                {
                                    // this coin looks like a trap as a stronger bot is adjacent to it
                                    if (map[x][y].coins >= info.coins)
                                    {
                                        map[coins[i][X_INDEX]][coins[i][Y_INDEX]].negativeWeight+=100000;
                                    }
                                    else
                                    {
                                        // are we adjacent the coin? we might be able to kill another bot if it trys to get the coin
                                        if (Math.abs(info.locationX-coins[i][X_INDEX])<=1 && Math.abs(info.locationY-coins[i][Y_INDEX])<=1)
                                        {
                                            map[coins[i][X_INDEX]][coins[i][Y_INDEX]].negativeWeight+=-20;
                                        }
                                        // another bot is likely to get this coin... make it less attractive
                                        else
                                        {
                                            map[coins[i][X_INDEX]][coins[i][Y_INDEX]].negativeWeight=+100;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            // add the coin attractiveness, more for gold coins
            map[coins[i][X_INDEX]][coins[i][Y_INDEX]].negativeWeight += i === 0?-20:-10;
        }


        var pathBest = {moveDirection:IDLE, pathLength: 2147483647, pathScore: 2147483647};

        if (info.coins > MIDGAME_THRESHOLD)
        {
            var viableCoinCount =0;
            var viableCoins = new Array(5); 


            // find coins that are reachable before any other bot
            outer1:
            for (j = 0 ; j<coins.length;j++)
            {
                var contention = 0;

                var myDistanceToCoin = Math.abs(info.locationX-coins[j][X_INDEX]) + Math.abs(info.locationY-coins[j][Y_INDEX]);

                for (i = 0 ; i<bots.length;i++)
                {
                    var dist = Math.abs(bots[i][X_INDEX]-coins[j][X_INDEX]) + Math.abs(bots[i][Y_INDEX]-coins[j][Y_INDEX]);
                    if (dist < myDistanceToCoin)
                    {
                        continue outer1;
                    }
                }
                viableCoins[viableCoinCount++] = j;
            }

            // no coins are reachable before another bot so find the cell that is furthest away from any bot and head there
            if (viableCoinCount ===0)
            {
                var mostIsolatedCellX = mapSize/2;
                var mostIsolatedCellY = mapSize/2;
                var mostIsolatedCellMinBotDistance = 0;

                for (x=5;x<mapSize-5;x++)
                {
                    for (y=5;y<mapSize-5;y++)
                    {
                        if (x!= info.locationX && y!=info.locationY)
                        {

                            // ignore coin attractiveness
                            map[x][y].negativeWeight = map[x][y].negativeWeight<-4?map[x][y].negativeWeight:1;


                            var currentCellMinBotDistance = 2147483647;

                            for (i = 0 ; i<bots.length;i++)
                            {
                                var dist = Math.abs(bots[i][X_INDEX]-x) + Math.abs(bots[i][Y_INDEX]-y) + Math.abs(info.locationX-x) + Math.abs(info.locationY-y);
                                if (dist < currentCellMinBotDistance )
                                {
                                    {
                                        currentCellMinBotDistance = dist;                           
                                        if (currentCellMinBotDistance>mostIsolatedCellMinBotDistance)
                                        {
                                            mostIsolatedCellMinBotDistance = currentCellMinBotDistance;
                                            mostIsolatedCellX=x;
                                            mostIsolatedCellY=y;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }

                // attempt to find path to most isolated cell
                pathBest = pathFind(info.locationX, info.locationY, mostIsolatedCellX,mostIsolatedCellY, map, mapSize);
            }

            // attempt to find paths to each viable coin, keeping the best result
            for (i = 0 ; i<viableCoinCount;i++)
            {
                var path = pathFind(info.locationX, info.locationY, coins[viableCoins[i]][X_INDEX],coins[viableCoins[i]][Y_INDEX], map, mapSize);
                if (path.pathScore < pathBest.pathScore)
                {
                    pathBest = path;
                }
            }
        }
        else
        {
            // attempt to find paths to each coin, keeping the best result
            for (i = 0 ; i<coins.length;i++)
            {
                var path = pathFind(info.locationX, info.locationY, coins[i][X_INDEX],coins[i][Y_INDEX], map, mapSize);
                if (path.pathScore < pathBest.pathScore)
                {
                    pathBest = path;
                }
            }
        }


        var move = IDLE;
        if (pathBest.pathLength === 2147483647)
        {
            outer:
            for (i=0;i<MOVE_COMMANDS_COUNT;i++)
            {
                switch (i)
                {
                    case NORTH:
                        if (info.locationY-1 < 0)
                        {
                            continue;
                        }
                        move = i;
                        break outer;
                    case SOUTH:
                        if (info.locationY+1 === info.arenaLength)
                        {
                            continue;
                        }
                        move = i;
                        break outer;
                    case WEST:
                        if (info.locationX-1 < 0)
                        {
                            continue;
                        }
                        move = i;
                        break outer;
                    case EAST:
                        if (info.locationX+1 === info.arenaLength)
                        {
                            continue;
                        }
                        move = i;
                        break outer;
                    case IDLE:
                        move = i;
                        break;
                    default:
                }
            }
        }
        else
        {
            move = pathBest.moveDirection;
        }

        switch (move)
        {
        case NORTH:
            return "north";
        case SOUTH:
            return "south";
        case EAST:
            return "east";
        case WEST:
            return "west";
        default:
            return "none";
        }
    }
    return process(me, others, coins);
}

Bu bot, bizi öldürebilecek botlardan kaçınmak, tuzaklara değil, tuzaklara değil ve en az riskli paralara gitmek için bir hücre arzuları haritası ile birleştirilmiş yol bulma sistemini kullanıyor.

Kazanan yer için bir rakip gibi görünmüyor, ancak ilk eline geçerse hayatta kalacaktır ve maçın sonunda hayatta kalacaktır.

Bot, diğer botlardan önce ulaşamadığı paraları görmezden gelen orta-geç oyun stratejisine sahip ve herhangi bir madeni paraya gidemezse, kendisinden daha güçlü olan diğer tüm botlardan en uzaktaki en yakın hücreye gidiyor.

Şimdi kazanma şansı var.

Not berbat kodu için üzgünüm, otomatik Java dan çevirdim


Herhangi bir hatayı ve / veya güncellemeleri en geç, en geç 18 saat içinde sona erdirdiğinizden emin olun!
Redwolf Programları,

@RedwolfPrograms Bir hata gözlemlediniz mi? eğer öyleyse lütfen düzeltmeme izin verin. Teşekkürler
Moogie,

Hayır, ama asla bilemezsin. Tıpkı birçok botlar bir yanlış numara veya yanlış fonksiyonu veya yanlış yazmanız için Sayabileceğimden daha fazla kez nedeniyle kaybetmek görmeyeli, iki kez kontrol etmek emin olun
Redwolf Programları
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.