Dies ist ein Spiel, in dem die Flagge gefangen genommen wird, das stark inspiriert ist und auf Rot-Blau-Pixel-Team-Battlebots basiert . Das war eine großartige Frage (vielen Dank an Calvin'sHobbies; ich hoffe, es macht Ihnen nichts aus, dass ich Ihnen schamlos eine Menge Code gestohlen habe) - hier ist ein weiteres Team, das auf King-of-the-Hill basiert. Hoffentlich erfordert die Eroberung der Flagge mehr Teamzusammenarbeit sowie mehr Strategie.
Um es zu verwechseln, werden Sie im roten Team berücksichtigt, wenn die letzte Ziffer Ihrer ID zwischen 0
und 4
einschließlich liegt. Dies sollte verhindern, dass genau dieselben Teams erneut gegeneinander antreten, wenn dieselben Personen antworten. Der Vorstand ist 350px
von 350px
. Das blaue Team startet in der oberen Hälfte des Bretts und das rote Team startet in der unteren Hälfte.
Die Art und Weise, wie Sie spielen, um die Flagge zu erobern, ist folgende: Ziel des Spiels ist es, die Flagge des gegnerischen Teams zu nehmen und sie auf Ihre eigene Seite zurückzubringen. Wenn Sie auf ihrer Seite sind, können Sie markiert und ins Gefängnis geschickt werden. Wenn Sie im Gefängnis sind, können Sie sich nicht bewegen. Wenn Sie auf Ihrer Seite sind, besteht Ihre Aufgabe darin, gegnerische Teammitglieder zu markieren, um sie ins Gefängnis zu schicken. Die einzige Möglichkeit, aus dem Gefängnis auszusteigen, besteht für jemanden in Ihrem Team, dem es freisteht, alle im Gefängnis zu markieren. (Beachten Sie, dass sich das Gefängnis auf der Seite des gegnerischen Teams befindet.)
Speziell:
- Es gibt eine Konstante -
FIELD_PADDING
-, die auf 20 gesetzt ist. Dies ist die Auffüllung für das Feld. Wenn es Null wäre, wären die Flaggen und das Gefängnis genau in den Ecken der Leinwand. Da dies nicht der Fall ist, sind die Flagge und das Gefängnis 20 Pixel von den Ecken entfernt. - Die blaue Flagge (denken Sie daran: Das blaue Team befindet sich in der oberen Hälfte) befindet sich z.
(WIDTH - FIELD_PADDING, FIELD_PADDING) = (330, 20)
B. in der rechten oberen Ecke. - Die rote Fahne ist bei
(FIELD_PADDING, HEIGHT - FIELD_PADDING) = (20, 330)
- Das blaue Gefängnis (in dem rote Mitglieder untergebracht sind) befindet sich
(20, 20)
oben links auf der blauen Seite. - Das rote Gefängnis, in dem blaue Mitglieder untergebracht sind, befindet sich in
(330, 330)
Jedes Teammitglied startet zufällig an einer Position 45 < x < 305
und 45 < y < 175
für Blau und 175 < y < 305
für Rot. Kein Teammitglied kann innerhalb der DEFENSE_RADIUS = 25
Pixel seiner eigenen Flagge oder seines eigenen Gefängnisses gehen (es sei denn, Ihre eigene Flagge wurde von einem gegnerischen Bot erbeutet. In diesem Fall müssen Sie diesen Bot markieren). Dies soll verhindern, dass Welpen wie Bots bewacht werden. Wenn Sie in diesen Bereich gehen, werden Sie "zurückgedrängt". Ebenso kann kein Teammitglied die Grenzen überschreiten (weniger als null oder mehr als 350) - wenn Sie dies tun, werden Sie an den nächstgelegenen legalen Ort zurückgeschoben, an dem Sie sein können.
Jedes Mal, wenn Sie sich bewegen, verbrauchen Sie strength
. Ihr strength
fängt um an 20
und wird von 2
jeder Runde aufgefüllt . Die Stärke, die Sie verwenden, entspricht der zurückgelegten Strecke. Wenn Ihre Stärke durch das Bewegen zu einem bestimmten Ort negativ wird, können Sie diesen Zug nicht ausführen. Es ist wahrscheinlich eine gute Idee, einfach mit 2
normaler Geschwindigkeit zu jagen. Sie sollten höhere Geschwindigkeiten nur verwenden, wenn Sie kurz vor dem Sieg stehen und die zusätzliche Geschwindigkeit benötigen (meiner Meinung nach).
Spec :
Die Spezifikation ist der Pixel Team Battlebots-Frage ziemlich ähnlich. Sie sollten einen Codeblock (denken Sie daran, keine globalen Variablen) in Javascript schreiben. Es sollte ein Objekt mit einem x
-Wert und einem y
-Wert zurückgeben, die Ihre Änderung von x- und y-Werten darstellen. Die folgende Antwort:
return {
x: 0,
y: -2
};
bewegt sich immer nach oben, bis es gegen eine Wand stößt. Sie dürfen 8 Stunden nach dem Posten keine Änderungen vornehmen (mit Ausnahme von LegionMammal98, die dachten, dass der Controller seinen Code nicht geladen und nicht getestet hat) . Sie haben Zugriff auf die folgenden Variablen in Ihrem Code:
this
- Sie selbst als Spieler (siehe unten, was Spieler sind)move
- die runde Zahl, beginnend mit 0tJailed
- Eine Reihe von Spielern in Ihrem Team, die inhaftiert sindeJailed
- Eine Reihe aller Spieler der gegnerischen Mannschaft, die inhaftiert sindteam
- Eine Reihe von Spielern in Ihrem Team, nicht nur die in Ihrer Näheenemies
- Eine Reihe aller Spieler der anderen Mannschaft, NICHT nur der in Ihrer NähetFlag
- deine Flagge (du versuchst sie zu schützen)eFlag
- die andere Flagge (du versuchst sie zu stehlen)messages
- unten erklärt- Eine Liste von Konstanten:
WIDTH = 350
,HEIGHT = 350
,FIELD_PADDING = 20
,DEFENSE_RADIUS = 25
.
Jeder "Spieler" ist ein Objekt mit folgenden Eigenschaften:
x
undy
strength
id
isJailed
- wahr, wenn der Spieler im Gefängnis ist
Jede Flagge hat folgende Eigenschaften:
x
undy
pickedUpBy
- der Spieler, der aktuell die Flagge hat, oder null, wenn kein Spieler die Flagge hat.
Nun messages
ist ein Objekt, das unter Ihren Teamkollegen geteilt wird. Es ist mir egal, was du damit machst. Das gleiche Objekt wird gemeinsam genutzt und an alle Teammitglieder weitergegeben. Nur so können Sie kommunizieren. Sie können Eigenschaften anhängen, Objekte freigeben usw. Es kann so groß sein, wie Sie möchten - ohne Größenbeschränkung.
In jeder Runde passiert folgendes:
- Die Liste der Spieler (rot und blau) wird nach dem Zufallsprinzip in die richtige Reihenfolge gebracht.
- Jeder Spieler macht einen Zug.
- Wenn ein rotes Teammitglied ein blaues Teammitglied auf der roten Seite berührt (innerhalb von 10 Pixeln), schicke es ins Gefängnis und umgekehrt. Ein eingesperrter Spieler lässt seine Flagge fallen und die Stärke sinkt auf Null. Beachten Sie, dass die Schrittfunktion (der von Ihnen bereitgestellte Code) weiterhin aufgerufen wird. Sie können also Nachrichten abrufen / setzen, sich jedoch nicht im Gefängnis bewegen.
- Wenn ein Spieler die andere Flagge berührt (innerhalb von 10 Pixeln), wird die andere Flagge von diesem Spieler als "aufgenommen" markiert. Wenn sich der Spieler bewegt, bewegt sich die Flagge - bis der Spieler markiert ist und ins Gefängnis geht, das heißt.
- Wenn ein Spieler das Gefängnis der anderen Seite berührt, befreie alle in diesem Gefängnis. Wenn ein Spieler aus dem Gefängnis entlassen wird, wird er an einen zufälligen Ort auf seiner Seite teleportiert.
Hinweise:
- Zumindest beim regulären Erobern der Flagge funktionieren Angriffe viel besser, wenn viele Spieler gleichzeitig angreifen, da sie die Verteidiger eher verwirren, welchen Spielern sie nachjagen sollten.
- In ähnlicher Weise möchten Verteidiger möglicherweise koordinieren, wem sie nachjagen, damit Angriffe nicht durchgehen
Stack-Snippet:
window.onload=function(){(function(){function p(a,b,c,e){return Math.sqrt((a-c)*(a-c)+(b-e)*(b-e))}function l(a,b){this.x=this.y=0;this.id=a.id;this.title=a.title+" ["+this.id+"]";this.link=a.link||"javascript:;";this.team=b;this.isJailed=!1;this.flag=null;this.moveFn=new Function("move","tJailed","eJailed","team","enemies","tFlag","eFlag","messages","WIDTH","HEIGHT","FIELD_PADDING","DEFENSE_RADIUS",a.code);this.init()}function x(a,b){return Math.floor(Math.random()*(b-a))+a}function q(a,b){this.startX=this.x=a;this.startY=
this.y=b;this.following=null}function t(a,b){return a===e&&b||a===h&&!b?{x:20,y:20}:{x:g.width-20,y:g.height-20}}function y(){var a,b=$("#redTeam"),c=$("#blueTeam");for(a=0;a<e.length;++a)e[a].addToDiv(b);for(a=0;a<h.length;++a)h[a].addToDiv(c)}function z(){d.clearRect(0,0,g.width,g.height);d.beginPath();d.moveTo(0,g.height/2);d.lineTo(g.width,g.height/2);d.stroke();var a=e.concat(h),b,c;for(b=a.length-1;0<b;b--){c=Math.floor(Math.random()*(b+1));var f=a[b];a[b]=a[c];a[c]=f}for(b=0;b<a.length;++b)a[b].step(u);
for(b=0;b<e.length;++b)for(c=0;c<h.length;++c)10>p(e[b].x,e[b].y,h[c].x,h[c].y)&&(e[b].y<g.height/2&&e[b].goToJail(),h[c].y>g.height/2&&h[c].goToJail());for(b=0;b<a.length;++b)c=a[b].team===e!==!0?m:n,!c.following&&10>p(a[b].x,a[b].y,c.x,c.y)&&(c.following=a[b]);for(b=0;b<a.length;++b)if(c=t(a[b].team,!0),!a[b].isJailed&&10>p(a[b].x,a[b].y,c.x,c.y))for(c=a[b].team,f=0;f<c.length;++f)c[f].isJailed&&(c[f].isJailed=!1,c[f].init());m.follow();n.follow();b=m.y<g.height/2;c=n.y>g.height/2;b&&c&&alert("EXACT TIE!!!! This is very unlikely to happen.");
b&&!c&&(alert("Blue wins!"),$("#playpause").click().hide());c&&!b&&(alert("Red wins!"),$("#playpause").click().hide());for(b=0;b<a.length;++b)a[b].draw(d);m.draw("red");n.draw("blue");u++}$.ajaxSetup({cache:!1});var e=[],h=[],g=$("canvas")[0],d=g.getContext("2d"),v,u=0,m={},n={},r=!0,A={},B={},w;l.prototype.init=function(){this.x=x(45,g.width-45);this.y=x(45,g.height/2);this.team===e&&(this.y+=g.height/2);this.strength=20};l.prototype.makeShallowCopy=function(){return{x:this.x,y:this.y,strength:this.strength,
id:this.id,isJailed:this.isJailed}};l.prototype.goToJail=function(){this.isJailed=!0;var a=this.team===e!==!0?m:n;(this.team===e!==!0?m:n).following===this&&(a.following=null);a=t(this.team,!0);this.x=a.x;this.y=a.y;this.strength=0};l.prototype.step=function(a){function b(a,b,c){var e,d,f;for(e=0;e<a.length;++e)d=a[e],d!==C&&(f=d.makeShallowCopy(),d.isJailed?b.push(f):c.push(f))}var c=[],f=[],d=[],k=[],l=this.team===e?h:e,C=this,q=this.team===e?m:n,r=this.team===e?n:m;b(this.team,c,d);b(l,f,k);f=
this.moveFn.call(this.makeShallowCopy(),a,c,f,d,k,q.copy(),r.copy(),this.team===e?A:B,g.width,g.height,20,25);"object"===typeof f&&"number"===typeof f.x&&"number"===typeof f.y&&(d=p(0,0,f.x,f.y),a=t(this.team,!1),c=this.team===e!==!1?m:n,d<=this.strength&&(this.strength-=d,this.x+=f.x,this.y+=f.y,0>this.x&&(this.x=0),0>this.y&&(this.y=0),this.x>g.width&&(this.x=g.width),this.y>g.height&&(this.y=g.height),f=p(this.x,this.y,c.x,c.y),d=p(this.x,this.y,a.x,a.y),25>f&&null===c.following&&(this.x=25*(this.x-
c.x)/f*1.3+c.x,this.y=25*(this.y-c.y)/f*1.3+c.y),25>d&&(this.x=25*(this.x-a.x)/d*1.3+a.x,this.y=25*(this.y-a.y)/d*1.3+a.y)),this.isJailed||(this.strength+=2),20<this.strength&&(this.strength=20))};l.prototype.addToDiv=function(a){var b=$("<option>").text(this.title).val(this.id);a.find(".playersContainer").append(b)};l.prototype.draw=function(a){a.fillStyle=this.team===e?"red":"blue";a.beginPath();a.arc(this.x,this.y,5,0,2*Math.PI,!0);a.fill();!this.isJailed&&$("#labels").is(":checked")&&a.fillText(this.title,
this.x+5,this.y+10)};q.prototype.draw=function(a){d.strokeStyle=a;d.beginPath();d.arc(this.x,this.y,5,0,2*Math.PI,!0);d.stroke();d.fillStyle=a;d.strokeRect(this.x-2,this.y-2,4,2);d.beginPath();d.moveTo(this.x-2,this.y);d.lineTo(this.x-2,this.y+3);d.stroke()};q.prototype.copy=function(){return{x:this.x,y:this.y,pickedUpBy:this.following&&this.following.makeShallowCopy()}};q.prototype.follow=function(){null!==this.following&&(this.x=this.following.x,this.y=this.following.y)};$("#newgame").click(function(){function a(a,
b){w?b(w):$.get("https://api.stackexchange.com/2.2/questions/"+(49028).toString()+"/answers",{page:a.toString(),pagesize:100,order:"asc",sort:"creation",site:"codegolf",filter:"!JDuPcYJfXobC6I9Y-*EgYWAe3jP_HxmEee"},b,"json")}function b(g){w=g;g.items.forEach(function(a){function b(a){return $("<textarea>").html(a).text()}var d=4>=a.owner.user_id%10?e:h;a.owner.display_name=b(a.owner.display_name);if(!(a.hasOwnProperty("last_edit_date")&&28800<a.last_edit_date-a.creation_date&&33208!==a.owner.user_id||
-1<p.indexOf(a.owner.user_id))){p.push(a.owner.user_id);var g=c.exec(a.body);if(!(null===g||1>=g.length)){var f={};f.id=a.owner.user_id;f.title=a.owner.display_name;f.code=b(g[1]);f.link=a.link;d.push(new l(f,d))}}});g.has_more?a(++d,b):(console.log("Red team",e),console.log("Blue team",h),y(),clearInterval(v),r=!0,$("#playpause").show().click())}var c=/<pre><code>((?:\n|.)*?)\n<\/code><\/pre>/,d=1,p=[];e=[];h=[];u=0;m=new q(20,g.height-20);n=new q(g.width-20,20);$(".teamColumn select").empty();var k=
$("#testbotCode").val();0<k.length&&(console.log("Using test entry"),k={title:"TEST ENTRY",link:"javascript:;",code:k},$("#testbotIsRed").is(":checked")&&(k.id=-1,e.push(new l(k,e)),k.id=-3,e.push(new l(k,e))),$("#testbotIsBlue").is(":checked")&&(k.id=-2,h.push(new l(k,h)),k.id=-4,h.push(new l(k,h))));a(1,b)});$("#playpause").hide().click(function(){r?(v=setInterval(z,25),$(this).text("Pause")):(clearInterval(v),$(this).text("Play"));r=!r})})();}
#main{padding:10px;text-align:center}#testbot{padding:10px;clear:both}.teamColumn{width:25%;padding:0 10px;border:3px solid;border-color:#000;text-align:center;height:500px;overflow:scroll;white-space:nowrap}.playersContainer p{padding:0;margin:0}#redTeam{float:left;border-color:red;color:red;background-color:#fee}#blueTeam{float:right;border-color:#00f;color:#00f;background-color:#fee}#arena{display:inline-block;width:40%;text-align:center}canvas{border:1px solid #000}select{width:100%}
<script src=https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js></script><div id=main><div class=teamColumn id=redTeam><h1>Red Team</h1><select size=20 class=playersContainer></select></div><div id=arena><h1>Battlefield</h1><canvas width=350 height=350></canvas></div><div class=teamColumn id=blueTeam><h1>Blue Team</h1><select size=20 class=playersContainer></select></div><div id=loadingInfo><button id=newgame>New Game</button> <button id=playpause>Play</button><br><input type=checkbox id="labels"> Show labels</div></div><div id=testbot><textarea id=testbotCode placeholder="testbot code"></textarea><br><input type=checkbox id="testbotIsRed">Red Team<br><input type=checkbox id="testbotIsBlue">Blue Team<br></div>
Controller: http://jsfiddle.net/prankol57/4L7fdmkk/
Vollbild-Controller: http://jsfiddle.net/prankol57/4L7fdmkk/embedded/result/
Lassen Sie mich wissen, ob der Controller Fehler enthält.
Hinweis: Wenn Sie zum Controller gehen und glauben, dass er nichts lädt, drücken Sie "Neues Spiel". Es wird erst geladen, nachdem Sie auf "Neues Spiel" geklickt haben, damit alle Bots und möglichen Testbots gleichzeitig geladen werden können.
Viel Glück.
Wenn jemand ein Beispielspiel sehen möchte, habe ich einen Beispiel-Bot erstellt, den Sie kopieren und in das Textfeld "Testbot" einfügen können.
var r2 = Math.sqrt(2);
if (this.id === -1) {
// red team 1
// go after flag regardless of what is going on
if (eFlag.pickedUpBy !== null && eFlag.pickedUpBy.id === this.id) {
return {
x: 0,
y: 2
};
}
return {
x: this.x < eFlag.x ? r2 : -r2,
y: this.y < eFlag.y ? r2 : -r2
};
}
if (this.id === -2) {
// blue team 1
// a) go after opposing team members on your side b) get the other flag if no enemies on your side
var closestEnemy = null;
for (var i = 0; i < enemies.length; ++i) {
if (enemies[i].y < HEIGHT/2 && (closestEnemy === null || enemies[i].y < closestEnemy.y)) {
closestEnemy = enemies[i];
}
}
if (closestEnemy !== null) {
return {
x: this.x < closestEnemy.x ? r2 : -r2,
y: this.y < closestEnemy.y ? r2 : -r2
};
}
if (eFlag.pickedUpBy !== null && eFlag.pickedUpBy.id === this.id) {
return {
x: 0,
y: -2
};
}
return {
x: this.x < eFlag.x ? r2 : -r2,
y: this.y < eFlag.y ? r2 : -r2
};
}
if (this.id === -3) {
// red team 2
// a) defend the flag b) if at least half of enemies in jail and no enemies on this side, free jailed reds and quickly return
var closestEnemy = null;
for (var i = 0; i < enemies.length; ++i) {
if (enemies[i].y > HEIGHT/2 && (closestEnemy === null || enemies[i].y > closestEnemy.y)) {
closestEnemy = enemies[i];
}
}
if (closestEnemy !== null) {
return {
x: this.x < closestEnemy.x ? r2 : -r2,
y: this.y < closestEnemy.y ? r2 : -r2
};
}
if (enemies.length / eJailed.length <= 1 && tJailed.length > 0) {
return {
x: this.x < FIELD_PADDING ? r2 : -r2,
y: this.y < FIELD_PADDING ? r2 : -r2
};
}
if (this.y < 350/2) return {x: 0, y: 2};
return {
x: this.x < tFlag.x ? r2 : -r2,
y: this.y < tFlag.y ? r2 : -r2
};
}
if (this.id === -4) {
// blue team 2
// a) try freeing jail if there are jailed team members b) capture the flag
if (tJailed.length > 0) {
return {
x: this.x < WIDTH - FIELD_PADDING ? r2 : -r2,
y: this.y < HEIGHT - FIELD_PADDING ? r2 : -r2
};
}
if (eFlag.pickedUpBy !== null && eFlag.pickedUpBy.id === this.id) {
return {
x: 0,
y: -2
};
}
return {
x: this.x < eFlag.x ? r2 : -r2,
y: this.y < eFlag.y ? r2 : -r2
};
}