การต่อสู้ของทองคำ


43

ความท้าทายนี้สิ้นสุดลงแล้ว หากต้องการดูคะแนนสุดท้ายของคู่แข่งคลิกที่นี่

ในความท้าทายนี้การส่งแต่ละครั้งจะเป็นหนึ่งบอท บอทแต่ละอันควรเป็นฟังก์ชัน Javascript บอทจะต่อสู้เพื่อให้ได้มูลค่ารวมสูงสุดในทองคำ ทองสามารถทำไร่ไถนาหรือได้รับจากการฆ่าบอทอื่น ๆ และใช้เพื่อยกระดับการรักษาการโจมตีการป้องกันและการทำฟาร์ม

วัตถุประสงค์:

จำนวนรอบที่มีมากถึง 1,000 รอบ (จบลงเมื่อเหลือบอทเพียงอันเดียว) บอทที่มีมูลค่ารวมสูงสุด (ผลรวมของทองคำทั้งหมดที่ได้รับ) จะเป็นผู้ชนะ

ย้อนกลับ:

ในแต่ละเทิร์นบอททุกอันที่ยังมีชีวิตอยู่ (> 0 HP) จะถูกเรียกใช้ครั้งเดียว สามารถส่งคืนการย้ายซึ่งสามารถเป็นหนึ่งในสิ่งต่อไปนี้:

  • รักษา: ฟื้น HP
  • การโจมตี: ลบ HP ออกจากบอทอื่น
  • โล่: ป้องกันการโจมตีในภายหลัง
  • Stun: ข้ามการเปิดรอบถัดไปของ bot อื่น
  • ฟาร์ม: รับทองด้วยค่า HP
  • อัพเกรด: ทำให้การเคลื่อนไหวบางอย่างดีขึ้น

บอตทั้งหมดจะกลับมาเคลื่อนไหวก่อนที่จะถูกประหารดังนั้น stun, Heal, Attack, shield, ฯลฯ จะไม่ส่งผลต่อบอทที่เคลื่อนที่ในภายหลังในเทิร์นนั้น ตัวอย่างเช่นหากบอท A ตะลึงบอท B และบอทบีอยู่หลังบอท A ตามลำดับเทิร์นบอท B จะยังคงเคลื่อนที่ในภายหลังในเทิร์นเดียวกันและจะเกิดการสตันในเทิร์นถัดไป

การต่อสู้การทำนาและการอัพเกรด:

บอทแต่ละอันมี HP สูงสุดได้สูงสุด 100 และโพสต์ที่ได้รับมอบหมายระหว่าง 0 ถึง 99 โพสต์นี้จะเปลี่ยนหลังจากทุกรอบและเป็นวิธีที่บอตติดตามกันและกัน

การรักษาเป็นหนึ่งในท่าที่ง่ายที่สุดเพิ่ม HP ตามจำนวนที่กำหนด (เริ่มที่ 5 HP) บอทไม่สามารถรักษาได้ 100 HP ที่ผ่านมา

การโจมตีบอทด้วย UID ของมันนั้นเป็นไปได้อีกท่าหนึ่งโดยมีความเสียหายพื้นฐาน 5 HP ที่ระดับ 0 บอทสามารถถูกสตันได้ด้วยการข้ามรอบถัดไปของพวกเขาไปซึ่งยังใช้ UID ด้วย

บอทนั้นมีเกราะป้องกัน HP เพิ่มเติมซึ่งไม่มีขีด จำกัด โล่ HP นี้จะดูดซับความเสียหายจากการโจมตีโดยตรงจากบอทอื่น ๆ และถูกเพิ่มโดยการป้องกัน ที่ระดับ 0 การป้องกันจะเพิ่ม 5 โล่ HP

การทำฟาร์มจะได้รับทองคำ 5 ระดับที่ค่า HP 2 HP 2 ตัวนี้ไม่สามารถป้องกันได้ การใช้งานสำหรับทองเท่านั้น (เกินกว่าจะชนะ) คือการอัพเกรดการเคลื่อนไหว การรักษาการโจมตีและการป้องกันมีค่าพื้นฐาน 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 ทองทำให้พวกเขาอัพเกรดได้อย่างรวดเร็วทั้งสองย้ายเป็นระดับ 1 หรือย้ายไปที่ระดับ 2 ทองเริ่มต้นนี้จะไม่นับรวมกับมูลค่าบอททั้งหมด การฆ่าบอทจะให้ครึ่งหนึ่งของมูลค่าทั้งหมดของคุณในทองคำปัดเศษขึ้นและหากบอทสองตัวฆ่าอีกเทิร์นเดียวกันพวกเขาทั้งคู่จะได้รับรางวัล

