Trận chiến vàng KoTH


43

Thử thách này đã kết thúc. Để xem điểm số cuối cùng của các đối thủ, bấm vào đây

Trong thử thách này, mỗi bài nộp là một bot. Mỗi bot phải là một chức năng Javascript. Bots sẽ chiến đấu để có được tổng giá trị vàng cao nhất. Vàng có thể được nuôi, hoặc kiếm được từ việc giết các bot khác, và được sử dụng để nâng cấp chữa bệnh, tấn công, che chắn và canh tác.

Mục tiêu:

Qua một số vòng chứa tới 1000 lượt (kết thúc khi chỉ còn một bot), bot có tổng giá trị cao nhất (tổng số vàng thu được) là người chiến thắng.

Biến:

Trong mỗi lượt, mỗi bot còn sống (> 0 HP) sẽ được chạy một lần. Nó có thể trả về một nước đi, có thể là một trong những điều sau đây:

  • Chữa lành: Lấy lại HP
  • Tấn công: Loại bỏ HP khỏi bot khác
  • Khiên: Bảo vệ chống lại các cuộc tấn công sau này
  • Stun: Bỏ qua lượt tiếp theo của bot
  • Trang trại: Kiếm vàng với chi phí HP
  • Nâng cấp: Thực hiện một số di chuyển tốt hơn

Tất cả các bot sẽ quay trở lại di chuyển của chúng trước khi bất kỳ được thực hiện, do đó, làm choáng, hồi máu, tấn công, che chắn, v.v. sẽ không ảnh hưởng đến bất kỳ bot nào di chuyển sau đó trong lượt đó. Ví dụ: nếu Bot A làm choáng Bot B và Bot B đứng sau Bot A theo thứ tự lần lượt, Bot B vẫn sẽ di chuyển sau đó trong lượt đó và tình trạng choáng sẽ xảy ra ở lượt tiếp theo.

Chiến đấu, canh tác và nâng cấp:

Mỗi bot có HP tối đa là 100 và UID được chỉ định trong khoảng từ 0 đến 99. UID này thay đổi sau mỗi vòng và là cách các bot theo dõi lẫn nhau.

Chữa bệnh là một trong những động tác đơn giản nhất, thêm một lượng HP được xác định theo cấp độ của nó (bắt đầu từ 5 HP). Một bot không thể chữa lành quá 100 HP.

Tấn công bot bằng UID của nó là một động thái khả thi khác, với sát thương cơ bản là 5 HP ở cấp độ 0. Bots cũng có thể bị choáng, bỏ qua lượt tiếp theo của chúng, cũng sử dụng UID.

Bots có thêm lá chắn HP, không có giới hạn. Tấm khiên HP này sẽ hấp thụ sát thương từ các cuộc tấn công trực tiếp từ các bot khác, và được thêm vào bằng cách che chắn. Ở cấp độ 0, che chắn thêm 5 khiên HP.

Nuôi trồng sẽ kiếm được 5 vàng ở cấp 0, với chi phí là 2 HP. 2 HP này không thể được bảo vệ. Việc sử dụng duy nhất cho vàng (ngoài chiến thắng) là nâng cấp di chuyển. Chữa bệnh, tấn công và che chắn có giá trị cơ bản là 5 HP và bắt đầu nuôi ở mức 5 vàng. Mỗi bước di chuyển có các cấp độ riêng biệt, bắt đầu từ 0. Các công thức này sẽ xác định giá trị tính bằng HP hoặc vàng của một lần di chuyển, trong đó L là cấp độ:

  • Chữa bệnh: L + 5
  • Tấn công: 1.25L + 5
  • Che chắn: 1.5L + 5
  • Nông nghiệp: 2L + 5

Chi phí nâng cấp bất kỳ di chuyển nào là như nhau cho một cấp độ nhất định và được xác định bởi 2.5L² + 2.5L + 10, trong đó L là cấp độ hiện tại. Một bot có thể sử dụng chức năng cost(currentLevel)như một phím tắt để xác định điều này.

Bots bắt đầu với 25 vàng, cho phép họ nhanh chóng nâng cấp hai bước lên cấp 1 hoặc một lần chuyển lên cấp 2. Vàng bắt đầu này không được tính vào tổng giá trị bot. Giết một con bot mang lại cho bạn một nửa tổng giá trị vàng, làm tròn và nếu hai con bot giết một con khác trong cùng một lượt, cả hai đều nhận được phần thưởng.

