Bu, bayrak esir alma oyunudur, büyük ilhamdan esinlenilmiştir ve Red vs. Blue - Pixel Team Battlebots'a dayanır . Bu harika bir soruydu (çok teşekkür ederim Calvin'sHobbies; Umarım senden çok fazla kod utanmadan çaldığımı umursamıyorsun) - işte başka bir takım tabanlı tepenin kralı. Umarım bayrağı yakalamak daha fazla takım işbirliğinin yanı sıra daha fazla strateji gerektirir.
Karıştırmak için, kimliğinizin son basamağı arasında 0
ve 4
kapsayıcıysa kırmızı takımda değerlendirilirsiniz . Bu, aynı kişiler cevap vermeye karar verirse, aynı takımların tekrar savaşmasını engellemelidir. Yönetim kurulu 350px
tarafından 350px
. Mavi takım tahtanın üst yarısında başlar ve kırmızı takım alt yarısında başlar.
Bayrağı ele geçirme şekliniz şu şekildedir: Oyunun amacı rakip takımın bayrağını alıp kendi tarafınıza geri getirmektir. Onların yanındaysanız, etiketlenebilir ve hapse gönderilebilirsiniz. Hapisteyseniz, hareket edemezsiniz. Sizin tarafınızdaysanız, işiniz rakip ekip üyelerini onları hapse göndermek için etiketlemektir. Hapisten çıkmanın tek yolu, ekibinizdeki herkesi hapiste etiketlemekte özgür olan kişiler içindir. (Hapishanenin karşı takım tarafında yer aldığını unutmayın).
özellikle:
- Sabit -
FIELD_PADDING
- 20 olarak ayarlanmıştır. Bu alanın doldurulmasıdır. Sıfır olsaydı, bayraklar ve hapishane tam olarak tuvalin köşelerinde olurdu. Olmadığı için, bayrak ve hapishane köşelerden 20 piksel uzakta. - Mavi bayrak (unutmayın: mavi takım üst yarıdadır)
(WIDTH - FIELD_PADDING, FIELD_PADDING) = (330, 20)
yani sağ üst köşede bulunur. - Kırmızı bayrak
(FIELD_PADDING, HEIGHT - FIELD_PADDING) = (20, 330)
- Mavi hapishane (kırmızı üyelerin tutulduğu yer)
(20, 20)
yani mavi tarafta, sol üstte. - Mavi üyelerin tutulduğu kırmızı hapishane
(330, 330)
Her takım üyesi rastgele bir konumda başlayan 45 < x < 305
ve 45 < y < 175
mavi ve 175 < y < 305
kırmızı için. Hiçbir takım üyesi DEFENSE_RADIUS = 25
kendi bayrağının pikselleri veya kendi hapishanelerinin içine giremez (tabii ki kendi bayrağınız zıt bir bot tarafından alınmadıkça, bu durumda o botu etiketlemeniz gerekir). Bu, botlar gibi köpeklerin korunmasını önlemek içindir. Eğer o aralığa girerseniz, geri itilirsiniz. Benzer şekilde, hiçbir ekip üyesi sınır dışına çıkamaz (sıfırdan az veya 350'den fazla) - eğer yaparsanız, olabileceğiniz en yakın yasal yere geri itilirsiniz.
Her hareket ettiğinde, tükeniyorsun strength
. Başlangıç strength
saatiniz başlar 20
ve 2
her turda yenilenir . Kullandığınız güç miktarı seyahat ettiğiniz mesafeye eşittir. Eğer gücünüz belli bir yere taşınarak negatif hale gelirse, o hareketi yapmanız engellenir. Muhtemelen 2
normal kovalamaca hızlanmak iyi bir fikirdir . Daha yüksek hızları sadece kazanmaya yakınsanız ve ekstra hıza ihtiyacınız varsa kullanmalısınız (bence).
Spec :
Spesifikasyon, Pixel Team Battlebots sorusuna oldukça benziyor. Javascript bir kod bloğu yazmalısınız (unutmayın, global değişken yok). x
X'teki ve y
y değerlerindeki değişikliği temsil eden bir -value ve -value değerine sahip bir nesne döndürmelidir . Aşağıdaki cevap:
return {
x: 0,
y: -2
};
her zaman duvara çarpana kadar yukarı hareket eder. Gönderdikten sonra 8 saat düzenleyemezsiniz (denetleyicinin kodunu yüklemediğini ve test etmediğini düşünen LegionMammal98 hariç) . Kodunuzda aşağıdaki değişkenlere erişiminiz var:
this
- kendiniz, bir oyuncu olarak (oyuncuların ne olduğu için aşağıya bakın)move
- 0'dan başlayan yuvarlak sayıtJailed
- ekibinizdeki hapisteki tüm oyuncular dizisieJailed
- rakip takımdaki hapisteki tüm oyuncular dizisiteam
- ekibinizdeki tüm oyuncular dizisi, sadece yakınınızdakiler değilenemies
- sadece yakınınızdakiler DEĞİL, diğer takımdaki tüm oyunculardan oluşan bir dizitFlag
- bayrağınız (onu korumaya çalışıyorsunuz)eFlag
- diğer bayrak (çalmaya çalışıyorsun)messages
- aşağıda açıklanmıştır- Sabitler listesi:
WIDTH = 350
,HEIGHT = 350
,FIELD_PADDING = 20
,DEFENSE_RADIUS = 25
.
Her "oynatıcı" aşağıdaki özelliklere sahip bir nesnedir:
x
vey
strength
id
isJailed
- oyuncu hapiste ise doğru
Her bayrak aşağıdaki özelliklere sahiptir:
x
vey
pickedUpBy
- şu anda bayrağa sahip olan oyuncu veya bayrağa sahip olmayan oyuncu null.
Şimdi, messages
takım arkadaşlarınız arasında paylaşılan bir nesne. Onunla ne yaptığın umrumda değil. Aynı nesne paylaşılır ve ekip üyelerinizin her birine iletilir. İletişim kurmanın tek yolu budur. Ona özellikler ekleyebilir, nesneleri paylaşabilir, vb. İstediğiniz kadar büyük olabilir - boyut sınırı yoktur.
Her dönüşte şunlar olur:
- Oyuncu listesi (hem kırmızı hem de mavi) dönüş sırası için rastgele karıştırılır.
- Her oyuncu bir hamle yapar.
- Kırmızı takım üyelerinden herhangi biri kırmızı taraftaki mavi takım üyelerine dokunursa (10 piksel içinde), mavi takım üyelerini hapse gönderir veya bunun tersi de geçerlidir. Hapisteki bir oyuncu bayrağını düşürür ve gücü sıfıra düşer. Adım işlevinin (sağladığınız kod) hala çağrıldığını unutmayın - böylece iletileri alabilir / ayarlayabilirsiniz, ancak hapishanedeyken hareket edemezsiniz.
- Herhangi bir oyuncu diğer bayrağa dokunuyorsa (10 piksel içinde), o zaman diğer bayrak o oyuncu tarafından "alındı" olarak işaretlenir. Oyuncu hareket ettiğinde, bayrak hareket eder - oyuncu etiketlenene ve hapse girene kadar.
- Herhangi bir oyuncu diğer tarafın hapishanesine dokunuyorsa, o hapisteki herkesi serbest bırakın. Bir oyuncu hapisten kurtulduğunda, yanında rastgele bir yere ışınlanır.
İpuçları:
- En azından bayrağı düzenli olarak ele geçirirken, birçok oyuncu aynı anda gittiğinde saldırılar çok daha iyi çalışır, çünkü savunucuları hangi oyuncuyu kovalamaları gerektiği konusunda karıştırır.
- Benzer şekilde, savunmacılar kovaladıkları kişileri koordine etmek isteyebilir, böylece saldırılar gerçekleşmez
Yığın snippet'i:
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>
Denetleyici: http://jsfiddle.net/prankol57/4L7fdmkk/
Tam ekran denetleyicisi: http://jsfiddle.net/prankol57/4L7fdmkk/embedded/result/
Denetleyicide herhangi bir hata olup olmadığını bana bildirin.
Not: Denetleyiciye gidip hiçbir şey yüklemediğini düşünüyorsanız, "Yeni Oyun" a basın. Sadece "Yeni Oyun" a bastıktan sonra her şeyi yükler, böylece tüm botları ve olası test botlarını aynı anda yükleyebilir.
İyi şanslar.
Birisi örnek bir oyun görmek isterse, kopyalayıp "testbot" metin alanına yapıştırabileceğiniz bir örnek bot yaptım (testbot her takımda iki kopya oluşturur; hem kırmızı takımı hem de mavi takımı kontrol edin):
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
};
}