Bộ sưu tập vàng KoTH


48

Lưu ý: Bản khảo sát yêu thích của cộng đồng sẽ sớm được công bố

Trong KoTH này, mục tiêu là bot cuối cùng còn sống. Tiền xu sẽ được đặt trong các khu vực ngẫu nhiên và bot của bạn phải nhận được tiền trước. Nếu một bot chạy vào một bot khác, bot có nhiều xu hơn sẽ thắng và bot khác sẽ chết. Chi tiết bên dưới.

Các loại tiền xu

Sẽ có 2 loại tiền: vàng và bạc. Vàng thêm 5 đồng xu vào sức mạnh của bot và bạc thêm 2. Khi một đồng xu được thu thập, một đồng xu khác được đặt ở một vị trí khác trên bảng. Tại bất kỳ thời điểm nào, có một đồng vàng và bốn đồng bạc trên đấu trường.

Va chạm bot

Trong trường hợp hai bot cố gắng chiếm cùng một không gian, một bot có nhiều xu hơn sẽ ở lại, và một bot có ít hơn sẽ ... không. Bot chiến thắng sẽ kiếm được 85% tiền xu của đối thủ (Làm tròn số). Nếu chúng bị trói, cả hai đều chết. Nếu ba hoặc nhiều hơn cố gắng chiếm cùng một không gian, người chiến thắng mạnh nhất và nhận được 85% tất cả các đồng xu của bot khác. Trong trường hợp bot mạnh nhất là cà vạt, tất cả các bot chết đều cố gắng vào không gian.

Đấu trường

Chiều dài bên của đấu trường được tính toán với 4 + botCount. Khi đặt bot vào đầu trò chơi, các địa điểm ngẫu nhiên được chọn. Hệ thống đảm bảo rằng không có bot nào bắt đầu trong cùng một không gian hoặc cạnh nhau. Tiền xu tạo ngẫu nhiên, không bao gồm một hình vuông 3 x 3 tập trung vào mỗi bot. Nếu một bot được tìm thấy bên ngoài đấu trường, nó sẽ chết ngay lập tức. Đấu trường bắt đầu từ (0,0) hoặc Tây Bắc, ở góc trên bên trái và vị trí của bot luôn là một số nguyên.

Bot của bạn

Bot của bạn phải là một hàm, trong bất kỳ ngôn ngữ hướng đối tượng nào có mảng, số nguyên, chuỗi và hàm. Lưu ý rằng tất cả các bài nộp sẽ được chuyển đổi sang Javascript, để làm cho mọi thứ đơn giản. Để lưu trữ thông tin giữa các di chuyển, sử dụng botNotes.storeData(key, value)botNotes.getData(key, value). Bạn không được lưu trữ hoặc truy cập dữ liệu theo bất kỳ cách nào, ngoài dữ liệu được cung cấp thông qua các tham số và botNotes. Bạn nên tạo một chức năng đó, khi gọi, trả về một chuỗi north, east, south, west, hoặc none. Sẽ có 3 đối số cho hàm:

  • Một đối tượng với bốn số nguyên ( locationX, locationY, coins, arenaLength), vị trí hiện tại của bạn, đồng tiền của bạn, và độ dài của đấu trường

  • Một mảng nhiều chiều với tọa độ X và Y của các bot khác và số lượng xu của chúng, ngoại trừ[[0,5,4],[4,7,1],[7,4,12]]

  • Một mảng với các vị trí tiền được liệt kê (Vàng luôn là đầu tiên)

Đây là một vị vua của thử thách đồi, lỗ hổng tiêu chuẩn bị cấm. Chức năng của bạn sẽ được chạy vài nghìn lần, mỗi lần cho phép một lần "Di chuyển". Lưu ý rằng nếu trò chơi vượt quá 20.000 lần di chuyển , bot có nhiều xu nhất sẽ thắng. Điều này sẽ được thực hiện 8.000 lần, để loại bỏ tính ngẫu nhiên.

Phòng chat: https://chat.stackexchange.com/rooms/81347/gold-collector-koth

Giải thưởng:

Vị trí đầu tiên: Tiền thưởng 100 điểm
Cộng đồng yêu thích: Câu trả lời được chấp nhận 15 điểm

Người chiến thắng:

Vị trí thứ nhất: TBTPTGCBCBA
Vị trí thứ hai: Big King Little Hill
Vị trí thứ ba:
Vị trí thứ tư có tiềm năng : Vị tướng say rượu cận thị lịch sự
Vị trí thứ năm: Đồng tiền an toàn


6
"Lưu ý rằng tất cả các bài nộp sẽ được chuyển đổi thành Javascript, để làm cho mọi thứ đơn giản." Công việc này dự định làm như thế nào nhỉ? Bạn có thực hiện chuyển đổi không?
Laikoni

21
Không có gì sai với một koth chỉ cho phép một ngôn ngữ duy nhất, đặc biệt là một ngôn ngữ được phổ biến rộng rãi như JavaScript. Thay vì mơ hồ "chuyển đổi" các câu trả lời sang JavaScript (có lẽ là chính bạn và bằng tay), bạn chỉ nên giới hạn thử thách chỉ với JS. Rốt cuộc, chúng ta đã có rất nhiều koths chỉ dành cho Java và Python.
Skidsdev

2
Một phiên bản này, nơi bạn kiểm soát gia tốc thay vì vị trí sẽ khá tuyệt.
akozi

