นักสะสมเหรียญทอง


48

หมายเหตุ: การสำรวจความชื่นชอบของชุมชนจะเปิดตัวเร็ว ๆ นี้

ใน KoTH นี้เป้าหมายคือการเป็น bot สุดท้ายที่ยังมีชีวิตอยู่ เหรียญจะถูกวางในพื้นที่สุ่มและบอทของคุณจะต้องได้รับเหรียญก่อน ถ้าบอทวิ่งเข้าไปในบอทอื่นบอบ็อตที่มีเหรียญมากกว่าจะชนะ รายละเอียดเพิ่มเติมด้านล่าง

ประเภทเหรียญ

เหรียญมี 2 ประเภทคือทองคำและเงิน ทองเพิ่ม 5 เหรียญเพื่อความแข็งแรงของบอทและเงินเพิ่ม 2 เมื่อรวบรวมเหรียญแล้วจะมีการวางเหรียญอีกอันไว้ที่จุดอื่นบนกระดาน ในเวลาใดก็ตามมีเหรียญทองหนึ่งใบและเหรียญเงินสี่ใบในที่เกิดเหตุ

ชนบอท

ในกรณีที่บอทสองคนพยายามที่จะครอบครองพื้นที่เดียวกันคนที่มีเหรียญมากกว่าจะอยู่ต่อและคนที่มีน้อยจะไม่ ... บอที่ชนะจะได้รับ85%ของเหรียญของฝ่ายตรงข้าม (ปัดเศษขึ้น) หากพวกเขาถูกมัดทั้งคู่ก็ตาย หากสามคนหรือมากกว่าพยายามครอบครองพื้นที่เดียวกันการชนะที่ทรงพลังที่สุดและรับ 85% ของเหรียญบอทอื่น ๆ ทั้งหมด ในกรณีที่ ธ ปทที่มีประสิทธิภาพมากที่สุดคือผูกทั้งหมดของบอทตายที่พยายามที่จะเข้าสู่พื้นที่

อารีน่า

4 + botCountยาวด้านของสนามกีฬาที่มีการคำนวณด้วย เมื่อวางบอทในตอนเริ่มเกมจะมีการสุ่มเลือกสถานที่ ระบบตรวจสอบให้แน่ใจว่าไม่มีบ็อตเริ่มต้นในพื้นที่เดียวกันหรือติดกัน เหรียญสร้างแบบสุ่มไม่รวม 3 โดย 3 ตารางมีศูนย์กลางอยู่ที่แต่ละบอท หากพบบอทอยู่นอกสนามแข่งขันมันจะตายทันที เวทีเริ่มต้นที่ (0,0) หรือตะวันตกเฉียงเหนือที่มุมซ้ายบนและที่ตั้งของบอทมักจะเป็นจำนวนเต็มเสมอ

บอทของคุณ

บอทของคุณควรเป็นฟังก์ชันในภาษาเชิงวัตถุใด ๆ ที่มีอาร์เรย์จำนวนเต็มสตริงและฟังก์ชัน โปรดทราบว่าการส่งทั้งหมดจะถูกแปลงเป็น Javascript เพื่อให้ง่ายขึ้น ในการจัดเก็บข้อมูลระหว่างการเคลื่อนไหวที่ใช้และbotNotes.storeData(key, value) botNotes.getData(key, value)คุณอาจจะไม่จัดเก็บหรือการเข้าถึงข้อมูลทางใดทางหนึ่งกว่าที่อื่น ๆ botNotesที่มีให้ผ่านพารามิเตอร์และ คุณควรสร้างฟังก์ชั่นที่เรียกว่าเมื่อส่งกลับสตริงnorth, east, south, หรือwest noneจะมี 3 ข้อโต้แย้งสำหรับฟังก์ชั่น:

  • วัตถุที่มีสี่จำนวนเต็ม ( locationX, locationY, coins, arenaLength) ตำแหน่งปัจจุบันของคุณเหรียญของคุณและความยาวของสนามกีฬา

  • อาเรย์หลายมิติพร้อมพิกัด X และ Y ของบอตอื่น ๆ และการนับเหรียญ[[0,5,4],[4,7,1],[7,4,12]]

  • อาร์เรย์ที่มีตำแหน่งเหรียญอยู่ในรายการ (ทองคำเป็นอันดับแรกเสมอ)

นี่คือราชาแห่งความท้าทายเขาห้ามช่องโหว่มาตรฐาน ฟังก์ชันของคุณจะทำงานหลายพันครั้งในแต่ละครั้งอนุญาตให้ "ย้าย" หนึ่งครั้ง โปรดทราบว่าหากเกมมีการเคลื่อนไหวเกิน20,000 ครั้งบอทที่มีเหรียญมากที่สุดจะเป็นผู้ชนะ สิ่งนี้จะเกิดขึ้น 8,000 ครั้งเพื่อลบการสุ่ม

ห้องแชท: https://chat.stackexchange.com/rooms/81347/gold-collectors-koth

รางวัล:

ที่หนึ่ง:รางวัลความโปรดปราน 100 จุด
ชุมชนที่ชื่นชอบ:คำตอบที่ยอมรับ 15 จุด

ผู้ชนะ:

รางวัลที่หนึ่ง: TBTPTGCBCBA
อันดับที่สอง: Big King Little Hill
อันดับสาม:
อันดับที่สี่อาจได้รับชัยชนะ: Bot Bot ที่สุภาพและสายตาสั้น
อันดับที่ห้า:เหรียญความปลอดภัย


6
"โปรดทราบว่าการส่งทั้งหมดจะถูกแปลงเป็น Javascript เพื่อให้ง่ายขึ้น" มันควรจะทำงานอย่างไร คุณทำการแปลงหรือไม่
Laikoni

21
ไม่มีอะไรผิดปกติกับ koth เพียงอนุญาตให้ใช้ภาษาเดียวโดยเฉพาะอย่างยิ่งภาษาที่แพร่กระจายอย่างกว้างขวางเป็น JavaScript แทนที่จะตอบ "แปลง" คลุมเครือกับ JavaScript (สมมุติว่าตัวคุณเองและด้วยมือ) คุณควรจำกัดความท้าทายให้กับ JS เท่านั้น เรามี koths เพียงอย่างเดียวอย่าง Java และ Python เท่านั้นในอดีตที่ผ่านมาทั้งหมด
Skidsdev

2
เวอร์ชันนี้ที่คุณควบคุมความเร่งแทนตำแหน่งจะเจ๋งมาก
akozi

12
สำหรับทุกคน: มีความคิดเห็นมากเกินไป waaaay แล้ว อย่าปล่อยให้ความเห็นที่ไร้ประโยชน์เช่น "+1 บอดี"และทำการลบความคิดเห็นของคุณถ้ามันซ้ำซ้อน เราไม่ใช่ไซต์ถาม - ตอบทั่วไป แต่ไม่มีใครชอบอ่านคำสั่งหลายร้อยคำ
user202729

