언덕의 팀!


27

이 도전은 @HelkaHombaRed vs. Blue-Pixel Team Battlebots 의 탁월한 도전에서 영감을 받았습니다 . 그 도전은 아마도이 사이트에서 본 최고의 도전 일 것입니다. 이제까지.

내 도전은 여전히 ​​많이 다르지만 @HelkaHomba는 영감을 얻을만한 가치가 있습니다.

개요

입니다 팀 팀이 팀에 살아있는 모든 선수를함으로써 승리. 다시 말해, 마지막 팀 순위가 승리합니다. 추첨이 다시 완료됩니다.

당신은 보드에 있습니다. 당신 은 첫 번째 라운드에서 당신의 위치 알고 있습니다 (틱 0). 또한 주변 지역에 누가 있는지 알고 있습니다.

흰색 셀로 둘러싸인 9x9 그리드의 단일 빨간색 사각형.

이 경우, 당신은 주위에 아무도없는 혼자입니다. ontick핸들러 에 대한 첫 번째 인수에서 주변 항목을 볼 수 있습니다 . 나중에 API에 대해 자세히 알아보십시오.

당신의 팀

팀은 사용자 ID로 결정됩니다. 확인하려면 프로필 사진을 클릭하십시오.

내 프로필 사진

그런 다음 주소 표시 줄에서 사용자 ID를 찾으십시오.

/ users /와 / yourusername 사이에 있습니다.

이상하면 파란색 팀입니다.

짝 수면 빨간색 팀입니다.

손으로 그린 ​​서클에 오신 것을 환영합니다.

귀하의 (봇) 이름

봇 이름은 팀의 첫 글자 ( "r"또는 "b")로 시작합니다. 정규식과 일치해야합니다 /^(r|b)[A-Za-z_-]$/. 그 외에는 봇 이름을 선택할 수 있습니다. 이미 존재하는 것을 사용하지 마십시오.

시작

빨간색 플레이어는지도 상단에서 시작하고 파란색은 하단에서 시작합니다. 함수 environment매개 변수 의 첫 번째 틱 (턴)에 대한 특수 정보가 제공 ontick됩니다. 나는 그것을 저장하는 것이 좋습니다. 자세한 내용은 API를 참조하십시오.

네 차례에

턴 순서는 처음에 무작위 화되지만 동일하게 유지됩니다.

행동 전환

한 턴에 한 가지 행동 만 할 수 있습니다.

  • 움직임

    이사 this.move(num)하려면 API 를 호출 하십시오. num이동하려는 셀입니다.

    0은 왼쪽 상단, 1은 중간 상단, 2는 오른쪽 상단, 3은 오른쪽 중앙, 4는 왼쪽 중앙, 5는 왼쪽 하단, 6은 하단 중간, 7은 오른쪽 하단입니다.

    이동할 수있는 숫자의 상대 위치는 전역 상수에 저장됩니다 threeByThree.

[
    [0, 1, 2],
    [3, undefined, 4],
    [5, 6, 7]
]