Đầu ra đầu vào:

Để giao tiếp với bộ điều khiển, giá trị trả về của hàm được sử dụng để gửi thông tin di chuyển. Một trong những điều này nên được trả lại:

  • Chữa lành: heal()
  • Tấn công: attack(uid)
  • Cái khiên: shield()
  • Choáng stun(uid)
  • Nông trại: farm()
  • Nâng cấp: upgrade("heal" / "attack" / "shield" / "farm")

Để bỏ qua một lượt (không làm gì), không trả lại gì hoặc trả về giá trị giả.

Để lấy số lần lượt hiện tại (bắt đầu từ 1), hãy sử dụng turn().

Các đối số của chức năng của bạn sẽ bao gồm thông tin về bot của bạn, UID của các bot khác và lưu trữ giữa các lượt. Đối số đầu tiên là một đối tượng với các thuộc tính sau: uid, hp, gold, và shield. Đây là bản sao thông tin hiện tại của bot của bạn. Ngoài ra còn có một đối tượng lồng nhau levels, với những con số mức độ heal, attack, shield, và farm.

Đối số thứ hai là một mảng được xáo trộn của tất cả các bot còn sống không phải của bạn, được định dạng như một đối tượng có chứa các thuộc tính uid, hp(cộng với khiên) worthattack(mức độ tấn công). Đối số thứ ba là một đối tượng trống có thể được sử dụng để lưu trữ giữa các lượt.

Ví dụ Bots:

Bot này sẽ farm cho đến khi nó có thể nâng cấp đòn tấn công của mình lên cấp 5, sau đó tấn công bot ngẫu nhiên mỗi lượt cho đến khi nó chết (hoặc thắng). Không hiệu quả lắm do thiếu khả năng hồi máu / che chắn.

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

Bot này có hai chế độ: tấn công và phòng thủ. Nó sẽ làm choáng một bot ngẫu nhiên hoặc hồi máu khi ở chế độ phòng thủ, và nó sẽ tấn công hoặc che chắn khi ở chế độ tấn công. Nó sẽ cố gắng nâng cấp các cuộc tấn công của nó bất cứ khi nào có thể.

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

Quy tắc:

  • Lỗ hổng tiêu chuẩn bị cấm
  • Các bot không được đọc, sửa đổi hoặc thêm bất kỳ biến nào ngoài phạm vi của chúng, có thể không cố gắng gian lận và không thể gọi bất kỳ hàm DOM do bộ điều khiển xác định
  • Giá trị trả về phải là giả, hoặc một trong các đầu ra chức năng trên
  • Bots không nên được thiết kế để nhắm mục tiêu một bot cụ thể, nhưng có thể được thiết kế để tận dụng các chiến lược chung
  • Bots có thể không tự tấn công (được phát hiện do nhận xét của @Ness)
  • Các bot phải đủ khác biệt so với bất kỳ bot nào khác mà chúng có thể được coi là các mục riêng biệt
  • Lập nhóm bây giờ không được phép
  • Bộ điều khiển có thể được tìm thấy ở đây
  • Phòng chat

Gỡ lỗi bộ điều khiển mới:

Sử dụng tệp gold-battle-log.js, bạn có thể đặt giá trị thuộc debugtính của bot botDatathành 0 (không ghi nhật ký), 1 (di chuyển nhật ký) hoặc 2 (di chuyển nhật ký, hp, vàng, cấp độ, v.v.)

Thử thách kết thúc lúc 1700 UTC vào thứ Sáu, ngày 9 tháng 8


4
Tạo một ý chính với tất cả các bot. gist.github.com/Draco18s/2efbf95edcf98d6b1f264e26bbb669d1 Tôi sẽ cố gắng cập nhật (nhưng nếu không phải là một khởi đầu tốt).
Draco18

4
Bộ điều khiển tự động cập nhật với các bot bao gồm: redwolfprograms.com/koth
Chương trình Redwolf

4
Tôi đang bỏ phiếu để đóng câu hỏi này vì thực tế nó đã đóng lại với câu trả lời mới ("Thử thách này đã kết thúc. Để xem điểm số cuối cùng ...")
pppery

