골드 배틀 KoTH


43

이 도전은 끝났다. 경쟁사의 최종 점수를 보려면 여기를 클릭하십시오

이 과제에서 각 제출은 하나의 봇입니다. 각 봇은 자바 스크립트 함수 여야합니다. 봇은 금에서 가장 높은 총 가치를 얻기 위해 싸울 것입니다. 금은 농사를 짓거나 다른 봇을 죽임으로써 얻을 수 있으며 치유, 공격, 방어 및 농사를 업그레이드하는 데 사용됩니다.

객관적인:

최대 1000 턴 (한 봇만 남았을 때 끝남)을 포함하는 다수의 라운드에서 총 가치가 가장 높은 봇 (득한 모든 금의 합)이 승자입니다.

회전 :

매 턴마다 살아있는 모든 봇 (> 0 HP)이 한 번 실행됩니다. 이동을 반환 할 수 있으며 다음 중 하나 일 수 있습니다.

  • 치유 : HP 회복
  • 공격 : 다른 봇에서 HP를 제거합니다
  • 방패 : 이후의 공격으로부터 방어
  • 기절 : 다른 봇의 다음 턴을 건너 뜁니다.
  • 농장 : HP를 희생시키면서 금을 얻습니다
  • 업그레이드 : 특정 동작 개선

모든 봇은 실행되기 전에 이동을 반환하므로 기절, 치유, 공격, 보호막 등은 그 턴 후반에 이동하는 봇에는 영향을 미치지 않습니다. 예를 들어, 봇 A가 봇 B를 기절시키고 봇 B가 턴 순서에서 봇 A 다음에 오는 경우, 봇 B는 여전히 같은 턴에서 나중에 움직이며 다음 턴에 기절합니다.

전투, 농업 및 업그레이드 :

각 봇의 최대 HP는 100이고 할당 된 UID는 0에서 99 사이입니다.이 UID는 매 라운드마다 변경되며 봇이 서로를 추적하는 방법입니다.

치유는 레벨에 따라 결정되는 HP의 양을 추가하는 가장 간단한 동작 중 하나입니다 (5 HP에서 시작). 봇은 100 HP를 넘지 못한다.

UID로 봇을 공격하는 것은 레벨 0에서 5의 기본 피해를 입히는 또 다른 이동입니다. 봇은 기절하여 다음 턴을 건너 뛰고 UID도 사용합니다.

봇에는 추가 보호막 HP가 있으며 제한이 없습니다. 이 보호막 HP는 다른 봇으로부터의 직접적인 공격으로 인한 피해를 흡수하고 보호막으로 추가됩니다. 레벨 0에서 쉴딩은 5의 쉴드 HP를 추가합니다.

농업은 2 HP 비용으로 레벨 0에서 5 골드를 얻습니다. 이 2 HP는 보호 할 수 없습니다. 금메달 (승리 이외)의 유일한 용도는 움직임을 업그레이드하는 것입니다. 치유, 공격 및 방어의 기본 가치는 5 HP이며 농업은 5 골드부터 시작됩니다. 각 동작에는 0부터 시작하는 개별 레벨이 있습니다.이 공식은 HP 또는 금의 움직임 값을 결정합니다. 여기서 L은 레벨입니다.

  • 치료: L + 5
  • 공격 : 1.25L + 5
  • 차폐 : 1.5L + 5
  • 농업: 2L + 5

이동 업그레이드 비용은 특정 레벨에서 동일 2.5L² + 2.5L + 10하며 L은 현재 레벨입니다. 봇은이 기능 cost(currentLevel)을 바로 가기로 사용하여 이를 결정할 수 있습니다.

봇은 25 골드로 시작하여 레벨 2로 이동하거나 레벨 2로 한 번 이동합니다.이 시작 골드는 봇의 총 가치에 포함되지 않습니다. 봇을 처치하면 총 가치의 절반이 반올림되고 반올림되며 같은 차례에 두 봇이 다른 봇을 죽이면 보상을받습니다.

입출력:

컨트롤러와 통신하기 위해 함수의 반환 값을 사용하여 이동 정보를 보냅니다. 다음 중 하나가 반환되어야합니다.

  • 고치다: heal()
  • 공격: attack(uid)
  • 방패: shield()
  • 충격: stun(uid)
  • 농장: farm()
  • 업그레이드: upgrade("heal" / "attack" / "shield" / "farm")

회전을 건너 뛰거나 (아무것도하지 않음) 아무 것도 반환하지 않거나 잘못된 값을 반환합니다.

현재 회전 번호 (1부터 시작)를 얻으려면을 사용하십시오 turn().

함수의 인수에는 봇, 다른 봇의 UID 및 턴간 저장에 대한 정보가 포함됩니다. 첫 번째 인수에는 다음과 같은 속성을 가진 객체입니다 : uid, hp, gold,와 shield. 이들은 봇의 현재 정보 사본입니다. 중첩 된 개체도있다 levels수준 번호를, heal, attack, shield,와 farm.

두 번째 인수는 속성을 포함하는 객체로 포맷 네 제외한 모든 살아있는 로봇의 셔플 어레이이며 uid, hp(플러스 쉴드), worthattack(공격 레벨). 세 번째 인수는 턴간 저장에 사용할 수있는 빈 객체입니다.

봇 예 :

이 봇은 공격을 레벨 5로 업그레이드 할 수있을 때까지 농사를 짓고, 죽거나 이길 때까지 매 턴마다 무작위 봇을 공격합니다. 치유 / 차폐가 없기 때문에 효과적이지 않습니다.

function freeTestBotA(me, others, storage) {
    if (me.levels.attack < 5) {
        if (me.gold < cost(me.levels.attack))
            return farm();
        return upgrade("attack");
    }
    return attack(others[0].uid);
}

이 봇에는 공격 모드와 방어 모드가 있습니다. 방어 모드에있을 때 무작위 봇을 기절 시키거나 치유하며, 공격 모드에있을 때 공격하거나 방어합니다. 가능할 때마다 공격 업그레이드를 시도합니다.

function freeTestBotB(me, others, storage) {
    if (me.gold >= cost(me.levels.attack))
        return upgrade("attack");
    if (me.hp < 50)
        if (Math.random() < 0.5)
            return stun(others[0].uid);
        else
            return heal();
    else
        if (Math.random() < 0.5)
            return attack(others[0].uid);
        else
            return shield();
}

규칙 :

  • 금지 된 표준 허점
  • 봇은 범위를 벗어난 변수를 읽거나 수정하거나 추가 할 수 없으며 치트를 시도하지 않으며 컨트롤러 정의 또는 DOM 함수를 호출 할 수 없습니다
  • 반환 값은 거짓이거나 위의 함수 출력 중 하나 여야합니다.
  • 봇은 특정 봇을 대상으로하도록 설계되어서는 안되지만 일반적인 전략을 활용하도록 설계 될 수 있습니다
  • 봇은 스스로 공격 할 수 없습니다 (@Ness의 설명으로 인해 발견됨)
  • 봇은 다른 봇과 충분히 달라야 별도의 항목으로 간주 될 수 있습니다.
  • 팀 구성은 이제 허용 되지 않습니다
  • 컨트롤러는 여기 에서 찾을 수 있습니다
  • 채팅방

새로운 컨트롤러 디버깅 :

파일을 사용하여 봇 속성 gold-battle-log.js값 을 0 (로깅 없음), 1 (로그 이동) 또는 2 (로그 이동, hp, 금, 레벨 등)로 설정할 수 있습니다 .debugbotData

챌린지는 8 월 9 일 금요일 1700 UTC에 종료됩니다.


4
모든 봇과 요점을 만들었습니다. gist.github.com/Draco18s/2efbf95edcf98d6b1f264e26bbb669d1 업데이트를 유지하기 위해 노력할 것입니다 (그러나 시작이 아닌 경우).
Draco18s

4
봇이 포함 된 자동 업데이트 컨트롤러 : redwolfprograms.com/koth
Redwolf 프로그램

4
나는이 질문이 이미 사실상 새로운 답변에 가까워져 있기 때문에이 질문을 끝내기로 투표하고 있습니다 ( "이 도전은 끝났습니다. 최종 점수를보기 위해 ...")
pppery

3
@pppery 당신은 할 수 없습니까? 나는 비 경쟁적 답변으로 괜찮을 것이고 [closed], 결국 캐주얼 시청자들이 저의 도전을 읽는 것을 건너 뛰게 할 것입니다. 품질이 낮거나 주제가 아닌 것으로 가정합니다.
Redwolf 프로그램

5
@pppery 저는 오늘까지 끝나는 도전이 끝났다는 것을 들어 본 적이 없으며, 시행하려는 사회적 제한이 존재하지 않는다고 주장합니다. 닫을 필요가 없으며 닫고 싶지 않습니다. 저에게는 사이트의 이익을 위해서가 아니라 폐쇄를 위해 폐쇄하는 것처럼 보입니다. 누군가가 오래된 질문에 대한 답변을 게시하고 싶다면 가능해야합니다. 진지한 경쟁자 규칙에 따라 게시 될 때 진지한 경쟁자 여야한다는 언급은 없습니다. 그것은 승리를위한 경쟁자없는 경우에도 대답은 여전히 반칙으로 심각한 경쟁자가 될 수
Redwolf 프로그램

답변:


16

살해 할 수없는

Undyable 에서 분기 했습니다 .

function UnkillableBot(me){
    if(me.hp <= 100 - (me.levels.heal + 5)){
        return heal()
    }else if(turn() % 10 == 0 && me.shield < 800) {
        return shield()
    }else{
        if(me.gold >= cost(me.levels.shield) && me.levels.shield <= 9){
            return upgrade("shield")
        }else if(me.gold >= cost(me.levels.farm)){
            return upgrade("farm")
        }else{
            if(me.shield < 500 && me.levels.shield > 4) {
                return shield()
            }
            return farm()
        }
    }
}