12
Gửi mọi người: Đã có quá nhiều bình luận rồi. Đừng để lại những bình luận vô ích như "+1, bot đẹp"vui lòng xóa bình luận của bạn nếu nó dư thừa . Chúng tôi không phải là một trang web Hỏi & Đáp điển hình, nhưng không ai thích đọc hàng trăm lệnh.
dùng202729

5
.
BradC

Câu trả lời:


26

BaitBot - JavaScript Node.JS

Tại sao phải đuổi theo hoặc chạy nếu bạn không bao giờ có thể bắt? Thay vào đó, BaitBot tìm thấy đồng tiền gần nhất và chờ đợi một bot yếu hơn cũng tiếp cận nó. Khi cả hai đều liền kề nhau, mồiBot đi tìm đồng xu với giả định bot yếu hơn cũng sẽ như vậy. Nếu mồiBot đang chờ đợi và một bot mạnh hơn tiếp cận, anh ta chỉ cần lấy đồng xu và skedaddles. Thử tôi!

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

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

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



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

}

1
Ha, đó là một ý tưởng gọn gàng, tôi thích nó.
Sundar

Cách tiếp cận này khá tuyệt ... không, rất tuyệt
Các chương trình Redwolf

1
BaitBot cần nearestThreat && distanceTo(nearestThreat)chứ không chỉ distanceTo(nearestThreat). Nó thất bại khi không có mối đe dọa.
Chương trình Redwolf

1
Có, nearestThreatundefinednếu tất cả các bot khác có nhiều điểm hơn của bạn.
Đêm2

1
Chà, tôi nhận được thông báo như [10] Bot Bait Bot tired of this world, and jumped off its edgetrong nhật ký sự kiện của mình
Chương trình Redwolf

17

Có khả năng Victorious | JavaScript

Màu sắc ưa thích cho bot này là #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];
}

(Xin lỗi về định dạng cẩu thả, 4 chỗ thụt lề cho trang web này không phù hợp với tùy chỉnh sử dụng tab của tôi.)

Giải thích thô bạo

Tôi xin từ chức trong nỗ lực cập nhật giải thích về các công thức. Các hệ số liên tục thay đổi và thật khó để giữ cho lời giải thích được cập nhật. Vì vậy tôi sẽ chỉ giải thích nguyên tắc chung.

Mỗi đồng xu và mỗi bot tạo ra một trường lực với một số tiềm năng. Tôi chỉ cần thêm các tiềm năng từ mọi thứ lại với nhau và bot sau đó đi bất cứ nơi nào tiềm năng là thấp nhất. (Rõ ràng ý tưởng này bị đánh cắp từ vật lý.)

Tôi sử dụng hai loại tiềm năng. Đầu tiên là một giả hấp dẫn (hoạt động ở bất kỳ phạm vi nào), với Chữ k là một "thế mạnh" của lĩnh vực này và, với sự lựa chọn dấu hiệu này, tiềm năng là hấp dẫn. Các r ở đây (và ở khắp mọi nơi khác) là khoảng cách trong taxi mét, r = | x₁ - x₂ | + | y₁ - y₂ | .

U=kr+1511+n.

Tôi sử dụng k = 40 cho tiền vàng và k = 10 cho tiền bạc. n là số lượng bot gần với đồng tiền cụ thể hơn chúng ta. Mặt khác, chúng tôi hoàn toàn bỏ qua các bot khác (nếu chúng tôi cản trở một bot mạnh hơn, chúng tôi sẽ chạy trốn, nhưng đó là nó). Tôi đánh giá đồng tiền vàng nhiều hơn giá trị của chúng bởi vì nếu không thì các bot chủ yếu đi sau vàng luôn đánh bại tôi.

Tiềm năng thứ hai là một phân rã theo cấp số nhân (chỉ hoạt động hiệu quả ở khoảng cách rất nhỏ). Cái này được tạo ra bởi cái kia, chủ yếu là các bot mạnh hơn.

Chúng tạo ra một trường có Lực lượng này cực kỳ mạnh ở phạm vi 0-1, nhưng phân rã thành gần như không có gì ở khoảng cách lớn hơn. (Khoảng cách + 1 có nghĩa là cắt lực trong 1/20.)

U=5×1400e3r.

Chúng tôi thường không cố tình tấn công các bot khác (tất nhiên nếu chúng cản đường chúng tôi và chúng tôi giẫm lên chúng, đó là lỗi của chúng), nhưng có khả năng làm điều đó. Nếu một số điều kiện khắc nghiệt được đáp ứng, chúng tôi có thể vào chế độ săn bắn , tập trung vào một bot. Để vào chế độ săn bắn:

  1. Chúng ta phải có ít nhất 25 đồng tiền. (Chúng ta cần nhận được một số tiền đầu tiên.)
  2. Họ phải có nhiều nhất (xu của chúng tôi - 5) đồng xu và ít nhất 10 đồng xu. (Chúng tôi không muốn săn lùng ai đó lấy một đồng xu và đột nhiên mạnh hơn và chúng tôi cũng không muốn theo đuổi các bot không có xu nào.)
  3. Chúng ta phải tụt lại phía sau bot hiện đang dẫn đầu ít nhất 1/10 số tiền của mình. (Bạn cần phải may mắn để săn một cái gì đó, vì vậy không cần phải cho đi một vị trí tốt chỉ để thử vận ​​may của chúng tôi.)
  4. Chúng ta không được ở trong thời gian hồi chiêu (xem bên dưới).