5
(สำหรับคำถามของฉันเอง): ตาม NP ในการแชทมันเป็นเรื่องหลัง: บอททั้งหมดย้ายจากนั้นความขัดแย้งทั้งหมดได้รับการแก้ไขแล้วปิ๊กอัพเหรียญทั้งหมดจะเกิดขึ้นจากนั้นจึงวางเหรียญใหม่ทั้งหมด
BradC

คำตอบ:


26

BaitBot - JavaScript Node.JS

ทำไมต้องไล่ล่าหรือวิ่งถ้าคุณไม่สามารถจับได้? แต่ BaitBot ค้นหาเหรียญที่ใกล้ที่สุดและรอให้ bot ที่อ่อนกว่าเข้าหามัน เมื่อทั้งคู่อยู่ติดกัน BaitBot จะไปหาเหรียญโดยสมมติว่า ธ ปท. ที่อ่อนแอลงเช่นกัน หาก baitBot กำลังรอและบอทที่แข็งแกร่งกว่าเขาก็คว้าเหรียญและ skedaddles ลองฉัน!

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

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

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



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

}

1
ฮ่า, นั่นเป็นความคิดที่เรียบร้อยฉันชอบมัน
sundar

วิธีการนี้ค่อนข้างดี ... ไม่เจ๋งมาก
โปรแกรม Redwolf

1
BaitBot ต้องการมากกว่าแค่nearestThreat && distanceTo(nearestThreat) distanceTo(nearestThreat)มันล้มเหลวเมื่อไม่มีการคุกคาม
โปรแกรม Redwolf

1
ใช่nearestThreatคือundefinedถ้าบอตอื่น ๆ มีคะแนนมากกว่าของคุณ
คืนที่ 2

1
ฉันได้รับแจ้งเช่น [10] Bot Bait Bot tired of this world, and jumped off its edgeในบันทึกเหตุการณ์ของฉัน
โปรแกรม Redwolf

17

ชัยชนะที่อาจเกิดขึ้น JavaScript

#1600a6สีที่แนะนำสำหรับบอตนี้คือ

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

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

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

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

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

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

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

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

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

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

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

    return potential;
    }

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

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

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

(ขออภัยสำหรับการจัดรูปแบบเลอะเทอะการเยื้องช่องว่าง 4 รายการสำหรับไซต์นี้ไม่เป็นไปด้วยดีกับการใช้แท็บที่กำหนดเอง)

คำอธิบายที่หยาบ

ฉันขอลาออกจากความพยายามที่จะอัพเดทคำอธิบายของสูตร สัมประสิทธิ์มีการเปลี่ยนแปลงอยู่ตลอดเวลาและเป็นการยากที่จะอธิบายให้ทันสมัยอยู่เสมอ ดังนั้นฉันจะอธิบายหลักการทั่วไป

แต่ละเหรียญและแต่ละบอทสร้างสนามพลังที่มีศักยภาพ ฉันแค่เพิ่มศักยภาพจากทุกอย่างเข้าด้วยกันและบอทก็จะไปที่ใดก็ตามที่มีศักยภาพต่ำที่สุด (เห็นได้ชัดว่าความคิดนี้ถูกขโมยจากฟิสิกส์)

ฉันใช้ศักยภาพสองแบบ อันแรกคือแบบหลอก - ความโน้มถ่วงอันหนึ่ง (ซึ่งทำหน้าที่ในทุกช่วง) ด้วย kคือ "ความแรง" ของสนามและมีทางเลือกของสัญลักษณ์นี้มีศักยภาพเป็นที่น่าสนใจ Rนี่ (และทุกที่อื่น) เป็นระยะทางในรถแท็กซี่ตัวชี้วัดที่r = | x₁ - x₂ | + | y₁ - y₂ | .

U=kr+1511+n.

ฉันใช้k = 40สำหรับเหรียญทองและk = 10สำหรับเหรียญเงิน nคือจำนวนบอทที่ใกล้เคียงกับเหรียญที่เราต้องการมากกว่า มิฉะนั้นเราจะไม่สนใจบ็อตอื่น ๆ อย่างแน่นอน (ถ้าเราเข้าไปในบ็อตที่แข็งแกร่งกว่าเราก็วิ่งหนี แต่นั่นมัน) ฉันให้ความสำคัญกับเหรียญทองมากกว่าที่พวกเขามีค่าเพราะอย่างอื่นบอทที่ไปหลังจากทองคำตลอดเวลาเอาชนะฉัน

ศักยภาพที่สองคือการสลายตัวแบบเอกซ์โปเนนเชียลอย่างใดอย่างหนึ่ง (ซึ่งทำได้อย่างมีประสิทธิภาพเฉพาะในระยะทางที่น้อยมาก) สิ่งนี้สร้างขึ้นโดยคนอื่น ๆ ส่วนใหญ่มีประสิทธิภาพมากขึ้นบอท

เหล่านี้ผลิตข้อมูลที่มี พลังนี้มีความแข็งแกร่งในระดับ 0-1 แต่จะสลายตัวจนแทบไม่มีอะไรในระยะทางไกล (ระยะทาง + 1 หมายถึงการตัดกำลังใน 1/20)

U=5×1400e3r.

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

  1. เราต้องมีอย่างน้อย 25 เหรียญ (เราต้องได้รับเหรียญก่อน)
  2. พวกเขาจะต้องมีมากที่สุด(เหรียญของเรา - 5)เหรียญและอย่างน้อย 10 เหรียญ (เราไม่ต้องการที่จะตามล่าใครสักคนที่คว้าเหรียญหนึ่งเหรียญและมีพลังมากขึ้นในทันทีและเราก็ไม่ต้องการที่จะไล่ล่าบอทศูนย์เหรียญเช่นกัน)
  3. เราจะต้องล้าหลัง bot ที่เป็นผู้นำในปัจจุบันโดยอย่างน้อย 1/10 ของเหรียญของเขา (คุณต้องโชคดีในการตามล่าบางอย่างดังนั้นไม่จำเป็นต้องให้ตำแหน่งที่ดีเพียงเพื่อลองเสี่ยงโชคของเรา)
  4. เราจะต้องไม่อยู่ในคูลดาวน์การล่าสัตว์ (ดูด้านล่าง)

