झंडा कब्जा


12

यह रेड बनाम ब्लू - पिक्सेल टीम बैटलबोट्स पर आधारित, जोरदार तरीके से प्रेरित और ध्वज को पकड़ने का खेल है । यह एक भयानक सवाल था (बहुत-बहुत केल्विन हॉबीज़ का शुक्रिया; मुझे उम्मीद है कि आपको कोई आपत्ति नहीं है कि मैं बेशर्मी से आपसे बहुत कोड चुरा लूंगा) - यहाँ एक और टीम आधारित राजा-की-पहाड़ी है। उम्मीद है, ध्वज पर कब्जा करने के लिए अधिक टीम के सहयोग के साथ-साथ अधिक रणनीति की आवश्यकता होगी।

इसे मिलाने के लिए, आपको लाल टीम पर विचार किया जाता है यदि आपकी आईडी का अंतिम अंक 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सामान्य पीछा करने की गति पर जाएं । आपको केवल उच्च गति का उपयोग करना चाहिए यदि आप जीतने के करीब हैं और अतिरिक्त गति (मेरी राय में) की आवश्यकता है।

विवरण :

कल्पना काफी हद तक पिक्सेल टीम बैटलबोट्स प्रश्न के समान है। आपको जावास्क्रिप्ट में एक कोड ब्लॉक (याद रखें, कोई वैश्विक चर) नहीं लिखना चाहिए। यह x में आपके परिवर्तन और y मानों में परिवर्तन का प्रतिनिधित्व करते हुए x-value और y-value के साथ एक वस्तु वापस करना चाहिए । निम्नलिखित उत्तर:

return {
  x: 0,
  y: -2
};

हमेशा ऊपर जाता है, जब तक कि यह एक दीवार से टकराता नहीं है। आप पोस्ट करने के 8 घंटे बाद संपादित नहीं कर सकते हैं (LegionMammal98 को छोड़कर जो सोचते थे कि नियंत्रक उसका कोड लोड नहीं कर रहा था और परीक्षण नहीं किया था) । आपके पास अपने कोड में निम्नलिखित चर तक पहुंच है:

  • this - खुद, एक खिलाड़ी के रूप में (खिलाड़ियों के लिए नीचे देखें)
  • move - गोल संख्या, 0 से शुरू
  • tJailed - आपकी टीम के सभी खिलाड़ियों की एक सरणी जो जेल में बंद है
  • eJailed - जेल जाने वाली विरोधी टीम के सभी खिलाड़ियों की एक सरणी
  • team - आपकी टीम के सभी खिलाड़ियों की एक सरणी, न केवल आपके पास वाले
  • enemies - दूसरी टीम के सभी खिलाड़ियों की एक सरणी, न सिर्फ आप के पास वाले
  • tFlag - आपका झंडा (आप इसे बचाने की कोशिश कर रहे हैं)
  • eFlag - दूसरा झंडा (आप इसे चोरी करने की कोशिश कर रहे हैं)
  • messages - नीचे समझाया गया
  • स्थिरांक की एक सूची: 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/

मुझे पता है कि क्या नियंत्रक में कोई कीड़े हैं।

नोट: यदि आप नियंत्रक के पास जाते हैं और सोचते हैं कि यह कुछ भी लोड नहीं कर रहा है, तो "नया गेम" दबाएं। "न्यू गेम" को दबाने के बाद ही यह सब कुछ लोड करता है ताकि यह एक ही बार में सभी बॉट्स और संभावित टेस्ट बॉट्स को लोड कर सके।

सौभाग्य।


अगर कोई एक उदाहरण गेम देखना चाहता है, तो मैंने एक उदाहरण बॉट बनाया, जिसे आप "टेस्टबोट" टेक्स्टारिया में कॉपी और पेस्ट कर सकते हैं (टेस्टबोट प्रत्येक टीम पर दो डुप्लिकेट बनाता है; लाल टीम और ब्लू टीम दोनों की जांच करें):

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
  };
}