Input / Output:

เพื่อสื่อสารกับคอนโทรลเลอร์ค่าส่งคืนของฟังก์ชันใช้เพื่อส่งข้อมูลการย้าย หนึ่งในสิ่งเหล่านี้ควรถูกส่งคืน:

  • รักษา: heal()
  • โจมตี: attack(uid)
  • โล่: shield()
  • งัน: stun(uid)
  • ฟาร์ม: farm()
  • ปรับรุ่น: upgrade("heal" / "attack" / "shield" / "farm")

ในการข้ามการเลี้ยว (ไม่ทำอะไรเลย) ไม่ต้องส่งคืนหรือคืนค่าที่ผิดพลาด

เพื่อให้ได้จำนวนเปิดปัจจุบัน (เริ่มต้นที่ 1) turn()การใช้งาน

ข้อโต้แย้งของฟังก์ชั่นของคุณจะรวมถึงข้อมูลเกี่ยวกับบ็อต UID ของบ็อตอื่น ๆ และที่เก็บข้อมูลระหว่างทาง อาร์กิวเมนต์แรกเป็นวัตถุที่มีคุณสมบัติดังต่อไปนี้: uid, hp, และgold shieldนี่คือสำเนาของข้อมูลปัจจุบันของบอทของคุณ นอกจากนี้ยังมีวัตถุที่ซ้อนกันlevelsกับตัวเลขระดับของheal, attack, และshieldfarm

อาร์กิวเมนต์ที่สองเป็นอาร์เรย์สับของบอทมีชีวิตอื่น ๆ ทั้งหมดกว่าของคุณในรูปแบบที่เป็นวัตถุที่มีคุณสมบัติuid, hp(บวกโล่) worthและattack(ระดับการโจมตี) อาร์กิวเมนต์ที่สามเป็นวัตถุว่างซึ่งสามารถใช้สำหรับการจัดเก็บระหว่างเทิร์น

บอทตัวอย่าง:

บอทนี้จะทำฟาร์มจนกว่าจะสามารถอัพเกรดการโจมตีเป็นระดับ 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คุณสามารถตั้งค่าdebugคุณสมบัติของบอทbotDataเป็น 0 (ไม่มีการบันทึก), 1 (การย้ายบันทึก) หรือ 2 (บันทึกการเคลื่อนไหว, HP, ทอง, ระดับ ฯลฯ )

การท้าทายสิ้นสุดเวลา 1700 UTC ในวันศุกร์ที่ 9 สิงหาคม


4
สร้างส่วนสำคัญด้วยบอตทั้งหมด gist.github.com/Draco18s/2efbf95edcf98d6b1f264e26bbb669d1ฉันจะพยายามอัปเดตอยู่เสมอ (แต่ถ้าไม่ใช่เป็นการเริ่มต้นที่ดี)
Draco18s

4
อัพเดทคอนโทรลเลอร์อัตโนมัติพร้อมบอทรวม: redwolfprograms.com/koth
โปรแกรม Redwolf

4
ฉันลงคะแนนให้ปิดคำถามนี้เพราะมันอยู่ใกล้กับคำตอบใหม่แล้ว ("ความท้าทายนี้สิ้นสุดลงเพื่อดูคะแนนสุดท้าย ... ")
pppery

3
@pppery คุณทำไม่ได้เหรอ? ฉันพอใจกับคำตอบที่ไม่ได้แข่งขันและ[closed]ท้ายที่สุดก็น่าจะทำให้ผู้ชมทั่วไปข้ามการอ่านความท้าทายของฉันเนื่องจากพวกเขาคิดว่ามันมีคุณภาพต่ำหรือไม่เป็นหัวข้อ
โปรแกรม Redwolf