หากสิ่งเหล่านี้พอใจโหมดการล่าสัตว์จะเปิดใช้งาน สำหรับ 10 รอบถัดไปบอทที่ถูกล่าจะปล่อยพลังงาน หลังจากผ่านไป 10 รอบเราจะเข้าสู่คูลดาวน์การล่าสัตว์ในระหว่างที่เราไม่สามารถเข้าสู่โหมดการล่าสัตว์ได้อีก (นั่นคือเพื่อป้องกันเราจากการไล่ล่าบอทหนึ่งอันไม่มีที่สิ้นสุดและไร้ผลในขณะที่ทุกคนคว้าเหรียญอย่างมีความสุข) คูลดาวน์การล่าคือ 20 รอบเมื่อเรามี 25 เหรียญและเพิ่มขึ้น 20 เหรียญต่อการเพิ่มขึ้นสองเท่า (กล่าวอีกนัยหนึ่งคูลดาวน์คือ

U=150er.
20(1 + log2(c / 25)).) (เราใช้สิ่งนั้นเพราะใน endgame บอทที่ล่าได้ทั้งหมดน่าจะตายและดังนั้นการล่าสัตว์ใด ๆ ก็น่าจะไร้ประโยชน์ด้วยเหตุนี้เราจึงต้องการ จำกัด เวลาที่สูญเปล่า แต่บางครั้งโชคดีมาสาย - การกินเกมสามารถเปลี่ยนแปลงทุกสิ่งได้ดังนั้นเราจึงมีความเป็นไปได้)

ในที่สุดเวทีทั้งหมดจะถูกวางในหลุมที่ไม่มีที่สิ้นสุดซึ่งป้องกันไม่ให้บอทหนี


ฉันคิดว่าบอทนี้อาจจะทำให้การเคลื่อนไหวของฉันหนักเกินไป
fəˈnɛtɪk

@ fəˈnɛtɪk - ดังนั้นฉัน :—) ฉันคิดว่าอันนี้สามารถจัดการกับบ็อตอื่น ๆ ได้ดีขึ้นเล็กน้อย (มันไม่ใช่ "เหรียญ" ที่จัตุรัสที่อยู่ติดกัน) แต่ฉันให้ +1 กับคุณเพราะฉันเป็นแฟนตัวยงของความคิดนี้
Ramillies

คุณสามารถใช้หลักการของการกระทำน้อยที่สุดกับสิ่งนี้ได้หรือไม่?
สลายตัวเบต้า

@BetaDecay: ไม่มากฉันกลัวแคลคูลัสไม่ตอบสนองดีต่อปัญหาที่ไม่ต่อเนื่องเช่นนี้ แม้ในกรณีที่ต่อเนื่องมันจะไม่น่ารำคาญ (เพราะความเร็วคงที่) แต่ก็สามารถทำได้หลังจากเวทมนตร์พิกัดเชิงขั้วบางอย่างที่ฉันเดา
Ramillies

4
ที่นี่หนาว. ฉันไม่แน่ใจว่าความเสี่ยงนั้นเกี่ยวข้องกับระยะทางแบบ monotonically แต่ดูเหมือนว่าภัยคุกคามที่มี 2 ช่องทางมีแนวโน้มที่จะฆ่าคุณมากกว่าหนึ่งที่อยู่ติดกันเนื่องจากในกรณีหลังคุณต้องหยุดนิ่งเพื่อให้เกิดการปะทะกัน
ดัมและอีฟ

16

อัลกอริทึมการเรียนรู้ Gen แรก JavaScript (Node.js)

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

ลองออนไลน์!

คุณเคยเห็นขั้นตอนวิธีการเรียนรู้การเล่นเกมหรือไม่? พวกเขามักจะเคลื่อนที่แบบสุ่มในสองสามคนแรก ...


ฮ่า ๆ ... มันยังใช้ได้อยู่!
Redwolf

2
อัลกอริทึมการเรียนรู้ส่วนใหญ่ทำงานแบบสุ่มอย่างแท้จริงสำหรับการทำซ้ำสองสามครั้งแรกไม่ใช่เพียงแค่การสุ่มเท่านั้น
fəˈnɛtɪk

คาดเดาอะไร บอทนี้มีค่าเฉลี่ยเกือบ 0.22 เหรียญต่อรอบโดยเฉลี่ย!
โปรแกรม Redwolf

16

Big King Little Hill | JavaScript

function BigKingLittleHill(me, enemies, coins) {

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

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

ลองออนไลน์!

Big King Little Hill ตัดสินใจบนพื้นฐานของ“ ส่วนควบคุม” มันจะติดตามเหรียญที่อยู่ในเขตควบคุมเท่านั้นซึ่งหมายความว่ามันสามารถเข้าถึงเหรียญได้ก่อนที่บอทอื่นจะทำได้ เมื่อไม่มีเหรียญอยู่ในเขตของการควบคุมมันจะย้ายเพื่อเพิ่มขนาดของโซนการควบคุม Big King Little Hill คำนวณโซนการควบคุมของการเคลื่อนไหวที่เป็นไปได้ 5 แบบและสนับสนุนการเคลื่อนไหวที่เพิ่มขนาดของโซนการควบคุมให้สูงสุด ด้วยวิธีนี้บิ๊กคิงน้อยฮิลล์ในที่สุดก็มาถึงจุดสูงสุด (เนินน้อย) ในการควบคุมและรอเหรียญที่จะสร้างขึ้นภายในโซนของมัน นอกจากนี้บิ๊กคิงน้อยฮิลล์ปฏิเสธการเคลื่อนไหวใด ๆ ที่อาจส่งผลให้เสียชีวิตเว้นแต่จะไม่มีทางเลือกอื่น

Big King Little Hill เป็นผู้มองดูในแง่ร้าย (ชอบคำที่ชอบความจริง) เพราะมันไม่รบกวนการประกวดเหรียญใด ๆ ที่ไม่มั่นใจว่าจะได้รับ นอกจากนี้ยังเป็นผู้รักความสงบในการที่จะไม่ติดตามบอทที่อ่อนแอกว่าในแง่ใด ๆ (แม้ว่ามันอาจจะก้าวหนึ่ง ท้ายที่สุด Big King Little Hill เป็นคนขี้ขลาดที่จะไม่ทำลายชีวิตของตัวเองเพื่อรับรางวัลใด ๆ เว้นแต่จะได้รับอย่างแน่นอน


1
ยินดีต้อนรับสู่ PPCG! เป็นบอทที่ดีมาก = D
Luis felipe De jesus Munoz

นี่คือสิ่งที่ฉันคิดสำหรับบอท ทำได้ดีมาก
โจ

10

เหรียญเซฟตี้ JavaScript

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

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

บอทนี้มุ่งตรงไปยังเหรียญมูลค่าถ่วงน้ำหนัก (ค่า / ระยะทาง) ซึ่งไม่สามารถตายจากการเอื้อมถึงในเวลาเดียวกันหรือหลังจากบอทตัวอื่น หากไม่มีเหรียญที่ถูกต้องกับคุณสมบัตินี้มันจะอยู่ที่ไหนในขณะนี้บอทเคลื่อนที่ไปในทิศทางที่ปลอดภัยแบบสุ่ม (ความปลอดภัยหมายความว่าถ้าบอทเคลื่อนไปทางนั้นเหรียญเซฟตี้จะไม่สามารถชนกันได้ ถัดจากทันที) ให้น้ำหนักไปทางศูนย์กลางของสนามกีฬา


1
อืมสิ่งนี้อาจชนะได้จริง แม้ว่ามีจำนวนมากบอท
โปรแกรม Redwolf

วิธีการนี้จะมีปัญหามากขึ้นเมื่อวางบอทศัตรูที่มีค่าสูงกว่าหรือเท่ากัน
fəˈnɛtɪk

1
พวกเขาอาจจะทำให้เส้นตรงกับเหรียญใกล้เคียงกับพวกเขา / เหรียญทอง
โปรแกรม Redwolf

มันจะทำได้ดีถ้ามันจะได้รับเหรียญในตอนเริ่มต้น
fəˈnɛtɪk

และนั่นก็คือโชคส่วนใหญ่เนื่องจากสถานที่ที่สร้างเหรียญจะถูกสุ่มเลือก
โปรแกรม Redwolf

10

บอทที่เล่นเกมอย่างระมัดระวัง แต่สามารถก้าวร้าว | JavaScript

สีที่ต้องการ: #F24100

หมายเหตุ:แม้ว่าบอตนี้จะได้อันดับที่ 1 แต่เป็นเพราะการรวมกลุ่มกับ "Feudal Noble" ในตอนท้ายและกินเขาเพื่อรับเหรียญมากขึ้น มิฉะนั้นบ็อตนี้จะเป็นอันดับ 3 หากคุณมีความสนใจในบอทที่มีประสิทธิภาพมากขึ้นทีละชำระเงินที่อาจมีชัยและบิ๊กคิงลิตเติ้ลฮิลล์

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        return score + Math.random();
    };

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

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

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

    return topCommand;
}

