Este concurso ha terminado oficialmente. ¡El equipo azul ganó!
Arranqué automáticamente dos series de 50 batallas y, sorprendentemente, Blue ganó las 100. Mirando las estadísticas, está claro que las entradas cooperativas de PhiNotPi y Sp3000 fueron los verdaderos héroes. ¡Buen trabajo ustedes dos! De hecho, si descalificas a todos los demás miembros del Equipo Azul , los Sphibots aún luchan muy bien . Algunas personas del Equipo Rojo estaban planeando derribar a los Sphibots, pero este esfuerzo pareció agotarse. Lo siento equipo rojo.
El concurso ha terminado oficialmente, pero eso no significa que ya no puedas responder, solo significa que nunca volveré a declarar al ganador oficial. Ambos equipos son bienvenidos para seguir enviando bots, solo por diversión. El controlador permanecerá activo y seguirá funcionando mientras no lo rompan las entradas futuras.
Este es un concurso del rey de la colina , pero en lugar de que todos luchen entre sí, habrá dos equipos que competirán: Rojo y Azul. Solo uno será el ganador.
El equipo en el que está depende de su número de identificación de usuario PPCG . Para encontrar esto, haga clic en su avatar en la parte superior de la pantalla (debe iniciar sesión) y mire la URL de la página que se abre. El número siguiente users/
es su número de identificación:
https://codegolf.stackexchange.com/users/[id number]/[display name]
Por ejemplo, mi número de identificación de usuario PPCG es 26997:
https://codegolf.stackexchange.com/users/26997/calvins-hobbies
Tenga en cuenta que este número es diferente para diferentes sitios de Stack Exchange.
Si su identificación es un número par , entonces usted está en el equipo Rojo .
Si su identificación es un número impar , entonces usted está en el equipo Azul .
No hay forma de cambiar de equipo.
Debes trabajar con tu equipo para tratar de derrotar al otro equipo en una especie de batalla real donde cada usuario controla un "píxel" del color de su equipo en la cuadrícula de 128 × 128 que es el campo de batalla. Los píxeles pueden moverse, comunicarse con sus compañeros de equipo y eliminar los píxeles del otro equipo. Se saldría de control si alguien pudiera crear cualquier número de píxeles, por lo que cada usuario solo puede enviar una respuesta a esta pregunta.
Este fragmento de pila (una versión reducida de este violín [ pantalla completa ]) es el controlador de todo el concurso. Lee automáticamente los envíos, se asegura de que sean válidos y organiza batallas entre los equipos. Lo hace directamente en su navegador en cualquier momento que desee, utilizando JavaScript . Dado que JavaScript es el único lenguaje de secuencias de comandos del lado del cliente que admite la mayoría de los navegadores, todas las presentaciones deben escribirse también en 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 mayor visibilidad, el campo de batalla del Snippet se escala en un factor de 3, por lo que son 384 × 384 píxeles reales y los "píxeles" son 3 × 3.
Pixel Team Battlebots - Descripción general
Jugadores
Cada respuesta válida a esta pregunta representa un jugador . (Para obtener detalles sobre la validez, consulte "Reglas y descalificaciones" .) Cada jugador tiene control sobre una sola celda de 1 × 1 (también conocido como píxel) en el campo de batalla de 128 × 128 celdas . Los jugadores del equipo rojo tienen píxeles rojos y los jugadores del equipo azul tienen píxeles azules.
Batallas
Una batalla es una pelea entre todos los jugadores de ambos equipos, incluso si los equipos no tienen el mismo número de jugadores. Una batalla comienza con cada jugador colocado en una posición aleatoria en el campo de batalla, es decir, cualquier coordenada entera desde (0,0) en la parte superior izquierda, hasta (127,127) en la parte inferior derecha. Se garantiza que no habrá dos jugadores que comiencen en la misma posición.
Movimientos
Cada batalla se divide en 2048 movimientos . Solo un equipo realmente puede mover a sus jugadores durante cada movimiento. Ese equipo alterna de rojo a azul, por lo que cada equipo realiza 1024 movimientos en total (a menos que el juego termine antes).
El equipo que se mueve primero es una opción que debe configurar en el controlador.
Cuando las batallas se ejecutan automáticamente, el equipo que se mueve primero se alterna en cada batalla.
Movimientos de jugador
Cuando un equipo se mueve, todos los jugadores de ese equipo deben moverse. Estas llamadas se realizan en un orden completamente aleatorio para cada movimiento. Cuando se les llama, cada jugador recibe datos sobre el estado de la batalla para que puedan decidir qué camino tomar.
Todos los movimientos están a solo un píxel de distancia. Las ojeras en estos diagramas marcan a qué posiciones se puede mover cada jugador de color (los cuadrados):
Ambos colores pueden moverse en diagonal en cualquier dirección o permanecer quietos, pero solo los jugadores rojos pueden moverse hacia la derecha y hacia la izquierda, y solo los jugadores azules pueden moverse hacia abajo y hacia arriba. Gracias Phi y otros.
Si un jugador intenta moverse fuera de los límites del campo de batalla, o tarda demasiado en decidir qué camino tomar, o si tiene algún tipo de error, se quedará quieto automáticamente.
Además de moverse, durante un turno, un jugador puede leer mensajes escritos por sus compañeros de equipo y escribir mensajes que a su vez pueden leerse. Esto permite una forma cruda de comunicación en equipo.
El código que envía como respuesta es la lógica que determina la forma de mover su reproductor y qué mensajes leer y escribir (consulte "Cómo responder" ).
Eliminando jugadores enemigos
Cuando un jugador se mueve a la misma celda que un jugador del equipo contrario, ese jugador contrario se retira inmediatamente de la batalla. El jugador que acaba de moverse continúa de manera normal. ¡Este es el único mecanismo que elimina a los jugadores de la batalla y dominarlo es la clave para ganar!
Si hay varios jugadores enemigos en la celda a la que acaba de moverse un jugador, entonces todos los jugadores enemigos son eliminados. No pasa nada si dos jugadores del mismo equipo ocupan la misma celda.
Ganar una batalla
Una batalla termina una vez que se han realizado todos los movimientos de 2048 o cuando a un equipo no le quedan jugadores. El equipo con el mayor número de jugadores sobrevivientes gana. Es un empate si ambos equipos tienen el mismo número de jugadores sobrevivientes.
Cómo responder
En su respuesta, debe proporcionar el código JavaScript que decide de qué manera se moverá su píxel cuando se le solicite.
En el primer ejemplo de código sangrado en su respuesta (los prefijados con 4 espacios), escriba un cuerpo para esta función:
function moveMe(move, x, y, tCount, eCount, tNear, eNear, setMsg, getMsg) {
//the body goes here
}
No hay necesidad de jugar golf con su código.
Que devolver
El valor de retorno de la función determina de qué manera se mueve su píxel:
0
permanecer quieto
1
para moverse hacia la derecha para el equipo Rojo, hacia abajo para que el equipo Azul se
2
mueva hacia la izquierda para el equipo Rojo, hacia arriba para que el equipo Azul se
3
mueva diagonalmente hacia arriba y
4
hacia la derecha para moverse en diagonal hacia arriba y
5
hacia la izquierda para moverse en diagonal hacia abajo y hacia la izquierda
6
para moverse en diagonal abajo y a la derecha
Como un diagrama:
Su píxel permanecerá quieto de forma predeterminada si su código hace alguna de estas cosas:
- Devuelve cualquier cosa además de un entero de 0 a 6.
- Intenta mover píxeles fuera de los límites del campo de batalla.
- Tarda más de 15 milisegundos en ejecutarse.
- Lanza cualquier tipo de excepción.
Su entrada no necesita ser determinista; usar Math.random
está bien.
Los parametros
Los primeros 7 parámetros de función moveMe
brindan información sobre el estado de la batalla:
move
es un número entero que comienza en 1 y se incrementa después de cada movimiento hasta que sea 1024 en el último movimiento de su equipo.x
es su posición x actual, un número entero de 0 (más a la izquierda) a 127 (más a la derecha).y
es su posición y actual, un número entero de 0 (más arriba) a 127 (más abajo).tCount
es el número total actual de jugadores supervivientes en tu equipo.eCount
es el número total actual de jugadores sobrevivientes en el equipo enemigo.tNear
es una lista de los jugadores supervivientes actuales en su equipo que están a menos de 16 píxeles de distancia (distancia euclidiana). Cada elemento detNear
es un objeto conx
,y
yid
propiedades:
x
es la posición x del otro jugadory
es la posición y del otro jugadorid
es el número de identificación de usuario PPCG del otro jugador (como un entero)eNear
es exactamente como,tNear
excepto que es una lista de jugadores enemigos cercanos, no compañeros de equipo.
Los círculos en el fragmento son de cada jugador tNear
y eNear
rango.
Mensajes
Los últimos 2 parámetros setMsg
y getMsg
tienen propósitos ligeramente diferentes.
A lo largo de una batalla, cada jugador tiene una cadena de hasta 64 personajes que pueden manipular durante cada movimiento para almacenar datos y potencialmente comunicarse con sus compañeros de equipo. La secuencia de cada jugador comienza como la secuencia vacía. Cuando un jugador es eliminado de la batalla, su cadena se establece en "X".
setMsg
es una función de un argumento que establece su cadena a la cadena que se pasa.- Si el valor pasado no es una cadena, entonces su cadena no cambia.
- Si el valor es una cadena con más de 64 caracteres, solo se conservan los primeros 64.
getMsg
es una función de un argumento que toma el número de identificación de usuario PPCG (como un entero) de alguien en su equipo y devuelve su cadena.- Ese jugador puede estar en cualquier lugar de la cuadrícula. No necesitan estar en su radio de 16 píxeles.
undefined
se devuelve si no se encuentra la ID dada.
Presentación de ejemplo
Este jugador se mueve hacia arriba y hacia la derecha si hay un enemigo a la izquierda, o hacia abajo y a la izquierda si su compañero de equipo con ID 123 lo dice, pero por lo demás se queda quieto:
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
Tenga en cuenta que este bloque de código es todo lo que se requiere. La definición de la función y los corchetes no deben estar presentes.
Reglas y descalificaciones
Si un usuario no cumple con las reglas que se enumeran a continuación, puedo marcarlo como descalificado y el controlador ignorará automáticamente sus respuestas. Confío en que la mayoría de los usuarios aquí no romperán intencionalmente las reglas y solo habrá algunas descalificaciones temporales por causas accidentales.
Reglas importantes
Solo puede editar su respuesta durante la ventana de 8 horas directamente después de publicarla.
El controlador descalificará automáticamente las respuestas que se editen después de 8 horas desde el momento en que se publicaron. Esta regla es para evitar que las respuestas iniciales optimicen continuamente su enfoque, posiblemente robando ideas de respuestas posteriores. Su equipo tiene que conformarse con las respuestas con las que comenzó.No puede eliminar y volver a publicar su respuesta sin un permiso especial. Daré esto si alguien edita tu publicación inadvertidamente después de las 8 horas o algo así, pero no solo porque encontraste un error.
Si elimina su publicación y elige recuperarla, la regla de edición aún se aplica. (El controlador no puede ver las respuestas eliminadas).
Al declarar una nueva variable de JavaScript, debe usar la
var
palabra clave.
Esto se debe a que una variable declarada sin sevar
convierte en global en lugar de local, por lo que sería fácil meterse accidentalmente (o intencionalmente) con el controlador o comunicarse libremente con otros jugadores. Tiene que estar claro que no estás tratando de hacer trampa.Al declarar funciones, es mejor usar la
var
palabra clave también. es decir, usar envar f = function(...) {...}
lugar defunction f(...) {...}
. No estoy completamente seguro de por qué, pero a veces parece hacer la diferencia.Su código no debe ejecutarse durante un período de tiempo excesivo.
Si su código tarda más de 15 milisegundos en ejecutarse, su píxel no se moverá en absoluto. Sin embargo, dado que es difícil en JavaScript detener las funciones a mitad de la ejecución, todos los scripts de los jugadores se ejecutan hasta su finalización en cada movimiento, y el tiempo se verifica después. Esto significa que si su código requiere algo de tiempo, todos los que ejecuten el controlador lo notarán y se molestarán.
Descalificaciones automáticas
El controlador descalificó automáticamente las entradas por estos motivos:
- El usuario ya ha respondido.
- Las modificaciones se realizaron más de 8 horas después de la creación.
- El usuario está marcado específicamente como descalificado.
Otras reglas
En su código no puede ...
- intenta acceder o modificar el controlador u otro código de jugador.
- Intente modificar cualquier cosa integrada en JavaScript.
- intenta comunicarte con otros jugadores excepto mediante el uso de
getMsg
ysetMsg
. - hacer consultas web
- hacer cosas maliciosas de otra manera.
Estaré atento a otros comportamientos antideportivos, como robar código literalmente de otras respuestas o usar títeres de calcetín para meterse con el otro equipo.
Puede colaborar y planificar con su equipo, pero mantenga el concurso amigable y ético.
Si cree que alguien debe ser descalificado o cree que solucionó el motivo por el cual fue descalificado, deje un comentario aquí para mí o en el chat específico de la pregunta . No estoy participando en el concurso.
Formato de respuesta sugerido
#[team color] Team - [entry title]
//function body
//probably on multiple lines
Explanations, notes, etc.
El título de la entrada es un nombre opcional que puede dar si lo desea. El controlador no hace nada con él.
Puntuación
Este concurso finalizará oficialmente el 19 de abril de 2015. Ese día (alrededor de las 11 pm UTC) ejecutaré automáticamente al menos 100 batallas (posiblemente muchas más dependiendo de cuánto tiempo duran las batallas). El equipo que gane más será el ganador general. Si es un empate o muy cerca, correré más batallas hasta que quede claro que un equipo tiene la ventaja.
(Puede responder después de que se decida el ganador, pero no cambiaré el resultado oficial).
Los ejecutaré en la última versión de Google Chrome en una computadora portátil con Windows 8.1 de 64 bits, 4 GB de ram y un procesador de cuatro núcleos a 1.6GHz. Asegúrese de que su JavaScript funcione en Chrome.
La victoria se trata principalmente de la gloria del equipo, pero aceptaré la respuesta más votada en el equipo ganador.
A lo largo del concurso, tenga en cuenta que el aspecto basado en el equipo y el hecho de que se ejecuta completamente en un fragmento de pila son muy experimentales. Tengo muchas esperanzas, pero no puedo decir con certeza qué tan bien funcionarán las cosas.
Consejos:
- Puede probar entradas antes de responder. Edite el cuadro de texto "Entrada de prueba" cerca de la parte inferior del Fragmento de pila y haga clic en "Volver a cargar con entrada de prueba". Si no está vacío, se convierte en un jugador del equipo especificado.
- Las respuestas se ejecutan en un ámbito enmascarado, por lo que cosas como
alert
yconsole.log
no funcionarán. Elconsole
objeto solo se puede usar en la entrada de prueba. - Marque "Mensajes de depuración" en la parte inferior del Fragmento de pila y mire la consola de su navegador (F12). Se imprime mucha información útil cuando las batallas se están ejecutando.
- Puede usar la publicación Meta Sandbox como una especie de área de ensayo. Las respuestas allí son, por supuesto, diferentes a las de aquí, y el controlador allí puede estar desactualizado.
- Dado que no se trata de una aplicación Stack oficial , el controlador puede dejar de cargar respuestas por usted si la reinicia más de 300 veces en un día.
La "secuela" de este desafío: Block Building Bot Flocks!
enlaces rápidos
Fiddle Controller Pantalla completa Chat general Chat rojo (¿Chat azul?) SandboxPost
fuente
Respuestas:
Equipo azul - SphiNotPi3000
Este bot forma un par con el bot de Sp3000 .
La idea básica es que dos bots, colocados adyacentes entre sí, ayudan a cubrir las debilidades del otro, de modo que ninguno de los bot tiene un lado expuesto. Esto ayuda a proteger de las amenazas y a limitar las opciones de escape del objetivo.
Al comienzo del juego, navegan uno hacia el otro y forman un par. Este par luego se mueve como una sola unidad, con un bot liderando al otro. Los dos bots tienen un código casi idéntico, lo que les permite intercambiar posiciones y roles cuando sea necesario.
Cuando está inactivo, los bots se mueven por el tablero en busca de enemigos. Una vez que ven a un enemigo, se maniobran cuidadosamente en las posiciones correctas para atacar. Una característica muy clara es la capacidad de la formación de moverse en línea recta horizontalmente, lograda al hacer que los bots alternen lugares.
fuente
var
no se usa en esta publicación y Sp3000. Asignanj
a 0 de inmediato y no interfiere en absoluto con el controlador, por lo que afortunadamente no es un problema en este caso.Equipo azul - SphiNotPi3000
Este bot forma un par con el bot de PhiNotPi . Vea la publicación de Phi para una breve explicación de nuestra estrategia.
fuente
Equipo Rojo - SeekerBot
La máxima prioridad de SeekerBot es la supervivencia. Por lo tanto, solo considerará movimientos que no lo pondrán en peligro de ser asesinado en el siguiente turno (siempre que existan tales movimientos).
Cuando no hay oponentes a la vista, se moverá en un patrón sobre el campo de batalla, lo que asegurará que la mayor parte del terreno esté regularmente a la distancia de visualización.
Si SeekerBot ve a un enemigo, se moverá hacia él. Si puede matar a un enemigo, lo hará siempre que el movimiento se salve.
Si no puede matar a un enemigo pero el enemigo está en posición de matarlo en su próximo turno, SeekerBot intentará atraer al enemigo hacia un amigo (si hay uno visible). Si no hay ningún miembro del equipo a la vista, intentará moverse a una posición en la que pueda matar al enemigo en el próximo turno. Si esto no funciona 5 veces seguidas, cambiará de táctica y comenzará a moverse en un patrón aleatorio, posiblemente acercándose nuevamente al enemigo en la próxima ronda.
Para lo que vale, usará los primeros 7 caracteres del mensaje para gritar su propia posición en el formato "x; y" (donde x e y están rellenados con ceros).
Ciertamente no es el código más limpio, pero parece hacer lo que esperaba de él.
fuente
Equipo rojo - Groomba
Notas en los comentarios.
fuente
self
. Esa variable está reservada para señalarwindow.self
. UseI
(mayúscula i) en su lugar. Ome
. O inclusomyself
.Equipo rojo - Lazy Slayer
Esto es lo más básico que pude conseguir.Esto ya no es 100% básico.Solo se mueve SI SE REQUIERE .
Si un usuario envía un mensaje con 2 números entre-1
y1
(por ejemplo:)'1,0'
, separados por una coma, se moverá allí. Confía totalmente en sus compañeros de equipo.Esto ahora se comunica a través de JSON. Tiene una estructura muy básica:
Un ejemplo de un mensaje para controlarlo:
Que enviará:
También es un poco egoísta
y no te ayudaráy ahora él es útil como un faro estacionario.Si este mensaje es incorrecto (el formato no es correcto), intente agregar en
"}
lugar de}
.Esto fue editado después del límite de 6 horas y luego se extendió a 8.
Ya no está roto y permanecerá como la versión final.
fuente
Equipo rojo - El cobarde
Este bot permanece quieto para evitar ser detectado tanto como sea posible. Cuando uno o más enemigos están a la vista, pueden suceder varias cosas:
No se comunica con nadie, en caso de que alguien pueda escucharlo e ir tras él.
Puede que no sea el bot más útil para el equipo, pero fue divertido verlo tratando de alejarse de todos.
fuente
Equipo azul - águila
Estoy bastante feliz con mi bot en este momento. Tiene las siguientes tácticas:
fuente
Equipo azul - Enemyeater
Este pequeño píxel busca enimens a su alrededor e intenta comérselo, si no hay píxel alrededor se mueve en una dirección aleatoria. Tengo muchas ganas de ver qué se les ocurre a otras personas.
fuente
Math.floor
noMath.float
!(Math.random() * 6) & 6
or(Math.random() * 6) << 0
or(Math.random() * 6) >> 0
(útil para codegolf).Math.random() * 7
? He intentado algunas pruebas, y parece que tu bot no va a la parte inferior derecha. IIRCMath.random()
es inclusivo 0 y exclusivo 1, lo que significa que en* 6
realidad nunca es 6.Equipo rojo - Cargador rojo nervioso
El cargador rojo solo se mueve hacia la izquierda y hacia la derecha, con la esperanza de explotar la incapacidad del equipo azul para moverse en esas direcciones. Después de alcanzar una pared, se da la vuelta y carga en la dirección opuesta, con la esperanza de destruir ciegamente cualquier robot que se encuentre en su camino.
EDITAR: Red Charger acaba de beber un galón de bebida energética y ahora no puede dejar de temblar, también espera usar esto para su ventaja. Es demasiado cafeinado para escuchar a sus compañeros de equipo, pero está gritando cada uno de sus movimientos.
fuente
Equipo azul - LazySoldier
fuente
JSON.parse
en un bloque try / catch o algo así ... está causando demasiados errores.Equipo Azul - Asesino en Masa
Supongo una táctica bastante sencilla. Cuento enemigos directamente accesibles por mí (supongo que habrá toneladas de ellos :)) y mato la mayor cantidad. Si no hay ninguno, al menos intentaré protegerme subiendo o bajando la mayor cantidad de enemigos con la esperanza de matarlos en el siguiente paso.
Dejé de tener en cuenta los muros, así que simplemente los ignoré. Es bastante largo de todos modos.
No pude probar / ejecutar este código, por lo que habrá muchos errores.
fuente
Equipo azul - WatchDog
Se mueve al azar hasta que agarra a un aliado, si es así, lo sigue. Intenta evitar ser asesinado, y matar si puede. Perdón por el horrible código, fui directo y olvidé la refactorización. Intentaré imprimir la legibilidad si tengo tiempo :)
fuente
Equipo rojo - Comandante buscador
Esta es una copia de Minos 'SeekerBot con algunas modificaciones.
Memoria interna comprimida para una mejor distribución de mensajes.
"$":[seekmode]
Lee las posiciones enemigas de los aliados usando el formato JSON de Lazy Slayer
"e":"[positions]"
; acepta[positions]
compensado por ambos32
y174
Informa las posiciones enemigas en el formato JSON de Lazy Slayer,
"e":"[positions]"
compensado por174
Reporta el último movimiento con
"m":[move]
para indicar que este bot puede ser comandadoEmite comandos a otros bots usando
"[ally_id]":{"m":[move],"a":1,"id":29354}
. El comando usa el mismo algoritmo buscador excepto en la ubicación del aliado. Si otros bots escuchan estas órdenes, deben agruparse y cazar en un paquete. Las órdenes solo se dan si el mensaje de aliado incluye"m":
Sigue los comandos de otros bots, como:
"29354":[move]
o"29354":{"m":[move]
. Los comandos solo se siguen cuando no hay enemigos dentro del alcance y ningún otro aliado informa enemigosfuente
""a":0,"o":[122,70],"m":0,"e":"f""
. También puedes unirte a nosotros en el chat si quieres.Equipo Rojo - BouncerBot
Mi bot rebota de pared a pared (no exactamente, por lo que cubre diferentes terrenos) en busca de enemigos. Si tiene uno en su rango, ataca, los arrastra hacia una pared e intenta sacarlos (piense en un gorila en un club).
fuente
Equipo rojo - SideKick
Le gusta seguir a sus compañeros, ¡qué bueno que hay muchos!
fuente
Equipo azul - imán indeciso
Tiene múltiples estrategias: si puede vencer a un enemigo inmediatamente, lo hará, y huirá de los grupos de enemigos si están lo suficientemente lejos, de lo contrario luchará. Aparte de eso, solo está buscando miembros del equipo e intentando seguirlos.
fuente
Equipo azul - Recuperar [38953]
[ediciones: ¡resulta que funciona MUCHO mejor cuando uso mi ID real y no -1!]
Un pequeño bot tonto que corre alrededor del tablero, haciendo todo lo posible para atraer la atención y atraer cazadores, y luego correr hacia el medio donde (con suerte) encontrará a alguien que lo ayude, o simplemente detendrá al cazador y lo detendrá. de la caza
No parece tener un gran impacto en el puntaje general debido a lo poderoso que es el equipo de etiqueta azul, ¡pero al menos no empeoré las cosas!
Grita en las próximas 8 horas si quieres que agregue algo útil a mi mensaje.
fuente
Equipo Azul - PatrolBot
El código es una especie de autodocumentación. Cosas que podrían hacerse para mejorar PatrolBot
if (canBeKilled() || isInWall()) { moveToBetterPosition() }
justo antes de regresar.fuente
EQUIPO AZUL - 1 Punto Impresionante
Las prioridades del píxel:
La gravedad se establece en 64,64 en el movimiento 1
La gravedad se establece en la ubicación de los enemigos más cercanos (para guiar los píxeles a la ubicación del último enemigo, si el enemigo escapa)
La gravedad cambia aleatoriamente cuando el píxel ha alcanzado el centro de gravedad o cuando está cerca del borde
fuente
Rojo - LoyalFollower [15080]
Intenta encontrar a Minos y matar enemigos. Lamentablemente, el equipo rojo todavía pierde, tal vez porque somos menos jugadores ...
fuente
Equipo Azul - MiddleMan
MiddleMan es el hermano gemelo de WallFlower (a quien reemplazó). Al igual que su hermano, no tiende a ser un tipo social. Prefiere pasar el rato en el medio de la habitación, mirando y esperando. Pero eso no quiere decir que sea pasivo o tímido. Mientras está en su lugar o camino a él, si encuentra un enemigo, sin importar el tamaño, cargará para enfrentarse a él. Sabiendo que hay fuerza en los números, con gusto los atraerá hacia cualquier compañero de equipo que encuentre o, alternativamente, hacia el centro con la esperanza de encontrar a otros. Una vez que termina su negocio, regresa a su lugar, listo para la próxima oportunidad de ayudar a su equipo.
Cuidado, equipo rojo. Si bien puede no parecer mucho, es tan feroz y persistente como parece; un maestro de la lucha cuerpo a cuerpo en solitario. Es posible que no se comunique directamente con su equipo, pero los reconoce y trabajarán juntos para derrotar al enemigo común. Recientemente aprendió a enviar mensajes, aunque él mismo no escuchará ninguno, solo que no es su estilo. El formato es una cadena JSON que contiene una matriz como esta:
[[selfX,selfY],[[enemy1X,enemy1Y],[enemy2X,enemy2Y]]]
y así sucesivamente para más enemigos.fuente
Equipo azul : VersaBot, un motor polimórfico
Mi código seguirá automáticamente el bot más cercano cerca de él, proporcionando potencia de fuego y protección adicionales.
¡Disfrutar!
fuente