5
@pppery ฉันไม่เคยได้ยินเรื่องการท้าทายใด ๆ ที่จะปิดตัวจนกว่าจะถึงวันนี้และฉันจะเถียงข้อ จำกัด ทางสังคมที่คุณต้องการบังคับใช้ ไม่จำเป็นต้องปิดและฉันไม่ต้องการให้ปิด สำหรับฉันดูเหมือนว่าจะปิดเพื่อประโยชน์ในการปิดมากกว่าเพื่อประโยชน์ของเว็บไซต์ หากใครต้องการโพสต์คำตอบสำหรับคำถามเก่าพวกเขาควรจะสามารถ ไม่มีโน้ตหลังจากกฎการแข่งขันที่ร้ายแรงบอกว่าจะต้องเป็นคู่แข่งที่ร้ายแรงเมื่อโพสต์ คำตอบอาจเป็นคู่แข่งที่สำคัญสำหรับความท้าทายแม้ว่ามันจะไม่ใช่คู่แข่งสำหรับการชนะ
ก็ตาม

คำตอบ:


16

unkillable

คดเคี้ยวจาก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 ฉันแน่ใจว่ามันมีความสำคัญน้อยมาก - แต่เว็บไซต์นี้ไม่ได้เกี่ยวกับการปรับปรุงเล็กน้อยที่แทบไม่มีนัยสำคัญเลยใช่ไหม :)
Scots

@Scoots Healing เพื่อสุขภาพที่สูงสุดไม่ได้มีความสำคัญอะไรในความท้าทายนี้เนื่องจากไม่มีการคุกคามที่คุกคาม บอทตัวรุกที่แท้จริงอย่างเดียวคือ bullybot และคุณไม่สามารถทำอะไรกับเขาได้ มันอาจลดประสิทธิภาพลงเพื่อรักษาสุขภาพให้แข็งแรงอยู่เสมอ
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();
            }
        }
    }
}

มีบอทมากเกินไปมีทองคำไม่พอที่จะเดินไปมา บอทนี้เสนอทางออก

การฆ่าล้างเผ่าพันธุ์ใช่ แต่สุ่มแยกย้ายกันไปยุติธรรมกับคนรวยและคนจนเหมือนกัน

พวกเขาเรียกเขาว่าเป็นคนบ้า

ThanosBot ต้องการสิ่งที่ดีที่สุดสำหรับชุมชนบอทและยินดีที่จะไปตลอดทาง ในตอนแรกเขาจะอัพเกรดการโจมตีการทำฟาร์มและการรักษาเพื่อรวบรวมทรัพยากรอย่างมีประสิทธิภาพและชนะการต่อสู้ เขาจะเริ่มโจมตีผู้คนโดยการสุ่มในขณะที่ยังคงรวบรวมทรัพยากรเพื่อการต่อสู้ที่จะมาถึง เขาจะพัฒนากองทัพอาวุธและตัวเขาเองให้ดีขึ้น

เมื่อประชากร 50% ถูกกำจัดบอทที่เกิดมาจะรู้เพียงท้องเต็มและท้องฟ้าแจ่มใสเขาจะเกษียณชีวิตของการทำฟาร์มและดูดวงอาทิตย์ขึ้นบนเอกภพที่ขอบคุณ เขาจะกลายเป็นผู้รักสงบอย่างสมบูรณ์เพียงรักษาตัวเองด้วยซุปผักและการทำฟาร์ม


6
ฉันอยากจะเปลี่ยนชื่อ "จู่โจม" เป็น "สแน็ป"
โปรแกรม Redwolf

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

ฮิฮินั้นยุติธรรม ฉันจะต้องดาวน์โหลดบอททั้งหมดเมื่อฉันสามารถและดูว่าฉันสามารถหาวิธีแก้ไขปัญหาอื่นได้หรือไม่
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();
}

ทำไมต้องอัพเกรดค่าการโจมตีเมื่อคุณสามารถสร้างความเสียหายและยังได้รับเครดิตเต็ม?

กลับมาอีกครั้งเพื่อ piggybacking off Kill Stealer ฉันสามารถทำให้โค้ดหลาย ๆ บล็อกง่ายขึ้นโดยที่ข้อความนั้นเป็นจริงเสมอและซอกับตัวเลขบางส่วนที่ทำให้ได้กำไรมหาศาลจากต้นฉบับ