3
@pppery Bạn có thể không? Tôi sẽ ổn với các câu trả lời không cạnh tranh, và [closed]cuối cùng có khả năng khiến những người xem bình thường bỏ qua việc đọc thử thách của tôi vì họ cho rằng đó là chất lượng thấp hoặc lạc đề.
Chương trình Redwolf

5
@pppery Tôi chưa bao giờ nghe nói về một thách thức bị đóng cửa cho đến ngày hôm nay và tôi cho rằng hạn chế xã hội mà bạn muốn thực thi thậm chí không tồn tại. Không cần phải đóng nó và tôi không muốn nó đóng. Đối với tôi, điều đó có vẻ như đóng cửa vì mục đích đóng cửa, hơn là vì lợi ích của trang web. Nếu ai đó muốn đăng một câu trả lời cho một câu hỏi cũ, họ sẽ có thể. Không có lưu ý sau khi quy tắc ứng cử viên nghiêm túc nói rằng nó phải là một ứng cử viên nghiêm trọng khi nó được đăng; một câu trả lời vẫn có thể là một ứng cử viên nặng ký cho thử thách ngay cả khi đó không phải là ứng cử viên để chiến thắng
Chương trình Redwolf

Câu trả lời:


16

Không thành thạo

rẽ nhánh từ 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()
        }
    }
}

Do chi phí nâng cấp theo cấp số nhân, cũng có thể nâng cấp nông nghiệp nếu chúng ta không thể nâng cấp chữa bệnh, cho phép bot thu thập vàng hiệu quả hơn.


Hoàn toàn phá vỡ sự cạnh tranh trong các thử nghiệm của tôi
Chương trình Redwolf

1
Tôi cảm thấy bot này có thể mạnh hơn một chút khi ifcâu lệnh đầu tiên được sử dụng <=- hiện tại nó sẽ không bao giờ lành hoàn toàn.
Bắn

@Scoots Không chắc nó sẽ quan trọng đến mức nào, nhưng tôi sẽ thay đổi điều đó.
Draco18

2
@ Draco18s Tôi chắc chắn rằng nó rất quan trọng - nhưng đây không phải là trang web về những cải tiến nhỏ bé không đáng kể? :)
Bắn

@Scoots Chữa lành vết thương tối đa không quan trọng lắm trong thử thách này vì không có mối đe dọa tấn công thực sự nào. Bot thực sự gây khó chịu duy nhất là bullybot, và bạn không thể thực sự làm bất cứ điều gì về anh ta. Nó thực sự có thể làm giảm hiệu suất để giữ sức khỏe đầy đủ.
B0RDERS

13

ThanosBot

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

Có quá nhiều bot, không đủ vàng để đi khắp nơi. Bot này đề xuất một giải pháp.

Diệt chủng, có, nhưng ngẫu nhiên, vô tư, công bằng cho đến giàu và nghèo.

Họ gọi anh là kẻ điên.

ThanosBot muốn điều tốt nhất cho cộng đồng bot, và sẵn sàng đi hết con đường này. Ban đầu, anh ta sẽ nâng cấp cuộc tấn công, canh tác và chữa bệnh của mình, để thu thập tài nguyên hiệu quả hơn và giành chiến thắng trong các trận chiến. Tiên quyết, anh ta sẽ bắt đầu tấn công người một cách ngẫu nhiên trong khi vẫn thu thập tài nguyên, cho các trận chiến sắp tới. Anh ta sẽ tiếp tục cải thiện quân đội, vũ khí và bản thân.

Một khi 50% dân số đã bị loại bỏ, các bot sinh ra sẽ chỉ biết bụng đầy đủ và bầu trời trong xanh, anh ta sẽ nghỉ hưu với cuộc sống nông nghiệp và ngắm mặt trời mọc trên một vũ trụ biết ơn. Anh ta sẽ trở nên hoàn toàn hòa bình, chỉ tự chữa bệnh bằng súp rau và làm nông.


6
Tôi muốn đổi tên "tấn công" thành "snap"
Chương trình Redwolf

11

Giết kẻ đánh cắp

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

Bây giờ không chỉ ăn cắp giết, mà còn ăn cắp giết chết!

Bot này không làm được gì nhiều ngoài trang trại, và khi nhận thấy khả năng, nó tham gia vào đòn cuối cùng với kẻ thù đang hấp hối, và bằng cách nào đó quản lý rất tốt.


