Đây là một trò chơi bắt cờ, lấy cảm hứng rất nhiều và dựa trên Red vs. Blue - Pixel Team Battlebots . Đó là một câu hỏi tuyệt vời (cảm ơn bạn rất nhiều Calvin's Hy vọng, việc bắt được cờ sẽ đòi hỏi nhiều sự hợp tác của đội cũng như nhiều chiến lược hơn.
Để kết hợp nó, bạn được xem xét trong nhóm màu đỏ nếu chữ số cuối cùng của id của bạn nằm giữa 0
và 4
bao gồm. Điều này sẽ ngăn các đội chính xác chiến đấu một lần nữa, nếu cùng một người quyết định trả lời. Hội đồng quản trị là 350px
bởi 350px
. Đội màu xanh bắt đầu ở nửa trên của bảng và đội màu đỏ bắt đầu ở nửa dưới.
Cách bạn chơi bắt cờ như sau: đối tượng của trò chơi là lấy cờ của đội đối thủ và mang nó về phe của bạn. Nếu bạn đứng về phía họ, bạn có thể bị gắn thẻ và bị tống vào tù. Nếu bạn ở trong tù, thì bạn không thể di chuyển. Nếu bạn đứng về phía bạn, công việc của bạn là gắn thẻ các thành viên trong nhóm đối lập để tống họ vào tù. Cách duy nhất để ra khỏi tù là cho ai đó trong nhóm của bạn có thể tự do gắn thẻ mọi người trong tù. (Lưu ý rằng nhà tù nằm ở phía đối thủ).
Đặc biệt:
- Có một hằng số -
FIELD_PADDING
- được đặt thành 20. Đây là phần đệm cho trường. Nếu nó bằng 0, thì cờ và tù sẽ chính xác trên các góc của khung vẽ. Vì không phải vậy, cờ và tù cách các góc 20 pixel. - Cờ màu xanh (nhớ: đội màu xanh nằm ở nửa trên) được đặt tại
(WIDTH - FIELD_PADDING, FIELD_PADDING) = (330, 20)
góc trên bên phải. - Cờ đỏ là tại
(FIELD_PADDING, HEIGHT - FIELD_PADDING) = (20, 330)
- Nhà tù màu xanh (nơi giữ các thành viên màu đỏ) ở
(20, 20)
bên cạnh màu xanh, phía trên bên trái. - Nhà tù đỏ, nơi giữ các thành viên màu xanh, đang ở
(330, 330)
Mỗi thành viên trong nhóm bắt đầu ngẫu nhiên tại một vị trí 45 < x < 305
và 45 < y < 175
cho màu xanh và 175 < y < 305
màu đỏ. Không thành viên nào trong nhóm có thể đi theo DEFENSE_RADIUS = 25
pixel của cờ riêng hoặc nhà tù của riêng họ (tất nhiên trừ khi cờ của bạn bị bot đối lập lấy, trong trường hợp bạn cần gắn thẻ bot đó). Điều này là để ngăn chặn bảo vệ chó con như bot. Nếu bạn đi trong phạm vi đó, bạn sẽ bị "đẩy" lại. Tương tự, không thành viên nào trong nhóm có thể vượt ra khỏi giới hạn (dưới 0 hoặc hơn 350) - nếu bạn làm thế, bạn sẽ bị đẩy trở lại nơi hợp pháp gần nhất mà bạn có thể.
Mỗi khi bạn di chuyển, bạn sử dụng lên strength
. strength
Bắt đầu của bạn tại 20
và được bổ sung bởi 2
mỗi lượt. Lượng sức mạnh bạn sử dụng bằng với quãng đường bạn đi. Nếu sức mạnh của bạn trở nên tiêu cực bằng cách di chuyển đến một nơi nhất định, bạn sẽ bị ngăn không cho di chuyển. Có lẽ là một ý tưởng tốt để chỉ đi ở tốc độ 2
cho đuổi theo bình thường. Bạn chỉ nên sử dụng tốc độ cao hơn nếu bạn gần chiến thắng và cần thêm tốc độ (theo ý kiến của tôi).
Thông số :
Thông số kỹ thuật khá giống với câu hỏi Pixel Team Battlebots. Bạn nên viết một khối mã (hãy nhớ, không có biến toàn cục) trong javascript. Nó sẽ trả về một đối tượng có giá x
trị-và giá y
trị đại diện cho thay đổi của bạn trong x và thay đổi giá trị y. Câu trả lời sau:
return {
x: 0,
y: -2
};
luôn luôn di chuyển lên, cho đến khi nó chạm vào một bức tường. Bạn không thể chỉnh sửa 8 giờ sau khi đăng (ngoại trừ LegionMammal98, người nghĩ rằng bộ điều khiển không tải mã của mình và không kiểm tra) . Bạn có quyền truy cập vào các biến sau trong mã của mình:
this
- chính bạn, với tư cách là một người chơi (xem bên dưới để biết người chơi là gì)move
- số tròn, bắt đầu từ 0tJailed
- một loạt tất cả người chơi trong đội của bạn bị bỏ tùeJailed
- một loạt tất cả người chơi trong nhóm đối thủ bị bỏ tùteam
- một loạt tất cả người chơi trong đội của bạn, KHÔNG chỉ những người ở gần bạnenemies
- một loạt tất cả người chơi trong đội khác, KHÔNG chỉ những người ở gần bạntFlag
- cờ của bạn (bạn đang cố bảo vệ nó)eFlag
- cờ khác (bạn đang cố đánh cắp nó)messages
- giải thích bên dưới- Một danh sách các hằng số:
WIDTH = 350
,HEIGHT = 350
,FIELD_PADDING = 20
,DEFENSE_RADIUS = 25
.
Mỗi "người chơi" là một đối tượng có các thuộc tính sau:
x
vày
strength
id
isJailed
- đúng nếu người chơi ở tù
Mỗi cờ có các thuộc tính sau:
x
vày
pickedUpBy
- người chơi hiện có cờ hoặc null nếu không có người chơi nào có cờ.
Bây giờ, messages
là một đối tượng được chia sẻ giữa các đồng đội của bạn. Tôi không quan tâm bạn làm gì với nó. Cùng một đối tượng được chia sẻ và truyền cho mọi thành viên trong nhóm của bạn. Đây là cách duy nhất bạn có thể giao tiếp. Bạn có thể đính kèm các thuộc tính cho nó, chia sẻ các đối tượng, v.v. Nó có thể lớn như bạn muốn - không giới hạn kích thước.
Mỗi lượt sau đây xảy ra:
- Danh sách người chơi (cả đỏ và xanh) được xáo trộn ngẫu nhiên theo thứ tự lần lượt.
- Mỗi người chơi thực hiện một di chuyển.
- Nếu bất kỳ thành viên nhóm màu đỏ nào chạm vào (trong vòng 10 pixel), bất kỳ thành viên nhóm màu xanh nào ở bên cạnh màu đỏ, hãy gửi các thành viên nhóm màu xanh vào tù và ngược lại. Một người chơi bị bỏ rơi lá cờ của mình và có sức mạnh giảm xuống không. Lưu ý rằng chức năng bước (mã bạn cung cấp) vẫn còn được gọi - vì vậy bạn có thể nhận / đặt tin nhắn, nhưng bạn không thể di chuyển trong khi ở tù.
- Nếu bất kỳ người chơi nào chạm vào (trong vòng 10 pixel) thì cờ khác, thì cờ khác được đánh dấu là "được chọn bởi" người chơi đó. Khi người chơi di chuyển, cờ sẽ di chuyển - cho đến khi người chơi được gắn thẻ và vào tù, đó là.
- Nếu bất kỳ người chơi nào chạm vào nhà tù khác, hãy giải phóng mọi người trong nhà tù đó. Khi một người chơi được giải thoát khỏi nhà tù, anh ta / cô ta được dịch chuyển đến một vị trí ngẫu nhiên về phía anh ta / cô ta.
Gợi ý:
- Ít nhất là trong việc bắt giữ cờ thường xuyên, các cuộc tấn công hoạt động tốt hơn nhiều khi nhiều người chơi cùng một lúc, bởi vì nó có xu hướng gây nhầm lẫn cho những người bảo vệ rằng họ nên đuổi theo người chơi nào.
- Tương tự như vậy, những người bảo vệ có thể muốn phối hợp những người họ đang đuổi theo để các cuộc tấn công không đi qua
Đoạn trích:
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>
Trình điều khiển: http://jsfiddle.net/prankol57/4L7fdmkk/
Bộ điều khiển toàn màn hình: http://jsfiddle.net/prankol57/4L7fdmkk/embedded/result/
Hãy cho tôi biết nếu có bất kỳ lỗi trong bộ điều khiển.
Lưu ý: Nếu bạn truy cập bộ điều khiển và nghĩ rằng nó không tải bất cứ thứ gì, hãy nhấn "Trò chơi mới". Nó chỉ tải mọi thứ sau khi bạn nhấn "Trò chơi mới" để có thể tải tất cả các bot và các bot thử nghiệm có thể cùng một lúc.
Chúc may mắn.
Nếu bất cứ ai muốn xem một trò chơi mẫu, tôi đã tạo một bot mẫu mà bạn có thể sao chép và dán vào textarea "testbot" (testbot tạo hai bản sao trên mỗi đội; kiểm tra cả đội đỏ và đội xanh):
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
};
}