Ini adalah permainan untuk menangkap bendera, sangat terinspirasi dan didasarkan dari Merah atau Biru - Pixel Team Battlebots . Itu adalah pertanyaan yang luar biasa (terima kasih banyak Calvin Hobi; Saya harap Anda tidak keberatan bahwa saya tanpa malu mencuri banyak kode dari Anda) - inilah tim lain yang berbasis di king-of-the-hill. Mudah-mudahan, menangkap bendera akan membutuhkan lebih banyak kerja sama tim serta lebih banyak strategi.
Untuk mencampuradukkannya, Anda dianggap sebagai tim merah jika digit terakhir id Anda berada di antara 0dan 4inklusif. Ini harus mencegah tim yang sama persis dari bertarung lagi, jika orang yang sama memutuskan untuk menjawab. Dewan 350pxoleh 350px. Tim biru mulai di bagian atas papan dan tim merah mulai di bagian bawah.
Cara Anda bermain menangkap bendera adalah sebagai berikut: tujuan permainan adalah untuk mengambil bendera tim lawan dan membawanya kembali ke sisi Anda sendiri. Jika Anda berada di pihak mereka, Anda dapat ditandai dan dikirim ke penjara. Jika Anda berada di penjara, maka Anda tidak bisa bergerak. Jika Anda berada di pihak Anda, tugas Anda adalah menandai anggota tim lawan untuk mengirim mereka ke penjara. Satu-satunya cara untuk keluar dari penjara adalah untuk seseorang di tim Anda yang bebas untuk menandai semua orang di penjara. (Perhatikan bahwa penjara terletak di sisi tim lawan).
Secara khusus:
- Ada konstan -
FIELD_PADDING- set ke 20. Ini adalah bantalan untuk bidang. Jika nol, maka bendera dan penjara akan persis di sudut kanvas. Karena tidak, bendera dan penjara berjarak 20 piksel dari sudut. - Bendera biru (ingat: tim biru ada di bagian atas) terletak di
(WIDTH - FIELD_PADDING, FIELD_PADDING) = (330, 20)sudut kanan atas yaitu. - Bendera merah di
(FIELD_PADDING, HEIGHT - FIELD_PADDING) = (20, 330) - Penjara biru (tempat anggota merah disimpan) berada di
(20, 20)sisi biru, kiri atas. - Penjara merah, tempat anggota biru disimpan, berada di
(330, 330)
Setiap anggota tim mulai secara acak di posisi 45 < x < 305dan 45 < y < 175untuk biru dan 175 < y < 305merah. Tidak ada anggota tim yang bisa masuk dalam DEFENSE_RADIUS = 25piksel bendera mereka sendiri atau penjara mereka sendiri (kecuali, tentu saja, bendera Anda sendiri diambil oleh bot lawan, dalam hal ini Anda perlu memberi tag pada bot itu). Ini untuk mencegah anak anjing menjaga seperti bot. Jika Anda masuk dalam kisaran itu, Anda "didorong" kembali. Demikian pula, tidak ada anggota tim yang dapat keluar dari batasan (kurang dari nol atau lebih dari 350) - jika Anda melakukannya, Anda didorong kembali ke tempat legal terdekat.
Setiap kali Anda bergerak, Anda menggunakan strength. Anda strengthmulai pada 20dan diisi ulang oleh 2setiap belokan. Jumlah kekuatan yang Anda gunakan sama dengan jarak yang Anda tempuh. Jika kekuatan Anda akan menjadi negatif dengan pindah ke tempat tertentu, Anda dicegah untuk melakukan gerakan itu. Mungkin ide yang bagus 2untuk mengejar kecepatan normal. Anda hanya harus menggunakan kecepatan yang lebih tinggi jika Anda hampir menang dan membutuhkan kecepatan ekstra (menurut saya).
Spesifikasi :
Spesifikasi ini sangat mirip dengan pertanyaan Pixel Team Battlebots. Anda harus menulis blok kode (ingat, tidak ada variabel global) dalam javascript. Ini harus mengembalikan objek dengan x-value dan y-value mewakili perubahan Anda dalam x dan perubahan dalam nilai y. Jawaban berikut:
return {
x: 0,
y: -2
};
selalu bergerak ke atas, hingga menyentuh dinding. Anda tidak boleh mengedit 8 jam setelah posting (kecuali untuk LegionMammal98 yang berpikir bahwa controller tidak memuat kode-nya dan tidak menguji) . Anda memiliki akses ke variabel berikut dalam kode Anda:
this- diri Anda sendiri, sebagai pemain (lihat apa pemain di bawah ini)move- angka bulat, mulai dari 0tJailed- Array semua pemain di tim Anda yang dipenjaraeJailed- Array semua pemain di tim lawan yang dipenjarateam- Array semua pemain di tim Anda, BUKAN hanya yang di dekat Andaenemies- Array semua pemain di tim lain, BUKAN hanya yang di dekat AndatFlag- Bendera Anda (Anda berusaha melindunginya)eFlag- bendera lainnya (Anda mencoba mencurinya)messages- dijelaskan di bawah ini- Daftar konstanta:
WIDTH = 350,HEIGHT = 350,FIELD_PADDING = 20,DEFENSE_RADIUS = 25.
Setiap "pemain" adalah objek dengan properti berikut:
xdanystrengthidisJailed- benar jika pemain ada di penjara
Setiap bendera memiliki properti berikut:
xdanypickedUpBy- pemain yang saat ini memiliki bendera, atau nol jika tidak ada pemain yang memiliki bendera.
Sekarang, messagesadalah objek yang dibagikan di antara rekan satu tim Anda. Saya tidak peduli apa yang Anda lakukan dengan itu. Objek yang sama dibagikan dan diteruskan ke setiap anggota tim Anda. Ini adalah satu-satunya cara Anda dapat berkomunikasi. Anda dapat melampirkan properti padanya, berbagi objek, dll. Ini bisa sebesar yang Anda inginkan - tanpa batas ukuran.
Setiap belokan berikut terjadi:
- Daftar pemain (baik merah dan biru) secara acak dikocok untuk urutan giliran.
- Setiap pemain bergerak.
- Jika ada anggota tim merah menyentuh (dalam 10 piksel) anggota tim biru di pihak merah, kirim anggota tim biru ke penjara, dan sebaliknya. Seorang pemain yang dipenjara menjatuhkan benderanya dan kekuatannya turun ke nol. Perhatikan bahwa fungsi langkah (kode yang Anda berikan) masih dipanggil - sehingga Anda bisa mendapatkan / mengatur pesan, tetapi Anda tidak bisa bergerak saat di penjara.
- Jika ada pemain yang menyentuh (dalam 10 piksel) bendera lainnya, maka bendera lainnya ditandai sebagai "diambil oleh" pemain itu. Ketika pemain bergerak, bendera bergerak - sampai pemain ditandai dan masuk ke penjara, yaitu.
- Jika ada pemain yang menyentuh penjara pihak lain, bebaskan semua orang di penjara itu. Ketika seorang pemain dibebaskan dari penjara, dia dipindahkan ke lokasi acak di sisinya.
Petunjuk:
- Setidaknya dalam menangkap bendera secara teratur, serangan bekerja jauh lebih baik ketika banyak pemain pergi sekaligus, karena cenderung membingungkan pembela mengenai pemain mana yang harus mereka kejar.
- Demikian pula, para pembela HAM mungkin ingin mengoordinasikan siapa yang mereka kejar sehingga serangan tidak terjadi
Potongan tumpukan:
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>
Pengendali: http://jsfiddle.net/prankol57/4L7fdmkk/
Pengontrol layar penuh: http://jsfiddle.net/prankol57/4L7fdmkk/embedded/result/
Beritahu saya jika ada bug di controller.
Catatan: Jika Anda pergi ke controller dan berpikir itu tidak memuat apa pun, tekan "Game Baru." Ini hanya memuat semuanya setelah Anda menekan "Game Baru" sehingga dapat memuat semua bot dan kemungkinan bot percobaan sekaligus.
Semoga berhasil.
Jika ada yang ingin melihat contoh game, saya membuat bot contoh yang dapat Anda salin dan rekatkan ke textarea "testbot" (testbot membuat dua duplikat di setiap tim; periksa tim merah dan tim biru):
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
};
}