8
आप इसे मेटा में सैंडबॉक्स पोस्ट के रूप में पहले (या समवर्ती रूप से) पोस्ट करना चाह सकते हैं जैसे मैंने आरवीबी के साथ किया था । यह एक जटिल प्रकार की प्रतियोगिता है, और आपके और अन्य लोगों के लिए सामान रखने की जगह बहुत मददगार है। (Btw, मुझे आप पर मेरे कोड का उपयोग करने में कोई आपत्ति नहीं है, हालांकि मैं यह नहीं कह सकता कि यह दस्तावेज या यहां तक ​​कि बहुत अच्छी तरह से आयोजित किया गया था: P)
केल्विन के

1
यदि आप फुलस्क्रीन के लिए jsfiddle.net/prankol57/4L7fdmkk/embedded/result के कंट्रोलर लिंक को बदल देते हैं तो यह बहुत ही कम होगा ।
लीजनमोनमाल 978

2
नियंत्रक सबसे महत्वपूर्ण भागों में से एक नहीं है ...?
एलेक्स ए।

1
@ एलेक्सा हाँ, लेकिन इसे सैंडबॉक्स में पोस्ट करने से कंट्रोलर में बग्स को ठीक करने में मदद मिलेगी (उत्तर लोड नहीं करना, उत्तर चलाना)? लोगों को वास्तविक जवाब पोस्ट करना शुरू करना होगा जो काम करते हैं, जो मेरी राय में, मेटा के लिए क्या है, जिसका मतलब है कि मुझे शायद यहां पोस्ट करना चाहिए। नियमित रूप से KOTH नियंत्रकों में भी कीड़े अनिवार्य रूप से आएंगे।
सप्तपिंक

1
नियंत्रक पर मेरा बॉट दिखाई नहीं दे रहा है।
लीजनमोनमाल 978

जवाबों:


4

लाल - आलसी जेल हॉग | आलसी ध्वजवाहक

इन दोनों के करीब की ओर बढ़ता है: नीले रंग की जेल, या नीले रंग का झंडा।

  • यदि जेल के लिए जा रहा है, तो जेल में जाकर रुक जाएगा। (चूंकि नीला अपने स्वयं के जेल को नहीं छू सकता है, यह अजेय होगा और स्वचालित रूप से सभी सहयोगियों को मुक्त कर देगा)
  • यदि ध्वज के लिए जा रहा है, तो यह नेत्रहीन रूप से ध्वज के लिए आगे बढ़ेगा और वापस आ जाएगा।

अंत में, इसका मस्तिष्क पूरी तरह messages[29354]से पहले चरण में ही संग्रहीत और आरंभिक होता है। इस प्रकार, यदि सहयोगी इस बॉट के लिए एक बेहतर उपयोग पाते हैं, तो वे अपने मस्तिष्क को अपने उच्च उद्देश्य के लिए बदल सकते हैं।

if (move === 0) {
    //On the first turn, set messages[this.id] to the function I will call to move me
    messages[this.id] = function(move, tJailed, eJailed, team, enemies, tFlag, eFlag, messages) {
        //Arbitrary function to move to a point at some speed, which may be in the point
        //  If we are at the point, undefined is returned
        var moveTo = function(p, max) {
            if (!p) {
                return {x:0, y:0};
            }
            max = Math.min(this.strength, max || p.max || 2);
            var dx = p.x - this.x;
            var dy = p.y - this.y;
            var dist = Math.abs(dx)+Math.abs(dy);
            if (dist === 0) {
                return undefined; 
            } else if (dist < max) {
                return {x: dx, y: dy};
            }
            var ux = Math.floor(max * dx / dist);
            var uy = Math.floor(max * dy / dist);
            while (Math.abs(ux) + Math.abs(uy) < max) {
                if (ux + this.x !== p.x) {
                    ux += ux > 0 ? 1 : -1;
                } else if (uy + this.y !== p.y) {
                    uy += uy > 0 ? 1 : -1;
                } else {
                    break;
                }
            }
            return {x: ux, y:uy};
        }.bind(this);

        //Set the way points
        var points = [];
        if (this.x > WIDTH/2) {
            points.push({x: WIDTH-FIELD_PADDING, y:HEIGHT/2+5});
            points.push({x: WIDTH-FIELD_PADDING, y:FIELD_PADDING, max: 5});
            points.push({x: WIDTH-FIELD_PADDING, y:HEIGHT/2+25, max: 5});
        } else {
            points.push({x: FIELD_PADDING, y:HEIGHT/2+5});
            points.push({x: FIELD_PADDING, y:FIELD_PADDING, max: 5});
            points.push(undefined); //Special case to do nothing / hog the jail
        }

        //Move through the points
        var state = messages[this.id].state || 0;
        var ret;
        while (!ret) {
            //Special case: if we were doing nothing, make sure we're where we think we were
            if (!points[state]) {
                ret = moveTo(points[state-1]);
                if (ret) {
                    state = 0;
                }
            }

            //Move to the next point
            ret = moveTo(points[state]);
            if (!ret) {
                state = (state + 1) % points.length;
            }
        }
        messages[this.id].state = state;
        return ret;
    };
}
//Move me based on that function, which may be changed by my allies
return messages[this.id].call(this, move, tJailed, eJailed, team, enemies, tFlag, eFlag, messages);