Nó hoạt động vì tất cả các bot tham gia vào một đòn sát thủ đều nhận được phần thưởng đầy đủ.
Draco18

@ Draco18s Tôi hiểu tại sao nó có thể tốt, tôi chỉ không mong đợi một ý tưởng đơn giản như vậy để có được trung bình gấp đôi số điểm của bot tốt nhất tiếp theo (tại thời điểm thực hiện nó).
dzaima

Hehe, thật công bằng. Tôi sẽ phải tải xuống tất cả các bot khi tôi có thể và xem liệu tôi có thể tìm giải pháp khác không.
Draco18

9

Bộ cân bằng

Bot này tìm cách khôi phục hòa bình trong cộng đồng bot. Anh ta không ngừng nhắm vào các bot với đòn tấn công cao nhất, chỉ từ bỏ nếu khả năng hồi phục của bot tốt hơn tấn công của chính anh ta. Một khi không có bot nào chữa lành vết thương nặng hơn cuộc tấn công của nó, anh ta sẽ nghỉ hưu với một cuộc sống nông nghiệp yên bình.

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

Người lạc quan

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

Giả sử nó sẽ có thể dành 80% thời gian để canh tác một cách yên bình, do đó, nó bắt đầu bằng cách tối đa hóa việc canh tác, và chỉ sau đó bắt đầu chú ý đến các kỹ năng chiến đấu của nó. Chắc chắn sẽ không có gì sai!


8

Tòng phạm giết người

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

Tại sao nâng cấp giá trị tấn công khi bạn có thể gây sát thương plink mà vẫn nhận được tín dụng đầy đủ?

Một lần nữa trở lại để cõng Kill Stealer. Tôi đã có thể đơn giản hóa một số khối mã trong đó các câu lệnh luôn luôn đúng và sử dụng một số con số dẫn đến lợi nhuận lớn so với ban đầu.

Tôi phải trao nó cho @dzaima vì nhận ra rằng một đối thủ giàu có có khả năng tham gia vào một lượt hỗ trợ trước khi một vụ giết người xảy ra là khá thông minh. Một trong số (rất) vài lần Stun()có kết quả tổng dương. Một lần nữa tôi đã có thể cải thiện ý tưởng, vì biết rằng Kill Stealer sẽ chạy logic tương tự, Kill Assistant tìm kiếm mục tiêu "tốt thứ hai" (với một số quyết định) và thay vào đó làm choáng chúng.

Cập nhật nhỏ để ngăn chặn bot gây chết người và ngăn chặn bot gây chết người nhiều khả năng nhất.

Kết quả mẫu (rút ngắn top 5 sau 1000 trò chơi)

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

Đợi đã, ở thế giới nào Captain Farmer nhận được 14k vàng?
Chương trình Redwolf

Cái này:runGame(1) results: [...] captFarmer: 13768
Draco18s

Điều đó khá cao bất ngờ ... nó thường nhận được khoảng 10 nghìn trong các thử nghiệm của tôi
Chương trình Redwolf

* shrugh * Không có ý kiến. Tôi sẽ thực hiện cập nhật ý chính tự động chỉ để đảm bảo mọi thứ sạch sẽ.
Draco18

Bot yêu thích của tôi vào cuối thời hạn.
Đêm 2

7

Bot không thể phục hồi (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()
            }
        }        
    }   
}


Đừng bận tâm đến tôi ... Tôi sẽ mượn cái này.
Draco18

6

PatientStrargetistBot

Tôi đã cố gắng viết một bot bắt đầu đóng khung và phòng thủ khi cần thiết và sau đó chuyển sang giết các bot có giá trị cao khác sau này trong trò chơi.

Hiện tại, điều này dường như không hoạt động chính xác vì nó bị giết bởi một nhóm các robot giết người khi bắt đầu trò chơi hoặc bị mắc kẹt ở đâu đó trong chế độ tấn công của nó.