기하 급수적으로 업그레이드 비용을 감안할 때 치유를 업그레이드 할 수없는 경우 농업을 업그레이드하여 봇이 더 효율적으로 금을 모을 수 있습니다.


내 테스트에서 절대적으로 경쟁을 분쇄
Redwolf 프로그램

1
나는이 봇이 첫 번째 if문장이 사용 되었을 때 조금 더 강하다고 생각합니다. <=현재는 완전히 치유되지 않을 것입니다.
스쿠 트

@Scoots 얼마나 중요한지 잘 모르겠지만 변경하겠습니다.
Draco18s

2
@ Draco18s 매우 중요하지 않다고 확신합니다. 그러나이 사이트가 실제로 거의 중요하지 않은 개선점에 관한 것이 아닙니까? :)
스쿠 트

@Scoots 최대의 건강을 치유하는 것은 실제 공격 위협이 없기 때문에이 과제에서 중요하지 않습니다. 진정으로 공격적인 봇은 따돌림이며, 실제로 그에 대해 아무것도 할 수 없습니다. 실제로 건강을 유지하기 위해 성능을 저하시킬 수 있습니다.
B0RDERS

13

타 노스 봇

function ThanosBot(me, others, storage){
    if(turn()==1){
        storage.origPopulation = others.length;
        return upgrade("attack");
    }

    if (others.length < storage.origPopulation / 2)
    {
        if(me.hp <= 100 - (me.levels.heal + 5)){
            return heal();
        }
        else {
            return farm();
        }
    }

    if(me.hp <= 100 - (me.levels.heal + 5)){
        return heal()
    }else{
        if(me.gold >= cost(me.levels.attack)){
            return upgrade("attack")
        }else if(me.gold >= cost(me.levels.heal)){
            return upgrade("heal")
        }else if(me.gold >= cost(me.levels.farm)){
            return upgrade("farm")
        }else{
            if(Math.random() < 0.5){
                return attack(others[0].uid);
            }
            else{
                return farm();
            }
        }
    }
}

봇이 너무 많아서 금을 충분히 얻을 수 없습니다. 이 봇은 솔루션을 제안합니다.

대량 학살은 그렇습니다. 그러나 임의적이고 불쾌하며 부자와 가난한 사람들에게 공평합니다.

그들은 그를 미친 사람이라고 불렀습니다.

ThanosBot은 봇 커뮤니티를 위해 최선을 다하며 기꺼이 노력하고 있습니다. 처음에는 공격, 농업 및 치유를 업그레이드하여 자원을보다 효율적으로 수집하고 전투에서 승리합니다. 점차적으로, 그는 다가올 전투를 위해 자원을 수집하면서 무작위로 사람들을 공격하기 시작할 것입니다. 그는 자신의 군대, 무기 및 자신을 계속 향상시킬 것입니다.

일단 인구의 50 %가 제거되면, 태어난 봇은 배 전체를 맑게하고 하늘을 맑게 할뿐 아니라 농업 생활로 은퇴하고 감사하는 우주에서 해가 뜨는 것을 볼 수 있습니다. 그는 완전히 평화 주의자가되어 야채 수프와 농사로 자신을 치유합니다.


6
"공격"의 이름을 "스냅"으로
바꾸려고합니다.

11

킬러

function killStealer({hp, gold, attack:atck, shield:shld, levels:{heal:lHeal, shield:lShld, farm:lFarm, attack:lAtck}}, es, S) {
  let saneReduce = (a, f, n) => a.length? a.reduce(f) : n;
  let t = turn();
  if (t===1) {
    S.worth = 0;
    S.pHP = 100;
    S.pGold = 0;
    S.stat = {};
    S.pT = 0;
    for (let e of es) S.stat[e.uid] = {kills:0, seen:0};
  }

  let pT = S.pT;
  S.pT = t;

  let shp = shld+hp;

  let healP = lHeal      + 5;
  let shldP = lShld*1.5  + 5;
  let farmP = lFarm*2    + 5;
  let atckP = lAtck*1.25 + 5;
  let pheal = () => hp<5  ||  Math.min(100, hp+healP)-hp > shldP? heal() : shield();

  let attacked = S.pHP-hp-shld > 2;
  S.pHP = hp+shld;

  if (gold>S.pGold  &&  t!=1) S.worth+= gold-S.pGold;
  S.pGold = gold;

  let pes = S.pEs;
  let ces = {};
  for (let e of es) ces[e.uid] = {uid:e.uid, hp:e.hp, worth:e.worth};
  S.pEs = ces;

  if (t === 1) return shield(); // to not break things depending on previous frame

  if (t == pT+1) {
    for (let uidE in pes) {
      let e = pes[uidE];
      if (!ces[uidE]) { // dead
        if (e.worth < 30) continue; // don't bother, because others probably won't
        for (let a of es) {
          let pa = pes[a.uid];
          if (a.worth >= pa.worth + e.worth/2 - 2) {
            S.stat[a.uid].kills++;
          }
          if (a.worth != pa.worth || a.hp > pa.hp) S.stat[a.uid].seen++;
        }
      }
    }
  }


  let attackers = es.filter(c => {
    let k = S.stat[c.uid].kills;
    let s = S.stat[c.uid].seen;
    return k > 1  &&  k > s*.7;
  });
  let maxDmg = es.map(c=>c.attack).reduce((a, b) => Math.max(a, b), 0)*1.25 + 5;
  for (let e of es) {
    if (e.worth < farmP) continue;
    let p = pes[e.uid];
    let dmg = p.hp-e.hp;
    if (e.hp <= atckP) {
      return attack(e.uid);
    }
    if (e.hp-dmg-atckP <= 0) {
      return attack(e.uid);
    }
    if (e.hp-maxDmg-atckP <= 0) {
      return attack(e.uid);
    }
    if (e.hp-maxDmg-dmg <= 0) {
      return attack(e.uid);
    }
  }
  if (attackers.length>0 && t>50) {
    for (let e of es) {
      if (e.hp - maxDmg*2 - atckP <= 0  &&  e.worth > 200) {
        let worst = saneReduce(attackers.filter(c => c.hp > 80), (a, b)=>a.worth>b.worth? a : b, null);
        if (worst) return stun(worst.uid);
      }
    }
  }



  if (t < 60  &&  t%5 == 1) return shield();
  if (t === 2) return upgrade("heal");
  if (t === 3) return upgrade("farm");
  if (t%10 == 1) return shield();

  if (gold>=cost(lShld) && lFarm>-2) return upgrade("shield");
  if (gold>=cost(lFarm) && !attacked) return upgrade("farm");

  if (es.length > 2) {
    let notDead = es.filter(c => c.hp > 20);
    if (notDead.length !== 0) {
      notDead.sort((a, b) => a.hp-b.hp);
      if (notDead[Math.min(2, notDead.length-1)].hp > shp) {
        return pheal();
      }
    }
  }


  if (gold>=cost(lHeal)  &&  lHeal+5 < lFarm) return upgrade("heal");
  if (gold>=cost(lAtck)  &&  lAtck+5 < lFarm  &&  es.every(c=>c.attack<=lAtck+2)) return upgrade("attack");

  if (lShld>5  &&  shp < 205+healP+t  &&  shp < 600+t*5) return pheal();
  if (es.every(c => c.worth < S.worth+farmP) && es.length>2 && t<100 && lShld<6) return pheal();
  if (shp<=120  ||  hp<5) return pheal();
  return farm();
}

이제 살인을 훔칠뿐만 아니라 훔친 살인도 훔칩니다!

이 봇은 농장을 제외하고는 많은 일을하지 않으며, 가능성을 알게되면 죽어가는 적에게 마지막 타격을 가하며 어쨌든 아주 훌륭합니다.


죽이는 타격과 관련된 모든 봇이 전액 보상을 받기 때문에 작동합니다.
Draco18s

@ Draco18s 나는 그것이 왜 좋을 수 있는지 이해합니다. 단순히 그와 같은 간단한 아이디어가 다음 번 최고의 봇 점수 (평균적으로 2 배)를 기대하지는 않았습니다.
dzaima

Hehe, 그건 공평 해 가능한 경우 모든 봇을 다운로드하고 다른 솔루션을 찾을 수 있는지 확인해야합니다.
Draco18s

9

이퀄라이저

이 봇은 봇 커뮤니티에서 평화를 회복하려고합니다. 그는 봇의 치유가 자신의 공격보다 나은 경우에만 포기하고 가장 높은 공격으로 봇을 끊임없이 대상으로합니다. 공격보다 더 나은 치유 능력을 가진 봇이 남아 있지 않으면 평화로운 농업 생활로 은퇴 할 것입니다.

function equalizer(me, others, storage){
  if(storage.agroKilled == null)storage.agroKilled = false;
  if(!storage.agroKilled){
    if(storage.blacklist == null)storage.blacklist = [];
    if(storage.lastAttack == null)storage.lastAttack = -1;
    var maxAtk = 0;
    var maxAtkUid = -1;
    var maxAtkHealth = 0;
    for(var i = 0; i < others.length; i++)if(others[i].uid == storage.lastAttack){
      maxAtk = others[i].attack*1.25+5;
      maxAtkUid = storage.lastAttack;
      maxAtkHealth = others[i].hp;
    }
    for(var i = 0; i < others.length; i++){
      if(storage.lastAttack == others[i].uid && others[i].hp >= storage.lastHealth){
        maxAtk = 0;
        maxAtkUid = -1;
        maxAtkHealth = 0;
        storage.blacklist.push(others[i].uid);
      }
    }
    storage.lastAttack = -1;
    var willHeal;
    for(var i = 0; i < others.length; i++)if(others[i].attack*1.25+5 > maxAtk){
      willHeal = false
      for(var j = 0; j < storage.blacklist.length; j++)if(others[i].uid==storage.blacklist[j])willHeal = true;
      if(!willHeal){
        maxAtk = others[i].attack*1.25+5;
        maxAtkUid = others[i].uid;
        maxAtkHealth = others[i].hp;
      }
    }
    if(me.hp < maxAtk) return heal();
    if(me.hp <= 100 - me.levels.heal - 5) return heal();
    var target = -1;
    var targetWorth = me.levels.farm * 2 + 5;
    for(var i = 0; i < others.length; i++) {
      if (others[i].hp <= maxAtk && others[i].worth / 2 > targetWorth) {
        target= others[i].uid;
          targetWorth = others[i].worth / 2;
      }
    }
    if(target!=-1) return attack(target);
    if(me.gold >= cost(me.levels.attack)) return upgrade("attack");
    if(me.levels.heal + 7 < me.levels.attack && me.levels.heal < 9 && me.gold >= cost(me.levels.heal)) return upgrade("heal");
    if(maxAtkUid!=-1){
      storage.lastAttack = maxAtkUid;
      storage.lastHealth = maxAtkHealth;
      return attack(maxAtkUid);
    }
    storage.agroKilled = true;
  }
  if(me.hp < 30) return heal();
  if(me.gold > cost(me.levels.farm)) return upgrade("farm");
  return farm();
}