Nếu tất cả những điều này được thỏa mãn, chế độ săn bắn được kích hoạt. Trong 10 vòng tiếp theo, bot được săn chỉ phát ra tiềm năng Sau 10 vòng trôi qua, chúng tôi vào thời gian hồi chiêu, trong thời gian đó chúng tôi không thể vào chế độ săn bắn nữa. (Đó là để ngăn chúng ta đuổi theo một con bot vô tận và vô ích trong khi tất cả những người khác vui vẻ lấy đồng xu.) Thời gian hồi chiêu là 20 vòng khi chúng ta có 25 xu, và tăng thêm 20 xu cho mỗi nhân đôi số đó. (Nói cách khác, thời gian hồi chiêu là .) (Chúng tôi sử dụng điều đó bởi vì trong trò chơi cuối, tất cả các bot có thể săn được rất có thể đã chết, và vì vậy mọi cuộc săn sẽ rất có thể là vô ích. Vì vậy, chúng tôi muốn hạn chế thời gian lãng phí Nhưng đôi khi, một bữa ăn muộn trong trò chơi may mắn có thể thay đổi mọi thứ, vì vậy chúng tôi giữ khả năng này.)

U=150er.
20(1 + log2(c / 25))

Cuối cùng, toàn bộ đấu trường được đặt vào một cái giếng tiềm năng vô hạn để ngăn bot thoát ra.


Tôi nghĩ rằng bot này có thể đánh bại chuyển động có trọng lượng của tôi quá.
fnɛtɪk

@ fəˈnɛtɪk - Tôi cũng vậy:. Tôi nghĩ rằng cái này có thể xử lý các bot khác tốt hơn một chút. (Ngoài ra, nó không bị "làm mờ" bởi một đồng xu tại một hình vuông liền kề.) Nhưng tôi chắc chắn đã cho bạn +1 vì tôi là một fan hâm mộ lớn của ý tưởng này.
Ramillies

Bạn có thể áp dụng nguyên tắc ít hành động nhất cho việc này?
Beta Decay

@BetaDecay: Tôi không sợ lắm, tính toán không đáp ứng tốt với các vấn đề riêng biệt như thế này. Ngay cả trong trường hợp liên tục, nó sẽ không tầm thường (vì cường độ cố định của vận tốc), nhưng nó có thể thực hiện được sau một số phép thuật tọa độ cực mà tôi đoán.
Ramillies

4
Điều này thật tuyệt Tôi không chắc chắn rủi ro có liên quan đơn điệu đến khoảng cách mặc dù, có vẻ như mối đe dọa cách xa 2 khoảng cách có khả năng giết chết bạn hơn một người liền kề, vì trong trường hợp sau, một trong hai bạn cần đứng yên để xảy ra va chạm.
Cain

16

Thuật toán học tập Gen đầu tiên | JavaScript (Node.js)

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

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

Bạn đã bao giờ thấy những mốc thời gian của việc học thuật toán học chơi một trò chơi chưa? Chúng thường di chuyển gần như ngẫu nhiên trong một vài thế hệ đầu tiên ...


LOL ... Nó vẫn có thể hoạt động!
Chương trình Redwolf

2
Hầu hết các thuật toán học tập hoạt động ngẫu nhiên theo nghĩa đen trong vài lần lặp đầu tiên, không chỉ gần như ngẫu nhiên.
fnɛtɪk

Đoán xem cái gì? Bot này có trung bình gần 0,22 xu mỗi vòng!
Chương trình 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])
}

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

Big King Little Hill đưa ra quyết định dựa trên các khu vực kiểm soát của Cameron. Nó sẽ chỉ theo đuổi các đồng tiền nằm trong vùng kiểm soát của nó, nghĩa là nó có thể tiếp cận đồng xu trước khi bất kỳ bot nào khác có thể. Khi không có đồng xu trong vùng kiểm soát của nó, thay vào đó nó di chuyển để tối đa hóa kích thước của vùng kiểm soát. Big King Little Hill tính toán vùng kiểm soát của mỗi trong số 5 lần di chuyển có thể của nó và ưu tiên các bước di chuyển tối đa hóa kích thước của vùng kiểm soát. Theo cách này, Big King Little Hill cuối cùng đạt đến mức tối đa địa phương (ngọn đồi nhỏ) và chờ đợi một đồng xu được tạo ra trong khu vực của nó. Ngoài ra, Big King Little Hill từ chối bất kỳ động thái nào có thể dẫn đến cái chết của nó trừ khi không có lựa chọn thay thế nào.

Big King Little Hill là một người bi quan (nó thích thuật ngữ hiện thực) bởi vì nó không bận tâm đến việc tranh chấp bất kỳ đồng tiền nào mà nó không được đảm bảo để có được. Nó cũng là một người theo chủ nghĩa hòa bình ở chỗ nó không theo đuổi các bot yếu hơn theo bất kỳ ý nghĩa nào (mặc dù nó có thể bước lên một nếu chúng cản đường). Cuối cùng, Big King Little Hill là một kẻ hèn nhát sẽ không gây nguy hiểm cho cuộc sống của chính mình cho bất kỳ phần thưởng nào trừ khi nó thực sự phải làm.


1
Chào mừng đến với PPCG! Đó là một bot rất tốt = D
Luis felipe De jesus Munoz

Đây là những gì tôi đã nghĩ cho một bot. Làm tốt lắm.
Jo.

10