Vẫn khá hài lòng với việc đây là mã JS đầu tiên của tôi, vì vậy ... (Tôi đã ăn cắp đoạn mã từ đây & vì lý do đó nhanh hơn việc googling tất cả cú pháp cơ bản của 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

Thụy sĩ

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

Giống như tên cho thấy, bot này là trung tính chủ yếu là trung tính (bây giờ nó giúp tiêu diệt các bot sắp chết) và chỉ cần trang trại và chữa lành, từ từ xây dựng vàng của nó ( giống như switzerland )


6

Bot mà trang trại, tấn công, khiên và thậm chí chữa lành nhưng không bao giờ làm choáng

(Tên viết tắt là TBTFASAEHBNS , không được nhầm với 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();
}

Bot này về cơ bản:

  • Xây dựng trên trang trại khi bắt đầu
  • Tự vệ khi cần
  • Tấn công khi nó có thể giết hoặc khi nó nghĩ rằng có cơ hội để giết một ai đó
  • Nâng cấp ở đây và sau đó
  • Trang trại thời gian còn lại
  • Không bao giờ làm choáng

Chỉnh sửa 1: Đã sửa lỗi và cải thiện một số thứ nhỏ trong bot dựa trên các thử nghiệm với nhiều trò chơi.

Chỉnh sửa 2: Giảm nâng cấp khiên.


2
Ngay khi nhìn thấy cái tên tôi đã biết đó sẽ là bot của bạn (:
Chương trình Redwolf

Tôi xin lỗi về những cái tên dài, nhưng tôi nghiện nó!
Đêm 2

1
Có lẽ đó là dấu hiệu của một bot tốt ... các thử nghiệm của tôi cho thấy nó ở vị trí thứ 5
Chương trình Redwolf

5

Bắn tỉa

Bot này sẽ chỉ hiệu quả nếu ai đó bắt đầu thêm bot thực sự tấn công một cách thường xuyên. SmartFarmer là giải pháp tối ưu hóa hiện tại của tôi

  1. chữa lành nếu có thể có được một shot
  2. chữa lành nếu dưới 30
  3. tấn công bot nếu có thể nhặt nó ra và kiếm được nhiều tiền hơn làm nông
  4. nâng cấp nông nghiệp nếu có đủ khả năng
  5. nâng cấp chữa bệnh nếu dưới 80 tuổi và đủ khả năng
  6. trang trại

Kền kền không cần một cuộc tấn công

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

Mã định danh không mong muốn ( int) trên dòng 2. ReferenceError: Health không được xác định.
Draco18

Có nên me.hp?
mbomb007

lấy làm tiếc. mới sử dụng javascript. cảm ơn vì sự giúp đỡ
B0RDERS

Bạn if(me.hp <30 && ...)có thể được đơn giản hóa thành mệnh đề đầu tiên trên tài khoản cần một mức độ chữa lành vô lý cho vấn đề này (lv 65)
Veskah

@Veskah Cảm ơn bạn đã chỉ ra điều đó. Đó là tàn dư từ khi hp tối thiểu cao hơn
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);
}

Mashup của BullyBot và một số bit khác. Optimist có một đoạn tấn công cơ hội ngắn và ngọt ngào mà tôi đã nghĩ ra (mặc dù các bot khác cũng tính toán tương tự).

Thay vì bắt nạt mục tiêu bằng cách làm choáng chúng, nó giết chết chúng vì những chiến lợi phẩm ngọt ngào, ngọt ngào của chúng. Nó cũng nhắm mục tiêu yếu nhất trong đàn để bắt nạt, nhưng nó sẽ bỏ cuộc và chỉ đi làm nông nếu HP của mục tiêu yếu nhất quá cao.


bạn đang tự nuôi mình đến chết. Chấp nhận chỉnh sửa của tôi :)
B0RDERS

1
@AndrewBnings Ha, thậm chí không nghĩ về nó. Cảm ơn.
Draco18

Bot này là tuyệt vời cho đến khi những bot bảo vệ xuất hiện.
B0RDERS

@ B0RDERS Khiên rất mạnh, ngay cả khi nó lãng phí thời gian.
Draco18

5

FizzBuzz

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

Chủ yếu là bot gây khó chịu. Vô cùng khó chịu bởi thực tế là nó không thể thực sự là FizzBuzz nên thay vào đó nó chỉ gây tiếng vang một cách giận dữ. Khi nó không Fizzing hoặc Buzzing, nó sẽ biến mất ở một bot khác trong 30 lượt và từ bỏ và chọn một bot khác để nhắm mục tiêu nếu nó không đạt được tiến bộ.

Thực hiện bất thường không nhất quán. Đừng bận tâm, cập nhật bộ điều khiển, bây giờ dường như luôn ở giữa gói.