8

낙관론자

function Optimist(me, others, storage) {
    if (me.hp < 10)
        return heal();
    if ( (me.hp + me.shield) < 50 )
        return shield();
    if (me.gold >= cost(me.levels.farm) && cost(me.levels.farm) < 0.8 * (1000 - turn()))
        return upgrade("farm");
    rich_bots = others.sort( (x,y) => y.worth - x.worth );
    potential_victim = rich_bots.find( bot => bot.hp <= me.levels.attack * 1.25 + 5 );
    if (potential_victim)
        return attack(potential_victim.uid);
    if (me.gold < rich_bots[0].worth + cost(me.levels.farm) + 25)
        return farm();
    if (me.levels.heal < me.levels.farm)
        return upgrade("heal");
    if (me.levels.shield < me.levels.heal)
        return upgrade("shield");
    if (me.levels.attack < me.levels.shield)
        return upgrade("attack");
    return shield();
}

평화로운 농사 시간의 80 %를 평화롭게 보낼 수 있다고 가정하므로 농사를 최대한 활용하여 시작한 다음 전투 기술에주의를 기울이기 시작합니다. 분명히 아무것도 잘못되지 않을 것입니다!


8

처치 지원

function KillAssist(me, others, storage) {
  let t = turn();
  if (t===1) {
    storage.worth = 0;
    storage.pHP = 100;
    storage.pGold = 0;
  }
  let hp = me.hp;
  let gold = me.gold;
  let shld = me.shield;
  let lHeal = me.levels.heal+0.25;
  let lFarm = me.levels.farm;
  let lShld = me.levels.shield;
  let lAtck = me.levels.attack;
  let healPower = lHeal      + 4.75;
  let shldPower = lShld*1.5  + 5;
  let farmPower = lFarm*2    + 5;
  let atckPower = lAtck*1.25 + 5;

  let dmgTaken = storage.pHP-(hp+shld);
  let attacked = dmgTaken > 2;
  storage.pHP = (hp+shld);

  if (gold > storage.pGold) storage.worth+= gold-storage.pGold;
  if (gold-storage.pGold > farmPower+5)  storage.lastAtck = -10;
  storage.pGold = gold;
  let pOthers = storage.pOthers;
  storage.pOthers = {};
  for (let o of others) {
    storage.pOthers[o.uid] = {hp: o.hp, uid: o.uid, worth: o.worth};
  } 

  if (t === 1 || t === 2) return upgrade("shield");
  if (t === 3) return shield();

  let maxdmg = others.map(c=>c.attack).reduce((a, b) => Math.max(a, b))*1.25 + 5;
  let lowhp = others.map(c=>c.hp).reduce((a, b) => Math.min(a, b));
  let lowhpid = others.find(c=>c.hp == lowhp).uid;
  let maxAttacker = others.find(o => o.attack*1.25 + 5 == maxdmg).uid;
  for (let o of others) {
    if (o.hp < atckPower  &&  o.worth > farmPower) {
      storage.dead = o.uid;
      storage.deadWorth = o.worth;
      return attack(o.uid);
    }
    let pO = pOthers[o.uid];
    let dmg = pO.hp - o.hp;
    if (o.hp - dmg - atckPower <= atckPower && o.worth >= farmPower) {
      storage.dead = o.uid;
      storage.deadWorth = o.worth;
      return attack(o.uid);
    }
    if (o.hp - maxdmg - atckPower <= atckPower && o.worth >= farmPower) {
      storage.deadWorth = o.worth;
      return attack(o.uid); 
    }
  }
  let lowhpdiff = Math.max(pOthers[lowhpid].hp - others.find(o => o.uid == lowhpid).hp,0);
  if (others.some(o => o.hp > maxdmg && o.hp < lowhpdiff*2+atckPower+maxdmg && o.worth > farmPower)) {
    let bad = others.reduce((a, b) => a.worth>b.worth? a : b);
    let bad2 = others.reduce((a, b) => bad.uid == b.uid ? a : (bad.uid == a.uid ? b : (a.worth>b.worth ? a : b)));
    if(bad.worth < bad2.worth*3 && bad.hp >= (maxdmg+atckPower)*2 && bad.uid != maxAttacker && bad.uid != lowhpid) {
      return stun(bad.uid);
    }
    if(bad2.hp >= (maxdmg+atckPower)*2 && bad2.uid != maxAttacker && bad.uid != lowhpid) {
      return stun(bad2.uid);
    }
  }

  if (t%10 == 9  &&  lShld>4) return shield(); // slowly build up shield just in case
  if (shld+hp < 100) return shldPower>healPower || hp >= 100-healPower? shield() : heal();

  var bon = shldPower-maxdmg < 3 && t < 700 ? lShld/2 : 0;
  var bon2 = t/100;
  if (gold>=cost(lFarm) && lShld+2 > lFarm && bon == 0 && !attacked) return upgrade("farm"); // farm first, but make sure it doesn't get too far ahead
  if (gold>=cost(lShld) && t>20 && (lShld<10+bon || lShld+5+bon2 < lFarm+bon) && t < 900) return upgrade("shield");
  if (gold>=cost(lFarm)) return upgrade("farm"); // try upgrading farming again, because shield upgrading can be picky
  if (gold>=cost(lHeal) && (lHeal<3)) return upgrade("heal"); // healing isn't that important

  if (shld<200 && attacked || shld<500 && t>20 && others.filter(c=>c.hp>=100).every(o=>o.hp+10 > hp+shld)) return shldPower>healPower || hp >= 100-healPower? shield() : heal();

  let hpdelta = attacked ? dmgTaken+shldPower : maxdmg
  if (shld<lShld*60 && (1000-t)*(hpdelta) > shld+hp) return shield(); // we want to look impressive & terrifying
  if (hp<=100-healPower) return heal();

  return farm();
}

당신은 plink 피해를 입을 수 있고 여전히 완전한 신용을 얻을 수있을 때 왜 공격 가치를 업그레이드합니까?

Kill Stealer를 피기 백으로 다시 한 번. 나는 문장이 항상 참이고 몇 가지 숫자를 사용하여 원본보다 큰 이익을 얻은 몇 가지 코드 블록을 단순화 할 수있었습니다.

살해가 일어나기 전에 턴에 도움을 줄 수있는 부유 한 상대를 놀라게하는 것이 매우 영리하다는 것을 깨닫기 위해 @dzaima에게 전달해야합니다. (매우) 몇 번 중 하나는 Stun()긍정적 인 결과 를 가져옵니다 . Kill Stealer가 유사한 논리를 실행할 것이라는 것을 알면서 다시 한 번 아이디어를 개선 할 수있었습니다. Kill Assist는 "일부 재량을 가진"두 번째 최상의 대상을 찾고 대신 기절시킵니다.

봇 대공을 놀라게하는 것을 막고 봇을 죽일 가능성이 가장 높은 로봇을 놀라게하는 것을 방지하기위한 사소한 업데이트.

샘플 결과 (1000 게임 후 톱 5 잘림)

VM2406:1629 Kill Assist: 39495.679
VM2406:1629 The Accountant: 29990.267
VM2406:1629 Kill Stealer: 23530.153
VM2406:1629 Unkillable: 12722.604
VM2406:1629 captFarmer: 12232.466

잠깐만 요, 경감 파머 선장은 14k 골드를받을 수 있습니까?
Redwolf 프로그램

이것은 :runGame(1) results: [...] captFarmer: 13768
Draco18s

그것은 예상외로 꽤 높습니다 ... 내 테스트에서 일반적으로 약 10k를 얻습니다
Redwolf 프로그램

으 아아아 모든 것이 깨끗해 지도록 자동화 된 요지 업데이트를하겠습니다.
Draco18s

마감일이 끝날 때까지 내가 가장 좋아하는 봇.
Night2

7

썩지 않는 봇 (v3)

function undyableBot(me, others, storage){    

    if(me.hp < 100 - (me.levels.heal + 5)*2){
        return heal()
    }else{
        if(me.levels.heal < 10 && cost(me.levels.heal) / 2 < cost(me.levels.farm)){
            if(me.gold >= cost(me.levels.heal)){
                return upgrade("heal")
            }else{
                return farm()
            }
        }else{
            if(me.gold >= cost(me.levels.farm)){
                return upgrade("farm")
            }else{
                return farm()
            }
        }        
    }   
}


신경 쓰지 마 ... 이걸 빌릴거야.
Draco18s

6

환자 전략가 봇

필요에 따라 프레이밍 및 방어를 시작한 다음 봇을 작성하여 나중에 다른 고가의 봇을 죽이기로 전환했습니다.

현재 이것은 게임을 시작할 때 살인 봇 집단에 의해 살해되거나 공격 모드에서 어딘가에 붙어 있기 때문에 제대로 작동하지 않는 것 같습니다.

이것이 첫 번째 JS 코드이므로 여전히 행복합니다 ... (여기에서 코드 스 니펫을 훔쳤으며 모든 JS 기본 구문을 인터넷 검색하는 것보다 빠릅니다)

