นี้เป็นเกมของการจับภาพธงแรงบันดาลใจอย่างหนักและตามออกของสีแดงกับสีน้ำเงิน - Pixel ทีม BattleBots นั่นเป็นคำถามที่ยอดเยี่ยม (ขอบคุณมาก Calvin'sHobbies ฉันหวังว่าคุณจะไม่รังเกียจว่าฉันขโมยรหัสจากคุณไปอย่างไร้ยางอาย) - นี่คือทีมจาก King-of-the-hill อีกทีมหนึ่ง หวังว่าการยึดธงจะต้องอาศัยความร่วมมือของทีมและกลยุทธ์มากขึ้น
ในการมิกซ์มันคุณจะได้รับการพิจารณาในทีมสีแดงหากตัวเลขหลักสุดท้ายของ ID ของคุณอยู่ระหว่าง0
และ4
รวม สิ่งนี้ควรป้องกันไม่ให้ทีมเดียวกันต่อสู้อีกครั้งหากคนคนเดียวกันตัดสินใจที่จะตอบ คณะกรรมการจะโดย350px
350px
ทีมสีน้ำเงินเริ่มต้นครึ่งบนของกระดานและทีมสีแดงเริ่มครึ่งล่าง
วิธีที่คุณเล่นจับธงมีดังต่อไปนี้: เป้าหมายของเกมคือการยึดธงของทีมตรงข้ามและนำมันกลับไปด้านข้างของคุณเอง หากคุณอยู่ข้างๆคุณสามารถติดแท็กและส่งเข้าคุกได้ หากคุณอยู่ในคุกคุณจะไม่สามารถเคลื่อนไหวได้ ถ้าคุณอยู่ข้างคุณงานของคุณคือติดแท็กศัตรูของสมาชิกเพื่อส่งพวกเขาเข้าคุก วิธีเดียวที่จะออกจากคุกได้คือสำหรับใครบางคนในทีมของคุณที่สามารถติดแท็กทุกคนในคุกได้ (โปรดทราบว่าคุกนั้นตั้งอยู่ฝั่งทีมตรงข้าม)
โดยเฉพาะ:
- มีค่าคงที่ -
FIELD_PADDING
ตั้งไว้ที่ 20 นี่คือช่องว่างภายในสำหรับเขตข้อมูล ถ้ามันเป็นศูนย์ธงและคุกก็จะอยู่ตรงมุมผ้าใบ เนื่องจากไม่ใช่ธงและคุกอยู่ห่างจากมุม 20 พิกเซล - ธงสีฟ้า (จำไว้ว่า: ทีมสีน้ำเงินอยู่ครึ่งบน) ตั้งอยู่ที่
(WIDTH - FIELD_PADDING, FIELD_PADDING) = (330, 20)
มุมบนขวา - ธงสีแดงอยู่ที่
(FIELD_PADDING, HEIGHT - FIELD_PADDING) = (20, 330)
- เรือนจำสีน้ำเงิน (ซึ่งสมาชิกสีแดงจะถูกเก็บไว้) อยู่ที่
(20, 20)
ด้านสีน้ำเงินด้านบนซ้าย - คุกแดงซึ่งสมาชิกสีน้ำเงินถูกเก็บรักษาไว้อยู่ที่
(330, 330)
สมาชิกทุกคนในทีมเริ่มสุ่มที่ตำแหน่ง45 < x < 305
และ45 < y < 175
สำหรับสีน้ำเงินและ175 < y < 305
สีแดง สมาชิกในทีมไม่สามารถเข้าไปในDEFENSE_RADIUS = 25
พิกเซลของธงของพวกเขาเองหรือคุกของพวกเขาเอง (เว้นแต่แน่นอนว่าธงของคุณถูกยึดโดยบอตรงข้ามซึ่งในกรณีนี้คุณต้องติดแท็กบ็อตนั้น) นี่คือการป้องกันไม่ให้ลูกสุนัขเฝ้าเหมือนบอท หากคุณอยู่ในช่วงดังกล่าวคุณจะถูก "ดัน" กลับ ในทำนองเดียวกันสมาชิกในทีมไม่สามารถออกนอกขอบเขต (น้อยกว่าศูนย์หรือมากกว่า 350) - ถ้าคุณทำคุณจะถูกผลักกลับไปยังสถานที่ทางกฎหมายที่ใกล้ที่สุดที่คุณสามารถ
ทุกครั้งที่คุณเคลื่อนไหวคุณจะหมดstrength
แรง คุณstrength
เริ่มต้นที่20
และเติมเต็ม2
ทุกเทิร์น ปริมาณของความแข็งแรงที่คุณใช้เท่ากับระยะทางที่คุณเดินทาง หากความแข็งแรงของคุณจะกลายเป็นลบโดยการย้ายไปยังสถานที่หนึ่งคุณจะถูกขัดขวางจากการทำเช่นนั้น มันเป็นความคิดที่ดีที่จะไปที่ความเร็ว2
เพื่อไล่ตามปกติ คุณควรใช้ความเร็วที่สูงขึ้นหากคุณใกล้จะชนะและต้องการความเร็วที่เพิ่มขึ้น (ตามความเห็นของฉัน)
สเป็ค :
สเป็คค่อนข้างคล้ายกับคำถามของทีมพิกเซลบอทบอท คุณควรเขียน code block (จำไว้ว่าไม่มีตัวแปรทั่วโลก) ใน javascript มันควรจะคืนค่าออบเจกต์ด้วย - x
ค่าและ - y
ค่าแทนการเปลี่ยนแปลงของคุณใน x และเปลี่ยนค่า y คำตอบต่อไปนี้:
return {
x: 0,
y: -2
};
เลื่อนขึ้นเรื่อย ๆ จนกว่าจะชนกำแพง คุณไม่สามารถแก้ไข 8 ชั่วโมงหลังการโพสต์ (ยกเว้น LegionMammal98 ใครที่คิดว่าควบคุมไม่ได้โหลด / รหัสของเขาและเธอไม่ได้ทดสอบ) คุณสามารถเข้าถึงตัวแปรต่อไปนี้ในรหัสของคุณ:
this
- ตัวคุณเองในฐานะผู้เล่น (ดูด้านล่างสำหรับสิ่งที่ผู้เล่น)move
- จำนวนรอบเริ่มต้นที่ 0tJailed
- อาร์เรย์ของผู้เล่นทั้งหมดในทีมของคุณที่ถูกจำคุกeJailed
- อาร์เรย์ของผู้เล่นทั้งหมดในทีมตรงข้ามที่ถูกจำคุกteam
- อาร์เรย์ของผู้เล่นทุกคนในทีมของคุณไม่ใช่แค่คนที่อยู่ใกล้คุณenemies
- อาเรย์ของผู้เล่นทุกคนในทีมอื่น ๆ ไม่ใช่แค่คนที่อยู่ใกล้คุณtFlag
- ธงของคุณ (คุณกำลังพยายามปกป้องมัน)eFlag
- ธงอื่น ๆ (คุณกำลังพยายามขโมย)messages
- อธิบายไว้ด้านล่าง- รายการของค่าคงที่ A:
WIDTH = 350
,HEIGHT = 350
, ,FIELD_PADDING = 20
DEFENSE_RADIUS = 25
"ผู้เล่น" ทุกคนเป็นวัตถุที่มีคุณสมบัติดังต่อไปนี้:
x
และy
strength
id
isJailed
- จริงหากผู้เล่นอยู่ในคุก
ทุกธงมีคุณสมบัติดังต่อไปนี้:
x
และy
pickedUpBy
- ผู้เล่นที่มีสถานะปัจจุบันหรือเป็นโมฆะหากผู้เล่นไม่มีธง
ตอนนี้messages
เป็นวัตถุที่ใช้ร่วมกันระหว่างเพื่อนร่วมทีมของคุณ ฉันไม่สนใจสิ่งที่คุณทำกับมัน วัตถุเดียวกันจะถูกแชร์และส่งต่อให้กับสมาชิกในทีมของคุณทุกคน นี่เป็นวิธีเดียวที่คุณสามารถสื่อสารได้ คุณสามารถแนบคุณสมบัติเข้ากับมันแชร์วัตถุ ฯลฯ มันอาจมีขนาดใหญ่เท่าที่คุณต้องการ - ไม่ จำกัด ขนาด
ทุก ๆ สิ่งที่เกิดขึ้นมีดังต่อไปนี้:
- รายชื่อผู้เล่น (ทั้งสีแดงและสีน้ำเงิน) จะถูกสุ่มสับเพื่อเปลี่ยน
- ผู้เล่นทุกคนทำให้เคลื่อนไหว
- หากสมาชิกทีมสีแดงใด ๆ แตะ (ภายใน 10 พิกเซล) สมาชิกทีมสีน้ำเงินใด ๆ ที่อยู่ด้านข้างสีแดงให้ส่งสมาชิกทีมสีน้ำเงินเข้าคุกและในทางกลับกัน ผู้เล่นที่ถูกจำคุกจะทิ้งธงของตนและมีความแข็งแกร่งลดลงเหลือศูนย์ โปรดทราบว่ายังมีการเรียกใช้ฟังก์ชันขั้นตอน (รหัสที่คุณให้ไว้) เพื่อให้คุณสามารถรับ / ตั้งค่าข้อความได้ แต่คุณไม่สามารถเคลื่อนที่ในขณะที่อยู่ในคุกได้
- หากผู้เล่นคนใดแตะ (ภายใน 10 พิกเซล) ธงอื่น ๆ ธงอื่น ๆ จะถูกทำเครื่องหมายเป็น "หยิบโดย" ผู้เล่นนั้น เมื่อผู้เล่นเคลื่อนที่ธงจะขยับ - จนกว่าผู้เล่นจะถูกแท็กและเข้าคุกนั่นคือ
- หากผู้เล่นคนใดแตะต้องคุกของอีกฝั่งให้ปล่อยตัวทุกคนในคุกนั้น เมื่อผู้เล่นถูกปล่อยตัวออกจากคุกเขา / เธอจะถูกส่งไปยังตำแหน่งสุ่มที่ด้านข้างของเขา / เธอ
คำแนะนำ:
- อย่างน้อยในการยึดธงเป็นประจำการโจมตีจะทำได้ดีกว่ามากเมื่อผู้เล่นหลายคนไปพร้อมกันเพราะมันมีแนวโน้มที่จะสร้างความสับสนให้กับกองหลังว่าผู้เล่นคนไหนควรไล่ล่า
- ในทำนองเดียวกันผู้พิทักษ์อาจต้องการประสานงานผู้ที่กำลังไล่ล่าเพื่อให้การโจมตีไม่ผ่าน
ตัวอย่างสแต็ก:
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>
ผู้ควบคุม: http://jsfiddle.net/prankol57/4L7fdmkk/
ตัวควบคุมเต็มหน้าจอ: http://jsfiddle.net/prankol57/4L7fdmkk/embedded/result/
แจ้งให้เราทราบหากมีข้อบกพร่องใด ๆ ในตัวควบคุม
หมายเหตุ: หากคุณไปที่คอนโทรลเลอร์และคิดว่ามันไม่โหลดอะไรให้กด "เกมใหม่" มันโหลดทุกอย่างหลังจากคุณกด "เกมใหม่" เพื่อให้สามารถโหลดบอททั้งหมดและบอททดสอบที่เป็นไปได้ในครั้งเดียว
โชคดี.
หากใครต้องการเห็นเกมตัวอย่างฉันสร้างบอทตัวอย่างที่คุณสามารถคัดลอกและวางลงใน textarea "testbot" (testbot สร้างรายการที่ซ้ำกันสองรายการในแต่ละทีมตรวจสอบทั้งทีมสีแดงและทีมสีน้ำเงิน):
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
};
}