Tôi thích khái niệm này. Bất kể tình hình hiện tại, nó vẫn tiếp tục chạy theo tốc độ của riêng mình.
Ness

5

bắt nạt

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

Hãy thử trực tuyến!

Có thể không thắng nhưng chắc chắn sẽ cố gắng hết sức để đảm bảo mục tiêu của anh ta cũng không. bullyBot cũng trang trại ở lượt đầu tiên để nếu không có ảnh hưởng bên ngoài, anh ta sẽ đánh bại mục tiêu 5-0 hoặc buộc họ 5-5.


5

Chỉ cần

Tôi nghĩ tôi sẽ bắt đầu đơn giản.

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

13
Bot này sẽ tự sát do chi phí canh tác 2HP.
Draco18

@ Draco18s Mặc dù vòng đấu có thể kết thúc trước đó, tùy thuộc vào số lượng bot
Chương trình Redwolf

1
Mặc dù về mặt kỹ thuật , đồng hồ bấm giờ 50 vòng rất ngắn khi thời gian kết thúc mặc định là 1000.
Draco18s

Nó đánh bại hai bot mẫu, nhưng bây giờ có thêm một vài bài nộp tôi có thể cố gắng đưa ra một cái gì đó tốt hơn.
Ẩn danh

@Anonymous Có thể bao gồm cả nâng cấp chữa bệnh và canh tác sẽ là đủ. Vì nhận được nhiều vàng nhất là mục tiêu cuối cùng, giữ cho công việc chính của bot có thể hoạt động. Cho đến nay chưa có bot nào có "chế độ" như chế độ hồi máu và chế độ trang trại, có thể là một cách tiếp cận thú vị
Chương trình Redwolf

4

ScavengerBot (V2)

Nhận ra nó không phải là một người nhặt rác trước đây. Chiến lược mới là chờ cho đến khi nó có thể giết chết một bot khác. Nếu không ai có thể bị giết, nó ngồi và dựng lên khiên.

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?
Draco18

Bắt tốt, cố định
reffu

4

buồn rầu

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

Chiến lược mặc định của Moody là nâng cấp nông nghiệp và chữa bệnh trong một thời gian, sau đó loại bỏ các bot khác theo thứ tự giá trị giảm dần. Tuy nhiên, nếu nó bị tấn công, nó sẽ sợ hãi và tập trung vào việc chữa lành một chút. Nếu nó tấn công và "thất bại", bởi vì nạn nhân đang hồi phục hoặc che chắn hiệu quả hơn cuộc tấn công, nó sẽ tức giận và bỏ đi để nâng cấp khả năng tấn công của mình.


4

Tên cướp

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

Nỗ lực đầu tiên tại một bot học tăng cường. Hoàn toàn phòng thủ để thu hẹp không gian tìm kiếm. Sắp xếp một spinoff thông minh hơn của FizzBuzz - nó lặp đi lặp lại một loạt năm hành động cụ thể lặp đi lặp lại; năm hành động là những gì được RL chọn.

Nhưng hiện tại, nó chủ yếu dựa trên bảng liệt kê - Tôi chỉ tạo ra tất cả 3 ^ 5 = 243 hoán vị của chuỗi năm hành động phòng thủ lặp đi lặp lại và lưu trữ điểm trung bình của họ (chia cho 200, để đạt được mức tăng trung bình năm lượt) hơn 100 lần lặp trong storage.priormảng. Sau đó, trong trò chơi, nó thực hiện một cách tiếp cận tham lam epsilon để cập nhật các danh sách điểm số đó để nó trở thành bằng chứng trong tương lai. (Ngoài ra vì sử dụng epsilon = 0,3 đã tốt hơn epsilon = 0,1 nên tôi chỉ giữ nó.)

Nó không sao, liên tục đặt giữa scavengerBot và Optimist. Tôi hiện đang được đào tạo thêm về các trò chơi thực tế và đang tìm kiếm những cách tốt hơn để đóng khung chiến lược, để xem liệu tôi có thể cải thiện nó hay không.


4

Cơ hội

Cái này mượn một chút từ một vài người khác (đáng chú ý là ScavengerBot (V2) và Unkillable) vì họ có cùng ý tưởng với tôi, nhưng tôi thường thích phong cách tròn trịa và toàn diện hơn là chỉ tập trung vào một hoặc hai điều. Điều này có thể có nghĩa là tôi sẽ không giành chiến thắng, nhưng nó sẽ ở giữa một nơi nào đó (điều này xảy ra với tôi hầu hết thời gian trong nhiều thứ).