function PatientStratgistBot(me, others, storage) {

    //set up some stuff in first turn
    if (turn() == 1) {
    storage.selfWorth = 0;
    storage.attackMode = false;
    storage.expectHP = 100;
    storage.expectShield = 0;
    storage.shieldTarget = 0;
    storage.targetUid = "None";
    storage.attackRounds = 0;
    storage.targetStartHP = 100;

        return upgrade("farm");
    }

    let farmPower = me.levels.farm * 2 + 5;

    //defensive Actions

    var maxAtk = Math.max(...others.map(o => o.attack));

    storage.shieldTarget = Math.ceil(maxAtk * 1.25 / 1.5) + 1;

    if (me.levels.shield < storage.shieldTarget && me.gold >= cost(me.levels.shield) && me.levels.shield < me.levels.farm)
        return upgrade("shield");

    if (turn() >= 7 && me.shield < 10 && me.levels.shield * 1.5 >= me.levels.heal) return shield();

    if (turn() >= 15 && me.shield < 15 && me.levels.shield * 1.5 >= me.levels.heal) return shield();

    if (turn() >= 30 && me.shield < 20 && me.levels.shield * 1.5 >= me.levels.heal) return shield();

    //attack mode
    // check if there any targets worth to go for

    function findTarget(potentialTargets, baseR){
    var targetUID = "None";
    var best = 0;
    for( var i = 0; i < potentialTargets.length; i++) {
        //We upgrade to attack lvl12, so 20 dmg; assume an enemy can heal/shield up to 15 per round
        var killRounds = Math.ceil(potentialTargets[i].hp / 5)
        var gain = potentialTargets[i].worth / ( 2 * ( killRounds + baseR) )
        //console.log(me, turn(), potentialTargets[i], killRounds, baseR, gain, farmPower)
        if (gain > farmPower * ( killRounds + baseR ) && gain > best)
            targetUID = potentialTargets[i].uid;
            storage.targetStartHP =  potentialTargets[i].hp;
    }
    return targetUID;
    }


    if (turn() >= 600) {


    //check if a current target is dead
    const uids = others.map(x=>x.uid);
        if(storage.targetUid != "None" && !uids.includes(storage.targetUid)) {
        storage.targetUid = "None";
        storage.attackMode = false;
        storage.attackRounds = 0;
    }


    // check if we are doing enough damage to current target
    if (storage.targetUid != "None" && storage.attackRounds >= 3) {

        var deltaHP = storage.targetStartHP - others[storage.targetUid].hp

        if (deltaHP / storage.attackRounds < 5) {
            storage.targetUid = "None";
            storage.attackMode = false;
            storage.attackRounds = 0;

        }

    }

    var investCost = 0
    for( var i = me.levels.attack; i < 12; i++) investCost += cost(i);

    if (storage.attackMode == true && me.gold >= investCost && me.levels.attack < 12) return upgrade("attack");

    if (storage.attackMode == false) {
        baseRounds = investCost / farmPower * 1.2; //overestimation with the heal level we should have at this point

        if (findTarget(others, baseRounds) != "None")
            storage.attackMode = true;

        var betterThanMe = others.filter(o => o.worth >= storage.selfWorth);

        if (betterThanMe.length > 0)
            storage.attackMode = true;

        //storage.attackMode = true;


    }

    }

    if (storage.attackMode == true && me.levels.attack == 12) {

    if (storage.targetUid == "None") {

        var target = findTarget(others, 0)
        storage.targetUid = target;
        storage.attackRounds = 0;
        return attack(target);

    }

    return attack(storage.targetUid)

    }



    //otherwise farm

    if (me.hp < 50) {
    storage.expectHP += 5 + me.levels.heal;
        return heal();
    }

    if (me.gold >= cost(me.levels.farm) && storage.attackMode == false)
        return upgrade("farm");

    //upgrade heal, so we can farm more, but increase farm ability faster
    if (me.levels.farm > 5 && me.levels.heal < 10 && me.gold >= 2*cost(me.levels.heal))
        return upgrade("heal");


   //be opportunistic - check if killing someone is more profitable than farming
    killable = others.filter(o => o.hp < me.levels.attack * 1.25 + 5 && o.worth / 2 > farmPower);
    if (killable.length > 0){
    //ideally check for the most worth target here
        return attack(killable[0].uid);
    }

    storage.expectHP -= 2;
    storage.selfWorth += farmPower;
    return farm();

}

6

스위스

function switzerland(self,others,storage){
    let turnsLeft=999-turn()
    let lowestHpBots=others.sort((a,b)=>a.hp-b.hp)
    if(!storage.worth){
        storage.worth=0
        storage.prevGold=25
    }else if(self.gold>storage.prevGold){
        storage.worth+=self.gold-storage.prevGold
    }
    if(others.length===1&&storage.worth>others[0].worth){
        //stun lock the other bot if there are only 2 left and I can win
        return stun(others[0].uid)
    }else if(self.hp<=(95-self.levels.heal)){
        return heal()
    }else if(lowestHpBots[0]&&lowestHpBots[0].hp<20&&lowestHpBots[0].worth/2>2*self.levels.farm+5&&self.hp+self.shield>=110){
        //kill assist
        return attack(lowestHpBots[0].uid)
    } else if(self.shield<=50||self.shield<=5500/others.length&&self.shield<=1200&&turn()>=20||lowestHpBots[1]&&lowestHpBots[1].hp>self.hp+self.shield){
        return shield()
    }else if(self.gold>=cost(self.levels.shield)&&self.levels.shield<=8){
        return upgrade("shield")
    } else if(self.gold>=cost(self.levels.farm)&&(turnsLeft+1)*(2*(self.levels.farm)+5)<turnsLeft*(2*(self.levels.farm+1)+5)){
        return upgrade("farm")
    } else if(self.gold>=cost(self.levels.heal)&&(turnsLeft+1)/(self.levels.heal+5)*(2*self.levels.farm+5)<turnsLeft/(self.levels.heal+6)*(2*self.levels.farm+5)&&self.levels.heal<=2){
        return upgrade("heal")
    }else{
        return farm()
    }
}

이름에서 알처럼,이 봇은 중립 천천히 금을 구축 대부분 중립 (지금 도움이 죽일 죽을거야 봇) 그냥 농장과 치유, ( 다만 스위스 등 )


6

농장, 공격, 방패, 심지어 치유되는 봇

(짧은 이름입니다 TBTFASAEHBNS 와 착각하지, TBTPTGCBCBA )

function TBTFASAEHBNS(me, others, storage) {
    this.getLevel = function (type) {
        return (typeof me.levels[type] === 'undefined' ? 0 : me.levels[type]);
    };

    this.getPower = function (type, level) {
        if (typeof level === 'undefined') level = this.getLevel(type);
        if (type === 'heal') return level + 5;
        if (type === 'attack') return (level * 1.25) + 5;
        if (type === 'shield') return (level * 1.5) + 5;
        if (type === 'farm') return (level * 2) + 5;
    };

    this.canUpgrade = function (type) {
        return myGold >= cost(this.getLevel(type));
    };

    this.farmOrUpgradeFarm = function () {
        if (this.canUpgrade('farm')) return upgrade('farm');
        if (myHp < 3) return heal();
        return farm();
    };

    let currentTurn = turn(),
        myGold = me.gold,
        myHp = me.hp,
        myShield = me.shield,
        myTotalHp = myHp + myShield,
        myHealPower = this.getPower('heal'),
        myShieldPower = this.getPower('shield'),
        myAttackPower = this.getPower('attack'),
        myFarmPower = this.getPower('farm'),
        topAttackPower = 0,
        attackOptions1 = [],
        attackOptions3 = [],
        attackOptions2 = [],
        finalTurns = 980;

    if (currentTurn === 1) {
        storage.othersInfo = {};
    }

    others.sort((a, b) => b.attack - a.attack);
    for (let i = 0; i < others.length; i++) {
        let other = others[i];

        if (i < 3) topAttackPower += this.getPower('attack', other.attack);

        if (other.worth > myFarmPower) {
            if (other.hp <= myAttackPower) {
                attackOptions1.push(other);
            } else {
                if (typeof storage.othersInfo[other.uid] !== 'undefined') {
                    let otherHpChange = storage.othersInfo[other.uid].hp - other.hp;

                    if (other.hp - otherHpChange <= 0) {
                        attackOptions2.push(other);
                    } else if (other.hp - (otherHpChange * 3) <= 0) {
                        attackOptions3.push(other);
                    }
                }
            }
        }

        storage.othersInfo[other.uid] = {hp: other.hp};
    }

    if (myTotalHp < (topAttackPower * 7) + 5) return shield();
    if (currentTurn <= 10) return this.farmOrUpgradeFarm();

    if (attackOptions1.length > 0) {
        attackOptions1.sort((a, b) => b.worth - a.worth);
        return attack(attackOptions1[0].uid);
    } else if (attackOptions2.length > 0) {
        attackOptions2.sort((a, b) => b.worth - a.worth);
        return attack(attackOptions2[0].uid);
    } else if (attackOptions3.length > 0) {
        attackOptions3.sort((a, b) => b.worth - a.worth);
        return attack(attackOptions3[0].uid);
    }

    if (currentTurn <= 20) return this.farmOrUpgradeFarm();
    if (currentTurn < finalTurns && myShieldPower < topAttackPower / 2 && Math.random() * 15 < 1 && this.canUpgrade('shield')) return upgrade('shield');
    if (currentTurn < finalTurns && this.canUpgrade('farm')) return upgrade('farm');
    if (currentTurn < finalTurns && myHealPower < 10 && this.canUpgrade('heal')) return upgrade('heal');
    if (myHp < 3) return heal();
    return farm();
}

이 봇은 기본적으로 :

  • 시작시 농사를 짓습니다.
  • 필요할 때 스스로 방어
  • 죽일 수 있거나 누군가를 죽일 기회가 있다고 생각 될 때 공격
  • 여기 저기 업그레이드
  • 나머지 시간에 농장
  • 기절하지 마십시오

