Este concurso terminou oficialmente. A equipe azul venceu!
Criei dois conjuntos de 50 batalhas e, surpreendentemente, Blue venceu todos os 100 deles. Observando as estatísticas, fica claro que as entradas cooperativas do PhiNotPi e Sp3000 foram os verdadeiros heróis. Bom trabalho, vocês dois! De fato, se você desqualificar todos os outros membros da Equipe Azul , os Sphibots ainda lutam muito bem . Algumas pessoas da equipe vermelha estavam planejando derrubar os Sphibots, mas esse esforço pareceu esgotar-se. Desculpe Red Team.
O concurso terminou oficialmente, mas isso não significa que você não pode mais responder, apenas significa que nunca mais redeclararei o vencedor oficial. Ambas as equipes podem enviar bots, apenas por diversão. O controlador permanecerá ativo e permanecerá funcional enquanto nenhuma entrada futura o interromper.
Este é um concurso do tipo rei do monte , mas em vez de todos lutarem entre si, haverá duas equipes que competem: vermelho e azul. Apenas um será o vencedor.
A equipe em que você depende depende do seu número de ID do usuário PPCG . Para encontrar isso, clique no seu avatar na parte superior da tela (você deve estar logado) e veja o URL da página que é aberta. O número depois users/
é o seu número de identificação:
https://codegolf.stackexchange.com/users/[id number]/[display name]
Por exemplo, meu número de ID do usuário PPCG é 26997:
https://codegolf.stackexchange.com/users/26997/calvins-hobbies
Observe que esse número é diferente para diferentes sites do Stack Exchange.
Se seu ID for um número par , você estará no time Vermelho .
Se o seu ID for um número ímpar , você estará na equipe Blue .
Não há como mudar de equipe.
Você deve trabalhar com sua equipe para tentar derrotar a outra equipe em uma espécie de batalha real, onde cada usuário controla um "pixel" da cor de sua equipe na grade 128 × 128 que é o campo de batalha. Os pixels podem se mover, se comunicar com seus colegas de equipe e remover os pixels da outra equipe. Ficaria fora de controle se alguém pudesse criar qualquer número de pixels; portanto, todo usuário pode enviar apenas uma resposta a esta pergunta.
Este snippet de pilha (uma versão reduzida desse violino [ tela cheia ]) é o controlador de todo o concurso. Ele lê automaticamente os envios, garante que eles sejam válidos e organiza batalhas entre as equipes. Isso é feito no seu navegador a qualquer momento, usando JavaScript . Como o JavaScript é a única linguagem de script do lado do qual a maioria dos navegadores suporta, todos os envios também devem ser escritos em JavaScript.
function toggleDebug(){debug=$("#debug").is(":checked")}function rnd(e){return Math.floor(Math.random()*e)}function shuffle(e){for(var t,a,r=e.length;r;t=rnd(r),a=e[--r],e[r]=e[t],e[t]=a);return e}function maskedEval(e,t){var a={};for(i in this)a[i]=void 0;for(i in t)t.hasOwnProperty(i)&&(a[i]=t[i]);return new Function("with(this) { "+e+";}").call(a)}function createBattle(e,t,a,r){function n(){var e=rnd(i.length),t=i[e];return i.splice(e,1),t}var l={};l.width=l.height=128,l.totalMoves=2048,l.radius=16,l.msgMaxLength=64,l.timeLimit=15,l.move=0,l.redToMove=a,l.animated=r,l.running=!1,l.over=!1;for(var o=0,i=new Array(l.width*l.height),d=0;d<l.height;d++)for(var s=0;s<l.width;s++)i[o++]={x:s,y:d};l.redTeam=shuffle(e.slice()),l.redMsgs={},l.redKills={};for(var o=0;o<l.redTeam.length;o++){var u=n();l.redTeam[o].x=u.x,l.redTeam[o].y=u.y,l.redMsgs[l.redTeam[o].id]="",l.redKills[l.redTeam[o].id]=0}l.blueTeam=shuffle(t.slice()),l.blueMsgs={},l.blueKills={};for(var o=0;o<l.blueTeam.length;o++){var u=n();l.blueTeam[o].x=u.x,l.blueTeam[o].y=u.y,l.blueMsgs[l.blueTeam[o].id]="",l.blueKills[l.blueTeam[o].id]=0}return l}function drawBattle(e){function t(e){var t=3*e.x,a=3*e.y;ctx.fillRect(t,a,3,3),showNames.is(":checked")&&ctx.fillText(e.title,t+5,a+12)}function a(t){ctx.beginPath(),ctx.arc(3*t.x,3*t.y,3*e.radius,0,2*Math.PI),ctx.closePath(),ctx.fill()}e.animated&&(ctx.clearRect(0,0,canvas.width,canvas.height),showCircles.is(":checked")&&(ctx.fillStyle="rgba(255, 0, 0, 0.1)",e.redTeam.forEach(a),ctx.fillStyle="rgba(0, 0, 255, 0.1)",e.blueTeam.forEach(a)),ctx.fillStyle="red",e.redTeam.forEach(t),ctx.fillStyle="blue",e.blueTeam.forEach(t),moveCounter.text((e.move+1).toString()))}function movePlayer(e,t,a,r,n,l,o,i){function d(a){t.id!==a.id&&Math.sqrt(Math.pow(t.x-a.x,2)+Math.pow(t.y-a.y,2))<e.radius&&(u.push({x:a.x,y:a.y,id:a.id}),debug&&console.log(a.title+" is near"))}debug&&(console.log("--- Moving "+t.title+" ---"),console.log("position before move = ("+t.x.toString()+", "+t.y.toString()+")"));var s={};s.move=a,s.x=t.x,s.y=t.y,s.tCount=r.length,s.eCount=n.length,s.setMsg=function(a){"string"==typeof a&&(l[t.id]=a.length>e.msgMaxLength?a.substring(0,e.msgMaxLength):a,debug&&console.log('set message to "'+l[t.id]+'"'))},s.getMsg=function(e){var t=l.hasOwnProperty(e)?l[e]:void 0;return debug&&console.log('got message "'+t+'" from player with id '+e.toString()),t};var u=[];r.forEach(d),s.tNear=u,u=[],n.forEach(d),s.eNear=u,-1===t.id&&(s.console=console);var c=0,g=performance.now();try{c=maskedEval(t.code,s)}catch(v){c=0,debug&&(console.log("encountered error:"),console.log(v))}g=performance.now()-g,debug&&console.log("time taken = "+g.toString()+"ms"),g>e.timeLimit&&(c=0,debug&&console.log("went over the time limit of "+e.timeLimit+"ms"));var m=t.x,h=t.y;switch(c){case 1:e.redToMove?++m:++h;break;case 2:e.redToMove?--m:--h;break;case 3:++m,--h;break;case 4:--m,--h;break;case 5:--m,++h;break;case 6:++m,++h}m>=0&&m<e.width&&h>=0&&h<e.height&&(t.x=m,t.y=h),debug&&console.log("move direction = "+c);for(var f=0;f<n.length;f++)t.x===n[f].x&&t.y===n[f].y&&(debug&&console.log("took out "+n[f].title),++i[t.id],o[n[f].id]="X",n.splice(f--,1))}function advanceBattle(e){debug&&console.log("====== "+(e.redToMove?"Red ":"Blue ")+e.move.toString()+" ======");var t,a,r,n,l;e.redToMove?(t=e.redTeam,a=e.blueTeam,r=e.redMsgs,n=e.blueMsgs,l=e.redKills):(t=e.blueTeam,a=e.redTeam,r=e.blueMsgs,n=e.redMsgs,l=e.blueKills),t.forEach(function(o){movePlayer(e,o,Math.floor(e.move/2)+1,t,a,r,n,l)}),drawBattle(e);var o;return 0===a.length?(o=e.redToMove?1:-1,e.over=!0):++e.move>=e.totalMoves&&(o=e.redTeam.length>e.blueTeam.length?1:e.redTeam.length<e.blueTeam.length?-1:0,e.over=!0),e.redToMove=!e.redToMove,debug&&"undefined"!=typeof o&&console.log("win status = "+o.toString()),o}function newBattle(){if(0===redTeam.length||0===blueTeam.length)return void alert("Each team must have at least one player.");"undefined"!=typeof interval&&clearInterval(interval);var e=parseInt($("#delay").val());return isNaN(e)||0>e?void alert("Delay must be a non-negative integer."):(debug&&console.log("Created new battle with delay "+e.toString()),battle=createBattle(redTeam,blueTeam,$("#redMovesFirst").is(":checked"),!0),drawBattle(battle),void moveCounter.text("0").css("color","black"))}function reportKills(e,t){for(var a="Red Kills:\n",r=0;r<redTeam.length;r++)a+=e[redTeam[r].id].toString()+" by "+redTeam[r].title+"\n";a+="\nBlue Kills:\n";for(var r=0;r<blueTeam.length;r++)a+=t[blueTeam[r].id].toString()+" by "+blueTeam[r].title+"\n";return a}function intervalCallback(){var e=advanceBattle(battle);"undefined"!=typeof e&&(clearInterval(interval),battle.running=!1,alert([0===e?"Tie!":e>0?"Red Wins!":"Blue Wins!","Red remaining: "+battle.redTeam.length,"Blue remaining: "+battle.blueTeam.length,"\n"].join("\n")+reportKills(battle.redKills,battle.blueKills)))}function run(){if("undefined"!=typeof battle&&!battle.running&&!battle.over){battle.running=!0;var e=parseInt($("#delay").val());if(isNaN(e)||0>e)return void alert("Delay must be a non-negative integer.");interval=setInterval(intervalCallback,e)}}function pause(){"undefined"!=typeof battle&&(battle.running=!1),"undefined"!=typeof interval&&clearInterval(interval)}function step(){"undefined"==typeof battle||battle.running||battle.over||intervalCallback()}function autorunBattles(){function e(e){for(var t,i=createBattle(redTeam,blueTeam,e,!1);!i.over;)if(t=advanceBattle(i),"undefined"!=typeof t){i.over=!0,1===t?++a:-1===t?++n:++r;for(var d in i.redKills)i.redKills.hasOwnProperty(d)&&(l[d]+=i.redKills[d]);for(var d in i.blueKills)i.blueKills.hasOwnProperty(d)&&(o[d]+=i.blueKills[d])}}if(pause(),battle=void 0,0===redTeam.length||0===blueTeam.length)return void alert("Each team must have at least one player.");var t=parseInt($("#N").val());if(isNaN(t)||0>t)return void alert("N must be a non-negative integer.");console.log("Autorunning "+t.toString()+" battles");for(var a=0,r=0,n=0,l={},o={},i=0;i<redTeam.length;i++)l[redTeam[i].id]=0;for(var i=0;i<blueTeam.length;i++)o[blueTeam[i].id]=0;for(var i=0;t>i;i++)console.log("Battle "+i.toString()),e(i%2===0);alert([a===n?"Tie overall!":a>n?"Red wins overall!":"Blue wins overall!","Red wins: "+a.toString(),"Blue wins: "+n.toString(),"Ties: "+r.toString(),"\n"].join("\n")+reportKills(l,o))}function changeSelect(e){var t=e?redTeam:blueTeam,a=$(e?"#redSelect":"#blueSelect").val(),r=$(e?"#redCode":"#blueCode"),n=$(e?"#redLink":"#blueLink");null!==a&&a>-1?(r.text(t[a].code),n.attr("href",t[a].link)):(r.text(""),n.attr("href","javascript:;"))}function loadEntries(){function e(e,t){url="https://api.stackexchange.com/2.2/questions/"+qid.toString()+"/answers?page="+e.toString()+"&pagesize=100&order=asc&sort=creation&site=codegolf&filter=!JDuPcYJfXobC6I9Y-*EgYWAe3jP_HxmEee",$.get(url,t)}function t(d){d.items.forEach(function(e){function t(e,t){t.append(" ").append($("<a>").text(e.owner.display_name).attr("href",e.link))}function n(e){return $("<textarea>").html(e).text()}var d=e.owner.user_id%2===0,s=d?redTeam:blueTeam;if(e.owner.display_name=n(e.owner.display_name),e.hasOwnProperty("last_edit_date")&&e.last_edit_date-e.creation_date>r||dq.indexOf(e.owner.user_id)>-1||l.indexOf(e.owner.user_id)>-1)return void t(e,o);l.push(e.owner.user_id);var u=a.exec(e.body);if(null===u||u.length<=1)return void t(e,i);var c={};c.id=e.owner.user_id,c.title=e.owner.display_name+" ["+e.owner.user_id.toString()+"]",c.code=n(u[1]),c.link=e.link;var g=$(d?"#redSelect":"#blueSelect");g.append($("<option>").text(c.title).val(s.length)),s.push(c)}),d.has_more?e(++n,t):($("#loadStatus").hide(),$("#redCount").text(redTeam.length.toString()),$("#blueCount").text(blueTeam.length.toString()),0===o.html().length&&o.html(" none"),0===i.html().length&&i.html(" none"))}var a=/<pre><code>((?:\n|.)*?)\n<\/code><\/pre>/,r=28800,n=1,l=[],o=$("#disqualified"),i=$("#invalid");pause(),battle=void 0,redTeam=[],blueTeam=[],$("#loadStatus").show(),$("#redSelect").empty(),$("#redCode").empty(),$("#redLink").attr("href","javascript:;"),$("#blueSelect").empty(),$("#blueCode").empty(),$("#blueLink").attr("href","javascript:;");var d=$("#testbot").val();if(d.length>0){debug&&console.log("Using test entry");var s={id:-1,title:"TEST ENTRY [-1]",link:"javascript:;",code:d};$("#testbotIsRed").is(":checked")?(redTeam.push(s),$("#redSelect").append($("<option>").text(s.title).val(0))):(blueTeam.push(s),$("#blueSelect").append($("<option>").text(s.title).val(0)))}e(1,t)}var qid=48353,dq=[],ctx,moveCounter,showNames,showCircles,debug=!1,battle,redTeam,blueTeam,interval;$(document).ready(function(){ctx=$("#canvas")[0].getContext("2d"),moveCounter=$("#moveCounter"),showNames=$("#showNames"),showCircles=$("#showCircles"),loadEntries()});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><style>html *{font-family: Consolas, Arial, sans-serif;}select{width: 100%; margin: 12px 0 0 0;}button, select, input{font-size: 100%;}input{text-align: right;}textarea{font-family: "Courier New", monospace;}textarea[readonly]{background-color: #eee; width: 100%;}canvas{margin: 12px 0 0 0; border: 2px solid gray;}.redWrapper, .blueWrapper{width: 30%;}.redWrapper{float: left;}.blueWrapper{float: right;}.arenaWrapper{width: 40%; display: inline-block;}.redTeam, .blueTeam, .arena{padding: 12px;}.arena{text-align: center;}.redTeam, .blueTeam{border-style: solid; border-width: medium;}.redTeam{border-color: red; background-color: #fee;}.blueTeam{border-color: blue; background-color: #eef;}.redTitle, .blueTitle, .arenaTitle{text-align: center; font-size: 200%;}.redTitle, .blueTitle{font-weight: bold;}.redTitle{color: red;}.blueTitle{color: blue;}.control{margin: 12px 0 0 0;}.count{font-size: 75%; margin: 0 0 12px 0;}.footnotes{font-size: 75%; clear: both; padding: 12px;}</style><div id='loadStatus'> Loading entries...</div><div> <div class='redWrapper'> <div class='redTeam'> <div class='redTitle'> Red Team </div><select id='redSelect' size='20' onchange='changeSelect(true)'> </select> <div class='count'> <span id='redCount'></span> players </div>Code: <br><textarea id='redCode' rows='12' readonly></textarea> <br><a id='redLink' href='javascript:;'> Answer Link </a> </div></div><div class='arenaWrapper'> <div class='arena'> <div class='arenaTitle'> Battlefield </div><canvas id='canvas' width='384' height='384'> Your browser does not support the canvas tag. </canvas> <div>Move <span id='moveCounter'>0</span></div><br><div> <div class='control'> <input id='showNames' type='checkbox'>show names <input id='showCircles' type='checkbox'>show circles </div><div class='control'> <input id='redMovesFirst' type='checkbox'>red moves first </div><div class='control'> <input id='delay' type='text' size='4' value='20'> millisecond delay </div><div class='control'> <button type='button' onclick='newBattle()'> New Battle </button> <button type='button' onclick='run()'> Run </button> <button type='button' onclick='pause()'> Pause </button> <button type='button' onclick='step()'> Step </button> </div><hr class='control'> <div class='control'> <button type='button' onclick='autorunBattles()'> Autorun N Battles </button> N = <input id='N' type='text' size='4' value='16'> </div><div class='footnotes'> Autoruns may hang browser tab until complete. </div></div></div></div><div class='blueWrapper'> <div class='blueTeam'> <div class='blueTitle'> Blue Team </div><select id='blueSelect' size='20' onchange='changeSelect(false)'> </select> <div class='count'> <span id='blueCount'></span> players </div>Code: <br><textarea id='blueCode' rows='12' readonly></textarea> <br><a id='blueLink' href='javascript:;'> Answer Link </a> </div></div></div><div class='footnotes'> Test Entry: (id = -1) <input id='testbotIsRed' type='checkbox'>On Red Team <br><textarea id='testbot' rows='1' cols='32'></textarea> <br><button type='button' onclick='loadEntries()'> Reload with test entry </button> <br><br>This was designed and tested in Google Chrome. It might not work in other browsers. <br>Disqualified entries:<span id='disqualified'></span> <br>Could not find code block:<span id='invalid'></span> <br><input id='debug' type='checkbox' onclick='toggleDebug()'>Debug messages <br></div>
Para visibilidade, o campo de batalha do Snippet é dimensionado por um fator de 3, então possui 384 × 384 pixels reais e os "pixels" são 3 × 3.
Pixel Team Battlebots - Visão geral
Jogadoras
Cada resposta válida para esta pergunta representa um jogador . (Para detalhes sobre validade, consulte "Regras e desqualificações" .) Todo jogador tem controle sobre uma única célula 1 × 1 (também conhecida como pixel) no campo de batalha das células 128 × 128 . Os jogadores do time vermelho têm pixels vermelhos e os jogadores do time azul têm pixels azuis.
Batalhas
Uma batalha é uma luta entre todos os jogadores das duas equipes, mesmo que as equipes não tenham um número igual de jogadores. Uma batalha começa com cada jogador sendo colocado em uma posição aleatória no campo de batalha, ou seja, qualquer coordenada inteira de (0,0) no canto superior esquerdo a (127,127) no canto inferior direito. É garantido que não haverá dois jogadores na mesma posição.
Movimentos
Cada batalha é dividida em 2048 movimentos . Apenas uma equipe consegue mover seus jogadores durante cada movimento. Essa equipe alterna de vermelho para azul, para que cada equipe faça 1024 jogadas no total (a menos que o jogo termine mais cedo).
A equipe que começa a se mover primeiro é uma opção que você deve definir no controlador.
Quando as batalhas são autorun, a equipe que se move primeiro alterna em todas as batalhas.
Movimentos do jogador
Quando uma equipe se move, todos os jogadores dessa equipe são chamados a se mover. Essas chamadas são feitas em uma ordem completamente aleatória para cada movimento. Quando chamados, cada jogador recebe dados sobre o estado da batalha, para que eles possam decidir para que lado se mover.
Todos os movimentos têm apenas um pixel de distância. As olheiras nesses diagramas marcam quais posições cada jogador colorido (os quadrados) podem mover para:
Ambas as cores podem se mover na diagonal em qualquer direção ou ficar paradas, mas apenas jogadores vermelhos podem se mover para a direita e esquerda, e apenas jogadores azuis podem se mover para baixo e para cima. Obrigado Phi e outros.
Se um jogador tentar sair dos limites do campo de batalha, ou demorar muito para decidir para que lado se mover, ou tiver algum tipo de erro, ele ficará automaticamente parado.
Além de se mover, durante um turno, um jogador pode ler mensagens escritas por seus companheiros de equipe e escrever mensagens que, por sua vez, podem ser lidas. Isso permite uma forma grosseira de comunicação em equipe.
O código que você envia como resposta é a lógica que determina qual caminho mover seu player e quais mensagens ler e escrever (consulte "Como responder" ).
Remoção de jogadores inimigos
Quando um jogador se move para a mesma célula que um jogador do time adversário, esse jogador adversário é imediatamente removido da batalha. O jogador que acabou de se mudar continua normalmente. Este é o único mecanismo que remove os jogadores da batalha e dominá-los é a chave para vencer!
Se houver vários jogadores inimigos na célula para a qual um jogador acabou de se mudar, todos os jogadores inimigos serão removidos. Nada acontece se dois jogadores do mesmo time ocupam a mesma célula.
Vencendo uma batalha
Uma batalha termina assim que todos os movimentos de 2048 forem feitos ou quando um time não tiver mais jogadores. A equipe com o maior número de jogadores sobreviventes vence. É um empate Se ambas as equipes tiverem um número igual de jogadores sobreviventes.
Como responder
Na sua resposta, você precisa fornecer o código JavaScript que decide para que lado seu pixel será movido quando solicitado.
No primeiro exemplo de código recuado em sua resposta (os prefixados com 4 espaços), escreva um corpo para esta função:
function moveMe(move, x, y, tCount, eCount, tNear, eNear, setMsg, getMsg) {
//the body goes here
}
Não há necessidade de jogar golfe seu código.
O que Devolver
O valor de retorno da função determina para que lado seu pixel se move:
0
ficar parado
1
para mover para a direita para a equipe vermelha, para baixo para a equipe azul
2
para a esquerda para a equipe vermelha, para cima para a equipe azul
3
para mover na diagonal para cima e
4
para a direita para mover na diagonal para cima e
5
para a esquerda para mover na diagonal para baixo e
6
para a esquerda para mover na diagonal para baixo e para a direita
Como um diagrama:
Seu pixel ficará parado por padrão se o seu código executar uma destas ações:
- Retorna qualquer coisa além de um número inteiro de 0 a 6.
- Tentativas de mover o pixel para fora dos limites do campo de batalha.
- Leva mais de 15 milissegundos para ser executado.
- Lança qualquer tipo de exceção.
Sua entrada não precisa ser determinística; usando Math.random
é bom.
Os parametros
Os 7 primeiros parâmetros de função moveMe
fornecem informações sobre o estado da batalha:
move
é um número inteiro que começa em 1 e aumenta após cada jogada até 1024 na última jogada da sua equipe.x
é sua posição x atual, um número inteiro de 0 (mais à esquerda) a 127 (mais à direita).y
é sua posição y atual, um número inteiro de 0 (mais alto) a 127 (mais baixo).tCount
é o número total atual de jogadores sobreviventes em seu time.eCount
é o número total atual de jogadores sobreviventes no time inimigo.tNear
é uma lista dos jogadores sobreviventes atuais do seu time que estão a menos de 16 pixels (distância euclidiana). Cada elemento detNear
um objecto comx
,y
eid
propriedades:
x
é a posição x do outro jogadory
é a posição y do outro jogadorid
é o número de ID do usuário PPCG do outro player (como um número inteiro)eNear
é exatamentetNear
igual, exceto que é uma lista de jogadores inimigos próximos, não de companheiros de equipe.
Os círculos no snippet são de cada jogador tNear
e eNear
alcance.
Mensagens
Os últimos 2 parâmetros setMsg
e getMsg
têm finalidades ligeiramente diferentes.
Durante uma batalha, cada jogador tem uma série de até 64 caracteres que eles podem manipular durante cada movimento para armazenar dados e potencialmente se comunicar com seus companheiros de equipe. A corda de cada jogador começa como a corda vazia. Quando um jogador é removido da batalha, sua corda é definida como "X".
setMsg
é uma função de um argumento que define sua string para a string passada.- Se o valor passado não for uma sequência, ela não será alterada.
- Se o valor for uma sequência com mais de 64 caracteres, apenas os primeiros 64 serão mantidos.
getMsg
é uma função de um argumento que pega o número de ID do usuário do PPCG (como um número inteiro) de alguém em sua equipe e retorna sua sequência.- Esse jogador pode estar em qualquer lugar da grade. Eles não precisam estar no seu raio de 16 pixels.
undefined
será retornado se o ID fornecido não for encontrado.
Submissão de exemplo
Este jogador se move para cima e para a direita se houver um inimigo à esquerda, ou para baixo e para a esquerda se o companheiro de equipe com ID 123 pedir, mas, caso contrário, fica parado:
for (var i = 0; i < eNear.length; i++) {
if (eNear[i].x === x - 1)
return 3
}
if (getMsg(123) === 'move down and left')
return 5
return 0
Observe que esse bloco de código é tudo o que é necessário. A definição da função e os colchetes não devem estar presentes.
Regras e Desqualificações
Se um usuário não cumprir as regras listadas abaixo, posso marcá-lo como desqualificado e o controlador ignorará automaticamente suas respostas. Confio que a maioria dos usuários aqui não intencionalmente infringirá as regras e haverá apenas algumas desqualificações temporárias por causas acidentais.
Regras importantes
Você só pode editar sua resposta durante a janela de 8 horas imediatamente após publicá-la.
As respostas editadas após 8 horas a partir do momento em que foram postadas serão desqualificadas automaticamente pelo controlador. Esta regra é para impedir que as respostas iniciais otimizem continuamente sua abordagem, possivelmente roubando idéias de respostas posteriores. Sua equipe precisa se contentar com as respostas que começou.Você não pode excluir e repassar sua resposta sem permissão especial. Eu darei isso se alguém inadvertidamente editar sua postagem após a marca de 8 horas ou algo assim, mas não apenas porque você encontrou um bug.
Se você excluir sua postagem e optar por cancelar a exclusão, a regra de edição ainda será aplicada. (O controlador não pode ver as respostas excluídas.)
Ao declarar uma nova variável JavaScript, você deve usar a
var
palavra - chave
Isso ocorre porque uma variável declarada semvar
se torna global em vez de local, portanto, seria fácil mexer acidentalmente (ou intencionalmente) com o controlador ou se comunicar livremente com outros jogadores. Tem que ficar claro que você não está tentando trapacear.Ao declarar funções, é melhor usar a
var
palavra - chave também. ou seja, use emvar f = function(...) {...}
vez defunction f(...) {...}
. Não sei bem por que, mas às vezes parece fazer a diferença.Seu código não deve ser executado por um período excessivo de tempo.
Se o seu código demorar mais de 15 milissegundos para ser executado, seu pixel não será movido. No entanto, como é difícil no JavaScript interromper as funções no meio da execução, todos os scripts do player são executados até o fim a cada movimento e o tempo é verificado posteriormente. Isso significa que, se o seu código exigir muito tempo, todos os que estiverem executando o controlador perceberão e ficarão irritados.
Desqualificações automáticas
O controlador desqualificou automaticamente as entradas por estes motivos:
- O usuário já respondeu.
- As edições foram feitas mais de 8 horas após a criação.
- O usuário é especificamente marcado como desqualificado.
Outras regras
No seu código, você não pode ...
- tente acessar ou modificar o controlador ou o código de outro jogador.
- tente modificar qualquer coisa incorporada ao JavaScript.
- tente se comunicar com outros jogadores, exceto usando
getMsg
esetMsg
. - faça consultas na web.
- faça coisas maliciosas.
Vou ficar de olho em outros comportamentos antidesportivos, como roubar código literalmente de outras respostas ou usar fantoches para mexer com a outra equipe.
Você pode colaborar e planejar com sua equipe, mas mantenha o concurso amigável e ético.
Se você acha que alguém precisa ser desqualificado ou acha que você corrigiu o motivo pelo qual foi desqualificado, deixe um comentário aqui para mim ou no chat específico da pergunta . Eu não estou participando do concurso.
Formato de resposta sugerida
#[team color] Team - [entry title]
//function body
//probably on multiple lines
Explanations, notes, etc.
O título da entrada é um nome opcional que você pode fornecer, se quiser. O controlador não faz nada com ele.
Pontuação
Este concurso será encerrado oficialmente em 19 de abril de 2015. Nesse dia (por volta das 23:00 UTC), executarei automaticamente pelo menos 100 batalhas (possivelmente muito mais, dependendo de quanto tempo durar as batalhas). A equipe que ganhar mais será o vencedor geral. Se estiver empatado ou extremamente próximo, disputarei mais batalhas até que fique claro que uma equipe tem a vantagem.
(Você pode responder após a decisão do vencedor, mas não alterarei o resultado oficial.)
Vou executá-los na versão mais recente do Google Chrome em um laptop com Windows 8.1 de 64 bits, 4 GB de RAM e um processador quad core de 1,6 GHz. Verifique se o seu JavaScript funciona no Chrome.
A vitória é principalmente sobre a glória do time, mas aceitarei a resposta mais votada no time vencedor.
Durante o concurso, lembre-se de que o aspecto baseado em equipe e o fato de ser executado inteiramente em um snippet de pilha são muito experimentais. Tenho grandes esperanças, mas não posso dizer com certeza quão bem as coisas vão funcionar.
Dicas:
- Você pode testar as entradas antes de responder. Edite a caixa de texto "Entrada de teste" na parte inferior do snippet de pilha e clique em "Recarregar com entrada de teste". Se não estiver vazio, ele se torna um jogador no time especificado.
- As respostas são executadas em um escopo mascarado, para que coisas como
alert
econsole.log
não funcionem. Oconsole
objeto pode ser usado apenas na entrada de teste. - Marque "Mensagens de depuração" na parte inferior do snippet de pilha e observe o console do navegador (F12). Muitas informações úteis são impressas quando as batalhas estão em andamento.
- Você pode usar a postagem da Meta Sandbox como um tipo de área de preparação. As respostas são obviamente diferentes das aqui, e o controlador pode ficar desatualizado.
- Como este não é um aplicativo oficial da Stack , o controlador pode parar de carregar respostas para você se você o reiniciar mais de 300 vezes por dia.
A "sequela" deste desafio: Block Building Bot Flocks!
Links Rápidos
Fiddle Controller Tela cheia Chat geral Red Chat (Blue Chat?) SandboxPost
fonte
Respostas:
Equipe Azul - SphiNotPi3000
Este bot forma um par com o bot do Sp3000 .
A idéia básica é que dois bots, posicionados adjacentes um ao outro, ajudem a cobrir as fraquezas um do outro, de modo que nenhum dos bot tenha um lado exposto. Isso ajuda a proteger contra ameaças e limita as opções de fuga do alvo.
No início do jogo, eles navegam um em direção ao outro e formam um par. Esse par então se move como uma única unidade, com um bot liderando o outro. Os dois bots têm código quase idêntico, permitindo que eles negociem posições e funções quando necessário.
Quando ociosos, os robôs se movem pelo tabuleiro procurando por inimigos. Uma vez que eles avistam um inimigo, eles cuidadosamente se posicionam nas posições corretas para atacar. Uma característica muito interessante é a capacidade da formação de se mover horizontalmente, conseguida com os bots em locais alternados.
fonte
var
não é usado neste post e no Sp3000. Eles atribuemj
a 0 imediatamente e isso não interfere no controlador, portanto, felizmente, não é um problema neste caso.Equipe Azul - SphiNotPi3000
Este bot forma um par com o bot de PhiNotPi . Veja o post de Phi para uma breve explicação de nossa estratégia.
fonte
Equipe Vermelha - SeekerBot
A maior prioridade do SeekerBot é a sobrevivência. Portanto, ele só considerará jogadas que não colocam em risco de ser morto no próximo turno (desde que tais jogadas existam).
Quando nenhum oponente estiver à vista, ele se moverá em um padrão sobre o campo de batalha, o que garantirá que a maior parte do terreno esteja regularmente à distância de visualização.
Se o SeekerBot detectar um inimigo, ele se moverá em sua direção. Se ele puder matar um inimigo, fará isso enquanto o movimento for salvo.
Se ele não puder matar um inimigo, mas o inimigo estiver em posição de matá-lo no próximo turno, o SeekerBot tentará atrair o inimigo para um amigo (se ele estiver visível). Se nenhum membro da equipe estiver à vista, ele tentará passar para uma posição em que possa matar o inimigo no próximo turno. Se isso não funcionar 5 vezes seguidas, ele mudará de tática e começará a se mover de maneira aleatória, possivelmente se aproximando do inimigo novamente na próxima rodada.
Pelo que vale, ele usará os 7 primeiros caracteres da mensagem para gritar sua própria posição no formato "x; y" (onde x e y são preenchidos com zero).
Certamente não é o código mais limpo, mas parece fazer o que eu esperava dele.
fonte
Equipe vermelha - Groomba
Notas nos comentários.
fonte
self
. Essa variável está reservada para apontarwindow.self
. UseI
(capital i) em vez disso. Orme
. Ou atémyself
.Equipe vermelha - Slayer Slayer
Este é o mais básico que eu pude entender.Isso não é mais 100% básico.Ele só se move SE NECESSÁRIO .
Se um usuário enviar uma mensagem com 2 números entre-1
e1
(por exemplo'1,0'
:), separada por vírgula, ela será movida para lá. Confia totalmente em seus companheiros de equipe.Agora isso se comunica por JSON. Tem uma estrutura muito básica:
Um exemplo de uma mensagem para controlá-lo:
O que enviará:
Ele também é um pouco egoísta
e não vai te ajudare agora ele é útil como farol fixo.Se esta mensagem estiver incorreta (o formato não está correto), tente adicionar em
"}
vez de}
.Isso foi editado após o limite de 6 horas e depois foi estendido para 8.
Não está mais quebrado e permanecerá como a versão final.
fonte
Equipe Vermelha - O Covarde
Este bot fica parado para evitar ser detectado o máximo possível. Quando um ou mais inimigos estão à vista, várias coisas podem acontecer:
Não se comunica com ninguém, caso alguém possa ouvi-lo e ir atrás dele.
Pode não ser o bot mais útil para a equipe, mas foi divertido vê-lo tentando se afastar de todos.
fonte
Equipe azul - Eagle
Estou muito feliz com meu bot no momento. Possui as seguintes táticas:
fonte
Equipe azul - Enemyeater
Este pequeno pixel procura por enimens ao seu redor e tenta comê-lo, se não houver nenhum pixel ao redor dele se mover em uma direção aleatória. Estou ansioso para ver o que os outros povos inventam.
fonte
Math.floor
nãoMath.float
!(Math.random() * 6) & 6
ou(Math.random() * 6) << 0
ou(Math.random() * 6) >> 0
(útil para codegolf).Math.random() * 7
? Eu tentei algumas execuções de teste e parece que seu bot não vai para o canto inferior direito. IIRCMath.random()
é inclusiva 0 e exclusiva 1, que significa* 6
nunca realmente é 6.Equipe vermelha - Jittery Red Charger
O Carregador Vermelho se move apenas para a esquerda e para a direita, na esperança de explorar a incapacidade do Blue Team de se mover nessas direções. Depois de atingir um muro, ele se vira e avança na direção oposta, na esperança de destruir cegamente qualquer robô no caminho.
Edição: Red Charger acabou de beber um litro de bebida energética e agora não pode parar de tremer, ele espera usar isso a seu favor também. É cafeinado demais para ouvir seus companheiros de equipe, mas está gritando cada um de seus movimentos.
fonte
Equipe azul - LazySoldier
fonte
JSON.parse
em um bloco try / catch ou algo assim ... está causando muitos erros.Equipe Azul - Assassino em Massa
Eu acho uma tática bem direta. Conto inimigos diretamente alcançáveis por mim (suponho que haverá muitos deles :)) e mato a maior quantidade. Se não houver, pelo menos vou tentar me proteger, passando acima ou abaixo da maior quantidade de inimigos na esperança de matá-los no próximo passo.
Desisti de considerar as paredes, então simplesmente as ignorei. É bastante longo de qualquer maneira.
Não foi possível testar / executar esse código, portanto haverá muitos erros.
fonte
Equipe Azul - Cão de Guarda
Ele se move aleatoriamente até pegar um aliado, se for o caso. Ele tenta evitar ser morto e matar se puder. Desculpe pelo código horrível, fui direto e esqueci a refatoração. Vou tentar melhorar a legibilidade se tiver tempo :)
fonte
Equipe Vermelha - Comandante da Apanhadora
Esta é uma cópia do Minos 'SeekerBot com algumas modificações.
Memória interna compactada para melhor distribuição de mensagens
"$":[seekmode]
Lê posições inimigas de aliados usando o formato JSON do Lazy Slayer
"e":"[positions]"
; aceita[positions]
compensação por ambos32
e174
Informa as posições dos inimigos no formato JSON do Lazy Slayer,
"e":"[positions]"
compensado por174
Relatórios da última jogada com
"m":[move]
para indicar que este bot pode ser comandadoEmite comandos para outros bots usando
"[ally_id]":{"m":[move],"a":1,"id":29354}
. O comando usa o mesmo algoritmo buscador, exceto no local do aliado. Se outros robôs ouvirem essas ordens, eles devem se agrupar e caçar em um pacote. Ordens dadas apenas se a mensagem do aliado incluir"m":
Segue comandos de outros bots, como:
"29354":[move]
ou"29354":{"m":[move]
. Os comandos são seguidos apenas quando nenhum inimigo está ao alcance e nenhum outro aliado está relatando inimigos.fonte
""a":0,"o":[122,70],"m":0,"e":"f""
. Você pode se juntar a nós no bate-papo, se quiser também.Equipe Vermelha - BouncerBot
Meu bot salta de parede em parede (não exatamente, por isso cobre um terreno diferente) à procura de inimigos. Se ele conseguir um em seu alcance, ataca, arrasta-os em direção a uma parede e tenta derrubá-los (pense em um clube de segurança).
fonte
Time Vermelho - SideKick
Gosta de seguir colegas de equipe, ainda bem que existem muitos!
fonte
Equipe azul - ímã indeciso
Ele tem várias estratégias: se ele puder derrotar um inimigo imediatamente, o fará e fugirá de grupos de inimigos se estiverem longe o suficiente, caso contrário, ele lutará. Fora isso, ele está apenas procurando por membros da equipe e tentando segui-los.
fonte
Equipe azul - buscar [38953]
[edita: acontece que funciona MUITO melhor quando eu uso meu ID real e não -1!]
Um botzinho idiota que corre em volta do tabuleiro, fazendo o possível para atrair atenção e atrair caçadores, e depois corre para o meio, onde (espero) ele encontra alguém para ajudá-lo, ou ele simplesmente detém o caçador e o detém. da caça.
Não parece ter um grande impacto na pontuação geral devido à força da equipe azul, mas pelo menos eu não piorei as coisas!
Grite nas próximas 8 horas se você quiser que eu adicione algo útil à minha mensagem.
fonte
Equipe Azul - PatrolBot
O código é uma espécie de auto-documentação. O que pode ser feito para melhorar o PatrolBot
if (canBeKilled() || isInWall()) { moveToBetterPosition() }
pouco antes do retorno.fonte
EQUIPE AZUL - 1 ponto impressionante
As prioridades do pixel:
A gravidade é definida como 64,64 no movimento 1
A gravidade é definida no local mais próximo dos inimigos (para guiar o pixel até a última localização do inimigo, se o inimigo escapar)
A gravidade muda aleatoriamente quando o pixel atinge o centro de gravidade ou quando está perto da borda
fonte
Vermelho - LoyalFollower [15080]
Tenta encontrar Minos e matar inimigos. Infelizmente, o time vermelho ainda perde, talvez porque somos menos jogadores ...
fonte
Equipe azul - MiddleMan
MiddleMan é o irmão gêmeo do WallFlower (a quem ele substituiu). Como seu irmão, ele não costuma ser um tipo social de cara. Ele prefere ficar no meio da sala, assistindo e esperando. Mas isso não quer dizer que ele seja passivo ou tímido. Enquanto estiver em seu lugar ou a caminho, se ele encontrar um inimigo, não importa o tamanho, ele se encarregará de enfrentá-lo. Sabendo que há força nos números, ele os atrairá alegremente para todos os colegas de equipe que encontrar, ou alternativamente, para o centro, na esperança de encontrar outros. Quando seus negócios terminam, ele volta ao seu lugar, pronto para a próxima oportunidade de ajudar sua equipe.
Cuidado, equipe vermelha. Embora ele não pareça muito, ele é tão feroz e persistente quanto eles vêm; um mestre de combates individuais de curta distância. Ele pode não se comunicar diretamente com sua equipe, mas os reconhece e trabalhará em conjunto para derrubar o inimigo comum. Recentemente, ele aprendeu a enviar mensagens, apesar de não escutar nada, apenas seu estilo. O formato é uma string JSON contendo uma matriz como esta:
[[selfX,selfY],[[enemy1X,enemy1Y],[enemy2X,enemy2Y]]]
e assim por diante para mais inimigos.fonte
Equipe Azul - VersaBot, um mecanismo polimórfico
Meu código seguirá automaticamente o bot mais próximo, fornecendo poder de fogo e proteção adicionais.
Desfrutar!
fonte