Vì vậy, nó ăn cắp giết chết ngon ngọt; chữa lành nếu cần thiết; nâng cấp trang trại, tấn công và chữa lành theo thứ tự đó; và trang trại khác.

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
Đối số thứ 2 nên làothers
SuperStormer

4

ScaredBot

  1. Nó tìm thấy các bot khác:
    • với cuộc tấn công cao nhất
    • với phần lớn tài sản và HP thấp hơn tấn công của chính mình
  2. Nếu khiên HP + của nó thấp hơn khiên tìm thấy highest attack * (25% of bots), hoặc nó ở gần đầu dưới HP + shield, thì nó che chắn
  3. Nếu nó tìm thấy một con bot có khiên thấp hơn đòn tấn công của chính nó, nó sẽ tấn công nó.
  4. Nếu sức khỏe của nó là < 50, nó chữa lành.
  5. Nếu nó có thể nâng cấp bất kỳ lá chắn, hồi máu và trang trại nào, nó sẽ nâng cấp cái có cấp độ thấp nhất
  6. Nó trang trại
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();
    }
}

Ý tưởng là sống lâu nhất có thể và nếu không hãy thử lấy vàng theo cách an toàn và rẻ tiền để có thể nâng cấp.

Ưu tiên nâng cấp có lẽ nên được điều chỉnh, cũng như điều kiện khi xác định có nên che chắn hay không.


3

SmartFarmer

Nông trại, nâng cấp nông nghiệp, chữa bệnh nếu sức khỏe thấp. Farming dường như bị áp đảo cho đến khi các bot thực sự tấn công đến. Bây giờ bot của tôi bị giết :-(

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
Tôi đã (bằng tay) thử nghiệm về cơ bản cùng một chiến lược để xem giá trị tối đa có thể đạt được là bao nhiêu và những con số tốt nhất tôi có thể nhận được, bằng cách trì hoãn một chút khi hồi máu được nâng cấp (tôi đã sử dụng vàng> = chi phí * 2) và lên đến lvl10 chữa lành .
Nicolai

Hệ số giá đó là một ý tưởng tốt. Tôi đã thêm một cái gì đó tương tự. Tôi sẽ quan tâm để xem những gì bạn có số
B0RDERS

3

Vữa

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

Mỗi lượt, so sánh lợi nhuận được khấu hao của việc giết từng bot với việc nuôi và chữa bệnh và chọn phương án tốt nhất. Thực sự nó nên sử dụng trạng thái để tính xem sẽ mất bao lâu để giết một con bot, nhưng bây giờ nó chỉ giả định rằng mỗi bot chữa lành hoặc che chắn trung bình 5 điểm một lượt sát thương mà các bot khác gây ra.


3

Bot thân thiện

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].hphp + shieldthay vì hp...


4
Bất cứ ai có thể giúp tôi dịch tên chức năng sang tiếng Anh? ^ _ ^
tsh

4
Theo Google Dịch, "" có nghĩa là "Bịt miệng". Khá chắc chắn đó không phải là điều bạn muốn và thực tế là một sử thi Google Dịch khác đã thất bại ... Tôi đã tìm kiếm thêm và tất cả các kết quả dường như đề cập rằng không có từ tiếng Anh nào có thể được sử dụng ở đây, vì vậy có lẽ tốt hơn là giữ nó như là thực ra, vì nó dường như là một giới từ của Trung Quốc thường có nghĩa là người ta nên làm việc âm thầm và để kết quả tự nói lên và đạt được một triết lý truyền thống. Thật không may, tôi hoàn toàn không biết tiếng Trung để dịch nó trực tiếp. : D
Erik the Outgolfer

1
với tư cách là một người nói tiếng Hoa bản địa, nó có nghĩa là "âm thầm tạo ra khối tài sản khổng lồ": v 闷声 cũng đồng nghĩa với việc cố ý im lặng, theo nghĩa đen là "che đậy âm thanh"
Biến đổi Fourier của Rin

1
Lén lút? Theo TheRadar? DontMindMe? Chú ý Deflector?
Peter Taylor

3

Kế toán