편집 1 : 많은 게임의 테스트를 기반으로 문제를 수정하고 봇의 작은 것들을 개선했습니다.

편집 2 : 쉴드 업그레이드 감소.


2
내가 그 이름을 보자 마자 나는 그것이 당신의 봇이 될 것이라는 것을 알았습니다 (:
Redwolf Programs

긴 이름에 대해 미안하지만 중독되어 있습니다!
Night2

1
어쩌면 그것은 좋은 봇의 표시 일 것입니다 ... 내 테스트에 따르면 5 위를 차지합니다
Redwolf 프로그램

5

스나이퍼 봇

이 봇은 누군가가 실제로 정기적으로 공격하는 봇을 추가하기 시작하는 경우에만 효과적입니다. SmartFarmer는 현재 최적화 된 솔루션입니다

  1. 원샷을 얻을 수 있으면 치유
  2. 30 세 미만이면 치료
  3. 농사보다 더 많은 돈을 벌 수 있다면 봇 공격
  4. 여유가 있다면 농업 업그레이드
  5. 체력이 80 이하인 경우 치유력이 향상되고
  6. 전원

독수리는 공격이 필요하지 않습니다

function sniperBot(me, others){
    if(me.hp < 30) return heal();
    for(var i = 0; i < others.length; i++)if(others[i].attack > me.hp)return heal();
    var target = -1;
    var targetWorth = me.levels.farm * 2 + 5;
    for(var i = 0; i < others.length; i++) {
        if (others[i].hp <= 1.25 * me.levels.attack + 5 && others[i].worth / 2 > targetWorth) {
            target= others[i].uid;
            targetWorth = others[i].worth / 2;
        }
    }
    if(target!=-1) return attack(target);
    if(me.gold >= cost(me.levels.farm)) return upgrade("farm");
    if(me.hp < 50 && me.gold >= cost(me.levels.heal)) return upgrade("heal");
    return farm();
}

int2 행의 예기치 않은 식별자 ( ). ReferenceError : 상태가 정의되지 않았습니다.
Draco18s

해야합니까 me.hp?
mbomb007

죄송합니다. 자바 스크립트가 처음입니다. 도움을 주셔서 감사합니다
B0RDERS

당신은 if(me.hp <30 && ...)이 (65 LVL) 문제에 대한 치유의 터무니없는 수준을 필요로의 계정에 바로 첫 번째 절을 단순화 할 수
Veskah

@Veskah 지적 해 주셔서 감사합니다. 그것은 최소 hp가 높을 때부터 남은 것입니다
B0RDERS

5

BullyDozerBot

function BullyDozerBot(me, others, storage){
    if(me.gold >= cost(me.levels.attack) && (storage.bullyTarget && storage.bullyTarget.hp < 500)) {
        return upgrade("attack");
    }
    if(storage.bullyTarget==null){
        storage.bullyTarget=others.sort((a,b) => a.hp - b.hp)[0];
    }
    potential_victim = others.find( bot => bot.hp <= me.levels.attack * 1.25 + 5 );
    if (potential_victim) {
        return attack(potential_victim.uid);
    }
    var targetlives = false;
    for(var i = 0; i < others.length; i++) {
        if (others[i] == storage.bullyTarget) {
            targetlives = true;
            break;
        }
    }
    if(!targetlives){
        storage.bullyTarget=others.sort((a,b) => a.hp - b.hp)[0];
    }
    if(storage.bullyTarget.hp >= 500) {
        if(me.gold >= cost(me.levels.farm)) {
            return upgrade("farm");
        }
        for(var i = 0; i < others.length; i++){
          if(others[i].attack*1.25+10 > me.hp){
            return heal();
          }
        }
        return farm();
    }
    return attack(storage.bullyTarget.uid);
}

BullyBot의 매쉬업 및 기타 비트. 낙관론자는 내가 요크 한 짧고 달콤한 기회 주의적 공격 청크를 가졌다 (다른 봇도 비슷한 계산을 수행하지만).

대상을 기절시켜 대상을 괴롭히는 대신 달콤하고 달콤한 전리품으로 살해합니다 . 또한 괴롭힘에 대해 무리에서 가장 약한 대상을 목표로하지만 가장 약한 대상의 HP가 너무 높으면 포기하고 농사를 지을 것입니다.


당신은 죽음에 자신을 농업하고 있습니다. 내 수정 사항 수락 :)
B0RDERS

1
@AndrewBorders Ha는 그것에 대해 생각조차하지 않았습니다. 감사.
Draco18s

이 봇은 보호자 봇이 돌아올 때까지 훌륭했습니다.
B0RDERS

@ B0RDERS 방패는 시간을 낭비하더라도 매우 강력합니다.
Draco18s

5

피즈 버즈

function FizzBuzz(me, others, storage) {
    if (!storage.target) storage.target = others[0].uid;
    const uids = others.map(x=>x.uid);
    if(!uids.includes(storage.target) || (turn() % 30 === 0 
        && others[uids.indexOf(storage.target)].hp>30))
        storage.target = others[0].uid;

    if (cost(me.levels.farm) < me.gold) return upgrade("farm");
    if (turn() % 15 === 0) return heal();
    if (turn() % 3 === 0) return farm();
    if (turn() % 5 === 0) return heal();

    if (cost(me.levels.attack) < me.gold) return upgrade("attack");
    return attack(storage.target);
}

대부분 공격적인 봇. 그것이 실제로 FizzBuzz를 할 수 없기 때문에 매우 화가 나서 대신 Buzzes를 대신합니다. Fizzing이나 Buzzing이 아닌 경우 다른 봇에서 30 턴 동안 칩을 버리고 진행하지 않을 경우 다른 봇을 포기하고 선택합니다.

일관되게 일관성이 없습니다. 신경 쓰지 말고 컨트롤러를 업데이트하십시오. 이제 항상 팩 중간에있는 것처럼 보입니다.


나는이 개념을 좋아한다. 현재 상황에 관계없이 자체 속도로 계속 흔들립니다.
Ness

5

불량배

function bullyBot(me, others, storage){
    if(turn()==1){return farm();}
    if(storage.bullyTarget==null){storage.bullyTarget=others[0].uid;}

    var targetlives = false;
    for(var i = 0; i < others.length; i++) {
        if (others[i].uid == storage.bullyTarget) {
            targetlives = true;
            break;
        }
    }
    if(!targetlives){storage.bullyTarget = others[0].uid;}

    return stun(storage.bullyTarget);
}

온라인으로 사용해보십시오!

이길 수는 없지만 목표를 달성하지 못하도록 최선을 다할 것입니다. bullyBot은 또한 첫 번째 턴에 농장을 운영하여 외부 영향이 없다면 목표를 5-0으로이기거나 5-5로 묶습니다.


5

저스트 팜

나는 간단하게 시작할 것이라고 생각했다.

function justFarm(me, others){
    return farm();
}

13
이 봇은 2HP 농업 비용으로 인해 자살 할 것입니다.
Draco18s

@ Draco18s 라운드는 그 전에
끝나지만

1
기술적으로 사실 이지만 기본 종료 시간이 1000
Draco18s

두 가지 예제 봇을 이겼지 만 더 나은 결과를 도출하기 위해 몇 가지 제출이 더 있습니다.
익명

@Anonymous 아마도 치유와 농업 업그레이드를 포함하는 것으로 충분할 것입니다. 가장 많은 금을 얻는 것이 궁극적 인 목표이므로 봇의 주요 직무를 그대로 유지할 수 있습니다. 지금까지 치료 모드 및 팜 모드와 같은 "모드"가있는 봇은 없었습니다. 흥미로운 접근 방식이 될 수 있습니다.
Redwolf 프로그램

4

스 캐빈 저봇 (V2)

전에는 그다지 스 캐빈 저가 아니라는 것을 깨달았습니다. 새로운 전략은 다른 봇을 죽일 수있을 때까지 기다립니다. 아무도 죽일 수 없다면, 앉아서 방패를 만듭니다.

function scavengerBot(me, others) {
    if (me.shield < (me.levels.shield * 1.5 + 5)) {
        return shield();
    }
    var currentAttack = 1.25 * me.levels.attack + 5;
    var hasVictim = false;
    var victimUid = 0;
    var maxWorth = 0;
    for (var i = 0; i < others.length; i++) {
        var hp = others[i].hp;
        var worth = others[i].worth;
        if (hp <= currentAttack && worth > maxWorth) {
            hasVictim = true;
            victimUid = others[i].uid;
            maxWorth = worth;
        }
    }

    if (hasVictim) {
        return attack(victimUid);
    }

    if (me.gold >= cost(me.levels.attack)) {
        return upgrade("attack");
    }

    if (me.gold >= cost(me.levels.shield)) {
        return upgrade("shield");
    }
    return shield();
}

1
me.levels.attacl?
Draco18s

좋은 캐치, 고정
반박

4

무디

function Moody(me, others, storage) {
    health = me.hp + me.shield;
    damage = storage.previous_health - health;
    storage.previous_health = health;
    if( damage > 2 ) {
        storage.fear = 2;
    }
    if( storage.fear ) {
        storage.fear -= 1;
        if( me.gold >= cost(me.levels.heal) )
            return upgrade("heal");
        return heal();
    }
    if ( me.hp <= 50 ) {
        return heal();
    }
    if (cost(me.levels.farm) < 0.15 * (1000 - turn())) {
        if( me.gold >= cost(me.levels.farm) )
            return upgrade("farm");
        if( me.gold >= cost(me.levels.heal) )
            return upgrade("heal");
        return farm();
    }
    rich_bots = others.sort( (x,y) => y.worth - x.worth );
    richest_enemy = rich_bots[0];
    if (richest_enemy.hp >= storage.target_hp) {
        storage.anger = true;
    }
    storage.target_hp = NaN;
    if (storage.anger) {
        if( me.gold >= cost(me.levels.attack) ) {
            storage.anger = 0;
            return upgrade("attack");
        }
        return farm();
    }
    storage.target_hp = richest_enemy.hp;   
    return attack(richest_enemy.uid);   
}