벽이나 다른 플레이어로 이동하면 아무 일도 일어나지 않습니다.

  • 회전

    회전하려면을 호출하십시오 this.rotate(num). Num은 회전하려는 방향입니다.

    0은 맨 위, 1은 오른쪽, 2는 아래쪽, 3은 왼쪽

    회전은 절대적입니다.

  • 죽이다

    다른 플레이어 (다른 팀의 플레이어)가 상대하고있는 셀에 있으면 전화를 걸어 this.kill()죽일 수 있습니다. 아무도 없거나 팀원 인 경우 아무 것도하지 않습니다. 예:

    위와 동일한 숫자, 0 셀은 녹색, 1은 파란색, 2는 주황색, 3은 노란색

    로 설정되어 있으면 0녹색을 죽일 수 있습니다. 1 세가되면 파란색으로 죽일 수 있습니다. 2 세가되면 오렌지를 죽일 수 있습니다. 3 세가되면 노랑을 죽일 수 있습니다.

  • 폭탄

    폭격은 주위의 9 칸에있는 당신과 팀원포함한 모든 플레이어 죽 입니다. 예:

    각 셀에 "x"가있는 9x9 격자가 있습니다.

    왜 이렇게하고 싶습니까? 카미카제 . 주위에있는 9 개의 셀에 없는 플레이어가 더 있으면 에있는 것입니다. 폭격을 고려할 수 있습니다. (동료에게 먼저 알리는 것이 좋습니다!)

  • 지뢰를 배치

    이것은 당신의 팀이 아닌 다른 사람들을위한 죽음의 광장을 만듭니다. 지뢰를 놓을 때도 밟지 않도록 움직입니다. 당신은 전화 this.landMine(num)NUM 당신이 가고 싶은 광장입니다. 예:

    흰색 셀로 둘러싸인 9x9 그리드의 단일 빨간색 사각형.

    그런 다음 전화 this.landMine(4):

    [중간에 빨간색 "M"이 있고 오른쪽 중앙에 빨간색 셀이있는 9x9 격자.

    "M"보이죠? 지뢰입니다. 다른 사람들은 지금 볼 수 있습니다. 팀원이 아닌 사람이라도 자신이 배치 한 진드기에서 지뢰를 볼 수 있습니다. 그러나 그 진드기가 끝난 후에는 아무도 볼 수 없습니다 . 그러나 적이 지나가 자마자 폭발 할 것이다. 예:

    두 개의 9x9 그리드, 첫 번째 가운데 왼쪽의 파란색 셀, 첫 번째 가운데의 빨간색 "M", 두 번째 가운데의 빨간색 "x"및 그 사이의 화살표.

    지뢰와 BOOM에서 블루가 움직였습니다! 방금 다른 살인을당했습니다.

    직접 살해 또는 지뢰에서 2 명을 죽일 때마다 1 개의 지뢰를 추가로 얻습니다. 당신은 또한 처음에 하나를 얻을.

  • 파기

    발굴 할 때 주변의 5x5 지역에서 지뢰를 찾습니다. 지뢰를 배치 한 봇 팀은 표시되지 않습니다. (팀원이 배치 한 지뢰에 의해 살해 될 수 없음을 명심하십시오.)

    그런 다음의 반환 값은 다음과 this.dig()같습니다.

[undefined,undefined,undefined,true,undefined,
undefined,undefined,undefined,undefined,undefined,
undefined,undefined,undefined,undefined,
undefined,undefined,true,undefined,undefined,
true,undefined,undefined,undefined,undefined]

배열 인덱스는 자신을 포함하지 않고 왼쪽 위에서 시작하여 오른쪽에서 아래쪽으로 시작합니다.

총 23 개가 있으며 상대 위치는 전역 상수에 저장됩니다 fiveByFive.

[
    [0, 1, 2, 3, 4],
    [5, 6, 7, 8, 9],
    [10, 11, undefined, 12, 13],
    [14, 15, 16, 17, 18],
    [19, 20, 21, 22, 23]
]

발굴은와 달리 이전 진드기에 놓인 광산을 나타냅니다 aroundMe.

통신

다른 사람과 대화하고 싶을 때는으로 전화하십시오 this.sendMessage(recipients, team, data). 데이터는 원하는 모든 것이 될 수 있으며 원하는 다른 사람, 심지어 다른 팀의 플레이어에게도 보낼 수 있습니다 . 이것은 잘못 프로그래밍 된 봇을 속이는 데 사용될 수 있지만, 모든 플레이어는 누가 메시지를 보냈는지, 누가 팀인지를 볼 수 있습니다.

예:

"redisbest"라는 봇에게 무언가를 보내십시오 :

this.sendMessage("redisbest", undefined, "Hi!");

"redisbest"및 "blueiscool"이라는 봇에게 무언가를 보냅니다.

this.sendMessage(["redisbest", "blueiscool"], undefined, {hello: "there"});

전체 빨간 팀에게 무언가 보내기

this.sendMessage(undefined, "red", {hello: "red"});

모든 사람 에게 무언가 보내기

this.sendMessage(undefined, "*", {hello: "everyone"});

빨간색 팀 전체와 "blueiscool"이라는 봇에게 무언가를 보냅니다.

this.sendMessage("blueiscool", "red", {hello: "bots"});

API

귀하의 코드는 구성되어야 하나의 전화 받는 createBot기능. 다른 건 없어 샘플 코드 :

createBot({
    ontick: function(environment) {
        return new Promise((resolve, reject)=>{
            this.move(0);//example
            resolve();//please call this when you are done
        });
    },
    onmessage: function(data, from, fromBot) {
        console.log("onMessage: " + this.name + " from " + this.team + " got message ", data, " from " + from + ", on team " + fromTeam);
        this.sendMessage(["bot", "otherbot"], "team", "some data");
    },
    team: "red",//your team
    name: "rmyteamname",//team name must begin with the first letter of your team's name
    onkill: function(){
        //say goodbye
    }
});

(무료로 복사하여 붙여 넣을 수 있습니다. 팀 등에 맞게 수정하면됩니다.)

행동 양식

  • ontick(environment)

    네 차례가되면 전화 해 Promise1 초 이내에 해결되는 a 를 반환해야 합니다. 그렇지 않으면 무시됩니다. 이것은 성능상의 이유로 탭이 걸리지 않는 좋은 부작용이 있습니다.

    this (ontick에있을 때)

    • landMines 당신은 얼마나 많은 지뢰를 남겼습니다. 더 많이 죽일수록 더 많은 지뢰를 얻습니다. 봇 2 명을 죽일 때마다 지뢰 1 개가 추가로 획득됩니다. 또한 1을 시작합니다.
    • direction 당신이 향하고있는 방향.
    • storageonTick및에 대한 호출 사이에 유지되는 스토리지입니다 onMessage. 시작시 빈 개체입니다. 어떤 목적 으로든 수정하지만 올바르게 유지되도록 항상 배열 또는 객체인지 확인하십시오.
    • move(num) 지정된 위치로 이동하십시오. 유효하지 않은 경우 아무 것도 수행하지 않습니다. 자세한 내용은 위를 참조하십시오.
    • rotate(num) 지정된 위치로 회전합니다. 유효하지 않은 경우 아무 것도 수행하지 않습니다. 자세한 내용은 위를 참조하십시오.
    • kill() 당신이 존재하고 있고 당신의 팀에 있지 않은 경우, 당신이 직면하고있는 플레이어를 처치합니다. 자세한 내용은 위를 참조하십시오.
    • bomb() 자신을 포함하여 주위의 9 칸에있는 사람을 모두 죽입니다.
    • landMine(num) 현재 위치에 지뢰를 배치 한 다음 지정된 위치로 이동합니다. 유효하지 num않거나 남은 것이 없으면 아무것도하지 않습니다 . 자세한 내용은 위를 참조하십시오.
    • dig() 새로운! 주변의 5x5 영역에있는 지뢰에 대한 정보 배열을 반환합니다. 자세한 내용은 위를 참조하십시오.
    • sendMessage(recipients, team, data) recipients단일 봇 (문자열), 봇 배열 또는 undefined/ 일 수 null있습니다. 메시지를 보내려는 사람입니다. team메시지를 보내려는 팀의 문자열입니다. "*"모든 사람에게 메시지를 보내는 데 사용 합니다. dataJS 함수에 전달할 수있는 것입니다. 수신자에게 전송됩니다. 객체 또는 배열 인 경우 reference전달 되므로 사용자와 수신자는이를 저장 storage하여 객체를 수정하면 봇의 사본 모두에 영향을 미칩니다. 참고받는 사람 것을 하나 봇의 목록이 정확한 봇이 문자열에 지정된 또는 사용자가 지정한 팀의 봇,이 메시지가 표시됩니다.

environment

첫 진드기

  • x: 플레이어의 x 위치
  • y: 플레이어의 y 위치
  • gridWidth: 격자의 너비 (셀 단위)
  • gridHeight: 격자의 높이 (셀 단위)

    모든 진드기

  • aroundMe: 플레이어와 지뢰의 배열. 선수들은 닮은 물건 {name: "bot name", team: "bot team"}이고 지뢰는 그렇습니다 {team: "team of bot who placed mine"}. 배열의 인덱스 :

    0은 왼쪽 상단, 1은 중간 상단, 2는 오른쪽 상단, 3은 오른쪽 중앙, 4는 왼쪽 중앙, 5는 왼쪽 하단, 6은 하단 중간, 7은 오른쪽 하단입니다.

    현재 지름 이외 의 진드기에 배치 된 지뢰 는 표시되지 않습니다.

    aroundMe 예:

    이것이 그리드라고 가정 해 봅시다 (빨간색입니다).

    왼쪽 위는 연한 파란색, 오른쪽 위는 회색 "M", 가운데는 빨강, 왼쪽 가운데는 노랑, 왼쪽 아래는 빨강 "M"입니다.

    당신의 aroundMe모습은 다음과 같습니다 :

[
    {name: "bexamplebluebot", team: "blue"},
    undefined,//sparse array, nothing in index 1
    undefined,//there is technically a landmine here, but it wasn't placed this tick, so it is not shown
    undefined,//nothing in 3
    {name: "yexampleyellowbot", team: "yellow"},
    {team: "red"},//this is a landmine, you can tell is not a bot because it has no name. mines have the team name of the player they were placed by. This mine was placed this tick, otherwise you couldn't see it
    //nothing else after index 5, so the array's length is 5.
]

배열의 인덱스는 다음과 같습니다.

0은 왼쪽 상단, 1은 중간 상단, 2는 오른쪽 상단, 3은 오른쪽 중앙, 4는 왼쪽 중앙, 5는 왼쪽 하단, 6은 하단 중간, 7은 오른쪽 하단입니다.

당신의 봇은 이것을 효과적으로 본다 :

왼쪽 상단의 연한 파란색 상자에는 검은 색 숫자 0이 있고 왼쪽 가장자리의 노란색 상자에는 검은 색 숫자 4가 있고 왼쪽 하단의 빨간색 "M"은 검은 색 5입니다.

  • onmessage(data, fromBot, fromTeam)

    this (메시지에있을 때)

    • sendMessage(recipients, team, data) 표준 메시지 전송 기능.
    • storage 표준 스토리지.

    data발신자가 보낸 데이터입니다. fromPlayer메시지를 보낸 플레이어 fromTeam메시지를 보낸 팀

  • onkill()

    this (온킬시)

    • sendMessage(recipients, team, data) 표준 메시지 전송 기능.

편리한 (일정한) 전역 배열 :

threeByThree:

[
    [0, 1, 2],
    [3, undefined, 4],
    [5, 6, 7]
]

데이터를 이동 함수로 전달하고 해석하는 데 유용합니다 aroundMe. 위 참조.

fiveByFive :

[
    [0, 1, 2, 3, 4],
    [5, 6, 7, 8, 9],
    [10, 11, undefined, 12, 13],
    [14, 15, 16, 17, 18],
    [19, 20, 21, 22, 23]
]

핸들러 의 this.dig()함수에 유용 ontick합니다.

사용해보십시오!

컨트롤러는 성능상의 이유로 로컬 호스트의 내 컴퓨터에서 실행되지만 CodePen 을 사용하여 봇을 테스트 할 수 있습니다 .

Enter실행을 클릭하기 전에 콘솔에 코드를 붙여넣고 를 눌러야합니다. 원하는만큼 봇을 붙여 넣을 수 있습니다. "테스트 봇"은 테스트 할 예제입니다. 당신이 그들 모두를 이길 수 있거나 묶을 수 있다면, 당신은 적어도 괜찮은 봇이 있습니다.

제출물

규칙

규칙 (컨트롤러에 의해 시행)

  • 기본 ontick코드는 1 초 이상 걸리지 않아야합니다. 우리는 라운드가 영원히 걸리기를 원하지 않습니다. 코드가 1 초 이상 걸리면 중지됩니다.
  • 턴당 하나 이상의 행동을 시도하거나 무효 행동 (예 : this.move(-1)벽으로 이동)을 시도하면 무시됩니다.
  • 더 빨리 올 수 있습니다 ...

규칙 (나에 의해 시행되고 DQ를 초래할 수 있음)

  • 쓰기 전역 변수 ( 읽기 괜찮습니다 ).
  • 코드는 Nodejs에서 작동해야합니다 (컨트롤러가 Nodejs로 이식 된 경우) . JSON.parse(...)하지만 괜찮습니다 alert().
  • createBot컨트롤러를 어떤 식 으로든 호출 하거나 방해 할 수 없습니다 .
  • 허가없이 중대한 변경없이 다른 사람의 코드를 사용하지 마십시오. 카 피봇이 없습니다.
  • 허점이 없습니다!
  • 더 빨리 올 수 있습니다 ...

내 봇

봇은 다음과 같습니다.

이 봇은 무작위로 행동을 선택합니다. 글쎄, 그것은 가중 무작위이지만 여전히 꽤 무작위입니다. 이 봇을 죽일 수 있다면 (최소한 괜찮은 봇을 가진 것보다 결국 스스로 죽일 것입니다.) 그것을 게시하고 어떻게되는지보십시오!

내 봇의 이름은 "x"로 시작하고 팀은 "없음"입니다. 당신은이 코드의 일부를 사용 오신 것을 환영합니다,하지만 적어도 제발 일부 수정. 당신이 적어도 숫자를 조정할 귀찮게하지 않으면, 당신은 이길 수 없습니다.

제출 형식

이 형식을 사용하십시오 :

# rmyamazingbot

    createBot({
        ontick: function(environment) {
            return new Promise((resolve, reject)=>{
                this.move(0);//example
                resolve();//please call this when you are done
            });
        },
        onmessage: function(data, fromTeam, fromBot) {
            console.log("onMessage: " + this.name + " from " + this.team + " got message ", data, " from " + from + ", on team " + fromTeam);
            this.sendMessage(["bot", "otherbot"], "team", "some data");
        },
        team: "red",//your team
        name: "rmyteamname",//team name must begin with the first letter of your team's name
        onkill: function(){
            //say goodbye
        }
    });

Long, but cool explanation...

기능 요청, 버그, 질문 등?

아래의 코멘트! 해당 의견이 이미 있는지 확인하십시오. 이미있는 경우 상향 조정하십시오.

팀과 이야기하고 싶습니까?

빨간색파란색 의 대화방을 사용하십시오 .

언어

현재 JS와 JS로 컴파일되는 것만 지원되지만 다른 언어를 Nodejs와 함께 사용할 수있는 방법을 알고 있다면 컨트롤러를 Nodejs로 이식하게되어 기쁩니다.

최종 노트

전략 아이디어

팀을 도와주세요! 다른 봇을 도와 공동 작업하도록 설계된 봇 만들기. 이 전략 Red vs. Blue-Pixel Team Battlebots에 효과적 이었습니다.

담당자

우승팀에 대해 가장 높은 투표 응답을받습니다. 이전 답변은 더 많은 표를 얻는 경향이 있지만, 약점을 찾아서 악용 할 가능성이 더 높습니다.

또한, 당신이 곧 대답하면 +100 현상금을 얻을 수 있습니다.


1
의견은 긴 토론을위한 것이 아닙니다. 이 대화는 채팅 으로 이동 되었습니다 .
Dennis

하나 이상의 봇을 만들 수 있습니까? (죄송합니다, 대화가 옮겨 졌다는 것을 알고 있습니다. 방금 채팅했습니다.)
Matthew Roh

@SIGSEGV 네,하지만 다른 사람 이 게시해야합니다. 한 봇을 게시하고 다른 봇 코드를 팀의 누군가에게 줄 수는 있지만 두 번 게시 할 수는 없습니다.
programmer5000

[0, 0]-인덱싱 된 셀은 어디에 위치합니까? 왼쪽 상단 셀입니까? 또한, 메시징은 당신의 행동을 소비합니까? 감사.
Thrax

@Thrax 예, 아니오. 메시지에 대한 응답으로 메시지를 보낼 수도 있습니다.
programmer5000

답변:


7

xscared (비경쟁)

createBot({
    ontick: function(environment) {
        var reverse = [0, 1, 2, 3, 4, 5, 6, 7].reverse();
        return new Promise((resolve, reject)=>{
            (this.aroundMe || []).forEach((item,idx)=>{
                this.move(reverse[idx]);
                return resolve();
            });
            this.move(~~(Math.random() * 8));
            return resolve();
        });
    },
    onmessage: function() {
    },
    team: "none",
    name: "xscared",
    onkill: function(){
    }
});

사람들이 무서워. 처음 보는 사람 (또는 지뢰)에서 멀어집니다. 그렇지 않으면 무작위로 이동합니다. 이것은 경쟁이 아니라 단지 예일뿐입니다. 이길려고!


6

백업, 블루 봇

채팅에서 경고했듯이, 나는 내 인생에서 자바 스크립트로 아무것도 쓰지 않았으므로 실수를 발견하면 알려주십시오! (이미 도움을 주신 @ programmer5000에게 감사합니다.)
이 봇의 개념은 같은 팀의 다른 봇과 통신하고 찾은 광산의지도와 함께 위치를 전송한다는 것입니다. 가장 가까운 블루 봇에 합류하려고 시도하고 ([x, y] 배열로 제공된 위치 데이터를 전송하는 경우), 가까이에 머물면서 (가능한 한 많이 돌려 받음), 레드 봇에게 다가 가거나 광산에 앞서.

createBot({
    team: 'blue',
    name: 'backup',
    ontick: function(environment) {
        return new Promise((resolve, reject) => {
            //if (typeof this.x != "undefined") this.storage['position'] = [this.x, this.y];
            if (typeof environment.x != "undefined") this.storage['position'] = [environment.x, environment.y]; //Modified according to @WasteD
            if (typeof this.storage['map'] == "undefined") { //Create empty map
                var map = [[]];
                //for(i=0;i<this.gridHeight;i++) map[i]=[];
                for(i=0;i<environment.gridHeight;i++) map[i]=[]; //Modified according to @WasteD
                this.storage['map'] = map;
            }
            var blue = []
            var red = []
            var x = this.storage['position'][0];
            var y = this.storage['position'][1];
            var dx = [-1, 0, 1, -1, 0, 1, -1, 0, 1]
            var dy = [1, 1, 1, 0, 0, 0, -1, -1, -1]
            (this.aroundMe || []).forEach((item, idx) => { // Update map and list positions of surrounding blues and reds
                if (item && item.team == 'red' && typeof item.name != "undefined") red += idx;
                if (item && item.team == 'red' && typeof item.name == "undefined") this.storage['map'][x+dx[idx]][y+dy[idx]] = 'M';
                if (item && item.team == 'blue' && typeof item.name != "undefined") blue += idx;
            });
            this.sendMessage(undefined, "blue", {"position": this.storage['position'], 'map': this.storage['map']}); //Send to buddies my position and the map
            if (red.indexOf([1, 4, 6, 3][this.direction]) > -1) this.kill() ; //If red guy is in front of
            else if (red.indexOf([1,4,6,3]) > -1) this.rotate(red.indexOf([1,4,6,3])); //If red guy is next but not in front of
            else if (blue.indexOf(3) > -1){ //If blue buddy on the left
                if (blue.indexOf(4) > -1){ //If another one is on the right
                    if (blue.indexOf(1) > -1 && this.direction != 2) this.rotate(2); //...and a third one at the top
                    else var digging = this.dig();
                    }
                else if (this.direction != 1) this.rotate(1);
                else var digging = this.dig();
            }
            else if (blue.indexOf(1) > -1){
                if (blue.indexOf(6) > -1 && this.direction != 3) this.rotate(3);
                else if (this.direction != 2) this.rotate(2);
                else var digging = this.dig();
            }
            else if (blue.indexOf(4) > -1){
                if (this.direction != 3) this.rotate(3);
                else var digging = this.dig();
            }
            else if (blue.indexOf(6) > -1 && this.direction != 0) this.rotate(0);
            else if (blue.indexOf([0,2]) > -1){ //If no blue next to me but one in diagonal, move next
                this.move(1);
                this.storage['position'][1] = y+1; //Update position
            }
            else if (blue.indexOf([5,7]) > -1){
                this.move(6);
                this.storage['position'][1] = y-1;
            }
            else if (typeof this.storage['other_blue'] != "undefined"){ //Check if buddies said where they were, try to go near the closest one
                var dmin = 99999;
                var pos = []
                (this.storage['other_blue'] || {}).forEach((item, idx) => {
                    var d = Math.sqrt(Math.pow(item['position'][0]-x,2) + Math.pow(item['position'][1]-y,2));
                    if (d < dmin){
                        dmin = d;
                        pos = item['position'];
                        }
                });
                if (pos[0]-x > 0){
                    this.move(4);
                    this.storage['position'][0] = x+1
                }
                else if (pos[0] < 0){
                    this.move(3);
                    this.storage['position'][0] = x-1
                }
                else if (pos[1] > 0){
                    this.move(1);
                    this.storage['position'][1] = y+1
                }
                else{
                    this.move(6);
                    this.storage['position'][1] = y-1
                }
            }
            else var digging = this.dig();
            if (typeof digging != "undefined"){ //Check out surroundings if dig() was played and update the map accordingly
                var dx2 = [-2,-1,0,1,2,-2,-1,0,1,2,-2,-1,0,1,2,-2,-1,0,1,2,-2,-1,0,1,2];
                var dy2 = [2,2,2,2,2,1,1,1,1,1,0,0,0,0,0,-1,-1,-1,-1,-1,-2,-2,-2,-2,-2];
                (digging || []).forEach((item, idx) => {
                    //if (item && item.team == 'red' && typeof item.name == "undefined") this.storage['map'][x+dx2[idx]][y+dy2[idx]] = 'M';
                    if (item) this.storage['map'][x+dx2[idx]][y+dy2[idx]] = 'M'; //previously misread what dig() returned
                });
            }
            resolve();
        });
    },
    onmessage: function(data, fromTeam, fromBot) {
        if (typeof data['position'] != "undefined" && fromTeam == 'blue') { //If position sent by a blue bot
            if (typeof this.storage['other_blue'] == "undefined") this.storage['other_blue'] = [];
            for (i in this.storage['other_blue']){
                var found = false;
                if ('name' in i){
                    if (i['name'] == fromBot){
                        i['position'] = data['position'];
                        found = true; //Update if position already known from previous ticks
                        }
                }
            }
            if (!found) this.storage['other_blue'] += {'position':data['position'], 'name':fromBot}; //Add position if previously unknown
            this.sendMessage(fromBot, undefined, "roger.");
        }
    },
    onkill: function() {this.sendMessage(undefined, "blue", {"position": this.storage['position'], 'map': this.storage['map']});}
});

이봐, 내가 이걸 입력해도 상관 없지만 (다른 이름으로) 나도 푸른 색이야
Christopher

@Christopher 아니요, 괜찮습니다.하지만 적어도 조금 다른 (적어도 존재하는 2 봇을 보완하기 위해) 조금 다르게 만들면 그것은 당신과 팀에게 더 흥미로울 것입니다.
plannapus

그렇게 할 것입니다. 나는 그것을 바꿀 것이다
Christopher

코드 펜으로 봇을 실행하려고하면 사용 this.x하고 있기 때문에 작동하지 않지만 environment.x잘못되었거나 잘못 되었습니까?
WasteD

@WasteD 내가 말했듯이 Javascript를 전혀 모른다는 것이 가능합니다. 이 경우 다음의 경우하지만 그것도해야 추측 environment.gridHeight하고 environment.aroundMe? 이 경우 다른 봇은을 사용하므로 작동하지 않아야합니다 this.aroundMe.
plannapus

5

파랑, 파랑, 내 세상은 푸른

createBot({
    team: 'blue',
    name: 'blue-blue-my-world-is-blue',
    ontick: function(environment) {
        return new Promise((resolve, reject) => {
            var red = 0;
            // See who's around me
            (this.aroundMe || []).forEach((item, idx) => {
                if (item && item.team == 'red') red++;
            });
            // If surrounded, take one for the team
            if (red >= 6) this.bomb();
            else {
                // Translate direction into position
                var kill = [1, 4, 6, 3][this.direction];
                // Random values
                var move = Math.floor(Math.random() * 8);
                var nsew = Math.floor(Math.random() * 4);
                // Lay a landmine if possible
                if (this.landMines) this.landMine(move);
                // Kill if someone is in the way
                else if (this.aroundMe && this.aroundMe[kill] && this.aroundMe[kill].team == 'red' && this.aroundMe[kill].name) this.kill();
                else {
                    // Move somewhere if already in the requested direction
                    if (nsew == this.direction) this.move(move);
                    // Otherwise just rotate to the requested direction
                    else this.rotate(nsew);
                }
            }
            resolve();
        });
    },
    onmessage: function(data, from, fromBot) {},
    onkill: function() {}
});

대체로 임의적이지만 포위 상태 일 경우 폭탄을 사용하며 주위를 점검하고 이동을 죽이는 것을 선호합니다.


똑똑한! 좋은데
programmer5000

3
요, 여기 푸른 세상에 사는 작은 남자에 대한 이야기가 있습니다.
Matthew Roh

3

편안한 밤

이 봇은 각면에 하나 이상의 자유 세포가있는 지점을 찾은 다음 광산을 심습니다. 적이 다가올 때까지 야영한다. 누군가가 가까이 다가 가면, 그는 내 봇을 앞뒤로 움직여 다른 봇을 먹이 게 할 것입니다. 그는 필요할 경우 회전하고 죽일 것입니다. 남은 것이 없으면 왼쪽 상단 모서리에서 등을 벽으로 향한 피난처를 찾아 위협 받으면 보복한다.

self키워드로 자신의 위치를 ​​팀에 알리는 것 외에는 특별한 팀 플레이가 없습니다 .

createBot({
    team: 'red',
    name: 'relaxed-bomber',
    ontick: function(environment) {
        return new Promise((resolve, reject) => {
            if (typeof this.storage['dropped'] == "undefined") {
                this.storage['dropped'] = false;
                this.storage['covered'] = false;
                this.storage['baited'] = false;
            }
            if (typeof environment.x != "undefined" && typeof environment.y != "undefined") {
                this.storage['pos'] = [environment.x, environment.y];
            }
            if (typeof environment.gridWidth != "undefined" && typeof environment.gridHeight != "undefined") {
                this.storage['grid'] = [environment.gridWidth, environment.gridHeight];
            }
            var x = this.storage['pos'][0];
            var y = this.storage['pos'][1];
            var x0 = this.storage['grid'][0];
            var y0 = this.storage['grid'][1];
            var source = [1, 4, 6, 3];
            var dest = [6, 3, 1, 4];
            var rot = [0, 1, 2, 3];
            var movex = [-1, 0, 1, -1, 1, -1, 0, 1];
            var movey = [-1, -1, -1, 0, 0, 1, 1, 1];
            var action = false;
            if (this.landMines > 0) { 
                var move = [false, false, false, false];
                var moveIndex = -1;
                if (x <= 0) { move[1] = true; }
                if (x >= x0 - 1) { move[3] = true; }
                if (y <= 0) { move[2] = true; }
                if (y >= y0 - 1) { move[0] = true; }    
                if (move[0] && !move[1] && !move[2] && move[3]) { moveIndex = 0; }
                if (move[0] && !move[1] && !move[2] && !move[3]) { moveIndex = 1; }
                if (move[0] && move[1] && !move[2] && !move[3]) { moveIndex = 2; }
                if (!move[0] && !move[1] && !move[2] && move[3]) { moveIndex = 3; }
                if (!move[0] && move[1] && !move[2] && !move[3]) { moveIndex = 4; }
                if (!move[0] && !move[1] && move[2] && move[3]) { moveIndex = 5; }
                if (!move[0] && !move[1] && move[2] && !move[3]) { moveIndex = 6; }
                if (!move[0] && move[1] && move[2] && !move[3]) { moveIndex = 7; }  
                if (moveIndex >= 0) {
                    this.storage['pos'] = [ x + movex[moveIndex], y + movey[moveIndex]];
                    this.move(moveIndex);
                } else {
                    this.storage['dropped'] = true;
                    this.storage['covered'] = false;
                    this.landMine(1);
                }
            } else {
                if (this.storage['dropped']) {
                    this.storage['dropped'] = false;
                    this.storage['covered'] = true;
                    this.storage['pos'] = [ x + movex[6], y + movey[6]];
                    this.move(6);
                } else if (this.storage['covered']) {
                    for (var i = 0; i < source.length; i++) {
                        if (typeof environment.aroundMe[source[i]] != "undefined" && typeof environment.aroundMe[source[i]].team != "undefined" && environment.aroundMe[source[i]].team == "blue" && typeof environment.aroundMe[source[i]].name != "undefined") {
                            this.storage['covered'] = false;
                            this.storage['baited'] = true;
                            this.storage['mine'] = this.storage['pos'].slice();
                            this.storage['reverse'] = source[dest[i]];
                            this.storage['pos'] = [ x + movex[dest[i]], y + movey[dest[i]]];
                            this.move(dest[i]);
                            action = true;
                        }
                    }
                    if (!action) {
                        this.dig();
                    }
                } else if (this.storage['baited']) {
                    for (var i = 0; i < source.length; i++) {
                        if (typeof environment.aroundMe[source[i]] != "undefined" && typeof environment.aroundMe[source[i]].team != "undefined" && environment.aroundMe[source[i]].team == "blue" && typeof environment.aroundMe[source[i]].name != "undefined") {
                            if (this.direction == rot[source[i]]) {
                                this.kill();
                                this.storage['baited'] = false;
                                action = true;
                            } else {
                                this.rotate(rot[source[i]]);
                                action = true;
                            }
                        }
                    }
                    if (!action) {
                        if (this.storage['mine'][0] == this.storage['pos'][0] && this.storage['mine'][1] == this.storage['pos'][1]) {
                            this.storage['pos'] = [ x + movex[this.storage['reverse']], y + movey[this.storage['reverse']]];
                            this.move(this.storage['reverse']);
                            this.storage['reverse'] = source[this.storage['reverse']];
                        } else {
                            this.storage['pos'] = [ x + movex[this.storage['reverse']], y + movey[this.storage['reverse']]];
                            this.move(this.storage['reverse']);
                            this.storage['reverse'] = dest[this.storage['reverse']];
                        }
                    }
                } else {
                    for (var i = 0; i < source.length; i++) {
                        if (typeof environment.aroundMe[source[i]] != "undefined" && typeof environment.aroundMe[source[i]].team != "undefined" && environment.aroundMe[source[i]].team == "blue" && typeof environment.aroundMe[source[i]].name != "undefined") {
                            if (this.direction == rot[source[i]]) {
                                this.kill();
                                this.storage['baited'] = false;
                                action = true;
                            } else {
                                this.rotate(rot[source[i]]);
                                action = true;
                            }
                        }
                    }
                    if (!action) {
                        if (x > 0 && y > 0) {
                            this.storage['pos'] = [ x + movex[0], y + movey[0]];
                            this.move(0);
                        } else if (x > 0 && y == 0) {
                            this.storage['pos'] = [ x + movex[3], y + movey[3]];
                            this.move(3);
                        } else if (x == 0 && y > 0) {
                            this.storage['pos'] = [ x + movex[1], y + movey[1]];
                            this.move(1);
                        } else {
                            this.rotate(1);
                        }
                    }
                }
            }
            this.sendMessage(undefined, "red", {'self': this.storage['pos'] });
            resolve();
        });
    },
    onmessage: function(data, fromTeam, fromBot) {},
    onkill: function() {}
});

당신은 어떤 팀에 있습니까?
programmer5000

@ programmer5000 봇의 이름은 팀의 문자로 시작해야하므로 팀 레드라고 생각합니다.)
Thrax