Bot thực tế này tính toán động thái có lợi nhất về kinh tế, nhưng anh ta thích giữ cho hồ sơ tấn công của mình ở mức thấp để tránh rắc rối từ tất cả các bot vigilante. Anh ta không cố gắng giúp đỡ những người không phòng thủ hoặc con mồi trên chúng. Thay vào đó, anh ấy làm những gì giúp anh ấy nhiều nhất.

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

reallyCommnedTurtle

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

Vấn đề là như thế này. Nó thực sự nguy hiểm ngoài kia. Farming ở tất cả làm tăng giá trị của bạn, làm cho bạn một mục tiêu. Vì vậy, nó thực sự không an toàn để canh tác cho đến khi bạn xây dựng một lá chắn khổng lồ và tất cả bạo lực đã tàn lụi. Sau đó, bạn có thể thò đầu ra khỏi vỏ và bắt đầu nuôi. Hoặc hỗ trợ tiêu diệt. Bất cứ điều gì trả tiền tốt hơn.


2

vệ binh, vệ thần

Tôi có thể có nhiều hơn một đệ trình, phải không?

Một ngã ba của CampBot. Không che chắn, thay vào đó tập trung vào tấn công. Hiển thị ưu tiên cho người chơi tấn công có chỉ số tấn công cao hơn, thay vì tấn công ngẫu nhiên như CampBot. Tập trung vào nâng cấp trang trại của nó hơn là chữa bệnh.

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

bot của tôi không tấn công ngẫu nhiên ...
SuperStormer

Bạn có thể đăng bao nhiêu lần tùy ý, tôi càng cho rằng càng nhiều
Chương trình Redwolf

@SuperStormer Tôi nhận ra bạn không hoàn toàn ngẫu nhiên, nhưng:let victim=potentialVictims[Math.floor(Math.random()*potentialVictims.length)]
Ẩn danh

nhưng trước tiên, nó lọc ra những thứ không đáng để tấn công
SuperStormer

Tôi đã làm việc trên một bot tương tự có tên là bộ cân bằng khi bạn đăng bài này. Tôi vẫn tinh chỉnh nó, nhưng tôi thích một số ý tưởng của bạn.
B0RDERS

2

Rando

Anh chàng ngớ ngẩn này sẽ chọn hành động dựa trên sự ngẫu nhiên thống nhất với một số sai lệch. Nếu một hành động được chọn ngẫu nhiên sẽ không hoạt động, thì nó sẽ rơi xuống lựa chọn tiếp theo.

Vì vậy, trung bình, anh ta nên tấn công gần 2/9 thời gian và farm gần 3/9 thời gian. Phần còn lại là khoảng 1/9 cơ hội nếu anh ta có thể nâng cấp, hoặc nếu khả năng hồi phục / che chắn là xứng đáng, v.v.

Anh ta có thể sẽ không thể hiện tốt, nhưng ít nhất có một cơ hội nhỏ mà anh ta trị vì tối cao. Và đó là toàn bộ mục đích của Rando. Anh chỉ cần tin vào chính mình! Tất cả các lựa chọn được đặt trước mặt anh ta. Anh ta chỉ cần chọn những gì cần thiết cho bất kỳ tình huống nào.

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

(Tôi biết "mặc định" là không cần thiết, nhưng tôi nghĩ rằng đó là cách thực hành mã hóa tốt cho mã mạnh mẽ.)


2
"Anh ấy chỉ cần tin vào chính mình" ... Hiện tại tôi đang cười rất nhiều
Chương trình Redwolf

2

Giết Bot

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

Một bot đơn giản, Kill Bot chỉ muốn giết kẻ thù của nó. Vì việc che chắn hiệu quả hơn nhiều so với hồi máu (đặc biệt là khi lên cấp), Kill Bot chỉ cố gắng luôn là mục tiêu không hấp dẫn bằng cách che chắn bản thân mỗi khi bị tấn công. Kill Bot làm khá tốt trong số các bot yếu, hòa bình ở đây (bạn có thể cảm thấy sự khinh bỉ của chúng đối với chúng).


3
Lưu ý rằng đó o.attacklà cấp độ tấn công, không phải sát thương của nó
Chương trình Redwolf

2

Bot FarmHeal

Ngã ba từ bot JustFarm của @Anonymous

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

2

Không thể phá hủy

Một bản sửa đổi của bot Draco18, sử dụng khiên (hiệu quả hơn so với các bot khác)

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();
        }
    }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.