Đồng xu an toàn | 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";}
  }
}

Bot này hướng thẳng đến một đồng tiền có giá trị (giá trị / khoảng cách) mà nó không thể chết khi tiếp cận cùng lúc hoặc sau một bot khác. Nếu không có đồng xu hợp lệ với tài sản này thì nó nằm ở chỗ bot hiện đang di chuyển theo hướng an toàn ngẫu nhiên (an toàn có nghĩa là nếu bot di chuyển về phía nó, đồng tiền an toàn không thể va chạm. Điều này cho phép bot hoán đổi vị trí với bot khác nếu ngay bên cạnh nó), hướng về trung tâm của đấu trường.


1
Huh, điều này thực sự có thể giành chiến thắng. Mặc dù, có rất nhiều bot
Chương trình Redwolf

Phương pháp này sẽ có nhiều vấn đề hơn khi các bot đối phương không đồng đều với giá trị cao hơn hoặc bằng nhau được đặt.
fnɛtɪk

1
Chà, có lẽ tất cả họ sẽ tạo ra một dòng tiền cho đồng tiền gần họ nhất / đồng vàng.
Chương trình Redwolf

Nó sẽ chỉ làm tốt nếu nó quản lý để có được một số tiền ngay khi bắt đầu.
fnɛtɪk

Và đó chủ yếu là may mắn, vì nơi tạo ra tiền được quyết định ngẫu nhiên
Chương trình Redwolf

10

Bot chơi trò chơi một cách thận trọng nhưng có thể hung hăng | JavaScript

Màu sắc ưa thích: #F24100

Lưu ý: Mặc dù bot này đã chiếm vị trí số 1, nhưng đó là do hợp tác với "Feudal Noble" ở cuối và ăn anh ta để kiếm thêm tiền. Nếu không bot này sẽ là thứ 3. Nếu bạn quan tâm đến các bot mạnh hơn từng cá nhân, hãy kiểm tra Potential VictoriousBig King Little Hill .

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

Bot này (còn gọi là "TBTPTGCBCBA") cố gắng đưa ra quyết định tốt nhất có thể bằng cách tạo điểm số cho mỗi lần di chuyển có thể và chọn nước đi có điểm cao hơn cho mỗi lượt.

Hệ thống tính điểm có nhiều chi tiết được phát triển kể từ khi bắt đầu thử thách. Chúng có thể được mô tả chung như thế này:

  • Các đồng xu càng gần với một nước đi có thể, thì càng có nhiều điểm di chuyển. Nếu một đồng xu không có thí sinh nào khác, điểm số sẽ còn cao hơn nữa. Nếu một đồng xu có các thí sinh khác có thể, điểm số sẽ thấp hơn.
  • Nếu một bot khác gần với một nước đi có thể và có ít tiền hơn, tùy thuộc vào giai đoạn của trò chơi, điều đó có thể có nghĩa là nhiều điểm hơn cho di chuyển đó. Vì vậy, thật bình thường khi "TBTPTGCBCBA" ăn một vài bot khác trong mỗi trò chơi.
  • Nếu một bot khác gần với một nước đi có thể có điểm bằng hoặc nhiều hơn, thì nước đi đó có đủ điểm âm để đảm bảo tránh được cái chết. Tất nhiên có thể có một số trường hợp tất cả các động thái có thể là xấu và cái chết không thể tránh được, nhưng điều đó rất hiếm.
  • Có một cơ chế để theo dõi số lượng bot ở giữa bảng trong 20 lượt cuối cùng. Nếu trung bình là đủ thấp, tất cả các di chuyển về phía tiền xu ở giữa sẽ nhận được nhiều điểm hơn và nếu trung bình cao, thì tất cả các di chuyển về phía đồng tiền ở giữa đều có điểm thấp hơn. Cơ chế này cho phép tránh xung đột với "Cao quý phong kiến". Vì "Feudal Noble" luôn ở giữa (trừ khi nó bị truy đuổi), số lượng bot trung bình ở giữa tăng lên và "TBTPTGCBCBA" hiểu để tránh giữa nếu có lựa chọn tốt hơn bên ngoài khu vực giữa. Nếu "Feudal Noble" chết, trung bình sẽ giảm và "TBTPTGCBCBA" hiểu rằng nó có thể sử dụng giữa.
  • Có một số yếu tố thay đổi linh hoạt dựa trên giai đoạn của trò chơi (được phát hiện từ số bot còn sống), những yếu tố này ảnh hưởng đến việc ghi điểm trong mỗi mục trên.
  • Bot này có một khả năng đặc biệt. Theo thời gian, nó trở nên mệt mỏi vì sự ích kỷ của "Cao quý phong kiến" và sự áp bức của nông dân. Vào đúng thời điểm, nó sẽ vươn lên để chấm dứt hệ thống phong kiến ​​khó chịu. Một nỗ lực thành công không chỉ giúp đỡ nông dân nghèo, mà còn mang lại cơ hội chiến thắng cao hơn nhờ những đồng tiền được lấy từ "Cao quý Feudal".

Có vẻ như ... thông minh hơn nhiều so với những người khác
Chương trình Redwolf

5
Tôi thích phần quái vật của các thông số
Chương trình Redwolf

9

AntiCapitalist | Javascript