ฉันต้องมอบมันให้กับ @dzaima เพื่อให้ทราบว่าฝ่ายตรงข้ามที่ร่ำรวยซึ่งน่าจะมีส่วนร่วมในการช่วยเหลือก่อนที่การฆ่าจะเกิดขึ้นนั้นค่อนข้างฉลาด หนึ่งในไม่กี่ครั้งที่Stun()มีผลบวกเป็นบวก อีกครั้งที่ฉันสามารถพัฒนาความคิดนี้ได้เพราะเมื่อรู้ว่า Kill Stealer จะใช้ตรรกะที่คล้ายกัน Kill Assist มองหาเป้าหมายที่ "ดีที่สุด" (ขึ้นอยู่กับดุลยพินิจ) และทำให้ตกใจแทน

การอัปเดตเล็กน้อยเพื่อป้องกันบอทเกี่ยวกับการตายที่น่าทึ่งและการป้องกันบอทที่น่าจะฆ่าได้

ตัวอย่างผลลัพธ์ (ตัดทอน 5 อันดับแรกหลังจาก 1000 เกม)

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

รอสักครู่ Captain Farmer จะได้รับทองคำ 14k ในโลกนี้?
โปรแกรม Redwolf

อันนี้:runGame(1) results: [...] captFarmer: 13768
Draco18s

มันค่อนข้างสูงโดยไม่คาดคิด ... โดยปกติแล้วจะได้ประมาณ 10k ในการทดสอบของฉัน
โปรแกรม Redwolf

* shrugh * ไม่มีความคิด ฉันจะอัปเดตส่วนสำคัญโดยอัตโนมัติเพียงเพื่อประกันทุกอย่างให้สะอาด
Draco18s

บอทที่ฉันโปรดปรานในตอนท้ายของกำหนด
คืนที่ 2

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

PatientStrategistBot

ฉันพยายามเขียนบอทที่เริ่มต้นสร้างเฟรมและป้องกันตามที่จำเป็นแล้วจึงเปลี่ยนเป็นการฆ่าบอทที่มีมูลค่าสูงอื่น ๆ ในเกม

ขณะนี้สิ่งนี้ดูเหมือนจะไม่ทำงานอย่างถูกต้องเนื่องจากมันถูกฆ่าโดยแก๊งบ็อตสังหารในตอนเริ่มเกมหรือติดอยู่ที่ไหนซักแห่งในโหมดก้าวร้าว

ยังคงมีความสุขอยู่กับสิ่งนี้เป็นรหัส JS ตัวแรกของฉันดังนั้น ... (ฉันขโมยตัวอย่างโค้ดจากที่นี่ & มีสาเหตุที่เร็วกว่า googling ไวยากรณ์พื้นฐาน 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

ฉันขอโทษเกี่ยวกับชื่อยาว แต่ฉันติดมัน!
Night2

1
อาจเป็นสัญญาณของบอตที่ดี ... การทดสอบของฉันแสดงว่าอยู่ในอันดับที่ 5
โปรแกรม Redwolf

5

SniperBot

บอทนี้จะมีผลก็ต่อเมื่อมีใครบางคนเริ่มเพิ่มบอทที่โจมตีเป็นประจำ SmartFarmer เป็นโซลูชันที่ได้รับการปรับปรุงในปัจจุบันของฉัน

  1. รักษาถ้าสามารถรับ one-shot
  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();
}

ตัวระบุที่ไม่คาดคิด ( int) ที่บรรทัด 2 ReferenceError: health ไม่ได้ถูกกำหนดไว้
Draco18s

ควรเป็นme.hpอย่างไร
mbomb007

ขอโทษ ใหม่กับจาวาสคริปต์ ขอบคุณสำหรับความช่วยเหลือ
B0RDERS

คุณif(me.hp <30 && ...)สามารถทำให้ประโยคแรกง่ายขึ้นเพราะจำเป็นต้องมีระดับการรักษาที่ไร้สาระ (เรื่อง 65)
Veskah

@Veskah ขอบคุณสำหรับการชี้ให้เห็นว่า นั่นเป็นเศษเล็กเศษน้อยจากเมื่อจำนวนแรงม้าต่ำกว่า
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 ของ BullyBot และบิตอื่น ๆ Optimist มีการโจมตีแบบฉวยโอกาสสั้น ๆ และหวาน ๆ ที่ฉันนึกถึง (แม้ว่าบอตอื่นจะทำการคำนวณที่คล้ายกัน)

