Dieser Wettbewerb ist offiziell beendet. Das blaue Team hat gewonnen!
Ich habe zwei Sätze mit je 50 Gefechten durchgeführt und erstaunlicherweise hat Blue alle 100 gewonnen. Wenn man sich die Statistiken ansieht , ist klar, dass die kooperativen Einträge von PhiNotPi und Sp3000 die wahren Helden waren. Gute Arbeit ihr beiden! In der Tat, wenn Sie jedes andere Mitglied des Blue Teams disqualifizieren , liefern sich die Sphibots immer noch einen sehr guten Kampf . Einige Red Team-Leute planten, die Sphibots auszuschalten, aber diese Anstrengung schien nachzulassen. Entschuldigung, rotes Team.
Der Wettbewerb ist offiziell beendet, aber das heißt nicht, dass Sie nicht mehr antworten können, sondern nur, dass ich den offiziellen Sieger nie wieder erkläre. Beide Teams sind herzlich eingeladen, aus Spaß weiterhin Bots einzureichen. Der Controller bleibt aktiv und funktionsfähig, solange er von zukünftigen Einträgen nicht unterbrochen wird.
Dies ist ein King-of-the-Hill- Wettbewerb, aber stattdessen treten zwei Teams gegeneinander an: Rot und Blau. Nur einer wird der Gewinner sein.
Das Team, dem Sie angehören, hängt von Ihrer PPCG- Benutzer-ID-Nummer ab. Um dies zu finden, klicken Sie oben auf dem Bildschirm auf Ihren Avatar (Sie müssen angemeldet sein) und sehen Sie sich die URL der sich öffnenden Seite an. Die Nummer danach users/
ist Ihre ID-Nummer:
https://codegolf.stackexchange.com/users/[id number]/[display name]
Meine PPCG-Benutzer-ID lautet beispielsweise 26997:
https://codegolf.stackexchange.com/users/26997/calvins-hobbies
Beachten Sie, dass diese Nummer für verschiedene Stack Exchange-Standorte unterschiedlich ist.
Wenn Ihre ID eine gerade Zahl ist , gehören Sie zum Roten Team .
Wenn Ihre ID eine ungerade Zahl ist , gehören Sie zum blauen Team .
Es gibt keine Möglichkeit, Teams zu wechseln.
Sie müssen mit Ihrem Team zusammenarbeiten, um zu versuchen, das andere Team in einer Art Battle Royal zu besiegen, in dem jeder Benutzer ein "Pixel" der Farbe seines Teams auf dem 128 × 128-Gitter kontrolliert, das das Schlachtfeld ist. Pixel können sich bewegen, mit ihren Teamkollegen kommunizieren und die Pixel des anderen Teams entfernen. Es würde außer Kontrolle geraten, wenn jemand eine beliebige Anzahl von Pixeln erstellen könnte, sodass jeder Benutzer nur eine Antwort auf diese Frage einreichen kann.
Dieses Stack Snippet (eine verkleinerte Version dieser Geige [ Vollbild ]) ist der Controller für den gesamten Wettbewerb. Die Einsendungen werden automatisch gelesen, ihre Gültigkeit wird überprüft und es werden Kämpfe zwischen den Teams ausgetragen. Mit JavaScript können Sie dies jederzeit in Ihrem Browser tun . Da JavaScript die einzige clientseitige Skriptsprache ist, die von den meisten Browsern unterstützt wird, müssen alle Einsendungen auch in JavaScript geschrieben sein.
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>
Zur besseren Sichtbarkeit ist das Schlachtfeld des Snippets um den Faktor 3 skaliert, sodass es 384 × 384 echte Pixel und die "Pixel" 3 × 3 sind.
Pixel Team Battlebots - Übersicht
Spieler
Jede gültige Antwort auf diese Frage repräsentiert einen Spieler . (Einzelheiten zur Gültigkeit finden Sie unter "Regeln und Disqualifikationen" .) Jeder Spieler hat die Kontrolle über eine einzelne 1 × 1-Zelle (auch Pixel genannt) auf dem 128 × 128-Zellen- Schlachtfeld . Spieler im roten Team haben rote Pixel und Spieler im blauen Team blaue Pixel.
Kämpfe
Ein Kampf ist ein Kampf zwischen allen Spielern beider Mannschaften, auch wenn die Mannschaften nicht die gleiche Anzahl von Spielern haben. Ein Kampf beginnt damit, dass jeder Spieler an einer zufälligen Position auf dem Schlachtfeld platziert wird, dh mit einer beliebigen Ganzzahl-Koordinate von (0,0) oben links bis (127,127) unten rechts. Es ist garantiert, dass keine zwei Spieler in der gleichen Position starten.
Bewegt
Jede Schlacht ist in 2048 Züge unterteilt . Tatsächlich darf nur eine Mannschaft ihre Spieler pro Zug bewegen. Dieses Team wechselt von Rot nach Blau, sodass jedes Team insgesamt 1024 Züge macht (es sei denn, das Spiel endet vorzeitig).
Das Team, das sich zuerst bewegen darf, muss in der Steuerung eingestellt werden.
Wenn die Kämpfe automatisch ablaufen, wechselt das Team, das sich zuerst bewegt, in jedem Kampf.
Spieler bewegt sich
Wenn sich eine Mannschaft bewegt, werden alle Spieler dieser Mannschaft aufgefordert, sich selbst zu bewegen. Diese Aufrufe erfolgen in einer völlig zufälligen Reihenfolge für jeden Zug. Bei einem Aufruf erhält jeder Spieler Daten über den Stand des Kampfes, damit er entscheiden kann, in welche Richtung er sich bewegen soll.
Alle Bewegungen sind nur bis zu einem Pixel entfernt. Die dunklen Kreise in diesen Diagrammen markieren die Positionen, zu denen sich jeder farbige Spieler (die Quadrate) bewegen kann:
Beide Farben können sich diagonal in jede Richtung bewegen oder stehen bleiben, aber nur rote Spieler können sich nach rechts und links bewegen, und nur blaue Spieler können sich nach unten und oben bewegen. Danke Phi und anderen.
Wenn ein Spieler versucht, sich außerhalb des Spielfeldes zu bewegen oder zu lange braucht, um zu entscheiden, in welche Richtung er sich bewegt, oder einen Fehler hat, bleibt er automatisch stehen.
Zusätzlich zum Bewegen kann ein Spieler während eines Spielzugs Nachrichten lesen, die von seinen Teammitgliedern geschrieben wurden, und Nachrichten schreiben, die wiederum gelesen werden können. Dies ermöglicht eine grobe Form der Teamkommunikation.
Der Code, den Sie als Antwort senden, ist die Logik, die festlegt, wie der Player bewegt und welche Nachrichten gelesen und geschrieben werden sollen (siehe "So antworten Sie " ).
Entfernen von feindlichen Spielern
Wenn ein Spieler in dieselbe Zelle zieht wie ein Spieler der gegnerischen Mannschaft, wird dieser gegnerische Spieler sofort aus dem Kampf entfernt. Der Spieler, der sich gerade bewegt hat, fährt normal fort. Dies ist der einzige Mechanismus, der Spieler aus dem Kampf entfernt und dessen Beherrschung der Schlüssel zum Sieg ist!
Befinden sich mehrere gegnerische Spieler in der Zelle, zu der sich ein Spieler gerade bewegt hat, werden alle gegnerischen Spieler entfernt. Es passiert nichts, wenn zwei Spieler derselben Mannschaft dieselbe Zelle belegen.
Eine Schlacht gewinnen
Ein Kampf endet, wenn alle 2048 Züge ausgeführt wurden oder wenn eine Mannschaft keine Spieler mehr hat. Das Team mit der größten Anzahl überlebender Spieler gewinnt. Es ist ein Unentschieden, wenn beide Teams gleich viele überlebende Spieler haben.
Wie man antwortet
In Ihrer Antwort müssen Sie den JavaScript-Code angeben, der entscheidet, in welche Richtung sich Ihr Pixel bewegt, wenn Sie dazu aufgefordert werden.
Schreiben Sie im ersten eingerückten Codebeispiel Ihrer Antwort (die mit 4 Leerzeichen vorangestellt sind) einen Text für diese Funktion:
function moveMe(move, x, y, tCount, eCount, tNear, eNear, setMsg, getMsg) {
//the body goes here
}
Sie müssen Ihren Code nicht spielen.
Was soll ich zurückgeben?
Der Rückgabewert der Funktion bestimmt, wie sich Ihr Pixel bewegt:
0
still zu bleiben
1
, um sich nach rechts für das rote Team zu bewegen, nach unten für das blaue Team
2
, um sich nach links für das rote Team zu bewegen, nach oben für das blaue Team
3
, um sich diagonal nach oben und nach rechts
4
zu bewegen
5
, um sich diagonal nach unten und nach links
6
zu bewegen runter und rechts
Als Diagramm:
Ihr Pixel bleibt standardmäßig still, wenn Ihr Code eine der folgenden Aktionen ausführt:
- Gibt alles außer einer Ganzzahl von 0 bis 6 zurück.
- Versucht, Pixel außerhalb der Schlachtfeldgrenzen zu bewegen.
- Die Ausführung dauert länger als 15 Millisekunden.
- Wirft jede Art von Ausnahme.
Ihr Eintrag muss nicht deterministisch sein. Verwenden Math.random
ist in Ordnung.
Die Parameter
Die ersten 7 Funktionsparameter moveMe
geben Auskunft über den Stand der Schlacht:
move
ist eine Ganzzahl, die bei 1 beginnt und nach jedem Zug inkrementiert wird, bis der letzte Zug Ihres Teams 1024 ergibt.x
ist Ihre aktuelle x-Position, eine Ganzzahl von 0 (ganz links) bis 127 (ganz rechts).y
ist Ihre aktuelle y-Position, eine ganze Zahl von 0 (ganz oben) bis 127 (ganz unten).tCount
ist die aktuelle Gesamtzahl der überlebenden Spieler in Ihrem Team.eCount
ist die aktuelle Gesamtzahl der überlebenden Spieler im gegnerischen Team.tNear
ist eine Liste der aktuellen überlebenden Spieler in Ihrem Team, die weniger als 16 Pixel entfernt sind (euklidischer Abstand). Jedes ElementtNear
ist ein Objekt mitx
,y
undid
Eigenschaften:
x
ist die x-Position des anderen Spielersy
ist die y-Position des anderen Spielersid
ist die PPCG-Benutzer-ID des anderen Spielers (als Ganzzahl)eNear
ist genau wie,tNear
nur dass es sich um eine Liste der in der Nähe befindlichen feindlichen Spieler handelt, nicht um Teamkollegen.
Die Kreise im Snippet sind die des jeweiligen Spielers tNear
und dessen eNear
Reichweite.
Mitteilungen
Die letzten beiden Parameter setMsg
und getMsg
haben leicht unterschiedliche Zwecke.
Während eines Kampfes verfügt jeder Spieler über eine Reihe von bis zu 64 Zeichen, die er während jeder Bewegung manipulieren kann, um Daten zu speichern und möglicherweise mit seinen Teammitgliedern zu kommunizieren. Die Saite jedes Spielers beginnt als leere Saite. Wenn ein Spieler aus dem Kampf entfernt wird, wird seine Zeichenfolge auf "X" gesetzt.
setMsg
ist eine Ein-Argument-Funktion, die Ihren String auf den übergebenen String setzt.- Wenn der übergebene Wert keine Zeichenfolge ist, ändert sich die Zeichenfolge nicht.
- Wenn der Wert eine Zeichenfolge mit mehr als 64 Zeichen ist, werden nur die ersten 64 Zeichen beibehalten.
getMsg
ist eine Ein-Argument-Funktion, die die PPCG-Benutzer-ID-Nummer (als Ganzzahl) einer Person in Ihrem Team verwendet und deren Zeichenfolge zurückgibt.- Dieser Spieler kann irgendwo in der Startaufstellung sein. Sie müssen sich nicht in Ihrem 16-Pixel-Radius befinden.
undefined
wird zurückgegeben, wenn die angegebene ID nicht gefunden wird.
Beispiel Einsendung
Dieser Spieler bewegt sich nach oben und rechts, wenn sich links ein Feind befindet, oder nach unten und links, wenn der Mitspieler mit der ID 123 dazu sagt, bleibt aber ansonsten still:
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
Beachten Sie, dass dieser Codeblock alles ist, was erforderlich ist. Die Funktionsdefinition und die Klammern sollten nicht vorhanden sein.
Regeln und Disqualifikationen
Wenn sich ein Benutzer nicht an die unten aufgeführten Regeln hält, kann ich ihn als disqualifiziert markieren und der Controller ignoriert seine Antworten automatisch. Ich vertraue darauf, dass die meisten Benutzer hier nicht absichtlich gegen die Regeln verstoßen und es nur einige vorübergehende Disqualifikationen wegen versehentlicher Ursachen geben wird.
Wichtige Regeln
Sie können Ihre Antwort nur während des 8-Stunden-Fensters direkt nach dem Posten bearbeiten.
Antworten, die 8 Stunden nach dem Zeitpunkt der Veröffentlichung bearbeitet wurden, werden vom Controller automatisch disqualifiziert. Diese Regel soll verhindern, dass erste Antworten ihren Ansatz kontinuierlich optimieren und möglicherweise Ideen aus späteren Antworten stehlen. Ihr Team muss sich mit den Antworten begnügen, mit denen es begonnen hat.Sie dürfen Ihre Antwort nicht ohne besondere Erlaubnis löschen und erneut veröffentlichen. Ich gebe dies, wenn jemand versehentlich Ihren Beitrag nach der 8-Stunden-Marke oder so etwas bearbeitet, aber nicht nur, weil Sie einen Fehler gefunden haben.
Wenn Sie Ihren Beitrag löschen und wiederherstellen möchten, gilt die Bearbeitungsregel weiterhin. (Der Controller kann keine gelöschten Antworten sehen.)
Wenn Sie eine neue JavaScript-Variable deklarieren, müssen Sie das
var
Schlüsselwort verwenden.
Dies liegt daran, dass eine Variable, die ohne deklariert wurde,var
eher global als lokal wird, so dass es einfach ist, versehentlich (oder absichtlich) mit dem Controller zu spielen oder frei mit anderen Spielern zu kommunizieren. Es muss klar sein, dass Sie nicht versuchen zu betrügen.Wenn Sie Funktionen deklarieren, verwenden Sie am besten auch das
var
Schlüsselwort. dhvar f = function(...) {...}
statt verwendenfunction f(...) {...}
. Ich bin nicht ganz sicher warum, aber manchmal scheint es einen Unterschied zu machen.Ihr Code sollte nicht übermäßig lange ausgeführt werden.
Wenn die Ausführung Ihres Codes länger als 15 Millisekunden dauert, bewegt sich Ihr Pixel überhaupt nicht. Da es in JavaScript schwierig ist, Funktionen während der Ausführung zu stoppen, werden alle Player-Skripte bei jedem Zug vollständig ausgeführt und die Zeit danach überprüft. Das bedeutet, dass jeder , der den Controller ausführt, es bemerkt und genervt ist, wenn Ihr Code einige zeitintensive Aufgaben ausführt.
Automatische Disqualifikationen
Der Controller hat Einträge aus folgenden Gründen automatisch disqualifiziert:
- Der Benutzer hat bereits geantwortet.
- Die Änderungen wurden mehr als 8 Stunden nach der Erstellung vorgenommen.
- Der Benutzer ist ausdrücklich als disqualifiziert gekennzeichnet.
Andere Regeln
In deinem Code darfst du nicht ...
- Versuchen Sie, auf den Controller oder den Code eines anderen Spielers zuzugreifen oder diesen zu ändern.
- Versuchen Sie, alles in JavaScript eingebaute zu ändern.
- Versuche mit anderen Spielern zu kommunizieren, außer mit
getMsg
undsetMsg
. - Web-Abfragen machen.
- ansonsten böswillige Dinge tun.
Ich halte Ausschau nach anderen unsportlichen Verhaltensweisen, wie zum Beispiel das wörtliche Stehlen von Code aus anderen Antworten oder die Verwendung von Sockenpuppen, um mit dem anderen Team in Konflikt zu geraten.
Sie sind herzlich eingeladen, mit Ihrem Team zusammenzuarbeiten und zu planen, aber halten Sie den Wettbewerb freundlich und ethisch korrekt.
Wenn Sie der Meinung sind, dass jemand disqualifiziert werden muss oder Sie den Grund für die Disqualifizierung behoben haben, hinterlassen Sie hier einen Kommentar für mich oder im fragenspezifischen Chat . Ich nehme nicht am Wettbewerb teil.
Vorgeschlagenes Antwortformat
#[team color] Team - [entry title]
//function body
//probably on multiple lines
Explanations, notes, etc.
Der Titel des Eintrags ist ein optionaler Name, den Sie bei Bedarf eingeben können. Der Controller macht nichts damit.
Wertung
Dieser Wettbewerb wird offiziell am 19. April 2015 beendet sein. An diesem Tag (gegen 23 Uhr UTC) werde ich mindestens 100 Gefechte autorun (möglicherweise noch viel mehr, je nachdem, wie lange die Gefechte dauern). Das Team, das am meisten gewinnt, ist der Gesamtsieger. Wenn es ein Unentschieden oder extrem knapp ist, werde ich weitere Kämpfe austragen, bis klar ist, dass eine Mannschaft den Vorteil hat.
(Sie können antworten, nachdem der Gewinner ermittelt wurde, aber ich werde das offizielle Ergebnis nicht ändern.)
Ich werde sie in der neuesten Version von Google Chrome auf einem Laptop mit Windows 8.1 64-Bit, 4 GB RAM und einem 1,6-GHz-Quad-Core-Prozessor ausführen. Stellen Sie sicher, dass Ihr JavaScript in Chrome funktioniert.
Der Sieg hängt in erster Linie vom Team-Ruhm ab, aber ich werde die am höchsten bewertete Antwort des Siegerteams akzeptieren.
Denken Sie während des gesamten Wettbewerbs daran, dass der teambasierte Aspekt und die Tatsache, dass er vollständig in einem Stack-Snippet ausgeführt wird, sehr experimentell sind. Ich habe große Hoffnungen, aber ich kann nicht genau sagen, wie gut die Dinge funktionieren werden.
Tipps:
- Sie können Einträge vor der Beantwortung testen. Bearbeiten Sie das Textfeld "Test Entry" am unteren Rand des Stack-Snippets und klicken Sie auf "Reload with test entry". Wenn es nicht leer ist, wird es ein Spieler der angegebenen Mannschaft.
- Die Antworten werden in einem maskierten Bereich ausgeführt, sodass Dinge wie
alert
undconsole.log
nicht funktionieren. Dasconsole
Objekt kann nur im Testeintrag verwendet werden. - Überprüfen Sie "Debug-Meldungen" am unteren Rand des Stack-Snippets und sehen Sie sich die Konsole Ihres Browsers an (F12). Viele nützliche Informationen werden gedruckt, wenn Schlachten stattfinden.
- Sie können den Meta Sandbox-Post als eine Art Staging-Bereich verwenden. Die Antworten dort sind natürlich anders als hier und der Controller dort könnte veraltet sein.
- Da dies keine offizielle Stack-App ist , lädt der Controller möglicherweise keine Antworten mehr, wenn Sie ihn mehr als 300 Mal pro Tag neu starten.
Die "Fortsetzung" dieser Herausforderung: Block Building Bot Flocks!
Schnellzugriff
Fiddle Controller Vollbild Allgemeiner Chat Roter Chat (Blauer Chat?) SandboxPost
quelle
Antworten:
Blaues Team - SphiNotPi3000
Dieser Bot bildet ein Paar mit dem Bot von Sp3000 .
Die Grundidee ist, dass zwei nebeneinander positionierte Bots dabei helfen, die Schwächen des anderen zu verbergen, sodass keiner der Bots eine exponierte Seite hat. Dies schützt vor Bedrohungen und schränkt die Fluchtmöglichkeiten des Ziels ein.
Zu Beginn des Spiels navigieren sie aufeinander zu und bilden ein Paar. Dieses Paar bewegt sich dann als eine Einheit, wobei ein Bot den anderen anführt. Die beiden Bots haben fast den gleichen Code, sodass sie bei Bedarf Positionen und Rollen tauschen können.
Im Leerlauf bewegen sich die Bots auf dem Brett und suchen nach Feinden. Sobald sie einen Feind entdeckt haben, manövrieren sie sich vorsichtig in die richtigen Positionen, um anzugreifen. Ein sehr nettes Merkmal ist die Fähigkeit der Formation, sich horizontal gerade zu bewegen, indem die Bots abwechselnd platziert werden.
quelle
var
gibt, an dem nicht in diesem Beitrag und Sp3000 verwendet wird. Sie weisenj
sofort 0 zu und es stört den Controller überhaupt nicht, daher ist es in diesem Fall zum Glück kein Problem.Blaues Team - SphiNotPi3000
Dieser Bot bildet ein Paar mit PhiNotPis Bot . Im Beitrag von Phi finden Sie eine kurze Erklärung unserer Strategie.
quelle
Rotes Team - SucherBot
Die höchste Priorität von SeekerBot ist das Überleben. Daher werden nur Züge berücksichtigt, die nicht in Gefahr sind, in der nächsten Runde getötet zu werden (sofern solche Züge existieren).
Wenn keine Gegner in Sicht sind, bewegt es sich in einem Muster über das Schlachtfeld, wodurch sichergestellt wird, dass sich der größte Teil des Bodens regelmäßig in Sichtweite befindet.
Wenn der SeekerBot einen Feind entdeckt, bewegt er sich auf ihn zu. Wenn es einen Feind töten kann, tut es dies, solange der Zug sicher ist.
Wenn ein Feind nicht getötet werden kann, der Feind jedoch in der Lage ist, ihn in seinem nächsten Zug zu töten, versucht SeekerBot, den Feind zu einem Freund zu locken (sofern einer sichtbar ist). Wenn kein Teammitglied in Sicht ist, wird versucht, sich in eine Position zu bewegen, in der es den Feind in der nächsten Runde töten kann. Wenn dies nicht fünfmal hintereinander funktioniert, wechselt es die Taktik und bewegt sich in zufälliger Reihenfolge. In der nächsten Runde wird der Feind möglicherweise wieder angegriffen.
Für das, was es wert ist, verwendet es die ersten 7 Zeichen der Nachricht, um seine eigene Position im Format "x; y" (wobei x und y mit Nullen aufgefüllt sind) anzuzeigen.
Es ist sicherlich nicht der sauberste Code, aber es scheint zu tun, was ich von ihm erwartet habe.
quelle
Rote Mannschaft - Groomba
Anmerkungen in Kommentaren.
quelle
self
. Diese Variable ist reserviert, um auf zu zeigenwindow.self
. Verwenden SieI
stattdessen (capital i). Oderme
. Oder sogarmyself
.Rotes Team - Fauler Jäger
Dies ist das grundlegendste, was ich bekommen konnte.Dies ist nicht mehr 100% basisch.Es bewegt sich nur, wenn erforderlich .
Wenn ein Benutzer eine Nachricht mit zwei durch Komma getrennten Ziffern zwischen-1
und1
(z. B. :) sendet'1,0'
, wird sie dorthin verschoben. Es vertraut voll und ganz seinen Teamkollegen.Dies kommuniziert jetzt über JSON. Es hat eine sehr grundlegende Struktur:
Ein Beispiel für eine Nachricht zur Steuerung:
Welches wird senden:
Er ist auch ein bisschen egoistisch
und werde dir nicht helfenund jetzt ist er als stationäres Leuchtfeuer hilfreich.Wenn diese Meldung falsch ist (das Format stimmt nicht), fügen Sie
"}
stattdessen hinzu}
.Dies wurde nach dem 6-Stunden-Limit bearbeitet und nach dem 8 verlängert.
Es ist nicht mehr kaputt und wird als endgültige Version erhalten bleiben.
quelle
Rotes Team - Der Feigling
Dieser Bot bleibt stehen, um nicht so oft wie möglich entdeckt zu werden. Wenn ein oder mehrere Feinde in Sicht sind, können verschiedene Dinge passieren:
Kommuniziert mit niemandem, falls jemand ihn hören und nach ihm gehen könnte.
Es ist vielleicht nicht der nützlichste Bot für das Team, aber es hat Spaß gemacht, ihm zuzusehen, wie er versuchte, von allen wegzukommen.
quelle
Blaues Team - Adler
Ich bin im Moment ziemlich zufrieden mit meinem Bot. Es hat die folgenden Taktiken:
quelle
Blaues Team - Feindfresser
Dieses kleine Pixel sucht nach Enimens und versucht es zu fressen, wenn es kein Pixel enthält, das sich in eine zufällige Richtung bewegt. Ich freue mich darauf zu sehen, was sich andere Leute einfallen lassen.
quelle
Math.floor
nichtMath.float
!(Math.random() * 6) & 6
oder(Math.random() * 6) << 0
oder(Math.random() * 6) >> 0
(nützlich für Codegolf).Math.random() * 7
? Ich habe ein paar Testläufe versucht und es scheint, dass Ihr Bot nicht nach rechts unten geht. IIRCMath.random()
ist inklusive 0 und exklusive 1, was bedeutet, dass* 6
niemals tatsächlich 6 ist.Rotes Team - nervöses rotes Ladegerät
Red Charger bewegt sich nur nach links und rechts, in der Hoffnung, die Unfähigkeit von Blue Team auszunutzen, sich in diese Richtungen zu bewegen. Nachdem er eine Mauer erreicht hat, dreht er sich um und stürmt in die entgegengesetzte Richtung, in der Hoffnung, auf seinem Weg befindliche Bots blind zu zerstören.
EDIT: Red Charger hat gerade eine Gallone Energy-Drink getrunken und kann jetzt nicht aufhören zu zittern. Wir hoffen, dies auch zu seinem Vorteil zu nutzen. Es ist zu koffeinhaltig, um auf seine Teamkollegen zu hören, aber es schreit jede seiner Bewegungen aus.
quelle
Blaues Team - LazySoldier
quelle
JSON.parse
in einen Try / Catch-Block oder so setzen ... es verursacht viel zu viele Fehler.Blaues Team - Massenmörder
Ich denke, die Taktik ist ziemlich einfach. Ich zähle Feinde, die direkt von mir erreichbar sind (ich nehme an, es werden Tonnen von ihnen sein :)) und töte die größte Menge. Wenn es keine gibt, werde ich zumindest versuchen, mich abzuschirmen, indem ich über oder unter die größte Menge an Feinden trete, in der Hoffnung, sie im nächsten Schritt töten zu können.
Ich habe es aufgegeben, Mauern in Betracht zu ziehen, also ignoriere ich sie einfach. Es ist sowieso ziemlich lang.
Ich konnte diesen Code nicht testen / ausführen, daher wird es viele Fehler geben.
quelle
Blaues Team - Wachhund
Es bewegt sich zufällig, bis es einen Verbündeten ergreift, wenn dem so ist, folgt es ihm. Es versucht zu vermeiden, getötet zu werden und zu töten, wenn er kann. Entschuldigung für den schrecklichen Code, ich ging geradewegs und vergaß das Refactoring. Ich werde versuchen, die Lesbarkeit zu verbessern, wenn ich die Zeit habe :)
quelle
Rotes Team - Kommandant der Sucher
Dies ist eine Kopie von Minos 'SeekerBot mit einigen Modifikationen.
Komprimierter interner Speicher für eine bessere Nachrichtenverteilung
"$":[seekmode]
Liest feindliche Positionen von Verbündeten im JSON-Format von Lazy Slayer
"e":"[positions]"
. akzeptiert[positions]
Versatz durch beide32
und174
Meldet feindliche Positionen im JSON-Format
"e":"[positions]"
von Lazy Slayer, versetzt um174
Berichte, die zuletzt mit verschoben wurden
"m":[move]
, zeigen an, dass dieser Bot befohlen werden kannGibt Befehle an andere Bots aus, die verwenden
"[ally_id]":{"m":[move],"a":1,"id":29354}
. Der Befehl verwendet denselben Suchalgorithmus, außer an der Position des Verbündeten. Wenn andere Bots diese Befehle hören, sollten sie sich gruppieren und in einem Rudel jagen. Bestellungen werden nur erteilt, wenn die Nachricht von Verbündeten Folgendes enthält"m":
Folgt Befehlen von anderen Bots wie:
"29354":[move]
oder"29354":{"m":[move]
. Befehle werden nur ausgeführt, wenn sich keine Feinde in Reichweite befinden und keine anderen Verbündeten Feinde meldenquelle
""a":0,"o":[122,70],"m":0,"e":"f""
. Wenn Sie möchten, können Sie auch mit uns chatten .Rotes Team - BouncerBot
Mein Bot hüpft von Wand zu Wand (nicht genau, es deckt also einen anderen Boden ab) und sucht nach Feinden. Wenn es einen in Reichweite hat, greift es an, zieht sie gegen eine Wand und versucht, sie herauszunehmen (denken Sie an einen Türsteher in einem Club).
quelle
Rotes Team - SideKick
Mag es, Teamkollegen zu folgen, gut, dass es viele davon gibt!
quelle
Blaues Team - unentschlossener Magnet
Es hat mehrere Strategien: Wenn es einen Feind sofort schlagen kann, wird es dies tun, und es wird vor Gruppen von Feinden davonlaufen, wenn sie weit genug entfernt sind, sonst wird es kämpfen. Davon abgesehen sucht es nur nach Teammitgliedern und versucht ihnen zu folgen.
quelle
Blaues Team - Holen [38953]
[Änderungen: Es stellt sich heraus, dass es VIEL besser funktioniert, wenn ich meine tatsächliche ID und nicht -1 verwende!]
Ein dummer kleiner Bot, der um das Brett läuft und sein Bestes tut, um Aufmerksamkeit zu erregen und Verfolger anzuziehen. Dann rennt er in die Mitte, wo er (hoffentlich) jemanden findet, der ihm hilft, oder er blockiert einfach den Verfolger und stoppt ihn von der Jagd.
Scheint keinen großen Einfluss auf das Gesamtergebnis zu haben, da das Blue Tagteam so mächtig ist, aber zumindest habe ich es nicht noch schlimmer gemacht!
Schreien Sie in den nächsten 8 Stunden, wenn Sie möchten, dass ich meiner Nachricht etwas Nützliches hinzufüge.
quelle
Blaues Team - PatrolBot
Der Code ist sozusagen selbstdokumentierend. Dinge, die getan werden könnten, um PatrolBot zu verbessern
if (canBeKilled() || isInWall()) { moveToBetterPosition() }
Kurz vor der Rücksendung hinzufügen .quelle
BLAUES TEAM - 1 Punkt Genial
Die Prioritäten des Pixels:
Bei Zug 1 ist die Schwerkraft auf 64,64 eingestellt
Die Schwerkraft wird auf den nächstgelegenen feindlichen Ort eingestellt (um Pixel zum Ort des letzten Feindes zu leiten, falls der Feind entkommt).
Die Schwerkraft ändert sich zufällig, wenn das Pixel den Schwerpunkt erreicht hat oder sich dem Rand nähert
quelle
Rot - LoyalFollower [15080]
Versucht Minos zu finden und Gegner zu töten. Leider verliert die rote Mannschaft immer noch, vielleicht weil wir weniger Spieler sind ...
quelle
Blaues Team - MiddleMan
MiddleMan ist der Zwillingsbruder von WallFlower (den er ersetzt hat). Wie sein Bruder neigt er nicht dazu, ein sozialer Typ zu sein. Er würde lieber mitten im Raum rumhängen, zuschauen und warten. Aber das heißt nicht, dass er passiv oder schüchtern ist. Wenn er auf seinem Platz oder auf dem Weg dorthin einen Feind findet, greift er an, egal wie groß er ist. Da er weiß, dass es Stärke in Zahlen gibt, zieht er sie gerne zu seinen Teamkollegen oder alternativ zum Zentrum, um andere zu finden. Sobald sein Geschäft erledigt ist, kehrt er zu seinem Platz zurück und ist bereit für die nächste Gelegenheit, seinem Team zu helfen.
Vorsicht, rotes Team. Obwohl er nicht viel zu sein scheint, ist er so heftig und hartnäckig wie sie kommen; ein Meister des Nahkampfs. Er kann nicht direkt mit seinem Team kommunizieren, aber er erkennt sie an und wird zusammenarbeiten, um den gemeinsamen Feind zu besiegen. Er hat kürzlich gelernt, wie man Nachrichten sendet, obwohl er selbst nicht auf jemanden hört, nur nicht auf seinen Stil. Das Format ist eine JSON-Zeichenfolge, die ein Array wie das folgende enthält:
[[selfX,selfY],[[enemy1X,enemy1Y],[enemy2X,enemy2Y]]]
usw. für weitere Gegner.quelle
Blue Team - VersaBot, ein polymorpher Motor
Mein Code folgt automatisch dem nächsten Bot in der Nähe und bietet zusätzliche Feuerkraft und Schutz.
Genießen!
quelle