บอทนี้ (หรือที่รู้จักในนาม "TBTPTGCBCBA") พยายามทำการตัดสินใจที่ดีที่สุดโดยการทำคะแนนสำหรับการย้ายแต่ละครั้งที่เป็นไปได้และเลือกการย้ายที่มีคะแนนสูงกว่าสำหรับการเลี้ยวแต่ละครั้ง

ระบบการให้คะแนนมีรายละเอียดมากมายที่พัฒนามาตั้งแต่เริ่มต้นการท้าทาย พวกเขาสามารถอธิบายได้โดยทั่วไปเช่นนี้

  • ยิ่งเหรียญอยู่ใกล้กับการเคลื่อนไหวมากเท่าไหร่ก็ยิ่งได้คะแนนมากขึ้นเท่านั้น หากเหรียญไม่มีผู้เข้าแข่งขันคนอื่น ๆ คะแนนจะสูงขึ้น หากเหรียญมีผู้เข้าแข่งขันคนอื่น ๆ คะแนนจะลดลง
  • หากบอทอื่นอยู่ใกล้กับท่าที่เป็นไปได้และมีเหรียญน้อยกว่าขึ้นอยู่กับระยะของเกมอาจหมายถึงคะแนนที่มากกว่าสำหรับท่านั้น ดังนั้นจึงเป็นเรื่องง่ายสำหรับ "TBTPTGCBCBA" ที่จะกินบอทอื่น ๆ ในแต่ละเกม
  • หากบอทอื่นอยู่ใกล้กับท่าที่เป็นไปได้ที่มีแต้มเท่ากันหรือมากกว่านั้นการแทงนั้นจะได้รับคะแนนลบมากพอที่จะทำให้แน่ใจได้ว่าหลีกเลี่ยงการเสียชีวิต แน่นอนว่าอาจมีบางกรณีที่การเคลื่อนไหวที่เป็นไปได้ทั้งหมดนั้นไม่ดีและไม่สามารถหลีกเลี่ยงความตายได้ แต่มันหายากมาก
  • มีกลไกในการติดตามจำนวนของบอทที่อยู่ตรงกลางกระดานในรอบ 20 รอบสุดท้าย หากค่าเฉลี่ยต่ำพอทุกอย่างจะเคลื่อนไปสู่เหรียญที่อยู่ตรงกลางได้รับคะแนนมากขึ้นและถ้าค่าเฉลี่ยสูงแล้วทุกอย่างจะย้ายไปที่เหรียญที่อยู่ตรงกลางได้รับคะแนนที่ต่ำกว่า กลไกนี้อนุญาตให้หลีกเลี่ยงความขัดแย้งกับ "ศักดินาโนเบิล" เนื่องจาก "Feudal Noble" นั้นอยู่ตรงกลางเสมอ (เว้นแต่จะถูกไล่ล่า) จำนวนเฉลี่ยของบอทที่อยู่ตรงกลางจะเพิ่มขึ้นและ "TBTPTGCBCBABA" เข้าใจเพื่อหลีกเลี่ยงการอยู่ตรงกลางหากมีตัวเลือกที่ดีกว่าพื้นที่กลาง หาก "ศักดินาโนเบิล" ตายลงค่าเฉลี่ยจะลดลงและ "TBTPTGCBCBA" เข้าใจว่าสามารถใช้ตรงกลางได้
  • มีปัจจัยบางอย่างที่เปลี่ยนแปลงแบบไดนามิกตามช่วงของเกม (ตรวจพบจากจำนวนบอทที่ยังมีชีวิตอยู่) ปัจจัยเหล่านี้มีผลต่อการให้คะแนนในแต่ละรายการข้างต้น
  • บอทนี้มีความสามารถพิเศษ เมื่อเวลาผ่านไปมันเริ่มเบื่อกับความเห็นแก่ตัวของ "ศักดินาสูงส่ง" และการกดขี่ของชาวนา ในเวลาที่เหมาะสมมันจะเพิ่มขึ้นเพื่อยุติระบบศักดินาที่ไม่พึงประสงค์ ความพยายามที่ประสบความสำเร็จไม่เพียงช่วยชาวนาที่ยากจน แต่ยังให้โอกาสในการชนะที่สูงขึ้นเนื่องจากเหรียญที่นำมาจาก "ศักดินาขุนนาง"

ดูเหมือนว่าฉลาดกว่าคนอื่น ๆ
โปรแกรม Redwolf

5
ฉันชอบส่วนสัตว์ประหลาดของ params
โปรแกรม Redwolf

9

AntiCapitalist | จาวาสคริ

ไม่มีแรงจูงใจที่จะไล่ตามเหรียญ แต่พยายามวางตัวเองระหว่างบอทที่ร่ำรวยที่สุดทั้งสองด้วยจำนวนเงินเท่ากันโดยหวังว่าพวกเขาจะตามล่าเขาและจับเขาในที่สุดในเวลาเดียวกันพานายทุนสองคนไปกับเขาเมื่อเขาตาย . ไม่ต่อต้านการรับเหรียญอย่างแข็งขันดังนั้นเขาอาจกลายเป็นเป้าหมายที่ฉ่ำมากขึ้น

function antiCapitalist(me, capitalists, coins){

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

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

            previousCapitalist = capitalist;
        }

        return false;
    }

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

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

    return move();
}

9

GUT, JavaScript

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

    var objects = [];

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

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

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

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

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

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

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

    // y acceleration
    var y_acceleration = 0;

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

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

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