แทนที่จะรังแกเป้าหมายด้วยการทำให้พวกมันตะลึงงัน มันยังมีเป้าหมายที่อ่อนแอที่สุดในฝูงจากการรังแก แต่มันจะยอมแพ้และออกไปทำฟาร์มถ้า HP เป้าหมายที่อ่อนแอที่สุดนั้นสูงเกินไป


คุณกำลังทำฟาร์มด้วยตัวเองจนตาย ยอมรับการแก้ไขของฉัน :)
B0RDERS

1
@AndrewBorders ฮาไม่ได้คิดเกี่ยวกับมัน ขอบคุณ
Draco18s

บอทนี้ยอดเยี่ยมจนกระทั่งบอทป้องกันเหล่านั้นมา
B0RDERS

@ B0RDERS Shield นั้นแข็งแกร่งมากแม้ว่ามันจะเสียเวลาก็ตาม
Draco18s

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

บอทที่น่ารังเกียจเป็นส่วนใหญ่ อารมณ์เสียอย่างมากจากความจริงที่ว่ามันไม่สามารถ FizzBuzz อย่างแท้จริงดังนั้นมันจึงเป็นเพียง Buzzes แทนด้วยความโกรธ เมื่อมันไม่ใช่ Fizzing หรือ Buzzing มันจะไปที่บ็อตอื่นเป็นเวลา 30 รอบและยอมแพ้และเลือกบอทอื่นเพื่อตั้งเป้าหมายถ้ามันไม่คืบหน้า

ดำเนินการอย่างไม่สอดคล้องกันเป็นพิเศษ ไม่เป็นไรอัปเดตคอนโทรลเลอร์ตอนนี้ดูเหมือนจะอยู่กลางแพ็คเสมอ


ฉันชอบแนวคิดนี้ ไม่คำนึงถึงสถานการณ์ในปัจจุบันมันยังคงสับเปลี่ยนไปตามจังหวะของตัวเอง
เนส

5

bullyBot

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

JustFarm

ฉันคิดว่าฉันจะเริ่มง่าย

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

13
บอทนี้จะฆ่าตัวตายเนื่องจากต้นทุนการทำฟาร์ม 2HP
Draco18s

@ Draco18s แม้ว่ารอบอาจสิ้นสุดก่อนหน้านั้นขึ้นอยู่กับจำนวนของบอท
โปรแกรม Redwolf

1
ในขณะที่เป็นจริงในทางเทคนิคตัวจับเวลา 50 รอบสั้นมากเมื่อเวลาสิ้นสุดเริ่มต้นคือ 1,000
Draco18s

มันเอาชนะบอทสองตัวอย่าง แต่ตอนนี้มีการส่งอีกสองสามครั้งที่ฉันอาจลองหาสิ่งที่ดีกว่า
ไม่ระบุชื่อ

@Anonymous อาจรวมถึงการรักษาและการอัพเกรดฟาร์มอาจจะเพียงพอ เนื่องจากการได้รับทองคำมากที่สุดคือเป้าหมายสูงสุดทำให้งานหลักของบ็อตสามารถทำงานได้ ยังไม่เคยมีบอทใดเลยที่มี "โหมด" เช่นโหมดรักษาและโหมดฟาร์มอาจเป็นวิธีที่น่าสนใจ
โปรแกรม Redwolf

4