좋은 봇! 당신도 당신의 주위에있는 것을 당신의 팀에게 캐스트하기를 제안합니다.
programmer5000

1

다른 블루 봇 1 개 백업 (이전에 수행하지 않은 경우)

createBot({
    team: 'blue',
    name: 'backup1',
    ontick: function(environment) {
        return new Promise((resolve, reject) => {
            //if (typeof this.x != "undefined") this.storage['position'] = [this.x, this.y];
            if (typeof environment.x != "undefined") this.storage['position'] = [environment.x, environment.y]; //Modified according to @WasteD
            if (typeof this.storage['map'] == "undefined") { //Create empty map
                var map = [[]];
                //for(i=0;i<this.gridHeight;i++) map[i]=[];
                for(i=0;i<environment.gridHeight;i++) map[i]=[]; //Modified according to @WasteD
                this.storage['map'] = map;
            }
            var blue = []
            var red = []
            var x = this.storage['position'][0];
            var y = this.storage['position'][1];
            var dx = [-1, 0, 1, -1, 0, 1, -1, 0, 1]
            var dy = [1, 1, 1, 0, 0, 0, -1, -1, -1]
            (this.aroundMe || []).forEach((item, idx) => { // Update map and list positions of surrounding blues and reds
                if (item && item.team == 'red' && typeof item.name != "undefined") red += idx;
                if (item && item.team == 'red' && typeof item.name == "undefined") this.storage['map'][x+dx[idx]][y+dy[idx]] = 'M';
                if (item && item.team == 'blue' && typeof item.name != "undefined") blue += idx;
            });
            this.sendMessage(undefined, "blue", {"position": this.storage['position'], 'map': this.storage['map']}); //Send to buddies my position and the map
            if (red.indexOf([1, 4, 6, 3][this.direction]) > -1) this.kill() ; //If red guy is in front of
            else if (red.indexOf([1,4,6,3]) > -1) this.rotate(red.indexOf([1,4,6,3])); //If red guy is next but not in front of
            else if (blue.indexOf(3) > -1){ //If blue buddy on the left
                if (blue.indexOf(4) > -1){ //If another one is on the right
                    if (blue.indexOf(1) > -1 && this.direction != 2) this.rotate(2); //...and a third one at the top
                    else var digging = this.dig();
                    }
                else if (this.direction != 1) this.rotate(1);
                else var digging = this.dig();
            }
            else if (blue.indexOf(1) > -1){
                if (blue.indexOf(6) > -1 && this.direction != 3) this.rotate(3);
                else if (this.direction != 2) this.rotate(2);
                else var digging = this.dig();
            }
            else if (blue.indexOf(4) > -1){
                if (this.direction != 3) this.rotate(3);
                else var digging = this.dig();
            }
            else if (blue.indexOf(6) > -1 && this.direction != 0) this.rotate(0);
            else if (blue.indexOf([0,2]) > -1){ //If no blue next to me but one in diagonal, move next
                this.move(1);
                this.storage['position'][1] = y+1; //Update position
            }
            else if (blue.indexOf([5,7]) > -1){
                this.move(6);
                this.storage['position'][1] = y-1;
            }
            else if (typeof this.storage['other_blue'] != "undefined"){ //Check if buddies said where they were, try to go near the closest one
                var dmin = 99999;
                var pos = []
                (this.storage['other_blue'] || {}).forEach((item, idx) => {
                    var d = Math.sqrt(Math.pow(item['position'][0]-x,2) + Math.pow(item['position'][1]-y,2));
                    if (d < dmin){
                        dmin = d;
                        pos = item['position'];
                        }
                });
                if (pos[0]-x > 0){
                    this.move(4);
                    this.storage['position'][0] = x+1
                }
                else if (pos[0] < 0){
                    this.move(3);
                    this.storage['position'][0] = x-1
                }
                else if (pos[1] > 0){
                    this.move(1);
                    this.storage['position'][1] = y+1
                }
                else{
                    this.move(6);
                    this.storage['position'][1] = y-1
                }
            }
            else var digging = this.dig();
            if (typeof digging != "undefined"){ //Check out surroundings if dig() was played and update the map accordingly
                var dx2 = [-2,-1,0,1,2,-2,-1,0,1,2,-2,-1,0,1,2,-2,-1,0,1,2,-2,-1,0,1,2];
                var dy2 = [2,2,2,2,2,1,1,1,1,1,0,0,0,0,0,-1,-1,-1,-1,-1,-2,-2,-2,-2,-2];
                (digging || []).forEach((item, idx) => {
                    //if (item && item.team == 'red' && typeof item.name == "undefined") this.storage['map'][x+dx2[idx]][y+dy2[idx]] = 'M';
                    if (item) this.storage['map'][x+dx2[idx]][y+dy2[idx]] = 'M'; //previously misread what dig() returned
                });
            }
            resolve();
        });
    },
    onmessage: function(data, fromTeam, fromBot) {
        if (typeof data['position'] != "undefined" && fromTeam == 'blue') { //If position sent by a blue bot
            if (typeof this.storage['other_blue'] == "undefined") this.storage['other_blue'] = [];
            for (i in this.storage['other_blue']){
                var found = false;
                if ('name' in i){
                    if (i['name'] == fromBot){
                        i['position'] = data['position'];
                        found = true; //Update if position already known from previous ticks
                        }
                }
            }
            if (!found) this.storage['other_blue'] += {'position':data['position'], 'name':fromBot}; //Add position if previously unknown
            this.sendMessage(fromBot, undefined, "roger.");
        }
    },
    onkill: function() {this.sendMessage(undefined, "blue", {"position": this.storage['position'], 'map': this.storage['map']});}
});