नियंत्रक आंदोलनों के लिए यूक्लिडियन दूरी का उपयोग करता है।
TheNumberOne

4

रेड - द गार्ड

यह बॉट ध्वज को बहुत अच्छा बनाएगा। इसके रास्ते में मत आओ ...

if (!messages[this.id]) {
    //On the first turn, set messages[this.id] to the function I will call to move me. You can replace this function on subsequent turns
    //to control it. Additionally, you can use it as a library to find one of the best places to go to defend.
    messages[this.id] = function(move, tJailed, eJailed, team, enemies, tFlag, eFlag, messages, WIDTH, HEIGHT, FIELD_PADDING, DEFENSE_RADIUS) {
        var distance = function(p1, p2) {
            var dx = p1.x - p2.x;
            var dy = p1.y - p2.y;
            return Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2));
        }

        var moveTo = function(p) {
            if (!p) {
                return {x:0, y:0};
            }
            var dx = p.x - this.x;
            var dy = p.y - this.y;
            var max = this.strength;
            var dist = distance(p, this);
            if (dist < max) {
                return {x: dx, y: dy};
            }
            dx = dx * max / dist;
            dy = dy * max / dist;
            while (Math.sqrt(Math.abs(dx)+Math.abs(dy)) > max) {
                if (dx > dy) {
                    dx = dx - 0.001;
                } else {
                    dy = dy - 0.001;
                }
            }
            return {x: dx, y:dy};
        }.bind(this);

        if (tFlag.pickedUp) {
            if (tFlag.y - HEIGHT / 2 > distance(this, {x: tFlag.x, y: HEIGHT / 2})) {
                return moveTo(tFlag);
            } else {
                return moveTo({y: Math.min(this.y, tFlag.y), x: tFlag.x });
            }
        }

        if (eFlag.pickedUp == this.id) {
            return moveTo({x: x, y: HEIGHT / 2});            
        }

        var targetPoints = [];
        var crossedBorder = false;

        var weightedMiddlePoint = function(enemy) {
            var x1 = (enemy.x + tFlag.x) / 2;
            var y1 = (enemy.y + tFlag.y) / 2;
            var w = 1/Math.pow(distance(enemy, tFlag),2);
            return {x:x1,y:y1,w:w};
        }

        for (var i = 0; i < enemies.length; i++) {
            var enemy = enemies[i];
            if (enemy.isJailed){
                continue;
            }
            if (enemy.y > HEIGHT / 2) {
                crossedBorder = true;
            }
        }

        for (var i = 0; i < enemies.length; i++) {
            enemy = enemies[i];
            if (enemy.isJailed){
                continue;
            }
            if (crossedBorder) {
                if (enemy.y > HEIGHT / 2) {
                    targetPoints.push(weightedMiddlePoint(enemy));
                }
            } else {
                targetPoints.push(weightedMiddlePoint(enemy));
            }
        }

        if (targetPoints.length == 0) {
            return moveTo(eFlag);
        }

        var sumX = 0;
        var sumY = 0;
        var sumW = 0;

        for (var i = 0; i < targetPoints.length; i++) {
            point = targetPoints[i];
            sumX += point.x * point.w;
            sumY += point.y * point.w;
            sumW += point.w;
        }

        var targetPoint = {x: sumX / sumW, y: sumY / sumW};

        return moveTo(targetPoint);

    };
}