ด้วยชัยชนะที่อาจเกิดขึ้นเรามีสองฟิลด์: ฟิลด์ bot และฟิลด์เหรียญ อย่างไรก็ตามธรรมชาตินั้นไม่ซับซ้อน ถึงเวลาที่จะรวมกันทั้งสองสาขาการผลิตทฤษฎีเอกภาพแกรนด์

ประการแรกเราต้องหาว่าสนามมีศักยภาพเท่าใด สมมติว่า ธ ปท. ของเราไม่มีอิทธิพลใด ๆ กับสนามเราสามารถเขียนสิ่งนี้เป็น:

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

kn(xn,yn)

มีการคำนวณคุณสมบัติสัมพัทธ์ของวัตถุดังนี้:

k=cobjectcme

ccme=cself+1cself

ขอเพียงโทรส่วนการแก้ไขนี้ดัดแปลง Betanian Dynamics (MOBD)

นอกจากนี้เรายังสามารถค้นหาพลังงานจลน์เป็น:

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

ตอนนี้เราสามารถคำนวณการกระทำ:

หนังบู๊=a(T-V)dเสื้อ=a(12ฉัน(x˙2+Y˙2)-Σnkn(อีkn2-100(x-xn)2+อีkn2-100(Y-Yn)2))dเสื้อ

และลากรองจ์ของบอทของเราในเขตเหรียญบอทคือ:

L=12ฉัน(x˙2+Y˙2)-Σnkn(อีkn2-100(x-xn)2+อีkn2-100(Y-Yn)2)

ตอนนี้เราต้องแก้สมการออยเลอร์ - ลากรองจ์:

ddเสื้อLx˙=Lx

และ:

ddเสื้อLY˙=LY

ดังนั้น:

ddเสื้อLx˙=ddเสื้อ[ฉันx˙]=ฉันx¨

Lx=Σn200kn(x-xn)อีkn2-100(x-xn)2

x¨=Σn200knฉัน(x-xn)อีkn2-100(x-xn)2

และนอกจากนี้ยังมี:

ddเสื้อLY˙=ddเสื้อ[ฉันY˙]=ฉันY¨

LY=Σn200kn(Y-Yn)อีkn2-100(Y-Yn)2

Y¨=Σn200knฉัน(Y-Yn)อีkn2-100(Y-Yn)2

ตอนนี้เราไม่จำเป็นต้องไปไกลกว่านี้อีก: เราแค่ดูทิศทางของการเร่งความเร็วโดยรวม:

เอาท์พุต={ทางทิศเหนือถ้า Y¨<0 และ |Y¨|>|x¨|ทางทิศใต้ถ้า Y¨>0 และ |Y¨|>|x¨|ทิศตะวันตกถ้า x¨<0 และ |x¨|>|Y¨|ทางทิศตะวันออกถ้า x¨>0 และ |x¨|>|Y¨|ไม่มีถ้า |Y¨|=|x¨|

และเช่นนั้นเราได้รวมเหรียญและบอทไว้ด้วยกัน รางวัลโนเบลของฉันอยู่ที่ไหน


5
รางวัลโนเบลของคุณสูญหายทางไปรษณีย์ แต่เราสามารถมอบรางวัลเอ็มมี่แทน
โปรแกรม Redwolf

1
ดูเหมือนว่าฟิสิกส์จะเริ่มได้รับความนิยมในการท้าทายนี้ :-D และแน่นอนฉันอยากรู้ว่ามันจะทำอย่างไรดี
Ramillies

1
(โดยวิธีการที่คุณสามารถบันทึกความยุ่งยากด้วยสมการออยเลอร์ - ลากรองจ์เพราะพวกเขาลดความจริงที่รู้จักกันดีว่า F = c_me a = - ผู้สำเร็จการศึกษา U :—).)
Ramillies

@Ramillies Meh มันสนุกมากกว่าที่ทำแบบนี้: D
Beta Decay

1
คุณแน่ใจหรือไม่ว่าต้องการใช้ k = เหรียญอย่างอื่น / เหรียญของคุณ? คุณเริ่มต้นด้วยเหรียญไม่มี ... และด้วย NaN ทุกหนทุกแห่งคุณไม่น่าจะได้รับมากเกินไป
Ramillies

8

Goldilocks, JavaScript (Node.js)

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

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

  return mymove
}

ลองออนไลน์!

เพียงล็อคไปยังตำแหน่งของเหรียญทองและเคลื่อนไปทางนั้นทุกครั้ง (ขอบคุณบอท 'B33-L1N3' ของ @ Mayube สำหรับรหัสดั้งเดิมที่ใช้แม้ว่าจะไม่เหลือเลย)


นี่เป็นบอทที่สวยและเรียบง่าย ฉันชอบมัน.
โปรแกรม Redwolf