Không có động lực để theo đuổi tiền, nhưng cố gắng đặt chính xác giữa hai con bot giàu nhất có cùng số tiền, với hy vọng họ sẽ săn lùng anh ta và cuối cùng bắt được anh ta cùng lúc, mang theo hai nhà tư bản khi anh ta chết . Không chủ động chống lại việc kiếm tiền, vì vậy anh ta có thể trở thành mục tiêu ngon ngọt hơn.

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

Với tiềm năng Victorious, chúng tôi đã có hai lĩnh vực: lĩnh vực bot và lĩnh vực tiền xu. Tuy nhiên, thiên nhiên không phức tạp lắm. Đã đến lúc thống nhất hai lĩnh vực để tạo ra Lý thuyết thống nhất lớn .

Đầu tiên, chúng ta cần tìm ra tiềm năng của lĩnh vực này là gì. Giả sử bot của chúng ta không ảnh hưởng đến trường theo bất kỳ cách nào, chúng ta có thể viết điều này như sau:

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

kn(xn,yn)

Thuộc tính tương đối của đối tượng được tính như vậy:

k=cobjectcme

ccme=cself+1cself

Chúng ta hãy gọi phần điều chỉnh này của Động lực Betanian đã sửa đổi (MOBD) .

Chúng ta cũng có thể tìm thấy động năng như:

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

Bây giờ chúng ta có thể tính toán hành động:

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

Và vì vậy Lagrangian của bot của chúng tôi trong lĩnh vực coin-bot là:

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

Bây giờ chúng ta cần giải các phương trình Euler-Lagrange:

ddtLx˙=Lx

và:

ddtLy˙=Ly

Vì thế:

ddtLx˙=ddt[cmex˙]=cmex¨

Lx=n200kn(xxn)ekn2100(xxn)2

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

Và cũng:

ddtLy˙=ddt[cmey˙]=cmey¨

Ly=n200kn(yyn)ekn2100(yyn)2

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

Bây giờ chúng ta không cần phải đi thêm nữa: chúng ta chỉ cần nhìn vào hướng tăng tốc tổng thể:

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

Và cứ như thế, chúng tôi đã thống nhất tiền xu và bot. Giải thưởng Nobel của tôi đâu?


5
Giải thưởng Nobel của bạn đã bị mất trong thư, nhưng chúng tôi có thể trao cho bạn giải thưởng Emmy thay thế
Các chương trình Redwolf

1
Có vẻ như vật lý bắt đầu trở nên phổ biến trong thử thách này. :-CƯỜI MỞ MIỆNG. Và tất nhiên tôi rất tò mò về việc nó sẽ làm tốt như thế nào.
Ramillies

1
(Nhân tiện, bạn có thể đã cứu được rắc rối với các phương trình Euler-Lagrange, vì chúng giảm đến thực tế nổi tiếng rằng F = c_me a = - grad U: đùa).)
Ramillies

@Ramillies Meh, sẽ vui hơn khi làm theo cách này: D
Beta Decay

1
Bạn có chắc chắn rằng bạn muốn sử dụng k = xu của thứ khác / tiền của bạn không? Bạn bắt đầu không có tiền ... và với NaN ở mọi nơi, bạn không có khả năng nhận được bất kỳ đồng nào.
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
}

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

Chỉ cần khóa vào vị trí của đồng tiền vàng và di chuyển về phía đó mỗi lần. (Cảm ơn bot 'B33-L1N3' của @ Mayube cho mã gốc được sử dụng, mặc dù hầu như không còn lại.)


Đây là một bot khá đẹp, đơn giản. Tôi thích nó.
Chương trình Redwolf

2
Nhân tiện, tôi đang sử dụng bot này làm thử nghiệm cho bộ điều khiển của mình (:
Chương trình Redwolf

8

Thuật toán học tập thế hệ thứ ba | 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)];
}

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

Sau một vài thế hệ học tập, bot này đã học được rằng rời khỏi đấu trường = xấu


Ồ tốt. Tôi đã nghe điều này được gọi là "Chọn lọc tự nhiên"
Các chương trình Redwolf

5
Thế hệ thứ hai ở đâu
Luis felipe De jesus Munoz

11
@LuisfelipeDejesusMunoz Anh rời khỏi đấu trường.
Jo.

Đây là một bot tốt để gỡ lỗi bộ điều khiển
Chương trình Redwolf

3
Ồ, nhân tiện, đấu trường bắt đầu từ 0, vì vậy nó phải như vậy arenaLength - 1. Điều này đã giết bot của bạn một vài lần công bằng với nhiều người
Chương trình 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');
}

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

Làm cho một beeline cho đồng tiền gần nhất


Ồ, tôi nghĩ B33-L1N3 là một số kiểu mẫu
Chương trình Redwolf

+1 cho tên
Cain

let coins = ...Uncaught SyntaxError: Identifier 'coins' has already been declared
Đêm2

Xóa cáclet
Chương trình Redwolf

5

Sống trên 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';
  }
}

Cái này nghe rìa của đấu trường là một nơi nguy hiểm. Không biết sợ hãi, nó không mệt mỏi vòng quanh bảng theo chiều kim đồng hồ, chỉ cách cái chết nhất định đang chờ phía sau biên giới, chỉ hy vọng không có bot nào khác dám tiến gần đến khu vực lân cận.


1
Điều này sẽ không kết thúc tốt đẹp nếu một bot khác được tạo ra có thêm 1 đồng xu và tuần tra biên giới theo hướng ngược lại (:
Chương trình Redwolf

8
Tôi sẽ làm một trò đùa kiểm soát biên giới, nhưng tôi sẽ để lại một trò chơi lên đến @BetaDecay
Chương trình Redwolf

5

Thiệt hại, 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
}

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