return messages[this.id].call(this, move, tJailed, eJailed, team, enemies, tFlag, eFlag, messages, WIDTH, HEIGHT, FIELD_PADDING, DEFENSE_RADIUS);

4

नीला - लीजनमैमल 978

function repeat(el, n) // Helper function
{
    var rtn = [];
    for (var i = 0; i < n; i++)
        rtn.push(el);
    return rtn;
}
function sign(n) { return n ? n < 0 ? -1 : 1 : 0; } // Another helper function
if (!messages[this.id])
    messages[this.id] = { "dir": 1 };
if (this.isJailed) // Oh noes, I'm in jail!
{
    console.log(this.id, messages);
    if (!messages[this.id].jailTicks)
        messages[this.id].jailTicks = 0;
    messages[this.id].jailTicks++;
    // Call for help!
    messages.callsForHelp = repeat(["Help!", this.id, this.x, this.y], messages[this.id].jailTicks);
    return { "x": 0, "y": 0 };
}
if (messages[this.id].jailTicks)
    if (!(delete messages[this.id].jailTicks && delete messages.callsForHelp)) // Cleanliness
        messages[this.id].jailTicks = messages.callsForHelp = undefined;       // ...
var bounds = Math.floor(HEIGHT / 2); // Be safe with fractions
if (this.y > bounds - 5) // Get back to shelter!
    return { "x": 0, "y": this.y - this.strength <= bounds - 5 ? bounds - 5 - this.y : -4 };
var target = { "none": true, "x": WIDTH << 1, "y": HEIGHT << 1 };
enemies.forEach(function (en) { if (!en.isJailed && en.y < bounds - 5 && Math.abs(en.x - this.x) < Math.abs(target.x - this.x) && Math.abs(en.y - this.y) < Math.abs(target.y - this.y)) target = en; }, this);
if (target.none)
{
    if (this.y < bounds - 5)
        return { "x": 0, "y": 2 };
    var speed = this.strength < 30 ? 1 : 2;
    if (this.x == 5 || this.x == WIDTH - 5)
        messages[this.id].dir = -messages[this.id].dir;
    return { "x": speed * messages[this.id].dir, "y": 0 };
}
if (this.x - target.x >= 0 && this.x - target.x < this.strength)
{
    if (this.y - target.y > 0 && this.y - target.y < this.strength + target.x - this.x)
        return { "x": this.x - target.x, "y": this.y - target.y };
    if (target.y - this.y > 0 && target.y - this.y < this.strength + target.x - this.x)
        return { "x": this.x - target.x, "y": target.y - this.y };
}
if (target.x - this.x > 0 && target.x - this.x < this.strength)
{
    if (this.y - target.y > 0 && this.y - target.y < this.strength + this.x - target.x)
        return { "x": target.x - this.x, "y": this.y - target.y };
    if (target.y - this.y > 0 && target.y - this.y < this.strength + this.x - target.x)
        return { "x": target.x - this.x, "y": this.y - target.y };
}
return { "x": 6 * sign(target.x - this.x), "y": 6 * sign(target.y - this.y) };

रक्षा बॉट।


1
जावास्क्रिप्ट के बारे में छोटी सी बात - आप thisएक फ़ंक्शन के अंदर (अपने forEachलूप में) का उपयोग नहीं कर सकते । आपको इसे पहले से एक चर (यानी var _this = this;) के रूप में सहेजना होगा और उपयोग करना होगा _this। यदि आप जल्द ही संपादित करते हैं तो मैं आपको एक अपवाद के रूप में जोड़ूंगा क्योंकि आपको लगता है कि नियंत्रक आपके कोड को लोड नहीं कर रहा था और परीक्षण नहीं कर सकता था।
soktinpk

@soktinpk बस forEachवैकल्पिक इस्तेमाल किया thisArg
लेजिओनमाला 978

मैंने आपको देर से संपादित करने पर भी आपको अनुमति देने के लिए नियंत्रक को अद्यतन किया।
सोकटिनपेक

1

लाल - झंडा हंटर