2
โดยวิธีการที่ฉันใช้บอทนี้เป็นแบบทดสอบสำหรับตัวควบคุมของฉัน (:
โปรแกรม Redwolf

8

ขั้นตอนวิธีการเรียนรู้ Gen ที่สาม | JavaScript (Node.js)

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

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

ลองออนไลน์!

หลังจากการเรียนรู้ไม่กี่ชั่วอายุบอทนี้ได้เรียนรู้ว่าการออกจากเวที = เลว


โอ้ดี. ฉันเคยได้ยินสิ่งนี้เรียกว่า "การคัดเลือกโดยธรรมชาติ"
โปรแกรม Redwolf

5
Gen ที่สองอยู่ที่ไหน
Luis felipe De jesus Munoz

11
@LuisfelipeDejesusMunoz เขาออกจากเวที
โจ

นี่เป็นบอทที่ดีสำหรับการดีบั๊กตัวควบคุม
โปรแกรม Redwolf

3
โอ้โดยวิธีการที่เวทีเริ่มต้นที่ 0 arenaLength - 1ดังนั้นมันควรจะเป็น สิ่งนี้ทำให้บอทของคุณเสียเวลาไปหลายครั้ง
โปรแกรม Redwolf

7

B33-L1N3 | JavaScript (Node.js)

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

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

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

ลองออนไลน์!

สร้างเส้นตรงสำหรับเหรียญที่อยู่ใกล้ที่สุด


โอ้ฉันคิดว่า B33-L1N3 เป็นหมายเลขรุ่นบางอย่าง
โปรแกรม Redwolf

+1 สำหรับชื่อ
คาอิน

let coins = ...Uncaught SyntaxError: Identifier 'coins' has already been declared
กลางคืน 2


5

Livin 'บน Edge, JavaScript

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

คนนี้ได้ยินว่าขอบสนามกีฬาเป็นสถานที่ที่อันตราย ไม่รู้เลยว่ามันกลัวมันวนตามเข็มนาฬิกาเป็นวงกลมห่างจากความตายที่รออยู่ด้านหลังเพียงไม่กี่นิ้วโดยหวังว่าจะไม่มีบอทคนอื่นกล้าเคลื่อนไหวใกล้ชิดขอบ


1
สิ่งนี้จะไม่จบลงถ้าบอตอื่นถูกสร้างขึ้นที่มี 1 เหรียญมากขึ้นและตรวจสอบชายแดนในทิศทางตรงกันข้าม (:
โปรแกรม Redwolf

8
ฉันจะทำให้เรื่องตลกการควบคุมชายแดน แต่ฉันปล่อยให้หนึ่งที่ @BetaDecay
โปรแกรม Redwolf

5

Damacy, JavaScript (Node.js)

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

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

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

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

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

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

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

  if (!done)
    dir = 'none'


  return dir
}

ลองออนไลน์!

บอทหนึ่งที่ใช้ Katatari ตัวสุดท้ายสำหรับวันนี้เวลานี้มีหน่วยความจำเล็กน้อย ขอขอบคุณที่@BetaDecayสำหรับข้อเสนอแนะชื่อ - simplePredictorKatamariแน่นอนชื่อสนุกกว่าของฉัน

พยายามหาวิธีที่บอทเคลื่อนไหวในเทิร์นสุดท้ายและขึ้นอยู่กับว่ามันจะทำนายตำแหน่งที่พวกเขาจะพยายามเคลื่อนที่ในตอนท้ายของเทิร์นนี้ (สมมติว่าพวกมันยังคงเคลื่อนที่ในทิศทางเดียวกัน)

(ขอบคุณ @ fəˈnɛtɪk สำหรับการสังเกตว่าฉันกำลังเรียกชื่อฟังก์ชั่นที่ไม่ถูกต้องใน botNotes และ @ OMᗺเพื่อสังเกตเห็นข้อบกพร่องในรหัสฐาน)


นี่อาจเป็นเพียงคนเดียวในขณะนี้ที่สามารถจับคนอื่นนอกเหนือจากการโชคดี
ดัมและอีฟ

botnotes ไม่ควรเป็น "hiddenata" ไม่ใช่ setdata หรือไม่
fəˈnɛtɪk

@ fəˈnɛtɪk ดูแล้วต้องการตัวแก้ไขข้อผิดพลาด! :) ขอบคุณแก้ไขแล้ว
sundar

คุณควรแทนที่aWt = 1ใน params ด้วยaWtและวางไว้aWt = aWt || 1ข้างใต้ (เหมือนกับbWt) เป็นการป้องกันข้อผิดพลาด
Redwolf

5

โปรตอน JavaScript

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

เหรียญทั้งหมด (รวมถึงที่เก็บโดยบ็อตอื่น ๆ ) ปล่อยพลังอันน่ารังเกียจเข้าหา Protonbot ขึ้นอยู่กับแรงนี้มันสร้างความเร็วและกระเด้งออกมาจากผนัง (หันกลับทันทีเมื่อชนกับขอบเขต) ถ้ามันจบลงถัดจากบอทหรือเหรียญมันสามารถกินได้พลังนิวเคลียร์ที่แข็งแกร่งจะเข้ามาแทนที่มันจะเคลื่อนที่เพื่อกินมันจะลดความเร็วลงทุกเมื่อ


อืมฟิสิกส์นิวเคลียร์ใช้กับการตามล่าหาสมบัติเหรอ? ช่องวิทยาศาสตร์ช่องนี้ทุกวัน!
โปรแกรม Redwolf

คุณต้องแทนที่sinด้วยMath.sin, cosมีMath.cosและอื่น ๆ
โปรแกรม Redwolf

4

ไม่สุ่มสี่สุ่มห้า JavaScript (Node.js)

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

คุณเคยได้ยินเกี่ยวกับอัลกอริทึม A * pathfinding ไหม? นี่มันคือ มันสร้างเส้นทางที่ดีที่สุดจากจุดหนึ่งไปยังเหรียญที่มีค่าน้อยกว่า (เพราะทุกคนกำลังไปหาสิ่งที่มีค่าที่สุดไม่มีใครไปได้เลย) และพยายามที่จะไม่ชนกับผู้ใช้คนอื่น

ต้องการพารามิเตอร์ดังนี้:

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

บางทีฉันอาจทำอย่างนั้นเพื่อไปหาบอทคนอื่น


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

1
ว้าว ... เป็นอัลกอริธึมการค้นหาเส้นทางหรือไม่ 3 ชั่วโมงเท่านั้น!
โปรแกรม Redwolf

@ RedwolfPrograms อย่างที่ฉันบอกว่ามันถูกคัดลอกมาจากความท้าทายอื่นที่คล้ายคลึงกัน เพียงแค่ต้องปรับตัวให้เข้ากับสิ่งนี้
Luis felipe De jesus Munoz

อัลกอริธึมของฉันไปได้ว่าเหรียญไหนจะปลอดภัยที่สุด
fəˈnɛtɪk

4

คนขี้ขลาด Python 2

import random

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

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

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

        if safe:
            target = (x, y)
            break

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

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

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

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

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

    return random.choice(directions)

หลีกเลี่ยงบอทด้วยเงินมากขึ้นถ้าเป็นไปได้ทั้งหมด มิฉะนั้นคว้าเงินที่โกหกรอบ


นี่คือบอทพื้นฐานที่สุดที่มีโอกาสชนะ
โปรแกรม Redwolf

4

Bot Wild Goose Chase, Javascript

บอทที่เก่งมากในการหลบบอทอื่น ๆ แต่ก็แย่มากที่ได้รับเหรียญ


ขั้นตอนวิธีการ:

  1. หากไม่มีบอทที่อยู่ติดกันให้ส่งคืนไม่มี
  2. มิฉะนั้น:
    1. ไม่ส่งคืนด้วยโอกาสสุ่ม 1/500 โอกาส (เพื่อป้องกันไม่ให้ผู้มีทางตัน)
    2. กำหนดว่าช่องว่างใดปลอดภัยที่จะย้ายไปที่ (เช่นภายในเวทีและไม่ได้ครอบครองโดยบ็อตอื่น)
    3. ส่งคืนหนึ่งโดยการสุ่ม

รหัส:

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

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

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

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

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

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

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

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

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

ลองออนไลน์!

หมายเหตุถึงโปรแกรม Redwolf:

บอทนี้มีศักยภาพที่จะทำให้เกิดรอบที่ยาวมาก ฉันใช้เสรีภาพบางอย่างเพื่อป้องกันการถูกยัน แต่ไม่ได้ทดสอบว่ามีประสิทธิภาพจริงหรือไม่ หากบอทนี้กลายเป็นปัญหาระหว่างการทดสอบโปรดอย่าตัดสิทธิ์


ขอบคุณสำหรับการบันทึก ผู้ล่าผู้เชี่ยวชาญมีโอกาสโอเคถ้ามันเกิดขึ้นในการเก็บเหรียญมากพอในขณะที่ถูกไล่ล่า
โปรแกรม Redwolf