ScavengerBot (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

จับดีคงที่
reffu

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 คือการอัพเกรดการเลี้ยงและการรักษาสักระยะหนึ่งจากนั้นนำบอทอื่นออกมาในลำดับที่มีมูลค่าลดลง อย่างไรก็ตามถ้ามันถูกโจมตีมันจะหวาดกลัวและหวนกลับไปรักษาอีกสักหน่อย ถ้ามันโจมตีและ "ล้มเหลว" เพราะเหยื่อถูกรักษาหรือป้องกันได้อย่างมีประสิทธิภาพมากกว่าการโจมตีมันจะโกรธและออกไปเพื่ออัพเกรดความสามารถในการโจมตีของมัน


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

ความพยายามครั้งแรกที่ ธ ปท. เสริมการเรียนรู้ การป้องกันอย่างหมดจดสำหรับตอนนี้เพื่อ จำกัด พื้นที่การค้นหา เรียงลำดับของ spinoff ที่ชาญฉลาดกว่าของ FizzBuzz - ทำซ้ำซีรีย์เฉพาะห้าการกระทำซ้ำไปซ้ำมา การกระทำห้าอย่างคือสิ่งที่ RL เลือก

แต่ตอนนี้ส่วนใหญ่มาจากการแจงนับ - ตอนนี้ฉันเพิ่งสร้างพีชคณิต 3 ชุด 5 ^ 5 = 243 การกระทำห้าอย่างที่ซ้ำรอยซ้ำแล้วซ้ำอีกและเก็บคะแนนเฉลี่ยของพวกเขา (หารด้วย 200 เพื่อให้ได้กำไรโดยเฉลี่ย ห้ารอบ) การวนซ้ำมากกว่า 100 ครั้งในstorage.priorอาร์เรย์ จากนั้นในระหว่างเกมจะใช้วิธี epsilon-greedy เพื่ออัปเดตรายการคะแนนเหล่านั้นดังนั้นมันจึงเป็นหลักฐานในอนาคต (และเนื่องจากการใช้ 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
อาร์กิวเมนต์ที่ 2 ควรเป็นothers
SuperStormer

4

ScaredBot

  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) .
Nicolai

ตัวคูณราคานั้นเป็นความคิดที่ดี ฉันเพิ่มบางสิ่งที่คล้ายกัน ฉันสนใจที่จะดูว่าคุณได้รับตัวเลข
เท่าใด

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 แปลว่า "闷声发大财" หมายถึง "อู้อี้" ค่อนข้างแน่ใจว่านั่นไม่ใช่สิ่งที่คุณต้องการและอันที่จริงแล้วเป็นอีกหนึ่งมหากาพย์ Google Translate ที่ล้มเหลว ... ฉันค้นหาต่อไปและผลลัพธ์ทั้งหมดดูเหมือนจะพูดถึงว่าไม่มีคำภาษาอังกฤษเดียวที่สามารถใช้ที่นี่ได้ดังนั้นมันอาจจะดีกว่า ที่จริงแล้วดูเหมือนว่าจะเป็นคำบุพบทของจีนที่โดยทั่วไปหมายความว่าควรทำงานอย่างเงียบ ๆ และปล่อยให้ผลลัพธ์พูดด้วยตนเองและบรรลุตามปรัชญาดั้งเดิม น่าเสียดายที่ฉันไม่รู้ภาษาจีนเลยที่จะแปลโดยตรง : D
Erik the Outgolfer

1
ในฐานะผู้พูดภาษาจีนดั้งเดิมมันหมายถึงบางสิ่งบางอย่าง "ทำให้เกิดโชคลาภอย่างเงียบ ๆ ": v 闷声ยังมีความหมายว่าจงใจเงียบอย่างแท้จริง "ปกปิดเสียง"
ฟูริเยร์ฟูริเยร์แปลง

1
ส่อเสียด? UnderTheRadar? DontMindMe? AttentionDeflector?
Peter Taylor

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

คุณสามารถโพสต์ได้บ่อยครั้งเท่าที่คุณต้องการยิ่งฉันคิดว่า merrier ยิ่งกว่า
โปรแกรม Redwolf

@SuperStormer ฉันรู้ว่าคุณไม่ได้สุ่มทั้งหมด แต่:let victim=potentialVictims[Math.floor(Math.random()*potentialVictims.length)]
ไม่ระบุชื่อ

แต่ก่อนอื่นจะกรองสิ่งที่ไม่คุ้มค่ากับการโจมตี
SuperStormer

ฉันกำลังทำงานกับบอทที่คล้ายกันที่มีชื่อว่าอีควอไลเซอร์เมื่อคุณโพสต์สิ่งนี้ ฉันยังคงปรับจูน แต่ฉันชอบความคิดของคุณ
B0RDERS

2

Rando

คนโง่คนนี้จะเลือกการกระทำตามแบบแผนสุ่มที่มีอคติบางอย่าง หากการกระทำที่เลือกแบบสุ่มไม่ทำงานก็จะลดลงไปที่ตัวเลือกถัดไป

ดังนั้นโดยเฉลี่ยเขาควรโจมตีเกือบ 2/9 ของเวลาและทำฟาร์มเกือบ 3 ครั้ง ส่วนที่เหลือมีโอกาสประมาณ 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

ทำลายไม่ได้

การดัดแปลงบอทของ Draco18 โดยใช้ shields (มีประสิทธิภาพมากกว่าบอทอื่น ๆ )

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.