var distance = function(x1, y1, x2, y2) {
    return Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
}
var moveTo = function(x, y, max) {
    if (max > this.strength)
        max = this.strength;
    var dX = x - this.x;
    var dY = y - this.y;
    var dist = distance(x, y, this.x, this.y);
    if (dist <= max) {
        return {x: dX, y: dY};
    }
    dX = dX * max / dist;
    dY = dY * max / dist;
    while (Math.sqrt(Math.abs(dX)+Math.abs(dY)) > max) {
        if (dX > dY) {
            dX = dX - 0.001;
        } else {
            dY = dY - 0.001;
        }
    }
    return {x: dX, y:dY};
}.bind(this);

var getSurroundingPoints = function(x, y, dist) {
    var points = [];
    for (var i = x - dist; i <= x + dist; i+= 0.2) {
        for (var j = y - dist; j <= y + dist; j+= 0.2) {
            if (i >= 0 && j >= 0 && j <= 180 && distance(i,j,x,y) <= dist) {
                points.push({x: i, y: j, danger: 0});
            }
        }
    }
    return points;
}

if (this.isJailed) {
    return {x:0, y:0};
}

var destination = {x: eFlag.x, y: eFlag.y}; //default: try to get the flag
if (eFlag.pickedUpBy != null) { //we got the flag
    if (eFlag.pickedUpBy.id == this.id) { //I got the flag => get back to the red side
        if (distance(this.x, this.y, this.x, 175.1) <= this.strength) {
            return moveTo(this.x, 175.1, this.strength);
        }
        destination.x = this.x;
        destination.y = 180;
    } else { //someone else got the flag => free those in the jail
        destination.x = 20;
        destination.y = 20;
    }
} else if (this.y > HEIGHT / 2) { //I am on the red side
    return moveTo(175, 175, 2);
} else if (distance(this.x, this.y, eFlag.x, eFlag.y) <= 15)  { //I am in the safe zone (flag)
    if (this.strength < 20)
        return {x:0, y:0};
    return moveTo(eFlag.x, eFlag.y, 2); //get the flag
} else if (distance(this.x, this.y, eFlag.x, eFlag.y) - this.strength <= 15)  { //I can reach the safe zone (flag)
    return moveTo(eFlag.x, eFlag.y, distance(this.x, this.y, eFlag.x, eFlag.y) - 14);
} else if (distance(this.x, this.y, 20, 20) < 10)  { //I am in the safe zone (jail)
    if (this.strength < 20)
        return {x:0, y:0};
} else if (distance(this.x, this.y, eFlag.x, eFlag.y) - this.strength <= 15)  { //I can reach the safe zone (jail)
    return moveTo(20, 20, this.strength);
}

//I am somewhere on the blue side
var points = getSurroundingPoints(this.x, this.y, this.strength);
var me = this;
points.forEach(function(point) {
    if (point.y < 175) {
        enemies.forEach(function(enemy) {
            if (distance(enemy.x, enemy.y, point.x, point.y) <= enemy.strength+10) {
                point.danger += 5;
            }
        });
        if (distance(me.x, me.y, point.x, point.y) <= 2 && point.danger == 0) {
            point.danger--;
        }
    }
});
var bestPoint = points[0];
points.forEach(function(point) {
    if (point.danger < bestPoint.danger || (point.danger == bestPoint.danger && distance(point.x, point.y, destination.x, destination.y) < distance(bestPoint.x, bestPoint.y, destination.x, destination.y))) {
        bestPoint = point;
    }
});
return moveTo(bestPoint.x, bestPoint.y, this.strength);

झंडा पाने की कोशिश करता है। यदि किसी और को पहले से ही मिल गया, तो फ्लैग हंटर जेल की ओर चलता है, या तो दुश्मन को भ्रमित करता है या अपनी टीम के सदस्यों को मुक्त करता है।


1

ब्लू - एक जॉली अच्छा साथी

जावास्क्रिप्ट, और कोड-गोल्फ में प्रोग्रामिंग में दोनों का प्रयास करें। यह किसी भी चीज का पीछा करेगा, जो झंडे के बहुत करीब आता है, उनकी चालों को सामने लाने की कोशिश कर रहा है। अन्यथा, यह जेल में टीम के साथियों को बचाने के लिए चलेगा, या अन्य टीम के झंडे को पाने के लिए आलसी हो जाएगा।

// Euclidean distance
var distance = function(p1,p2){
 return Math.sqrt( (p1.x - p2.x)**2 + (p1.y - p2.y)**2 );
}