ฉันชอบสิ่งนี้. มันเกือบจะเหมือนเหยื่อล่อให้หุ่นยนต์ล่าสัตว์
เบต้าสลายตัว

4

KatamariWithValues, JavaScript (Node.js) ,

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

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

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

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

  if (!done)
    dir = 'none'

  return dir
}

ลองออนไลน์!

(ขอบคุณ @ OMᗺสำหรับการชี้จุดบกพร่องในรหัสต้นฉบับซึ่งเป็นไปตาม)

พยายามที่จะเติบโตโดย "กิน" บอทที่มีเหรียญน้อยกว่าตัวมันเอง หากไม่สามารถทำได้ (ไม่มีบอทนั้นอยู่) ให้ค้นหาเหรียญที่ใกล้ที่สุด

รุ่นนี้มีการปรับแต่งเล็กน้อยเพื่อ (ก) ให้การตั้งค่าที่สูงกว่าเหรียญทองมากกว่าเหรียญเงิน - ด้วยความเสี่ยงที่การหาเหรียญทองที่ห่างไกลกว่าอาจจบลงด้วยการเสียชีวิตของบอทหรือนำไปสู่การไล่ล่าหลังจากทองหลอก 0 เหรียญ - ไม่ต้องเสียเวลาไล่ล่าหลังจากนั้น


สมาร์ทนักล่า ... ดีที่ดียิ่งขึ้น!
โปรแกรม Redwolf

@ RedwolfPrograms มาหวังกันดีกว่า! :)
sundar

น่าจะเรียกสิ่งนี้ว่า Damacy;)
สลายตัวของเบต้า


4

Bot เมาสุราสายตาสั้น | JavaScript

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

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

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

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

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

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

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

นักเดินรอบรับเหรียญใกล้เคียง แต่สุ่มสลับทิศทางทุก ๆ ครั้ง ทำในสิ่งที่เขาสามารถทำได้เพื่อหลีกเลี่ยงการชนใคร แต่เขาได้ ... ทำสงคราม ... เมื่อกำเริบ มีแนวโน้มที่จะมีสติขึ้นเมื่อการแข่งขันดำเนินต่อไป

อาจต้องมีการแก้จุดบกพร่องบางอย่างเมื่อตัวควบคุมเสร็จสมบูรณ์ฉันจะทำงานกับมัน


3
อืมมันยกแท่งจากนั้นก็เมาไปเลย
รายการ Redwolf

4

ถ่วงน้ำหนักการเคลื่อนไหว JavaScript

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

เคลื่อนที่ไปในทิศทางที่กำหนดค่าสูงสุดในขณะที่หลีกเลี่ยงขอบบอร์ด

ค่าจะถูกคำนวณดังนี้:

  • เหรียญ = พลังของเหรียญ / ระยะทางถึงเหรียญ
  • Bot = ความแตกต่างของพลังของบอต / ระยะทาง 2 * ถึงบอท

1
ดูเหมือนว่าบ็อตที่ยอดเยี่ยมมาก อย่าลืมตรวจสอบเส้นทางเนื่องจากมันจะเป็นการสูญเสียอย่างแท้จริงถ้าบอทของคุณเป็นผู้เชี่ยวชาญในการหลบหนีจากเหรียญ (:
โปรแกรม Redwolf โปรแกรม

ก็ยัง ฉันจะต้องเป็นคนดีใช่มั้ย
โปรแกรม Redwolf

ดีโพสต์มัน! มันจะประกอบขึ้นเป็นบอทขนาดเล็กลงและเร็วขึ้นซึ่งยังมีอยู่ในขณะนี้ในปริมาณมาก
โปรแกรม Redwolf

for(i=0;i<6;i++){มีเพียง 5 เหรียญทั้งหมด 1 ทองและ 4 เงิน ลูปของคุณทำงาน 6 ครั้งตั้งแต่ 0 ถึง 5
กลางคืน 2

3

คนตาบอด | JavaScript (Node.js)

นี่จะไม่ชนะ แต่อย่างน้อยก็เข้าร่วม ลองครั้งแรกที่การท้าทายของ KoH มันเรียงลำดับเหรียญและไปที่หนึ่งที่ใกล้ที่สุด เขาไม่ได้มองหาผู้เล่นดังนั้นเขาจึงไม่สนใจว่าเขาจะปะทะกับคนอื่นหรือไม่

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

    if(coins.length == 0)
        return n

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

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

อืมมันอาจใช้งานได้เพราะบอตอื่น ๆ กำลังมองหาทองคำเป็นหลักซึ่งอาจทำให้คุณได้รับเงินโดยไม่ต้องต่อสู้ใด ๆ
โปรแกรม Redwolf

3

ศักดินาโนเบิล JavaScript

สีที่ต้องการ: #268299

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

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

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

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

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

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

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

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

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

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

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

        return score;
    };

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

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

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

    return topCommand;
}

ขุนนางศักดินานี้ยังคงอยู่ที่ใจกลางสนามและอ้างว่าเป็นวังของเขาเอง รวบรวมทุกสิ่งที่อยู่ตรงกลางสำหรับตัวเขาเอง แต่สิ่งใดในฟาร์มที่อยู่ห่างไกลควรถูกชาวนานำมาให้เขา แน่นอนถ้าชาวนาผู้โกรธแค้นปรากฏตัวที่วังขุนนางอาจหนีไปช่วยชีวิตเขาได้ แต่เขากลับมาทันทีที่ปลอดภัย!

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


2

Quantum Gnat Bot | JavaScript

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

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

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

  return chosenDir
}

บอทที่น่ารำคาญนี้พยายามที่จะส่งเสียงพึมพำรอบ ๆ บอทที่แข็งแกร่งที่สุดโดยไม่ได้รับการตีสองหน้าและมีโอกาสเล็กน้อยในการวางขั้นตอนผ่านผู้ที่พยายามตามล่ามัน มันมีแนวโน้มที่จะดึงบอทที่ทรงพลังที่สุดทั้งสองเข้าไปในระยะใกล้ ... ;)


หากเขาไม่สามารถหาเป้าหมายที่เหมาะสมได้getTargetDirections()สิ่งที่น่าสนใจก็จะเกิดขึ้น (เช่นการทำลายทุกอย่างเนื่องจากundefined has no property 0ข้อผิดพลาด)
Ramillies

2

ตัวแทน ICE ที่เกษียณแล้ว, JavaScript

สีที่ต้องการ: indianred

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

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

    avg /= others.length;

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

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

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

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

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

เกษียณแล้วตัวแทน ICE นี้จะขมขื่นเกี่ยวกับมนุษยชาติ ดังนั้น Retired ICE จึงตั้งเป้า bot ที่อ่อนแอที่สุดในขณะที่รักษาค่าของมันไว้สูงกว่าค่าเฉลี่ย (ตามนโยบายของ ICE)


2

Greedy-Pursuit | Haskell