Một bot dựa trên katamari cuối cùng cho ngày hôm nay, lần này với một chút bộ nhớ. Cảm ơn @BetaDecay về gợi ý tên - chắc chắn là một cái tên thú vị hơn tôi simplePredictorKatamari.

Cố gắng tìm hiểu làm thế nào các bot đã di chuyển trong lượt cuối cùng và dựa vào đó, dự đoán nơi chúng sẽ cố gắng di chuyển vào cuối lượt này (giả sử chúng tiếp tục di chuyển theo cùng một hướng).

(Cảm ơn @ fəˈnɛtɪk, vì đã nhận thấy rằng tôi đã gọi sai tên hàm trong botNotes và @ OMᗺ vì đã nhận thấy một lỗi trong mã cơ sở.)


Đây có lẽ là người duy nhất có thể bắt được những người khác ngoài sự may mắn.
Cain

Không phải các botnot được coi là "archiveata" không phải setdata sao?
fnɛtɪk

@ fəˈnɛtɪk Xem, đã cần một lỗi! :) Cảm ơn, sửa ngay.
Sundar

Bạn nên thay thế aWt = 1trong các thông số bằng aWtvà đặt aWt = aWt || 1bên dưới (Tương tự với bWt). Điều này ngăn ngừa lỗi.
Chương trình Redwolf

5

Proton | JavaScript

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

Tất cả các đồng tiền (bao gồm cả những đồng xu được giữ bởi các bot khác) phát ra một lực đẩy về phía Protonbot. Dựa trên lực này, nó tạo ra vận tốc và bật ra khỏi các bức tường (quay lại ngay lập tức khi chạm vào một ranh giới). Nếu nó kết thúc bên cạnh một bot hoặc đồng xu mà nó có thể tiêu thụ, lực hạt nhân mạnh sẽ chiếm lấy và nó di chuyển để tiêu thụ nó, giảm tất cả vận tốc khi nó làm như vậy.


Hmm, vật lý hạt nhân áp dụng cho săn tìm kho báu? Điều này đập kênh Khoa học bất cứ ngày nào!
Chương trình Redwolf

Bạn cần thay thế sinbằng Math.sin, cosbằng Math.cos, v.v.
Các chương trình Redwolf

4

Không mù quáng | JavaScript (Node.js)

Lưu ý quan trọng: Cách tiếp cận này không hoàn toàn thuộc về tôi và đã được trả lời trong một câu hỏi tương tự . Hãy chắc chắn để bỏ phiếu mà trả lời là tốt.

Haev bạn đã bao giờ nghe nói về thuật toán tìm đường A * chưa? nó đây rồi Nó tạo ra con đường tốt nhất từ ​​điểm này đến đồng tiền ít giá trị hơn (vì mọi người đều sẽ có giá trị cao nhất, không ai đi vì ít hơn) và cố gắng không va chạm với bất kỳ người dùng nào khác.

Mong đợi các tham số như sau:

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

Có lẽ tôi làm một cái mà đi săn các bot khác


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
Wow ... một thuật toán tìm đường đã có? Chỉ mới 3 giờ!
Chương trình Redwolf

@RedwolfPrograms Như tôi đã nói, nó được sao chép từ một thử thách tương tự khác. Chỉ cần thích ứng với nó.
Luis felipe De jesus Munoz

Các thuật toán của tôi đi cho bất kỳ đồng tiền nào là an toàn nhất để đi đến.
fnɛtɪk

4

Hèn nhát | Con trăn 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)

Tránh các bot có nhiều tiền hơn nếu có thể. Nếu không, lấy tiền đang nằm xung quanh.


Đây là bot cơ bản nhất có cơ hội chiến thắng
Chương trình Redwolf

4

Bot ngỗng hoang dã, Javascript

Một bot thực sự giỏi trong việc né các bot khác, nhưng rất tệ trong việc kiếm tiền.


Thuật toán:

  1. Nếu không có bot liền kề, không trả lại
  2. Nếu không thì:
    1. Trả lại không có cơ hội ngẫu nhiên 1/500 cơ hội (điều này nhằm ngăn chặn bế tắc).
    2. Xác định không gian nào an toàn để di chuyển đến (tức là bên trong đấu trường và không bị chiếm bởi bot khác)
    3. Trả lại một cách ngẫu nhiên

Mã số:

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

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

Lưu ý cho các chương trình Redwolf:

Bot này có khả năng gây ra các vòng rất dài. Tôi đã thực hiện một số quyền tự do để ngăn chặn bế tắc, nhưng chưa được thử nghiệm nếu chúng thực sự hiệu quả. Nếu bot này trở thành một vấn đề trong quá trình thử nghiệm, xin vui lòng loại bỏ nó.


Cảm ơn đã lưu ý. Một kẻ chuyên gia trốn tránh có cơ hội ổn nếu tình cờ thu thập đủ tiền trong khi bị truy đuổi
Chương trình Redwolf

Tôi thích điều này. Nó gần giống như mồi cho các robot săn bắn
Beta Decay

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
}

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

(Cảm ơn @ OMᗺ vì đã chỉ ra một lỗi trong mã gốc mà nó dựa trên.)

Cố gắng phát triển bằng cách "ăn" bot với ít tiền hơn chính nó. Nếu điều đó là không thể (không có bot như vậy tồn tại), thì hãy tìm kiếm đồng tiền gần nhất.