// points from p1 to p2
var direction = function(p1, p2){
 return Math.atan2( p2.y - p1.y, p2.x - p1.x);
}

//moving
var move2 = function(dir, step){
    if(isNaN(dir)){   dir = 0; };
    if(isNaN(step)){ step = 0; };
    return {
        x: Math.cos(dir)*step,
        y: Math.sin(dir)*step
    };
}


var intercept_at = function(me, they, field){
    if ( distance(me, they)<me.strength ){
        return they;
    }

    //console.log("I am at (", me.x, me.y, ") ");
    //console.log("They are at (", they.x, they.y, ") ");           


    //first goal
    if( field.my_flag.pickedUpBy == null ){
        their_goal = field.my_flag;
        eta = (distance(they, their_goal) - they.strength)/2;
        their_dir = direction(they, their_goal);
        for( var i=1; i<eta; i++){
          they_next = {
            x: they.x + Math.cos(their_dir)*(they.strength/2 + (i+1)*2),
            y: they.y + Math.sin(their_dir)*(they.strength/2 + (i+1)*2)
          };
          if( (distance(me, they_next) )<(1.95*i) ){
            //console.log("goal is flag at (", their_goal.x, their_goal.y, ") ");   
            //console.log("I can reach it at (", they_next.x, they_next.y, ") in less than ", i);
            return they_next;
          }
        }
    // second goal  
    }

    my_flag = field.my_flag;
    their_goal = { x: my_flag.x, y:field.h/2 - 5};
    eta = (distance(my_flag, their_goal) - they.strength)/2;
    their_dir = direction(my_flag, their_goal);
    for( var i=0; i<eta; i++){
        they_next = {
            x: my_flag.x + Math.cos(their_dir)*(they.strength/2 + (i+1)*2),
            y: my_flag.y + Math.sin(their_dir)*(they.strength/2 + (i+1)*2)
        };
        if( (distance(me, they_next) )<(1.95*i) ){
            //console.log("goal is escaping at (", their_goal.x, their_goal.y, ") "); 
            //console.log("I can front-run it at (", they_next.x, they_next.y, ") in less than ", i);
            return they_next;
        }       
    }
    //console.log("Goose chase at (", they.x, they.y, ") ");
    return they;
}

var intercept = function(me, they, field){
  they_at = intercept_at(me, they, field);
  they_at.y = Math.min(they_at.y, field.h/2-5)
  dist2me = distance(me, they_at);
  dir2me = direction(me, they_at);  
  if ( dist2me<me.strength ){
    return move2(dir2me, dist2me);
  }else{
    return move2(dir2me, 2);
  }
}


var closest_enemy = function(my_flag, enemies){
    cur_tgt_num = null;
    cur_tgt_dst = 999;

    for( var i=0; i<enemies.length; i++){
      if(!enemies[i].isJailed){
        cur_dst = distance(enemies[i], my_flag);
        if ( cur_dst < cur_tgt_dst ){
          cur_tgt_dst = cur_dst;
          cur_tgt_num = i;
        }
      }
    }    

    return enemies[cur_tgt_num];
}


var enemies_closer_than = function(enemies, radius, field){
    closer_than = 0;
    for( var i = 0; i<enemies.length; i++){
        if(!enemies[i].isJailed){
            closer_than = closer_than + ( distance(enemies[i], field.my_flag)<radius );
        }
    }
    return closer_than;
}


var team_jailed = function(team){
    for( var i = 0; i<team.length; i++){
        if(team[i].isJailed){
            return team[i];
        }
    }
    return null;
}


var bound_positions = function(p0, field){
    p0.x = Math.max(0, Math.min(p0.x, field.w));
    p0.y = Math.max(0, Math.min(p0.y, field.h));    
    return p0;
}