1

블루 파이터

createBot({
  team: "blue",
  name: "blue-fighter",
  ontick: function(environment) {
    return new Promise((resolve, reject)=>{
      let map = environment.aroundMe;
      let sides = [1, 4, 6, 3];
      let facing = sides[this.direction];
      let isTeam = (team,a) => a && a.team === team;
      let isRed = (a)=>isTeam("red",a);
      let isBlue = (a)=>isTeam("blue",a);
      let randomSquare = ()=>Math.floor(Math.random()*8);
      let redNum = map.filter(isRed).length;
      let blueNum =  map.filter(isBlue).length;
      if(redNum > blueNum && redNum > 2){
        this.bomb();
      }else if(isRed(map[facing])){
        this.kill();
      }else if(sides.includes(map.findIndex(isRed))){
        this.rotate(sides.indexOf(map.findIndex(isRed)));
      }else if(Math.random() < 0.5 && this.landMines > 0){
        this.landMine(randomSquare());
      }else{            
        this.move(randomSquare());
      }
      resolve();
    });
  },
  onmessage: function(data, from, fromBot) {},
  onkill: function(){}
});

블루 파이터는 무작위로 이동하고 지뢰를 치고 레드 플레이어를 향해 회전합니다. 주변 블록이 파란색보다 빨간색 인 경우 폭탄이 터집니다. 빨간색 플레이어를 향하면 죽입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.