Phiên bản này có các điều chỉnh nhỏ để (a) ưu tiên cao hơn cho tiền vàng so với tiền bạc - với nguy cơ tìm kiếm đồng tiền vàng ở xa hơn có thể sẽ khiến cuộc sống của bot mất đi hoặc dẫn đến việc đuổi theo vàng (b) bỏ qua bot 0 xu - không cần phải lãng phí thời gian để theo đuổi những thứ đó.


Một thợ săn thông minh ... tốt, điều đó thậm chí còn tốt hơn!
Chương trình Redwolf

@RedwolfPrograms Hãy hy vọng như vậy! :)
Sundar

Nên gọi đây là Damacy;)
Beta Decay


4

Bot say rượu cận thị lịch sự | 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
}

Lảo đảo xung quanh nhặt những đồng xu gần đó, nhưng ngẫu nhiên chuyển hướng thường xuyên. Làm những gì anh ta có thể để tránh va vào bất cứ ai, nhưng anh ta ... hiếu chiến ... khi trở nên trầm trọng hơn. Có xu hướng tỉnh táo khi cuộc thi diễn ra.

Có thể cần một số gỡ lỗi, khi bộ điều khiển hoàn tất, tôi sẽ làm việc với nó.


3
Hmm, nó tăng thanh, sau đó say rượu
Chương trình Redwolf

4

Chuyển động có trọng số | 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";
}

Di chuyển theo hướng nó đã gán giá trị cao nhất trong khi tránh chạy ra khỏi cạnh của bảng.

Giá trị được tính như vậy:

  • Coin = sức mạnh của đồng xu / khoảng cách đến đồng xu
  • Bot = Sự khác biệt về sức mạnh của bot / 2 * khoảng cách với bot

1
Chà, điều này trông giống như một bot khá tuyệt vời. Hãy chắc chắn kiểm tra các hướng dẫn, vì đó sẽ là một mất mát thực sự nếu bot của bạn là bậc thầy trong việc chạy trốn khỏi các đồng tiền (:
Chương trình Redwolf

Vâng, vẫn còn. Tôi đã trở nên tốt đẹp, phải không?
Chương trình Redwolf

Vâng, đăng nó! Nó sẽ bù đắp cho các bot nhỏ hơn, nhanh hơn cũng tồn tại vào lúc này với số lượng lớn.
Chương trình Redwolf

for(i=0;i<6;i++){chỉ có tổng cộng 5 đồng, 1 vàng và 4 bạc. Vòng lặp của bạn đang chạy 6 lần từ 0 đến 5.
Night2

3

Mù | JavaScript (Node.js)

Điều này chắc chắn sẽ không giành chiến thắng nhưng ít nhất là tham gia. Thử đầu tiên tại thử thách KoH. Nó sắp xếp các đồng tiền và đi đến gần nhất. Anh ta không tìm kiếm người chơi nên anh ta không quan tâm nếu anh ta va chạm với người khác.

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

    if(coins.length == 0)
        return n

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

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

Hmm, nó có thể hoạt động vì các bot khác sẽ tìm kiếm vàng chủ yếu, có khả năng khiến bạn nhận được bạc mà không cần phải chiến đấu
Chương trình Redwolf

3

Phong kiến ​​| JavaScript

Màu sắc ưa thích: #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;
}

Quý tộc phong kiến ​​này ở lại trung tâm của cánh đồng và tuyên bố đó là cung điện của chính mình. Thu thập bất cứ thứ gì ở trung tâm cho chính mình, nhưng bất cứ thứ gì ở các trang trại ở xa nên được nông dân mang đến cho anh ta. Tất nhiên nếu một người nông dân mạnh mẽ tức giận xuất hiện tại cung điện, quý tộc có thể chạy trốn để cứu mạng anh ta, nhưng anh ta quay lại ngay khi thấy an toàn!

Thời gian trôi qua, nông dân ngày càng mạnh hơn. Máy bay chiến đấu chuyên nghiệp và anh hùng mạnh mẽ bắt đầu vươn lên từ giai cấp nông dân. Sức mạnh của quý tộc cứ suy tàn. Anh ta cố gắng giữ sự giàu có và hệ thống phong kiến ​​của mình với nhau miễn là có thể. Nhưng cuối cùng cũng đến lúc anh nên chấp nhận đức tin của mình, anh nên chấp nhận rằng mọi người không muốn phong kiến ​​nữa. Đó là ngày mà giới quý tộc phong kiến ​​từ bỏ tất cả, không chạy trốn khỏi những người nông dân hùng mạnh nữa và bị giết bởi một trong số họ.


2

Bot lượng tử Gnat | 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
}

Bot khó chịu này cố gắng xôn xao xung quanh bot mạnh nhất mà không bị đánh tráo và có một chút cơ hội để vượt qua những người cố gắng săn lùng nó. Nó có xu hướng thu hút hai bot mạnh nhất vào gần nhau ...;)


Nếu anh ta không thể tìm thấy một mục tiêu phù hợp getTargetDirections(), thì những điều thú vị bắt đầu xảy ra. (Chẳng hạn như phá vỡ mọi thứ do undefined has no property 0lỗi.)
Ramillies

2

Đại lý ICE đã nghỉ hưu, JavaScript

Màu sắc ưa thích: 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";
            }
        }
    }
}