สีที่ต้องการ: #62bda4

import Data.List

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


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

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

ลองออนไลน์!* * * *

กลยุทธ์ง่ายๆสวยเลือกการตัดสินใจครั้งแรกจาก:

  • หากมีบอทที่มีเหรียญน้อยให้เลือกที่อยู่ใกล้ที่สุดและเคลื่อนที่ไปหามัน
  • หากมีเหรียญให้เลือกที่ใกล้เคียงที่สุดและย้ายไปหามัน
  • เริ่มต้น: อยู่

บอทพยายามที่จะจับบอทหรือเหรียญอื่น ๆ โดยไม่สนใจบอทที่แข็งแกร่งขึ้นซึ่งอาจพยายามที่จะจับมัน

* ฉันไม่รู้จัก JavaScript แต่ฉันทำสิ่งนั้นกับ google (อาจไม่ถูกต้อง): ลองออนไลน์!


6
ฉันสงสัยว่าเขาจะแปลฮาเซลเป็น js ได้อย่างไร
Luis felipe De jesus Munoz

3
@LuisfelipeDejesusMunoz: ใช่ฉันด้วย แต่โชคดีที่มันไม่ใช่รหัสที่ซับซ้อนมาก
ბიმო

@LuisfelipeDejesusMunoz เพียงใช้ Node.JS และprocess.open(หรือchild_process.spawnหรือคล้ายกัน) ด้วยการแยกวิเคราะห์
user202729

@LuisfelipeDejesusMunoz: ฉันพยายามที่จะแปลและเพิ่มลิงค์ แต่ฉันไม่มั่นใจในการเขียน JavaScript ดังนั้นมันอาจจะเป็นรถ
ბიმო

4
@LuisfelipeDejesusMunoz มันจะเป็นสิ่งหนึ่งถ้านี่คือโปรแกรมการเรียนรู้ AI 10,000 บรรทัด แต่ฉันคิดว่าฉันสามารถจัดการสิ่งนี้ได้ (:
โปรแกรม Redwolf

1

เหรียญแม่เหล็ก JavaScript

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

บอทนี้ค่อนข้างโง่มันเป็นหัวหน้าของเหรียญที่ได้รับมากที่สุด ซึ่งรวมถึงเหรียญที่ไม่สามารถรับได้เพราะบอทอื่นมีพลังสูงกว่าตัวมันเอง


1

ตัวแทนน้ำแข็ง จาวาสคริ

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

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

    avg /= others.length;

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

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

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

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

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

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

จุดของเส้นขอบคืออะไรหากไม่ได้รับการตรวจตรา ICE เลื่อนทวนเข็มนาฬิกาไปรอบ ๆ เพื่อหยิบบอทที่หลงทางเข้ามา

ก่อนที่จะสามารถทำเช่นนั้นได้จะต้องสามารถกินบอทอื่นก่อน ด้วยเหตุนั้น ICE จึงเก็บเหรียญไว้สูงกว่าค่าเฉลี่ยของบอททั้งหมด

รับประกันว่าจะขโมยเด็ก ๆ จากผู้ปกครอง™


นี่คงจะตลกกว่านี้ถ้ามันไม่เกี่ยวข้องเลย
Don Thousand

1

X Marks The Spot | JavaScript

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

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

X ทำเครื่องหมายจุดนั้นทองทั้งหมดจึงต้องอยู่บนแกน x ใช่ไหม? บอทของฉันสร้างเส้นตรงสำหรับ y = 0 บรรทัดจากนั้นอยู่ที่นั่นเคลื่อนที่แบบสุ่ม


Huh เป็นวิธีการที่น่าสนใจแน่นอน
โปรแกรม Redwolf


1
ระบุว่าThe arena starts at (0,0) in the upper left cornerเป็นคุณแน่ใจว่าต้องการที่จะย้ายsouthที่จะได้รับy=0?
AdmBorkBork

@AdmBorkBork ขอบคุณที่อาจไม่ดี
Beta Decay

1

Firebird

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

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

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

ปรับปรุงใหม่ทั้งหมดเพื่อเป็นอันตรายยิ่งกว่าเดิม (:


2
ผู้แพ้บอทที่แน่นอนของฉัน
โปรแกรม Redwolf

มันไม่ได้มุ่งเป้าไปที่พวกเขา แต่ก็หลีกเลี่ยงพวกเขา
โปรแกรม Redwolf

ขอโทษทีฉันเข้าใจผิด
สลายตัวของเบต้า

1

A-Path-y | JavaScript

#0077b3สีที่แนะนำสำหรับบอตนี้คือ

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

    var GOLD_POINTS = 5;
    var SILVER_POINTS = 2;

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

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

    var MIDGAME_THRESHOLD = 25;

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

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


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

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

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

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

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


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

             var currentIndex = -1;     

            var openListSize=1;
            var tileId=1;

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



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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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


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

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

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

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

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

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


                            var currentCellMinBotDistance = 2147483647;

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

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

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


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

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

บอทนี้ใช้การค้นหาเส้นทางควบคู่ไปกับแผนที่ความต้องการของเซลล์เพื่อหลีกเลี่ยงบอทที่อาจฆ่าเราไปหาเหรียญที่อยู่ใกล้ไม่ใช่กับดักและมีความเสี่ยงน้อยที่สุด

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

Bot ตอนนี้มีกลยุทธ์การเล่นเกมตั้งแต่กลางถึงปลายที่ไม่สนใจเหรียญมันไม่สามารถเข้าถึงก่อนบอทอื่นและหากไม่สามารถไปที่เหรียญใด ๆ แล้วย้ายไปยังเซลล์ที่ใกล้เคียงที่สุดซึ่งอยู่ห่างจากบอทอื่นที่แข็งแกร่งกว่าตัวมันเอง

ตอนนี้มีโอกาสชนะ

หมายเหตุขออภัยสำหรับรหัสเส็งเคร็งฉันได้แปลงจาก Java โดยอัตโนมัติ


ตรวจสอบให้แน่ใจว่าได้รับข้อบกพร่องและ / หรือการอัปเดตให้เร็วที่สุด 18 ชั่วโมงถึงวันครบกำหนด!
โปรแกรม Redwolf

@ RedwolfPrograms คุณสังเกตเห็นข้อผิดพลาดหรือไม่? ถ้าเป็นเช่นนั้นโปรดแจ้งให้เราทราบเพื่อให้ฉันสามารถแก้ไข ขอบคุณ
Moogie

ไม่ แต่คุณไม่มีทางรู้ เพียงแค่ให้แน่ใจว่าได้ตรวจสอบอีกครั้งเนื่องจากฉันเห็นว่าบอทจำนวนมากสูญเสียเนื่องจากหมายเลขหนึ่งผิดหรือฟังก์ชั่นที่ไม่ถูกต้องหรือพิมพ์ผิดครั้งมากกว่าที่ฉันสามารถนับได้
โปรแกรม Redwolf
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.