var avoid_obstacle = function(me, goal, obstacle, field, can_run){
    //we know that there is a safe haven
    if( distance(me, goal)<me.strength && can_run){
        return move2(direction(me, goal), me.strength)
    }

    if( obstacle == null ){
        return move2(direction(me, goal), 2);
    }

    ob_dir = direction(me, obstacle);
    if( distance(me, obstacle) < Math.sqrt(2)*(4+obstacle.strength)){
        me_next1 = bound_positions({x: me.x - 4*Math.cos(ob_dir),y: me.y - 4*Math.sin(ob_dir)}, field);
        me_next2 = bound_positions({x: me.x - 4*Math.sin(ob_dir),y: me.y - 4*Math.cos(ob_dir)}, field);
        me_next3 = bound_positions({x: me.x - 4*Math.sin(ob_dir),y: me.y - 4*Math.cos(ob_dir)}, field);
        if( distance(goal, me_next1) < distance(goal, me_next2) ){
          if( distance(goal, me_next1) < distance(goal, me_next3) ){
            me_next = me_next1;
          }else{
            me_next = me_next3;
          }
        }else{
          if( distance(goal, me_next2) < distance(goal, me_next3) ){
            me_next = me_next2;
          }else{
            me_next = me_next3;
          }
        }           

        //console.log("Escaping from (", obstacle.x, obstacle.y, ")");
        return move2(direction(me, me_next), 4);
    }

    eta = (distance(me, goal)/2);
    my_dir = direction(me, goal);
    me_next = me;
    i=0;
    while(i<eta && (distance(me_next, obstacle) > obstacle.strength+2*i)){
       i++;
       me_next = {x: me_next.x + i*Math.cos(my_dir),y: me_next.y + i*Math.sin(my_dir)};
       me_next = bound_positions(me_next, field);
       if( distance(me_next, obstacle) < obstacle.strength+2*i ){
         me_next1 = {x: me_next.x + i*Math.sin(ob_dir),y: me_next.y - i*Math.cos(ob_dir)};
         me_next2 = {x: me_next.x - i*Math.sin(ob_dir),y: me_next.y + i*Math.cos(ob_dir)};
         if( distance(goal, me_next1) > distance(goal, me_next2) ){
            me_next = bound_positions(me_next2, field);
         }else{
            me_next = bound_positions(me_next1, field);
         }
       }
    }
    if( distance(me_next, obstacle) > obstacle.strength+2*i ){
        //console.log("Trying to reach goal at (", goal.x, goal.y, ") by pointing at (",me_next.x, me_next.y,")");      
        return move2(direction(me, me_next), 2);
    }

    //console.log("Waiting to reach (", goal.x, goal.y,")");
    my_dir = direction(me, goal);
    me_next = {
        x: me.x + Math.cos(my_dir)*6,
        y: me.y + Math.sin(my_dir)*6
    }
    for( var i=0; i<field.team.length; i++){
        me_next.x = me_next.x - Math.sign(field.team[i].x - me_next.x);
        me_next.y = me_next.y - Math.sign(field.team[i].y - me_next.y);
    }               
    return move2(direction(me, me_next), Math.floor(Math.random() * 2));
}


var field = {
    w: WIDTH, 
    h: HEIGHT, 
    g: DEFENSE_RADIUS,
    my_flag: tFlag,
    their_flag: eFlag,
    team: team,
    enemies: enemies
    };

var n_enemy = enemies.length;


  if( enemies_closer_than(enemies, field.h*0.67, field)>0 || tFlag.pickedUpBy !== null){
    //console.log("My flag is in danger");      

    // directive defend
    messages[123 + this.id] = 'defend_own_flag';
    if ( tFlag.pickedUpBy !== null ) {
      return intercept(this, tFlag.pickedUpBy, field);
    }else{
      return intercept(this, closest_enemy(tFlag, enemies), field);
    }   
  }else{

    if( tJailed.length>0 ){

        // directive support
        console.log("rescueing team member");
        console.log(tJailed);
        return avoid_obstacle(this, tJailed[0], closest_enemy(this, enemies), field, 0);
    }else{

      // directive attack
      messages[123 + this.id] = 'capture_enemy_flag';
      if ( eFlag.pickedUpBy == null ){
        //console.log("Going to capture the flag");
        return avoid_obstacle(this, eFlag, closest_enemy(this, enemies), field, 0)

      }else if (this.id == eFlag.pickedUpBy.id){
        //console.log("I have the flag");
        return avoid_obstacle(this, {x:this.x, y:field.h/2 - 1}, closest_enemy(this, enemies), field, 1);      

      }else {
        //console.log("Someone else has the flag");
        return avoid_obstacle(this, eFlag, closest_enemy(this, enemies), field, 0);

      }
    }
  }

return move2(0,0);
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.