Bây giờ đã nghỉ hưu, đại lý ICE này cay đắng về nhân loại. Do đó, ICE đã nghỉ hưu hiện nhắm mục tiêu vào bot yếu nhất, trong khi vẫn giữ giá trị đồng xu của nó trên mức trung bình (theo chính sách của ICE).


2

Tham lam-Theo đuổi | Haskell

Màu sắc ưa thích: #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"

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

Chiến lược khá đơn giản, chọn quyết định đầu tiên từ:

  • nếu có bot có ít xu hơn: chọn gần nhất và tiến về phía nó
  • nếu có tiền: chọn gần nhất và tiến về phía nó
  • mặc định: ở lại

Bot chỉ cố gắng bắt các bot hoặc tiền khác mà không quan tâm đến các bot có khả năng mạnh hơn có thể cố gắng bắt nó.

* Tôi không thực sự biết JavaScript nhưng tôi đã làm điều đó với google (có thể không chính xác): Hãy thử trực tuyến!


6
Tôi tự hỏi làm thế nào anh ấy sẽ dịch haskell sang js
Luis felipe De jesus Munoz

3
@LuisfelipeDejesusMunoz: Vâng tôi cũng vậy. Nhưng may mắn thay, đó không phải là mã rất tinh vi.
ბიმო

@LuisfelipeDejesusMunoz Chỉ cần sử dụng Node.JS và process.open(hoặc child_process.spawn, hoặc tương tự) với một số phân tích cú pháp.
dùng202729

@LuisfelipeDejesusMunoz: Tôi đã cố dịch nó và thêm một liên kết, nhưng tôi không cảm thấy rất tự tin khi viết JavaScript, vì vậy nó có thể có lỗi.
ბიმო

4
@LuisfelipeDejesusMunoz Sẽ là một điều nếu đây là chương trình học AI 10.000 dòng, nhưng tôi nghĩ tôi có thể quản lý điều này (:
Chương trình Redwolf

1

Nam châm tiền xu | 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";
}

Bot này khá ngu ngốc, nó đi theo hướng của những đồng tiền đáng mua nhất. Điều này bao gồm các đồng tiền mà nó không thể nhận được vì các bot khác có sức mạnh cao hơn chính nó.


1

Đại lý ICE | Javascript

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

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

    avg /= others.length;

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

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

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

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

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

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

Điểm biên giới là gì nếu không được tuần tra? ICE di chuyển ngược chiều kim đồng hồ quanh biên giới, nhặt bất kỳ bot nào đi lạc vào đường đi của nó.

Trước khi nó có thể làm điều đó, nó cần phải có thể ăn các bot khác trước. Vì lý do đó ICE, giữ tiền của nó trên mức trung bình của tất cả các bot.

Đảm bảo đánh cắp trẻ em từ cha mẹ của chúng ™


Điều này sẽ buồn cười hơn nếu nó không liên quan lắm
Don Nghìn

1

X Đánh dấu vị trí | 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 đánh dấu vị trí, vì vậy tất cả vàng phải nằm trên trục x, phải không? Bot của tôi tạo ra một đường viền cho dòng y = 0 sau đó ở lại đó, di chuyển ngẫu nhiên.


Huh, một phương pháp thú vị thực sự
Các chương trình Redwolf


1
Cho rằng The arena starts at (0,0) in the upper left corner, bạn có chắc chắn muốn di chuyển southđể đến y=0?
admBorkBork

@AdmBorkBork Cảm ơn, điều đó có thể tệ
Beta Decay

1

Chim lửa

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

Hoàn toàn được tân trang lại để gây chết người hơn trước (:


2
Người thua cuộc tuyệt đối của tôi về bot
Chương trình Redwolf

Nó không nhắm mục tiêu vào họ, nó tránh họ
Chương trình Redwolf

Ôi xin lỗi, tôi đã hiểu nhầm
Beta Decay

1

A-Path-y | JavaScript

Màu sắc ưa thích cho bot này là #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 này sử dụng tìm đường đi cùng với bản đồ mong muốn của tế bào để tránh các bot có thể giết chúng ta, kiếm những đồng xu gần, không bẫy và ít rủi ro nhất.

Nó dường như không phải là một ứng cử viên cho vị trí chiến thắng, nhưng nó giữ vững và sẽ tồn tại vào cuối trận đấu nếu nó sống sót sau cuộc hỗn chiến ban đầu.

Bot hiện có chiến lược trò chơi từ giữa đến cuối mà bỏ qua các đồng tiền mà nó không thể đạt được trước các bot khác và nếu không thể đi đến bất kỳ đồng tiền nào thì hãy chuyển đến ô gần nhất cách xa tất cả các bot khác mạnh hơn chính nó.

Bây giờ nó có cơ hội chiến thắng.

Lưu ý xin lỗi về mã crappy, tôi đã tự động chuyển đổi nó từ Java


Hãy chắc chắn nhận được bất kỳ lỗi và / hoặc cập nhật sớm, 18 giờ đến ngày đáo hạn!
Chương trình Redwolf

@RedwolfPrograms Bạn đã quan sát thấy một lỗi? Nếu vậy xin vui lòng cho tôi biết để tôi có thể sửa chữa. Cảm ơn
Moogie

Không, nhưng bạn không bao giờ biết. Chỉ cần chắc chắn kiểm tra lại, vì tôi đã thấy nhiều bot bị mất do một số sai hoặc sai chức năng hoặc nhập sai nhiều lần hơn tôi có thể đếm
Chương trình Redwolf
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.