Moody 's의 기본 전략은 농업과 치유를 한동안 업그레이드 한 다음 다른 봇을 내림차순으로 빼는 것입니다. 그러나 공격을 받으면 겁이 나고 치유에 다시 초점을 맞 춥니 다. 피해자가 공격보다 더 효과적으로 치유하거나 보호하고 있기 때문에 공격하고 "실패"하면 분노를 느끼고 공격 능력을 업그레이드합니다.


4

적기

function Bandit(me, others, storage) {
    // stuff we need
    const epsilon = 0.3; // really high epsilon
    function argmax(xs) {
        var max = 0;
        var argmax = 0;
        for (var i=0; i<xs.length; i++) {
            if (xs[i]>max) {
                max = xs[i];
                argmax = i;
            }
        }
        return argmax;
    }
    function base3ToActionSeries(strategy) {
        const actions = [shield(), farm(), heal()];
        var idxs = []
        var strategy_cut = strategy;
        for (var i = 81; i >= 1; i /= 3) {
            if (strategy_cut >= 2 * i) {idxs.push(2); strategy_cut -= 2*i}
            else if (strategy_cut >= i) {idxs.push(1); strategy_cut -= i}
            else idxs.push(0);
        }
        return idxs.map(idx => actions[idx]);
    }

    // actual logic starts here
    // current strategy and info to calculate reward
    if (!storage.prior)
        storage.prior = [0,0.03325,0,0.0361,0.0361,0.2372,0,0.2372,0,0.00035,0.0361,0.23555,0.01305,0.0361,0.5798,0.23555,0.62065,0.23555,0,0.2372,0,0.20965,0.5841,0.2372,0,0.21905,0,0.0361,0.0361,0.2081,0.0361,0.0361,0.01455,0.000350,0.62065,0.205,0.000350,0.0361,0.3708,0.0361,0.0323,1.018050,0.5798,0.04495,0.5798,0.23555,0.62065,0.23555,0.62065,1.06395,0.62065,0.23555,0.62065,0.23555,0,0.2372,0,0.2372,0.5841,0.2372,0,0.2372,0,0.23555,0.62065,0.13775,0.5798,1.0257,0.5798,0.23555,0.62065,0.23555,0,0.2339,0,0.2372,0.5841,0.2339,0,0.2372,0,0.0342,0.0361,0.2372,0.03515,0.03325,0.6228,0.2372,0.5841,0.2372,0.0361,0.0130599,0.62065,0.03515,0.0361,1.0665,0.62065,0.24050,0.62065,0.23555,0.51465,0.2372,0.6228,1.0257,0.6228,0.2372,0.5841,0.2372,0.0361,0.0361,0.58195,0.0361,0.0313596,1.0614,0.58195,1.02315,0.58195,0.0342,0.0361,1.0206,0.02255,0.0183,0.02595,1.0206,1.5526,1.0206,0.58195,1.02315,0.58195,0.02765,0.0251,1.0614,0.0007,0.02085,0.3088,0.2372,0.5841,0.2273,0.6185,0.02255,0.6228,0.2372,0.5841,0.2372,0.62065,1.06395,0.62065,1.0665,0.0917,1.0665,0.62065,0,0.62065,0.2372,0.5841,0.2372,0.6228,1.0257,0.6228,0.2372,0.5841,0.2372,0,0.2372,0,0.23225,0.5841,0.2372,0,0.2372,0,0.23555,0.62065,0.23555,0.5798,1.0257,0.5798,0.23555,0.6142,0.23555,0,0.22235,0,0.2372,0.5841,0.2372,0,0.2372,0,0.23555,0,0.21905,0.62065,0.02255,0.62065,0.23555,0.61205,0.23555,0.5798,1.05885,0.5798,1.018050,0.03895,1.018050,0.5798,1.05885,0.5798,0.23555,0.62065,0.23555,0.62065,0.0361,0.62065,0.23555,0.62065,0.23555,0,0.2372,0,0.2372,0.3745,0.2372,0,0.2372,0,0.23555,0.62065,0.23555,0.5798,0.9452,0.5798,0.23555,0.5626,0.23555,0,0.2372,0,0.18175,0.5841,0.0138,0,0.2372,0]
    if (storage.lastScore == null)
        storage.lastScore = 0;
    if (storage.bestStrategy == null)
        storage.bestStrategy = argmax(storage.prior);

    if (cost(me.levels.heal) < me.gold) return upgrade("heal");
    if (cost(me.levels.farm) < me.gold) return upgrade("farm");

    // This barely explores and mostly exploits.
    if (turn() % 5 === 0) {
        // update
        const reward = me.gold/2 - storage.lastScore;
        // biased a bit towards later learned rewards
        storage.prior[storage.bestStrategy] += reward*0.01
        storage.prior[storage.bestStrategy] *= 100/101

        // explore
        if (Math.random() < epsilon) {
            storage.bestStrategy = Math.floor(Math.random()*243);
        }
        else { // exploit
            storage.bestStrategy = argmax(storage.prior);
        } 
        storage.lastScore = me.gold/2;
    }

    var action = base3ToActionSeries(storage.bestStrategy)[turn() % 5];
    return action;
}

먼저 강화 학습 봇에서 시도하십시오. 검색 공간을 좁히기 위해 순전히 방어 적입니다. FizzBuzz의 더 똑똑한 분사-그것은 일련의 다섯 가지 동작을 반복해서 반복합니다. 5 가지 행동은 RL에 의해 선택된 것입니다.

그러나 그것은 대부분 현재 열거를 기반으로합니다. 방금 반복해서 반복되는 5 가지 방어 행동 시리즈의 3 ^ 5 = 243 순열을 모두 생성하고 평균 점수 (200으로 나누어 평균 이득을 얻었습니다) storage.prior배열 에서 100 회 이상 반복합니다 . 그런 다음 게임 중에는 점수 목록을 업데이트하는 엡실론 욕심 접근 방식을 구현하여 미래를 보장합니다. (또한 epsilon = 0.3을 사용하면 epsilon = 0.1보다 나았 기 때문에 방금 유지했습니다.)

scavengerBot과 Optimist 사이에 일관되게 배치하면됩니다. 저는 현재 실제 게임에 대해 더 많은 교육을 진행하고 있으며 전략을 개선 할 수있는 더 나은 방법을 찾고 있습니다.


4

기회 주의자

이것은 내가 생각했던 것과 같은 아이디어를 가지고 있기 때문에 다른 사람들 (특히 ScavengerBot (V2) 및 Unkillable)에서 약간 빌려 왔습니다. 하나 또는 두 가지. 이것은 내가 이길 수 없다는 것을 의미하지만 어딘가 중간에 있어야합니다 (많은 일에서 나에게 대부분 발생합니다).

육즙이 많은 살인을 훔칩니다. 필요한 경우 치료하십시오; 순서대로 팜을 업그레이드하고 공격하고 치료합니다. 그렇지 않으면 농장.

function Opportunist(me, others, storage) {

    // Initializing and keeping track of selfWorth
    if (turn() == 1) {
        storage.selfWorth = 0;
    }
    else if (storage.previousGold < me.gold) {
        storage.selfWorth += (me.gold - storage.previousGold);
    }
    storage.previousGold = me.gold;

    // Me stats
    var me_attack = 1.25 * me.levels.attack + 5;
    var me_heal = me.levels.heal + 5;

    // Look for the juiciest hunk of loot
    // If there are multiple of the highest worth, the last is chosen
    var choice = others[0].uid;
    var mostWorthy = -1;
    for (var i = 0; i < others.length; i++) {
        worth = others[i].worth
        if (others[i].hp <= me_attack && worth >= mostWorthy) {
            choice = others[i].uid;
            mostWorthy = worth;
        }
    }

    // Actions in order of priority
    // The juicy targets must be worth the action
    if (mostWorthy > (storage.selfWorth * 0.25) ) {
        return attack(choice);
    }
    else if (me.hp <= 100 - me_heal) {
        return heal()
    }
    else if (me.gold >= cost(me.levels.farm)) {
        return upgrade("farm");
    }
    else if (me.gold >= cost(me.levels.attack)) {
        return upgrade("attack");
    }
    else if (me.gold >= cost(me.levels.heal)) {
        return upgrade("heal");
    }
    else {
        return farm();
    }
}

1
두 번째 주장은others
SuperStormer

4

겁 먹은 봇

  1. 다른 봇을 찾습니다.
    • 가장 높은 공격
    • 대부분의 부와 HP는 자신의 공격보다 낮습니다
  2. 자사의 HP + 방패 발견보다 낮은 경우 highest attack * (25% of bots), 또는의 하단 근처에 도착 HP + shield그것을 방패 다음,
  3. 자체 공격보다 방패가 낮은 봇을 발견하면 공격합니다.
  4. 건강이 < 50이면 치료됩니다.
  5. 방패, 치유 및 농장을 업그레이드 할 수 있으면 가장 낮은 레벨의 방패를 업그레이드합니다.
  6. 그것은 농장
function ScaredBot(me, others) {
    const my_attack = me.levels.attack * 1.25 + 5;
    const my_defense = me.hp + me.shield;

    var max_attack_val = 0;
    var min_hp_worth = 0;
    var min_hp_id = null;
    var hp_under_me = 0;
    for (var i=0; i<others.length; i++){
        if (others[i].hp < my_attack && others[i].worth > min_hp_worth){
            min_hp_id = others[i].uid;
            min_hp_worth = others[i].worth;
        }
        if (others[i].attack*1.25+5 > max_attack_val){
            max_attack_val = others[i].attack*1.25+5;
        }
        if (others[i].hp < my_defense && others[i].hp > 0){
            hp_under_me++;
        }
    }
    if (max_attack_val*0.25*others.length > my_defense || hp_under_me < 0.25*others.length){
        return shield();
    }
    else if (min_hp_id != null){
        return attack(min_hp_id);
    }
    else if (me.hp < 50){
        return heal();
    }
    else {
        var min_lvl = NaN;
        var min_name = null;
        const vals = [me.levels.heal, me.levels.shield, me.levels.farm];
        const names = ["heal", "shield", "farm"];
        for (var i=0; i<vals.length; i++){
            if (!(min_lvl < vals[i])){
                min_lvl = vals[i];
                min_name = names[i];
            }
        }
        if (me.gold > cost(min_lvl)){
            return upgrade(min_name);
        }
        return farm();
    }
}

아이디어는 가능한 한 오래 살아남고 그렇지 않으면 업그레이드 할 수있는 안전하고 저렴한 방법으로 금을 얻는 것입니다.

업그레이드 우선 순위와 차폐 여부를 결정할 때의 조건을 조정해야합니다.


3

SmartFarmer

농장, 업그레이드 농업, 건강이 좋지 않은 경우 치유합니다. 진정 공격적인 봇이 도착할 때까지 농업은 압도적으로 보였다. 이제 내 봇이 죽습니다 :-(

function smartFarmer(me, others){
    if(me.hp < 13) return heal();
    for(var i = 0; i < others.length; i++)if(others[i].attack * 1.25 + 5 > me.hp)return heal();
    if(me.gold >= cost(me.levels.farm)) return upgrade("farm");
    if(me.levels.heal < 9 && me.levels.farm > me.levels.heal + 7 && me.gold >= cost(me.levels.heal)) return upgrade("heal");
    return farm();
}

1
나는 (수동으로) 본질적으로 얻을 수있는 최대 가치와 내가 얻을 수있는 최고의 숫자를 확인하기 위해 동일한 전략을 테스트하고 있었고, 치유가 업그레이드 될 때 약간 금을 늦추고 (골드> = 비용 * 2 사용) lvl10까지 올라 갔다. .
니콜라이

그 가격 승수는 좋은 생각입니다. 비슷한 것을 추가했습니다. 나는 당신이 어떤 숫자를 가지고 있는지
알고 싶습니다

3

모트

function Mort(me, others, storage) {
    if (me.hp <= 100 - (me.levels.heal + 5))
        return heal();
    actions = ["farm", "heal", "attack"].filter(action => cost(me.levels[action]) <= me.gold).map( action => [upgrade(action), 1000 - turn() - cost(me.levels[action]) ] )
    my_damage = me.levels.attack * 1.25 + 5;
    actions = actions.concat(others.map( bot => [ attack(bot.uid), (bot.worth/2)/Math.max(bot.hp/(my_damage-(bot.hp > my_damage ? 5 : 0)),1) ] ));
    actions.push( [farm(), (2 * me.levels.farm + 5)*(1-2/(me.levels.heal+5))] );
    return actions.sort( (x,y) => y[1] - x[1] )[0][0];
}

각 턴은 각 봇을 죽일 때의 상각 이익과 농업 및 치유의 이익을 비교하고 최상의 옵션을 선택합니다. 실제로 상태를 사용하여 봇을 죽이는 데 걸리는 시간을 알아 내야하지만, 지금은 모든 봇이 다른 봇이받는 피해의 순으로 평균 5 점을 치유하거나 방어한다고 가정합니다.


3

친절한 봇

function menShengFaDaCai(me, others) {
  // heal if needed
  const maxAttack = Math.max(...others.map(bot => bot.attack));
  const maxAttackCost = maxAttack * maxAttack + 5;
  const othersHp = others.map(bot => bot.hp).sort();
  const targetHp = othersHp[Math.ceil(othersHp.length / 2)];
  if (me.hp < 95 && me.hp < Math.max(maxAttackCost * 2, targetHp, 50)) return heal();

  // upgrade heal and farm if possible
  const { heal: healLevel, farm: farmLevel } = me.levels;
  const gain = (heal, farm) => ((5 + heal) / 2) * (2 * farm + 5) / ((5 + heal) / 2 + 1);
  const gain0 = gain(healLevel, farmLevel);
  const gainUpgradeHeal = gain(healLevel + 1, farmLevel);
  const gainUpgradeFarm = gain(healLevel, farmLevel + 1);
  const gainUpgradeHealPerGold = (gainUpgradeHeal - gain0) / cost(healLevel);
  const gainUpgradeFarmPerGold = (gainUpgradeFarm - gain0) / cost(farmLevel);
  const preferUpgradeHeal = gainUpgradeHealPerGold > gainUpgradeFarmPerGold;
  const mayOffer = type => me.gold >= cost(me.levels[type]);
  if (preferUpgradeHeal && mayOffer('heal')) return upgrade('heal');
  if (!preferUpgradeHeal && mayOffer('farm')) return upgrade('farm');

  // keep farming
  return farm();
}

others[0].hp입니다 hp + shield대신 hp...


4
함수 이름을 영어로 번역 할 수있는 사람이 있습니까? ^ _ ^
tsh

4
Google Translate에 따르면 "闷声 发大财"은 "Muffled"를 의미합니다. 그것이 당신이 원하는 것이 아니며 실제로 또 다른 Google Translate epic 실패라고 확신하십시오. 더 자세히 검색했으며 모든 결과에는 여기에 사용할 수있는 단일 영어 단어가 없다고 언급하는 것처럼 보이므로 다음과 같이 유지하는 것이 좋습니다 사실, 그것은 일반적으로 우리가 조용히 일하고 결과가 스스로를 말하고 전통적인 철학에 도달해야한다는 것을 의미하는 중국 전치사 인 것처럼 보인다. 불행히도, 나는 그것을 직접 번역 할 중국어를 전혀 모른다. : D
Outgolfer Erik

1
또한 의도적으로 말 그대로, 조용한 것 "소리를 은폐"암시闷声V : 네이티브 중국어 스피커, 그것은 "자동으로 큰 돈을 벌"같은 것을 의미
린의 푸리에 변환

1
교활한? 언더 레이더? DontMindMe? 주의 디플렉터?
피터 테일러

3

회계사

이 실용적인 봇은 가장 경제적으로 유리한 움직임을 계산하지만 모든 경계 봇의 문제를 피하기 위해 공격 프로파일을 낮게 유지하는 것을 좋아합니다. 그는 무방비 또는 그들에게 먹이를 주려고하지 않습니다. 오히려 그는 가장 큰 도움을줍니다.

function accountant(me, others, storage) {
    if (turn() == 1) {
        storage.lastHP = me.hp + me.shield;
        storage.hisAttack = 5;
        storage.timesAttacked = 0;
        storage.lastAttack = -1;
        storage.healths = [], storage.uids = [], storage.heals = [];
        for (var i = 0; i < others.length; i++) {
            storage.healths.push(others[i].hp);
            storage.uids.push(others[i].uid);
            storage.heals.push(5);
        }
    }
    storage.timesAttacked++;
    if (storage.lastHP == me.hp + me.shield) storage.timesAttacked = 0;
    else storage.hisAttack = storage.lastHP - me.hp - me.shield;
    storage.lastHP = me.hp + me.shield;
    var attacks = [];
    for (var i = 0; i < others.length; i++) if (others[i].uid != me.uid) attacks[i] = 1.25 * others[i].attack + 5;
    attacks.sort();
    for (var i = 0; i < others.length; i++) {
        storageIndex = storage.uids.indexOf(others[i].uid);
        if (storage.heals[storageIndex] < others[i].hp - storage.healths[storageIndex] + (others[i].uid == storage.lastAttack ? 1.25 * me.levels.attack + 5 : 0)) others[i].hp - storage.healths[storageIndex] + (others[i].uid == storage.lastAttack ? 1.25 * me.levels.attack + 5 : 0);
    }
    var maxProfitTurn = 2 * me.levels.farm + 5, victimID = -1, tempProfit;
    for (var i = 0; i < others.length; i++) {
        storageIndex = storage.uids.indexOf(others[i].uid);
        tempProfit = others[i].worth / 2 * (1.25 * me.levels.attack + 5 - storage.heals[storageIndex]) / others[i].hp;
        if (tempProfit > maxProfitTurn) {
            victimID = others[i].uid;
            maxProfitTurn = tempProfit;
        }
    }
    maxUrgentProfit = 0;
    for (var i = 0; i < others.length; i++) if (maxUrgentProfit < others[i].worth / 2 && others[i].hp <= attacks.slice(0, 4).reduce((a, b) => a + b) + 1.25 * me.levels.attack + 5) {
        maxUrgentProfit = others[i].worth / 2;
        victimID = others[i].uid;
    }
    if (maxUrgentProfit > 0) {
        storage.lastAttack = victimID;
        return attack(victimID);
    }
    storage.lastAttack = -1;
    if (storage.timesAttacked == 0) {
        if (me.levels.shield < 20 && me.gold >= cost(me.levels.shield)) return upgrade("shield");
        if (me.levels.heal < 5 && me.levels.shield >= me.levels.heal + 5 && me.gold >= cost(me.levels.heal)) return upgrade("heal");
        if (Math.random() < Math.pow((me.hp + me.shield) / 100, -2)) {
            storage.lastHP += 1.5 * me.levels.shield + 5;
            return shield();
        }
    }
    else {
        if (Math.random() < .5 || me.hp + me.shield - storage.hisAttack - attacks[0] <= 10) {
            storage.lastHP += 1.5 * me.levels.shield + 5;
            return shield();
        }
        if (me.levels.shield < 20 && me.gold >= cost(me.levels.shield)) return upgrade("shield");
        if (me.hp <= 2) {
            storage.lastHP += me.levels.shield + 5;
            return heal();
        }
        storage.lastHP -= 2;
        return farm();
    }
    if (me.gold >= cost(me.levels.farm)) return upgrade("farm");
    storage.lastAttack = victimID;
    if (victimID != -1) return attack(victimID);
    if (me.hp <= 2) {
        storage.lastHP += me.levels.shield + 5;
        return heal();
    }
    storage.lastHP -= 2;
    return farm();
}

3

reallyCommittedTurtle

function reallyCommittedTurtle(me, others, storage) {
    if( storage.previousHP ) {
        others.forEach ( o => {storage.deltaHP[o.uid] = o.hp - storage.previousHP[o.uid]; storage.previousHP[o.uid] = o.hp } );
    }
    else {
        storage.previousHP = {};
        storage.deltaHP = {};
        others.forEach ( o => storage.previousHP[o.uid] = o.hp );
    }
    if (turn() < 3)
        return upgrade("shield");
    if ( me.shield < 400 || others.find( o=> o.deltaHP < -2 ) )
        return shield();
    if (me.hp <= 95 - me.levels.heal) {
        if (me.gold >= cost(me.levels.heal))
            return upgrade("heal");
        return heal();
    }
    rich_bots = others.sort( (x,y) => y.worth - x.worth );
        potential_victim = rich_bots.find( bot => bot.hp + storage.deltaHP[bot.uid] <= me.levels.attack * 1.25 + 5 );
        if (potential_victim && potential_victim.worth/2 > me.levels.farm*2 + 5)
            return attack(potential_victim.uid);
    if (me.gold >= cost(me.levels.farm))
        return upgrade("farm");
    return farm();
}

여기 있습니다. 정말 위험합니다. 농업은 당신의 가치를 높이고 목표로 삼습니다. 따라서 거대한 방패를 세우고 모든 폭력이 사라질 때까지 농사를 짓는 것은 안전하지 않습니다. 그런 다음 껍질에서 머리를 찌르고 농업을 시작할 수 있습니다. 또는 살해 지원. 더 나은 것을 지불하십시오.


2

보호자

하나 이상의 제출물을 가질 수 있습니다.

CampBot의 포크. 방패 대신 공격에 집중합니다. CampBot과 같이 무작위로 공격하지 않고 공격 통계가 높은 플레이어를 공격하는 데 우선 순위를 표시합니다. 치유보다는 농업 업그레이드에 중점을 둡니다.

function guardian(self,others,storage){
    if(!storage.victimBlacklist){
        storage.victimBlacklist=[]
    }
    let turnsLeft=999-turn()
    function findVictim(){
        let potentialVictims=others.filter(bot=>!storage.victimBlacklist.includes(bot.uid))
        if(potentialVictims.length>0){
            let victim=potentialVictims.reduce((el, em) => el.attack > em.attack ? el : em);
            storage.victimUid=victim.uid
            storage.victimPrevHp=victim.hp
            storage.prevMove="attack"
            return attack(victim.uid)
        }else{
            storage.prevMove="farm"
            return farm()
        }   
    }
    if(self.hp<=(95-self.levels.heal)){
        storage.prevMove="heal"
        return heal()
    } else if(self.gold>=cost(self.levels.attack)){
        storage.prevMove="upgrade"
        return upgrade("attack")
    } else if(self.gold>=cost(self.levels.farm)&&turnsLeft>100&&self.levels.heal<=1){
        storage.prevMove="upgrade"
        return upgrade("farm")
    } else if(!storage.victimUid){
        return findVictim()
    }else if(Object.values(others).map(bot=>bot.uid).includes(storage.victimUid)){
        let victimCurrHp=Object.values(others).filter(bot=>bot.uid==storage.victimUid)[0].hp
        if(storage.victimPrevHp<victimCurrHp&&storage.prevMove==="attack"){
            storage.victimBlacklist.push(storage.victimUid)
            storage.victimUid=undefined
            return findVictim()
        }else{  
            storage.victimPrevHp=victimCurrHp
            storage.prevMove="attack"
            return attack(storage.victimUid)
        }
    }else{
        storage.victimUid=undefined
        return findVictim()
    }
}

내 봇이 무작위로 공격하지 않습니다 ...
SuperStormer

원하는만큼 여러 번 게시 할 수 있습니다. 제가 생각하는
메리 어

@SuperStormer 나는 당신이 완전히 무작위가 아니라는 것을 알고 있습니다 :let victim=potentialVictims[Math.floor(Math.random()*potentialVictims.length)]
Anonymous

그러나 먼저 공격 할 가치가없는 것들을 걸러냅니다
SuperStormer

나는 당신이 이것을 게시했을 때 이퀄라이저라는 비슷한 봇에서 일하고있었습니다. 나는 아직도 그것을 잘 조정하고 있지만, 나는 당신의 아이디어 중 일부를 좋아합니다.
B0RDERS

2

란도

이 어리석은 녀석은 약간의 편견과 균일 한 무작위성을 기반으로 행동을 선택할 것입니다. 임의로 선택한 동작이 작동하지 않으면 다음 선택으로 내려갑니다.

따라서 평균적으로 그는 거의 2/9 시간을 공격하고 농장은 거의 3/9 시간을 공격해야합니다. 그가 업그레이드 할 수 있거나 치유 / 방패가 그만한 가치가 있다면 나머지는 약 1/9 확률입니다.

그는 잘 수행하지는 못하지만 적어도 그가 최고를 다 스릴 가능성은 적습니다. 이것이 Rando의 전체 목적입니다. 그는 단지 자신을 믿어야합니다! 모든 옵션은 그 앞에 놓여 있습니다. 그는 주어진 상황에 필요한 것을 선택하기 만하면됩니다.

function Rando(me, others, storage) {

    var rnum = Math.floor(Math.random() * 9);
    switch (rnum) {
        case 0:
            if (me.gold >= cost(me.levels.shield)) {
                return upgrade("shield");
            }
        case 1:
            if (me.hp >= 100 - (me.levels.heal + 5) && me.levels.shield >= me.levels.heal) {
                return shield();
            }
        case 2:
            if (me.hp < 100 - (me.levels.heal + 5)) {
                return heal();
            }
        case 3:
            if (me.gold >= cost(me.levels.farm)) {
                return upgrade("farm");
            }
        case 4:
            if (me.gold >= cost(me.levels.heal)) {
                return upgrade("heal");
            }
        case 5:
            if (me.hp > 2) {
                return farm();
            }
        case 6:
            // Beat down the leader!
            var currentLeader = others[0].uid;
            var leaderWorth = -1;
            for (var i = 0; i < others.length; i++) {
                worth = others[i].worth;
                if (worth > leaderWorth) {
                    currentLeader = others[i].uid;
                    leaderWorth = worth;
                }
            }
            return stun(currentLeader);
        case 7:
            if (me.gold >= cost(me.levels.attack)) {
                return upgrade("attack");
            }
        case 8:
            // Find the juiciest kill (if any), or attack the strongest
            var choice = others[0].uid;
            var choiceWorth = -1;
            var currentLeader = others[0].uid;
            var leaderWorth = -1;
            for (var i = 0; i < others.length; i++) {
                worth = others[i].worth
                if (worth > leaderWorth) {
                    currentLeader = others[i].uid;
                    leaderWorth = worth;
                }
                if (others[i].hp <= (1.25 * me.levels.attack + 5) && worth >= choiceWorth) {
                    choice = others[i].uid;
                    choiceWorth = worth;
                }
            }
            if (choice > -1) {
                return attack(choice);
            }
            else {

                return attack(currentLeader);
            }
        default:
            return false
    }
}

( "기본"은 불필요하지만 강력한 코드에는 좋은 코딩 방법이라고 생각합니다.)


2
"그는 단지 자신을 믿어야
만한

2

봇 죽이기

function killBot(me, others, storage) {
    // If I lost health since my last check, shield.
    if (me.hp < storage.hp){
        storage.hp = me.hp;
        return shield();
    }

    storage.hp = me.hp;

    health = Math.min(...others.map(o => o.hp));
    // If I have the least health or can be one-shot, shield.
    if (others.some(o => o.attack * 1.25 + 5 >= me.hp + me.shield) || (health > me.hp + me.shield && health < 500)) return shield();

    // If I can kill someone, kill them!
    targets = others.filter(o => o.hp < me.attack);
    if (targets.length > 0){
        wealth = Math.max(...targets.map(o => o.worth));
        targets = targets.filter(o => o.worth == wealth);
        target = targets[Math.floor(Math.random()*targets.length)];
        return attack(targets[0].uid);
    }

    // If I have the money, upgrade shielding or attack
    if (me.levels.shield <= me.levels.attack){
        if (cost(me.levels.shield) < me.gold) return upgrade("shield");
    } else {
        if (cost(me.levels.attack) < me.gold) return upgrade("attack");
    }

    // Otherwise, attack the weakest!
    targets = others.filter(o => o.hp == health);
    // And if there's a tie, attack the wealthiest.
    wealth = Math.max(...targets.map(o => o.worth));
    targets = targets.filter(o => o.worth == wealth);
    target = targets[Math.floor(Math.random()*targets.length)];
    return attack(targets[0].uid);
}

간단한 봇인 Kill Bot은 적을 죽이고 싶어합니다. 차폐는 치유보다 훨씬 효율적이기 때문에 (특히 수평이 맞을 때) Kill Bot은 공격 할 때마다 항상 스스로를 보호함으로써 항상 매력적이지 않은 대상이 되려고합니다. Kill Bot은 주변의 약하고 평화로운 봇들 사이에서 상당히 잘합니다 (당신은 그들에게 경멸감을 느낄 수 있습니다).


3
o.attack공격 수준이 아니라 데미지입니다
Redwolf 프로그램

2

농장 건강 봇

@Anonymous 'JustFarm 봇에서 분기

function farmhealBot(me, others, storage) {
  if (me.hp <= 95)
    return heal();
  else return farm();
}

2

불멸의

방패를 사용하여 Draco18의 봇 수정 (다른 봇보다 효과적)

function indestructible(me){
    if (me.hp < 100) {
        return heal();
    } else if (me.shield < 15) {
        return shield();
    } else {
        if (me.gold >= cost(me.levels.shield)) {
            return upgrade("shield");
        } else if (me.gold >= cost(me.levels.farm)) {
            return upgrade("farm");
        } else {
            return farm();
        }
    }
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.