ব্লক বিল্ডিং বট ফ্লক!


42

প্রতিযোগিতা শেষ!

ইন্ট্রো

এটি একটি ইন্টারেক্টিভ প্রতিযোগিতা যেখানে নিয়ামকটি পুরোপুরি প্রশ্নের নীচে স্ট্যাক স্নিপেটে অন্তর্ভুক্ত থাকে। নিয়ামক স্বয়ংক্রিয়ভাবে উত্তরগুলি পড়েন এবং গেমগুলির মাধ্যমে খেলেন। যে কেউ যে কোনও সময় যে কোনও সময় তাদের ব্রাউজারে এটি চালাতে পারেন।

এই প্রতিযোগিতার যান্ত্রিকগুলি রেড বনাম ব্লু - পিক্সেল টিম ব্যাটবটগুলির সাথে খুব মিল । গেমটি খেলতে ব্যতীত এখনও গ্রিড ভিত্তিতে সম্পূর্ণ ভিন্ন। প্রতিটি খেলা 1 বনাম 1 এবং কোনও দল নেই। প্রতিটি এন্ট্রি নিজের জন্য লড়াই করছে এবং কেবলমাত্র একজন চূড়ান্ত চ্যাম্পিয়ন হবে।

নিয়ামকটি জাভাস্ক্রিপ্ট ব্যবহার করে এবং জাভাস্ক্রিপ্টটি কেবলমাত্র ক্লায়েন্ট-সাইড স্ক্রিপ্টিং ভাষা হিসাবে বেশিরভাগ ব্রাউজার সমর্থন করে, সমস্ত উত্তর অবশ্যই জাভাস্ক্রিপ্টে লেখা উচিত

এই বৈশিষ্টটিতে, ইতালিযুক্ত পাঠ্যটি কোনও গেম মেকানিক বা সম্পত্তির আনুষ্ঠানিক শব্দটি নির্দেশ করতে ব্যবহৃত হয়। এই শর্তগুলি জুড়ে গেমের বিভিন্ন অংশের উল্লেখ করার সুসংগত এবং সুস্পষ্ট উপায় বজায় রাখতে সহায়তা করে।

গেমপ্লের

বুনিয়াদি

এই প্রশ্নের প্রতিটি উত্তর একজন খেলোয়াড়কে প্রতিনিধিত্ব করে । একটি গেম হ'ল পি 1 এবং পি 2 এই দুই খেলোয়াড়ের মধ্যে একটি প্রতিযোগিতা । প্রতিটি প্লেয়ার নিয়ন্ত্রন একটি পাল 8 বট , 7. গেম মাধ্যমে 0 সংখ্যাযুক্ত মধ্যে সঞ্চালিত হয় গ্রিড একটি 128 × 64, সেল Arena যার নিচ 8 সারি হিসাবে শুরু দেয়াল ( 'ব্লক') এবং অন্যান্য সারি হিসাবে শুরু বায়ু । গ্রিডের সীমানার বাইরে থাকা ঘরগুলি এয়ার হিসাবে বিবেচনা করা হয়।

গ্রিডের এক্স স্থানাঙ্কটি 0 থেকে বাম দিকে 127 ডানদিকে এবং y শীর্ষে 0 থেকে নীচে 63 পর্যন্ত রয়েছে।

নমুনা শুরু গ্রিড:

বটগুলি সর্বদা গ্রিড কোষের সাথে একত্র থাকে এবং একাধিক বট একই কক্ষটি দখল করতে পারে। বটগুলি কেবল বায়ু কোষগুলি দখল করতে পারে। পি 1 এর বটগুলি সর্বদা দেয়ালের উপরের সারির একেবারে বাম দিকে 0-7 একটি লাইনে শুরু হয় এবং পি 2 এর বটগুলি সর্বদা ডানদিকে 7-0 এ একটি লাইনে শুরু হয়।

প্রতিবেশীদের একটি বট বা সেল 8 কোষ সরাসরি লম্ব এবং এটি তির্যক হয়।

একটি বটের দৃশ্য ক্ষেত্র ( FOV ) হ'ল 13 13 13 বর্গ কেন্দ্র বর্গক্ষেত্র হয়। কোনও সেল বা শত্রু বট প্লেয়ারের কমপক্ষে যে কোনও একটি বটের FOV এ থাকলে কোনও প্লেয়ারের FOV এ থাকে।

চাল এবং ক্রিয়াগুলি

একটি গেমের সময়, প্রতিটি খেলোয়াড় 1000 বার স্থানান্তর করতে পারে । পি 1 প্রথমে চলে আসে, তারপরে পি 2, তারপরে পি 1 এবং আরও প্রায় 2000 টি মোট চালগুলি হয়ে গেছে, যেখানে গেমটি শেষ হয়।

পদক্ষেপ নেওয়ার সময়, প্রতিটি খেলোয়াড় তাদের FOV- এ গেমের অবস্থা এবং গ্রিড সেল এবং শত্রু বট সম্পর্কিত তথ্য পায় এবং তাদের প্রতিটি বোট গ্রহণের জন্য কোনও সিদ্ধান্ত নেওয়ার জন্য এটি ব্যবহার করে ।

ডিফল্ট ক্রিয়া কিছুই করা হয় না , যেখানে বটটি গ্রিডের সাথে সরানো বা ইন্টারঅ্যাক্ট করে না।

অন্যান্য ক্রিয়াগুলি স্থানান্তর , দখল এবং স্থান :

  • একটি বট তার প্রতিবেশী কোষ সি এর একটিতে যেতে পারে যদি:

    • সি সীমার বাইরে নয়,
    • সি বায়ু (অর্থাত্ প্রাচীর নয়),
    • এবং সি এর প্রতিবেশীদের কমপক্ষে একটি প্রাচীর।

    সফল হলে বটটি সি তে চলে যাবে

  • একটি বট তার প্রতিবেশী একটি সেল সি ধরতে পারে যদি:

    • সি সীমার বাইরে নয়,
    • সি একটি প্রাচীর,
    • এবং বটটি ইতিমধ্যে একটি প্রাচীর বহন করে না।

    যদি সফল হয় তবে সি বায়ুতে পরিণত হবে এবং বটটি এখন একটি প্রাচীর বহন করবে।

  • একটি বট করতে স্থান প্রতিবেশী কোষ সি যদি এক:

    • সি সীমার বাইরে নয়,
    • সি বায়ু হয়,
    • দু'জনেরই কোনও খেলোয়াড় সি দখল করে না,
    • এবং বটটি একটি প্রাচীর বহন করছে।

    সফল হলে সি একটি প্রাচীর হয়ে যাবে এবং বটটি আর দেয়াল বহন করবে না।

অসফল কর্মের ফলে কিছু হয় না।

কমপক্ষে একটি প্রাচীর বহনকারী বট দ্বারা দখল করা একটি কক্ষের উপরে একটি ছোট প্রাচীর বর্ণযুক্ত বর্গক্ষেত্র রয়েছে। বটগুলি দেয়াল ছাড়াই শুরু হয়।

স্মৃতি

সরানোর সময়, কোনও খেলোয়াড় তাদের স্মৃতি অ্যাক্সেস করতে এবং পরিবর্তন করতে পারে, প্রাথমিকভাবে খালি স্ট্রিং যা পুরো খেলা জুড়ে থাকে এবং কৌশলগত ডেটা সঞ্চয় করতে ব্যবহার করা যেতে পারে।

লক্ষ্য

হলুদ ক্রোশায়ের সেলটি লক্ষ্য , যা এলোমেলো অবস্থায় শুরু হয়। প্রতিটি খেলোয়াড়ের একটি স্কোর থাকে যা 0 থেকে শুরু হয় যখন কোনও খেলোয়াড়ের বট গোলের দিকে চলে যায়, তখন খেলোয়াড়ের স্কোর 1 বৃদ্ধি পায় এবং পরের বারের আগে গোলটি এলোমেলোভাবে স্থান করে দেওয়া হয়। একটি খেলা শেষে সর্বোচ্চ স্কোর প্লেয়ার জিতল। স্কোর সমান হলে এটি টাই।

যদি সরানোর সময় একাধিক বট গোলের দিকে যায় তবে প্লেয়ারটি কেবল একটি পয়েন্ট পায়।

যদি লক্ষ্যটি একই জায়গায় 500 টি পদক্ষেপের জন্য হয় তবে তা এলোমেলোভাবে আবার স্থান দেওয়া হয়। যে কোনও সময় লক্ষ্যটি এলোমেলোভাবে স্থিত করা হয়, এটি কোনও বট দ্বারা অধিষ্ঠিত কোনও কক্ষে স্থাপন না করার নিশ্চয়তা দেওয়া হয়।

কি প্রোগ্রাম

এই ফাংশনটির জন্য একটি বডি লিখুন :

function myMove(p1, id, eid, move, goal, grid, bots, ebots, getMem, setMem) {
    //body goes here
}

প্রতিবার যখন আপনার প্লেয়ারটি সরানো হয় তখন তাকে ডাকা হবে এবং সেই পদক্ষেপের সময় আপনার প্রতিটি বট যে পদক্ষেপ নিতে চান তা ফিরিয়ে আনতে হবে।

আপনি একটি সূচনা পয়েন্ট হিসাবে বেসলাইন কোডটি ব্যবহার করতে পারেন ।

পরামিতি

  • p1একটি bool যে হয় trueআপনি হল P1 এবং falseআপনি P2 এর দ্বারা
  • id একটি পূর্ণসংখ্যা যা আপনার উত্তরের উত্তর আইডি।
    • আপনি নীচের 'ভাগ করুন' লিঙ্কটি ক্লিক করে এবং a/URL এর ঠিক পরে নম্বরটি সন্ধান করে একটি উত্তরের আইডি খুঁজে পেতে পারেন ।
    • পরীক্ষার প্রবেশের আইডি -1 হয় 1
  • eid এটি একটি পূর্ণসংখ্যা যা আপনার শত্রুর উত্তরের আইডি।
  • move 1 থেকে 1000 এর পূর্ণসংখ্যা যা আপনাকে কী সরানো হয় তা বলে।
  • goalসঙ্গে একটি অবজেক্ট xএবং yবৈশিষ্ট্য। এগুলি হ'ল গোলের স্থানাঙ্ক। লক্ষ্যটি আপনার FOV এর বাইরে থাকলেও এগুলি দেওয়া হয়।
  • gridএক্স এবং ওয়াই আর্গুমেন্ট গ্রহণ করে এমন একটি ফাংশন grid(x,y)। এটি ফিরে আসে:
    • -1'অজানা' জন্য যদি x,yতর্কগুলি দুটি পূর্ণসংখ্যা না হয় বা যদি আপনার FOV এ না থাকে।
    • 0'বায়ু' জন্য যদি x,yসীমা ছাড়িয়ে যায় বা যদি ঘরটি x,yবায়ুতে থাকে।
    • 1'প্রাচীর' জন্য যদি ঘরটি x,yএকটি প্রাচীর হয়।
  • botsআপনার 8 বটের একটি অ্যারে তার উপাদান বৈশিষ্ট্য সঙ্গে বস্তু x, yএবং hasWall:

    • xএবং yবট এর স্থানাঙ্ক।
    • hasWallহয় trueযদি বট একটি প্রাচীর এবং বহন করা হয় falseযদি না।

    bots সর্বদা স্বাভাবিকভাবে অর্ডার করা হয়, নবম সূচকটি বট সংখ্যা এন এর সাথে মিলে যায়

  • ebotsসঙ্গে বস্তুর একটি অ্যারে x, yএবং hasWallবৈশিষ্ট্য ঠিক bots। আপনার এফওভিতে কেবল শত্রু বট রয়েছে ebots। যদি আপনার এফওভিতে কোনও শত্রু বট না থাকে তবে এটির দৈর্ঘ্য 0 হবে। এটি এলোমেলোভাবে আদেশ করা হয়।
  • getMem কোনও তর্ক ছাড়াই এমন একটি ফাংশন যা আপনার স্মৃতি ফিরে দেয়।
  • setMem এম এমন একটি ফাংশন যা একটি যুক্তি গ্রহণ করে এম। এম 256 অক্ষরের স্ট্রিং বা তার চেয়ে কম হয়, আপনার স্মৃতি এম তে আপডেট হয়, অন্যথায় কিছুই ঘটে না।

ব্রাউজার consoleঅবজেক্টটি কেবল টেস্ট এন্ট্রির জন্য উপলব্ধ।

ফেরত মূল্য

আপনার ফাংশনটিতে যথাযথ 8 টি পূর্ণসংখ্যার অ্যারেটি ফিরিয়ে নেওয়া উচিত, প্রতিটি 0 থেকে 24 এর মধ্যে থাকে index সূচ N এর মান হ'ল বট সংখ্যা এন গ্রহণ করবে।

আপনার সমস্ত বটগুলি আপনার ফাংশনটি করলে কিছুই করবে না:

  • কোনও ধরণের ত্রুটি ছুড়ে দেয়। ( ত্রুটি )
  • কার্যকর করতে 20 মিলিসেকেন্ডের চেয়ে বেশি সময় নেয় । ( সময়সীমা )
  • 0 থেকে 24. পর্যন্ত 8 পূর্ণসংখ্যার একটি অ্যারের ফেরত দেয় না ( বিকৃত )

সুবিধার জন্য, কোনও খেলা শেষ হয়ে গেলে ত্রুটির সংখ্যা, সময়সীমা এবং ত্রুটিযুক্ত ক্রিয়াগুলি প্রদর্শিত হয়।

0 থেকে 24 এর প্রতিটি সংখ্যার একটি নির্দিষ্ট বট ক্রিয়াটির সাথে মিলে যায়:

  • 0 কিছুই করার জন্য নয়।
  • 1-8 চলন্ত জন্য হয়।
  • 9-16 দখলের জন্য।
  • 17-24 রাখার জন্য হয়।

সরানো, দখল করা এবং স্থাপনের জন্য 8 টি মানের প্রত্যেকটিরই বটের প্রতিবেশী কোষগুলির সাথে সামঞ্জস্য হয়, যেমন এখানে প্রদর্শিত:

সুতরাং, উদাহরণস্বরূপ, 15বটের নীচে ঘরটি দখল করার ক্রিয়াটি।

বট ক্রমগুলি বট 0 থেকে বট 7 ক্রমে পরিচালনা করা হয় উদাহরণস্বরূপ, যদি একটি চলার সময় বট 0 কে একই বায়ু কোষ বট 1 তে একটি প্রাচীর স্থাপন করতে বলা হয়, বায়ু কোষ বটের আগে প্রাচীর হয়ে যাবে 1 এর ক্রিয়াটি পরিচালনা করা হয় এবং বট 1 ব্যর্থ হবে।

অসফল কর্মগুলি উল্লেখযোগ্য হয়ে ওঠে এবং বলা হয় যে এটি ব্যর্থ হয়েছে । গেম শেষ হয়ে গেলে ব্যর্থ অ্যাকশন কাউন্টারগুলিও প্রদর্শিত হয়।

বিধি

আমি সাময়িকভাবে বা স্থায়ীভাবে অযোগ্য বা ব্যবহারকারীদের বা এই নিয়মগুলি অনুসরণ করে না এমন উত্তরগুলি অযোগ্য করতে পারি। অযোগ্য এন্ট্রিগুলি জয়ের যোগ্য নয়।

  • ভেরিয়েবল বা ফাংশন ঘোষণা করার সময়, আপনাকে varকীওয়ার্ডটি ব্যবহার করতে হবে ।
    উদাহরণস্বরূপ var x = 10বা বিশ্বব্যাপী var sum = function(a, b){ return a + b }
    না varহয়ে ঘোষণা করা জিনিসগুলি এবং নিয়ামকের সাথে হস্তক্ষেপ করতে পারে। পদক্ষেপ নেওয়া হয়েছে যাতে এই হস্তক্ষেপটি অসম্ভব হওয়া উচিত তবে এটি নিশ্চিত করার জন্য এটি করুন।

  • আপনার কোডটি ধীরে ধীরে চলবে না বা সময় নষ্ট করা উচিত নয়।
    জাভাস্ক্রিপ্ট ফাংশন মিড-এক্সিকিউশন বন্ধ করা অসম্ভব, তাই প্রতিটি প্লেয়ারের কোডটি সমাপ্তিতে চালিত হয়। যদি আপনার কোডটি চালাতে দীর্ঘ সময় নেয়, আপনার প্লেয়ারটি চালাচ্ছেন প্রত্যেকে খেয়াল করবে এবং বিরক্ত হবে। আদর্শভাবে, এন্ট্রিগুলি সর্বদা 20 মিমি সীমার মধ্যে ভালভাবে চলবে।

  • ফায়ারফক্সের সর্বশেষ সংস্করণে আপনাকে অবশ্যই ECMAScript 5 এর সাথে সামঞ্জস্যপূর্ণ কোডটি ব্যবহার করতে হবে কারণ আমি এটি এটি চালাচ্ছি। ECMAScript 6 থেকে বৈশিষ্ট্যগুলি ব্যবহার করবেন না কারণ এটি এখনও অনেক ব্রাউজারে সমর্থিত নয়।
  • আপনি 3 বার পর্যন্ত উত্তর দিতে পারেন , তবে কেবলমাত্র যদি আপনার প্রতিটি কৌশলই যথেষ্ট আলাদা হয়। আপনি যতটা ইচ্ছা উত্তরগুলি সম্পাদনা করতে পারেন।
  • আপনার ব্যবহার getMemএবং ব্যবহার ব্যতীত কোনও ধরণের মেমরি থাকার চেষ্টা নাও করতে পারে setMem
  • আপনি নিয়ামক, অন্যান্য প্লেয়ারের কোড বা বাহ্যিক সংস্থানগুলিতে অ্যাক্সেস বা সংশোধন করার চেষ্টা করতে পারেন না।
  • আপনি জাভাস্ক্রিপ্ট মধ্যে নির্মিত যে কোনও কিছু পরিবর্তন করার চেষ্টা নাও করতে পারেন।
  • উত্তরগুলি হতাশাবোধমূলক হওয়া উচিত নয়। আপনি ব্যবহার করতে পারেন Math.random

উত্তর ফর্ম্যাট

#EntryName

Notes, etc.

<!-- language: lang-js -->

    //function body
    //probably on multiple lines

More notes, etc.

প্রথম মাল্টলাইন কোড ব্লকে অবশ্যই আপনার ফাংশন বডি থাকতে হবে।
প্রবেশের নামটি 20 টি অক্ষরের মধ্যে সীমাবদ্ধ।

আপনার এন্ট্রিটি শিরোনাম সহ নিয়ামকটিতে প্রদর্শিত হবে EntryName - Username [answer ID], [DQ]যদি এটি অযোগ্য হয় তবে।

জয়লাভ

যখন প্রশ্নটি কমপক্ষে 3 সপ্তাহ ধরে চলে যায় এবং একবার উত্তর দেওয়া বন্ধ হয়ে যায়, আমি চ্যাম্পিয়নকে মুকুট দেব।

আমি নিয়ামকের অটোরুন বৈশিষ্ট্যটি ব্যবহার করব । একটি অটোরান রাউন্ডে, অযোগ্য-অযোগ্য প্রত্যেক খেলোয়াড় একে অপরের সাথে দুটি খেলা খায়, একটি পি 1 হিসাবে, একটি পি 2 (একটি ডাবল রাউন্ড-রবিন)।

আমি কয়েক ঘণ্টার মধ্যে যতটা রাউন্ডে পারি তার স্বয়ংক্রিয়করণ করব। এটি সেখানে কতগুলি জমা রয়েছে এবং কতটা সময় নিবিড় তা নির্ভর করবে। তবে বিশ্রামের আশ্বাস, আমি একটি সঠিক চূড়ান্ত লিডারবোর্ড পেতে প্রতিশ্রুতিবদ্ধ। সর্বাধিক বিজয়ী খেলোয়াড় চ্যাম্পিয়ন এবং তাদের উত্তর গৃহীত হবে।

আমি উইন্ডোজ 8.1 64-বিট, 4 জিবি র‌্যাম এবং একটি 1.6GHz কোয়াড-কোর প্রসেসর সহ একটি ল্যাপটপে ফায়ারফক্স ব্যবহার করব।

পুরস্কার

আমি চ্যাম্পিয়নকে বিশেষভাবে উত্সর্গীকৃত একটি পিপিসিজি চ্যালেঞ্জ লিখব এবং পোস্ট করব। এটি কোনওভাবে তাদের ব্যবহারকারীর নাম বা অবতার বা তাদের সম্পর্কে কিছু জড়িত থাকবে। এই প্রতিযোগিতাটি শেষ হলে চ্যালেঞ্জটি কী হবে সে সম্পর্কে আমি ব্যক্তিগতভাবে সিদ্ধান্ত নেব। আমি এটিকে আমার যোগ্যতার সেরাটিতে লিখব এবং এটি একটি হট নেটওয়ার্ক প্রশ্নে পরিণত হয়েছে কিনা তা নিশ্চিত করার চেষ্টা করব।

নিয়ামক

নিয়ামকটি ব্যবহার করতে এই স্নিপেটটি চালান বা এই জেএসফিডেলে যান। এটি এলোমেলো খেলোয়াড় নির্বাচিত দিয়ে শুরু হয়। আমি এটি ফায়ারফক্স এবং ক্রোমে কেবল পুরোপুরি পরীক্ষা করেছি।

<style>html *{font-family:Consolas,Arial,sans-serif}canvas{margin:6px}button,input table,select{font-size:100%}textarea{font-family:monospace}input[type=text],textarea{padding:2px}textarea[readonly]{background-color:#eee}select{width:250pt;margin:3px 0}input[type=radio]{vertical-align:-.25em}input[type=checkbox]{vertical-align:-.15em}.c{margin:12px}.h{font-size:125%;font-weight:700}#main td{padding:12px;text-align:left}#main table{margin-left:auto;margin-right:auto}#main{text-align:center}#title{margin:12px;font-size:175%;font-weight:700;color:#333}#delay{text-align:right}#statsTable table{border-collapse:collapse}#statsTable td{border:1px solid gray;padding:3pt;font-family:monospace;text-align:center}#footnotes{margin:18px 0 0;font-size:75%}#arWrapper{border:2px solid red;background-color:#fff4f4}</style><div id=loadStatus>Loading entries...</div><div id=main><div id=title>Block Building Bot Flocks</div><div><span id=p1Title class=p1Color></span> vs. <span id=p2Title class=p2Color></span></div><canvas id=canvas>Canvas unsupported!</canvas><div><span id=p1Score class=p1Color>0</span> | <span id=moveCounter>0</span> | <span id=p2Score class=p2Color>0</span></div><div class=c><button id=runPause type=button onclick=runPause()>Run</button> <button id=moveOnce type=button onclick=moveOnce()>Move Once</button> <button type=button onclick=newGame()>New Game</button></div><div class=c><input id=delay size=4 value=20> ms delay <input id=showNumbers type=checkbox onclick=toggleNumbers()><label for=showNumbers>Show bot numbers</label>&nbsp;<input id=showLOS type=checkbox onclick=toggleLOS()><label for=showLOS>Show field of view</label></div><table><tr><td><div id=p1Header class="p1Color h">Player 1</div><div><select id=p1Select onchange=changeSelect(!0)></select></div><div><a id=p1Link href=javascript:;>Answer Link</a></div><td><div id=p2Header class="p2Color h">Player 2</div><div><select id=p2Select onchange=changeSelect(!1)></select></div><div><a id=p2Link href=javascript:;>Answer Link</a></div></table><div>Test Entry</div><div><textarea id=testEntry rows=8 cols=64>return [0,0,0,0,0,0,0,0]</textarea></div><div class=c><button type=button onclick=autorun()>Autorun N Rounds</button> N&nbsp;=&nbsp;<input id=N size=4 value=1> <input id=arTestEntry type=checkbox><label for=arTestEntry>Include Test Entry</label></div><div id=footnotes><input id=debug type=checkbox onclick=toggleDebug()><label for=debug>Console debug messages</label>&nbsp;| Scale: <input id=sc1 type=radio name=sc value=1><label for=sc1>Micro</label><input id=sc3 type=radio name=sc value=3><label for=sc3>Small</label><input id=sc6 type=radio name=sc value=6 checked><label for=sc6>Normal</label><input id=sc9 type=radio name=sc value=9><label for=sc9>Large</label>&nbsp;| Colors: <input id=normalCo type=radio name=co value=normal checked><label for=normalCo>Normal</label><input id=pastelCo type=radio name=co value=pastel><label for=pastelCo>Pastels</label><input id=neonCo type=radio name=co value=neon><label for=neonCo>Neon</label>&nbsp; <button type=button onclick=reload()>Reload</button><div id=invalidWrapper><br>No entry name/code found: <span id=invalid></span></div></div></div><div id=arWrapper><div id=arInfo class=c>Autorun in progress. Running game <span id=arProgress></span>.</div><div id=arResults><div class="c h">Autorun Results</div><div class=c>Players: <span id=arPlayers></span><br>Rounds: <span id=arRounds></span><br>Games per round: <span id=arGpR></span><br>Total games: <span id=arTotal></span><br></div><div class=c><strong>Leaderboard:</strong></div><div id=leaderboard class=c></div><div class=c>(W = wins, T = ties, L = losses, G = total goals, E = errors, I = timeouts, M = malformed actions, F = failed actions)</div><div class=c><strong>Player vs. Player Statistics:</strong></div><div id=statsTable class=c></div><div class=c>The top row has the ID's of P1.<br>The left column has the ID's of P2.<br>Every other cell not on the diagonal has the form "[P1 win count] [tie count] [P2 win count]".</div><div class=c><button type=button onclick=closeAutorun()>Close</button></div></div></div><script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><script>function setGlobals(e){G={},G.QID=50690,G.SITE="codegolf",G.DQ_ANSWERS=[],G.DQ_USERS=[],G.DEBUG=Q("#debug").is(":checked"),G.SHOW_NUMBERS=Q("#showNumbers").is(":checked"),G.SHOW_LOS=Q("#showLOS").is(":checked"),G.BOTS=8,G.LOS=6,G.W=128,G.H=64,G.SCALE=e?6:parseInt(Q('input[name="sc"]:checked').val()),G.CW=G.SCALE*G.W,G.CH=G.SCALE*G.H,G.TOTAL_MOVES=2e3,G.GOAL_LIFESPAN=500,G.MEM_MAX_LENGTH=256,G.TIME_LIMIT=20;var t=Q('input[name="co"]:checked').val();e||"normal"===t?G.COLORS={AIR:"#ccc",WALL:"#888",GOAL:"rgba(255,255,0,0.6)",BG:"#f7f7f7",P1:"#00f",P1_TEXT:"#008",P1_LOS:"rgba(0,0,255,0.1)",P2:"#f00",P2_TEXT:"#800",P2_LOS:"rgba(255,0,0,0.1)"}:"pastel"===t?G.COLORS={AIR:"#cef0ff",WALL:"#66cc66",GOAL:"rgba(0,0,0,0.3)",BG:"#fdfde6",P1:"#f4a034",P1_TEXT:"#a35f00",P1_LOS:"rgba(255,179,71,0.2)",P2:"#f67cf6",P2_TEXT:"#b408b4",P2_LOS:"rgba(249,128,249,0.2)"}:"neon"===t&&(G.COLORS={AIR:"#000",WALL:"#444",GOAL:"rgba(255,255,0,0.9)",BG:"#999",P1:"#0f0",P1_TEXT:"#5f5",P1_LOS:"rgba(255,128,0,0.15)",P2:"#f0f",P2_TEXT:"#f5f",P2_LOS:"rgba(0,255,255,0.15)"}),G.SCOREBOARD={P1SCORE:void 0,MOVE:void 0,P2SCORE:void 0},G.CTX=void 0,G.PLAYERS=void 0,G.GAME=void 0,G.TIMER=void 0,G.RUNNING=!1}function reload(){var e="undefined"==typeof G;e||stopTimer(),setGlobals(e);var t=Q("#canvas");t.width(G.CW).height(G.CH).prop({width:G.CW,height:G.CH}),G.CTX=t[0].getContext("2d"),G.CTX.font=(2*G.SCALE).toString()+"px Courier New",G.SCOREBOARD.P1SCORE=Q("#p1Score"),G.SCOREBOARD.MOVE=Q("#moveCounter"),G.SCOREBOARD.P2SCORE=Q("#p2Score"),Q("body").css("background-color",G.COLORS.BG),Q(".p1Color").css("color",G.COLORS.P1),Q(".p2Color").css("color",G.COLORS.P2),Q("#invalidWrapper").hide(),Q("#arWrapper").hide(),loadAnswers(G.SITE,G.QID,function(e){Q.isArray(e)?(Q("#loadStatus").remove(),loadPlayers(e),newGame()):Q("#loadStatus").text("Error loading entries - "+e)})}function maskedEval(e,t){var r={};for(i in this)r[i]=void 0;for(i in t)t.hasOwnProperty(i)&&(r[i]=t[i]);return new Function("with(this) { "+e+";}").call(r)}function toKey(e,t){return G.W*t+e}function fromKey(e){return{x:e%G.W,y:Math.floor(e/G.W)}}function outOfBounds(e,t){return 0>e||e>=G.W||0>t||t>=G.H}function rnd(e){return Math.floor(Math.random()*e)}function isInt(e){return"number"==typeof e&&e%1===0}function isString(e){return"string"==typeof e||e instanceof String}function decode(e){return Q("<textarea>").html(e).text()}function shuffle(e){for(var t,r,o=e.length;o;t=rnd(o),r=e[--o],e[o]=e[t],e[t]=r);}function makeTable(e){for(var t=Q("<table>"),r=0;r<e.length;r++){for(var o=Q("<tr>"),a=0;a<e[r].length;a++)o.append(Q("<td>").text(e[r][a]));t.append(o)}return t}function toggleDebug(){G.DEBUG=Q("#debug").is(":checked")}function toggleNumbers(){G.SHOW_NUMBERS=Q("#showNumbers").is(":checked"),drawGame(G.GAME)}function toggleLOS(){G.SHOW_LOS=Q("#showLOS").is(":checked"),drawGame(G.GAME)}function closeAutorun(){Q("#arWrapper").hide(),Q("#main").show()}function changeSelect(e){var t=Q(e?"#p1Select":"#p2Select").val(),r=Q(e?"#p1Link":"#p2Link");null===t&&0>t?r.attr("href","javascript:;"):r.attr("href",G.PLAYERS[t].link)}function stopTimer(){"undefined"!=typeof G.TIMER&&clearInterval(G.TIMER)}function moveOnce(){gameOver(G.GAME)||(moveGame(G.GAME),drawGame(G.GAME),gameOver(G.GAME)&&(stopTimer(),Q("#runPause").text("Run").prop("disabled",!0),Q("#moveOnce").prop("disabled",!0),G.DEBUG&&console.log("======== GAME OVER: "+G.GAME.p1.score+" TO "+G.GAME.p2.score+" ========"),alert(gameOverMessage(G.GAME))))}function runPause(){if(G.RUNNING)stopTimer(),Q("#runPause").text("Run"),Q("#moveOnce").prop("disabled",!1);else{var e=parseInt(Q("#delay").val());if(isNaN(e)||0>e)return void alert("Delay must be a non-negative integer.");Q("#runPause").text("Pause"),Q("#moveOnce").prop("disabled",!0),G.TIMER=setInterval(moveOnce,e)}G.RUNNING=!G.RUNNING}function newGame(){stopTimer();var e=G.PLAYERS[Q("#p1Select").val()],t=G.PLAYERS[Q("#p2Select").val()];G.RUNNING=!1,Q("#runPause").text("Run").prop("disabled",!1),Q("#moveOnce").prop("disabled",!1),Q("#p1Title").text(e.title),Q("#p2Title").text(t.title),G.GAME=createGame(e,t),drawGame(G.GAME)}function tryParse(e,t){var r=parseInt(Q(e).val());return!isNaN(r)&&r>=0?r:void alert(t+" must be a non-negative integer.")}function autorun(){function e(){for(var e=new Array(a.length),t={},r=["wins","goals","errors","timeouts","malformed","invalid"],n=0;n<e.length;n++){t.wins=t.ties=t.losses=t.goals=t.errors=t.timeouts=t.malformed=t.invalid=0;for(var l=0;l<e.length;l++)n!==l&&(t.ties+=s[n][l].ties+s[l][n].ties,t.losses+=s[n][l].p2.wins+s[l][n].p1.wins,r.forEach(function(e){t[e]+=s[n][l].p1[e]+s[l][n].p2[e]}));e[n]={wins:t.wins,text:a[n].title+" : "+t.wins+"W, "+t.ties+"T, "+t.losses+"L, "+t.goals+"G, "+t.errors+"E, "+t.timeouts+"I, "+t.malformed+"M, "+t.invalid+"F"}}e=e.sort(function(e,t){return t.wins-e.wins}).map(function(t,r){return r+1+". "+t.text+(r<e.length-1?"<br>":"")});for(var i=new Array(s.length+1),G=0;G<i.length;G++){i[G]=new Array(s.length+1);for(var c=0;c<i.length;c++){var f;i[G][c]=0===c&&0===G?"P2\\P1":0===c?a[G-1].id:0===G?a[c-1].id:(f=s[c-1][G-1])?f.p1.wins+" "+f.ties+" "+f.p2.wins:"-"}}Q("#arPlayers").text(a.length),Q("#arRounds").text(o),Q("#arGpR").text(S/o),Q("#arTotal").text(S),Q("#leaderboard").empty().append(e),Q("#statsTable").empty().append(makeTable(i)),Q("#arInfo").hide(),Q("#arResults").show()}function t(e,t){for(var r=createGame(a[e],a[t]);!gameOver(r);)moveGame(r);r.p1.score>r.p2.score?s[e][t].p1.wins++:r.p1.score<r.p2.score?s[e][t].p2.wins++:s[e][t].ties++,["p1","p2"].forEach(function(o){s[e][t][o].goals+=r[o].score,s[e][t][o].errors+=r[o].stats.errors,s[e][t][o].timeouts+=r[o].stats.timeouts,s[e][t][o].malformed+=r[o].stats.malformed,s[e][t][o].invalid+=r[o].stats.invalid.reduce(function(e,t){return e+t},0)})}function r(){if(c!==f&&(t(c,f),++p<=S&&Q("#arProgress").text(p+"/"+S)),f+1<a.length)f++;else if(f=0,c+1<a.length)c++;else{if(c=0,!(o>i+1))return void e();i++}setTimeout(r,0)}var o=parseInt(Q("#N").val());if(isNaN(o)||1>o)return void alert("N must be a positive integer.");var a=[];Q("#arTestEntry").is(":checked")&&a.push(G.PLAYERS[0]);for(var n=1;n<G.PLAYERS.length;n++)G.PLAYERS[n].dq||a.push(G.PLAYERS[n]);for(var s=new Array(a.length),n=0;n<a.length;n++){s[n]=new Array(a.length);for(var l=0;l<a.length;l++)n!==l&&(s[n][l]={ties:0,p1:{wins:0,goals:0,errors:0,timeouts:0,malformed:0,invalid:0},p2:{wins:0,goals:0,errors:0,timeouts:0,malformed:0,invalid:0}})}var i=0,c=0,f=0,p=1,S=o*a.length*(a.length-1);Q("#arProgress").text("1/"+S),Q("#main").hide(),Q("#arInfo").show(),Q("#arResults").hide(),Q("#arWrapper").show(),setTimeout(r,0)}function gameOver(e){return e.move>=G.TOTAL_MOVES}function gameOverMessage(e){function t(e,t){return"P"+(t?1:2)+": "+e.entry.title+"\nScore: "+e.score+"\nErrors: "+e.stats.errors+"\nTimeouts: "+e.stats.timeouts+"\nMalformed actions: "+e.stats.malformed+"\nFailed actions: ["+e.stats.invalid.toString().replace(/,/g,", ")+"]"}var r="GAME OVER - ";return r+=e.p1.score>e.p2.score?"PLAYER 1 WINS":e.p1.score<e.p2.score?"PLAYER 2 WINS":"TIE GAME",r+="\n\n"+t(e.p1,!0)+"\n\n"+t(e.p2,!1)}function createGame(e,t){function r(e){return{entry:e,bots:new Array(G.BOTS),mem:"",score:0,stats:{errors:0,timeouts:0,malformed:0,invalid:Array.apply(null,new Array(G.BOTS)).map(Number.prototype.valueOf,0)}}}var o={},a=Math.floor(.875*G.H)-1;o.move=0,o.walls=new Array(G.H);for(var n=0;n<G.H;n++){o.walls[n]=new Array(G.W);for(var s=0;s<G.W;s++)o.walls[n][s]=n>a}o.p1=r(e),o.p2=r(t);for(var l=0;l<G.BOTS;l++)o.p1.bots[l]={x:l,y:a,hasWall:!1},o.p2.bots[l]={x:G.W-1-l,y:a,hasWall:!1};if(-1===o.p1.entry.id||-1===o.p2.entry.id){var i=decode(Q("#testEntry").val());-1===o.p1.entry.id&&(o.p1.entry.code=i),-1===o.p2.entry.id&&(o.p2.entry.code=i)}return resetGoal(o),G.DEBUG&&console.log("======== NEW GAME: "+o.p1.entry.title+" VS "+o.p2.entry.title+" ========"),o}function moveGame(e){movePlayer(e,++e.move%2===1),++e.goal.age>=G.GOAL_LIFESPAN&&resetGoal(e)}function setupParams(e,t){function r(e,t){var r=toKey(e,t);if(!n.hasOwnProperty(r)){n[r]=!1;for(var a=0;a<G.BOTS;a++)if(Math.abs(o.bots[a].x-e)<=G.LOS&&Math.abs(o.bots[a].y-t)<=G.LOS){n[r]=!0;break}}return n[r]}var o=t?e.p1:e.p2,a=t?e.p2:e.p1,n={},s={};s.p1=t,s.id=o.entry.id,s.eid=a.entry.id,s.score=o.score,s.escore=a.score,s.move=Math.floor((e.move+1)/2),s.goal={x:e.goal.x,y:e.goal.y},s.getMem=function(){return o.mem},s.setMem=function(e){isString(e)&&e.length<=G.MEM_MAX_LENGTH&&(o.mem=e)},s.grid=function(t,o){return isInt(t)&&isInt(o)&&r(t,o)?outOfBounds(t,o)?0:e.walls[o][t]?1:0:-1},s.bots=new Array(G.BOTS),s.ebots=[];for(var l=0;l<G.BOTS;l++)s.bots[l]={x:o.bots[l].x,y:o.bots[l].y,hasWall:o.bots[l].hasWall},r(a.bots[l].x,a.bots[l].y)&&s.ebots.push({x:a.bots[l].x,y:a.bots[l].y,hasWall:a.bots[l].hasWall});return shuffle(s.ebots),-1===o.entry.id&&(s.console=console),s}function movePlayer(e,t){var r,o,a=t?e.p1:e.p2,n=t?e.p2:e.p1,s=setupParams(e,t);G.DEBUG&&(console.log("######## MOVE "+e.move+" - P"+(t?1:2)+" ########"),console.log("PARAMETERS:"),console.log(s)),o=performance.now();try{r=maskedEval(a.entry.code,s)}catch(n){return a.stats.errors++,void(G.DEBUG&&(console.log("!!!! ERRORED !!!!"),console.log(n)))}if(o=performance.now()-o,G.DEBUG&&console.log("TIME TAKEN: "+o+"ms"),o>G.TIME_LIMIT)return a.stats.timeouts++,void(G.DEBUG&&console.log("!!!! TIMED OUT !!!!"));if(G.DEBUG&&(console.log("ACTIONS:"),console.log(r)),!Array.isArray(r)||r.length!==G.BOTS)return a.stats.malformed++,void(G.DEBUG&&console.log("!!!! MALFORMED ACTIONS !!!!"));for(var l=0;l<G.BOTS;l++)if(!isInt(r[l])||r[l]<0||r[l]>24)return a.stats.malformed++,void(G.DEBUG&&console.log("!!!! MALFORMED ACTIONS !!!!"));performActions(e,a,r)}function performActions(e,t,r){function o(e){t.stats.invalid[e]++,G.DEBUG&&console.log("!! BOT"+e+" ACTION FAILED !!")}function a(e){return e.x!==i||e.y!==c}for(var n=!1,s=0;s<G.BOTS;s++){var l=r[s];if(l){var i,c;switch((l-1)%8){case 0:i=-1,c=-1;break;case 1:i=0,c=-1;break;case 2:i=1,c=-1;break;case 3:i=-1,c=0;break;case 4:i=1,c=0;break;case 5:i=-1,c=1;break;case 6:i=0,c=1;break;case 7:i=1,c=1}if(i+=t.bots[s].x,c+=t.bots[s].y,outOfBounds(i,c))o(s);else switch(Math.floor((l-1)/8)){case 0:!e.walls[c][i]&&(i>0&&c>0&&e.walls[c-1][i-1]||c>0&&e.walls[c-1][i]||i<G.W-1&&c>0&&e.walls[c-1][i+1]||i>0&&e.walls[c][i-1]||i<G.W-1&&e.walls[c][i+1]||i>0&&c<G.H-1&&e.walls[c+1][i-1]||c<G.H-1&&e.walls[c+1][i]||i<G.W-1&&c<G.H-1&&e.walls[c+1][i+1])?(t.bots[s].x=i,t.bots[s].y=c,i!==e.goal.x||c!==e.goal.y||n||(n=!0,G.DEBUG&&console.log("** BOT"+s+" REACHED GOAL **"))):o(s);break;case 1:e.walls[c][i]&&!t.bots[s].hasWall?(e.walls[c][i]=!1,t.bots[s].hasWall=!0):o(s);break;case 2:!e.walls[c][i]&&t.bots[s].hasWall&&e.p1.bots.every(a)&&e.p2.bots.every(a)?(e.walls[c][i]=!0,t.bots[s].hasWall=!1):o(s)}}}n&&(t.score++,resetGoal(e)),G.DEBUG&&(console.log("FINAL PLAYER STATE:"),console.log(t))}function resetGoal(e){for(var t={},r=[],o=0;o<G.BOTS;o++)t[toKey(e.p1.bots[o].x,e.p1.bots[o].y)]=!0,t[toKey(e.p2.bots[o].x,e.p2.bots[o].y)]=!0;for(var a=0;a<G.H;a++)for(var n=0;n<G.W;n++){var s=toKey(n,a);t.hasOwnProperty(s)||r.push(s)}var l=fromKey(r[rnd(r.length)]);e.goal={age:0,x:l.x,y:l.y}}function drawGame(e){function t(e,t){G.CTX.fillRect(e*G.SCALE,t*G.SCALE,G.SCALE,G.SCALE)}function r(e,t){G.CTX.fillRect(e*G.SCALE+1,t*G.SCALE+1,G.SCALE-2,G.SCALE-2)}G.CTX.fillStyle=G.COLORS.AIR,G.CTX.fillRect(0,0,G.CW,G.CH),G.CTX.fillStyle=G.COLORS.WALL;for(var o=0;o<G.H;o++)for(var a=0;a<G.W;a++)e.walls[o][a]&&t(a,o);if(G.SHOW_LOS){var n=(2*G.LOS+1)*G.SCALE;G.CTX.fillStyle=G.COLORS.P1_LOS;for(var s=0;s<G.BOTS;s++)G.CTX.fillRect((e.p1.bots[s].x-G.LOS)*G.SCALE,(e.p1.bots[s].y-G.LOS)*G.SCALE,n,n);G.CTX.fillStyle=G.COLORS.P2_LOS;for(var s=0;s<G.BOTS;s++)G.CTX.fillRect((e.p2.bots[s].x-G.LOS)*G.SCALE,(e.p2.bots[s].y-G.LOS)*G.SCALE,n,n)}G.CTX.fillStyle=G.COLORS.P1;for(var s=0;s<G.BOTS;s++)t(e.p1.bots[s].x,e.p1.bots[s].y);G.CTX.fillStyle=G.COLORS.P2;for(var s=0;s<G.BOTS;s++)t(e.p2.bots[s].x,e.p2.bots[s].y);G.CTX.fillStyle=G.COLORS.WALL;for(var s=0;s<G.BOTS;s++)e.p1.bots[s].hasWall&&r(e.p1.bots[s].x,e.p1.bots[s].y),e.p2.bots[s].hasWall&&r(e.p2.bots[s].x,e.p2.bots[s].y);if(G.SHOW_NUMBERS){var l=-.1,i=2.75;G.CTX.fillStyle=G.COLORS.P1_TEXT;for(var s=0;s<G.BOTS;s++)G.CTX.fillText(s.toString(),(e.p1.bots[s].x+l)*G.SCALE,(e.p1.bots[s].y+i)*G.SCALE);G.CTX.fillStyle=G.COLORS.P2_TEXT;for(var s=0;s<G.BOTS;s++)G.CTX.fillText(s.toString(),(e.p2.bots[s].x+l)*G.SCALE,(e.p2.bots[s].y+i)*G.SCALE)}G.CTX.fillStyle=G.COLORS.GOAL,t(e.goal.x+1,e.goal.y),t(e.goal.x-1,e.goal.y),t(e.goal.x,e.goal.y+1),t(e.goal.x,e.goal.y-1),G.SCOREBOARD.P1SCORE.text(e.p1.score),G.SCOREBOARD.MOVE.text(e.move),G.SCOREBOARD.P2SCORE.text(e.p2.score)}function loadPlayers(e){var t=/<pre\b[^>]*><code\b[^>]*>([\s\S]*?)<\/code><\/pre>/,r=/<h1\b[^>]*>(.*?)<\/h1>/;G.PLAYERS=[];var o={id:-1,dq:!1,code:void 0,link:"javascript:;",title:"TEST ENTRY [-1]"};G.PLAYERS.push(o);var a=[];e.forEach(function(e){var o=decode(e.owner.display_name),n=t.exec(e.body),s=r.exec(e.body);if(null===n||n.length<=1||null===s||s.length<=1)return a.push(" "),void a.push(Q("<a>").text(o).attr("href",e.link));var l={};l.id=e.answer_id,l.dq=G.DQ_ANSWERS.indexOf(e.answer_id)>-1||G.DQ_USERS.indexOf(e.owner.user_id)>-1,l.code=decode(n[1]),l.link=e.link,l.title=s[1].substring(0,20)+" - "+o+" ["+l.id.toString()+"]",l.dq&&(l.title+="[DQ]"),G.PLAYERS.push(l)}),a.length>0&&(Q("#invalid").empty().append(a),Q("#invalidWrapper").show());for(var n=new Array(G.PLAYERS.length),s=new Array(G.PLAYERS.length),l=0;l<G.PLAYERS.length;l++)n[l]=Q("<option>").text(G.PLAYERS[l].title).val(l),s[l]=Q("<option>").text(G.PLAYERS[l].title).val(l);Q("#p1Select").empty().append(n).val(rnd(G.PLAYERS.length)),changeSelect(!0),Q("#p2Select").empty().append(s).val(rnd(G.PLAYERS.length)),changeSelect(!1)}function loadAnswers(e,t,r){function o(){Q.get("https://api.stackexchange.com/2.2/questions/"+t.toString()+"/answers?page="+(s++).toString()+"&pagesize=100&order=asc&sort=creation&site="+e+"&filter=!YOKGPOBC5Yad4mOOn8Z4WcAE6q",a)}function a(e){e.hasOwnProperty("error_id")?r(e.error_id.toString()):(n=n.concat(e.items),e.hasMore?o():r(n))}var n=[],s=1;o(s,a)}Q=jQuery,Q(reload);</script>

এই প্রশ্নের নিজস্ব চ্যাটরুম রয়েছে। আমি সেখানে কয়েক দিন লিডারবোর্ড পোস্ট করব।



3
গ্রিডের আকার সামঞ্জস্য করতে বোতামগুলির জন্য ধন্যবাদ, আমি আমার ফোনে স্ট্যাক স্নিপেট চালাতে পারি :)
ট্রাইকোপল্যাক্স

3
প্রচুর ভালবাসা (কোডগল্ফ.স্ট্যাকেক্সেঞ্জার.কমেশনস /50768/) তবে এটি সহজ নয়
edc65

3
এটি দেখতে মন্ত্রমুগ্ধকর।
ডিএলসাস

1
@ স্টিফেন হ্যাঁ নিয়ম বুলেট 4: "আপনি উত্তরগুলি ইচ্ছামত সম্পাদনা করতে পারবেন।"
ক্যালভিনের

উত্তর:


13

কালো যোদ্ধা

এটি দাবা নাইটের মতো চলাফেরা করতে সক্ষম হওয়ার জন্য বটের নামটি প্রাথমিক পরিকল্পনা থেকে আসে: দু'জনের উপরে একজন, এক ইত্যাদি, যা কিছু ক্ষেত্রে দ্রুত হবে।

var moves = new Array(8),
    mem = getMem(), newMem = '';

var decodeMem = function(){
  //mmtxy
  for(var ind = 0; ind < 8; ind++){
    var sub = mem.substr(ind * 5, 5)
    bots[ind].lastMove = parseInt(sub[0], 36);
    bots[ind].last2Move = parseInt(sub[1], 36);
    bots[ind].timesStill = sub.charCodeAt(2) - 48;
    bots[ind].lastX = sub.charCodeAt(3) - 187;
    bots[ind].lastY = sub.charCodeAt(4) - 187;
  }
}
decodeMem();

var distanceTo = function(fromX, fromY, toX, toY){
  // Chebyshev distance
  return Math.max(Math.abs(fromX - toX),
                  Math.abs(fromY - toY));
}

var direction = function(from, to){ // Math.sign()
  var diff = to - from;
  return diff > 0 ? 1 : (diff < 0 ? -1 : 0);
}

var dirs = [
  [1, 2, 3],
  [4, 0, 5],
  [6, 7, 8]
];

var moveTo = function(from, to){
  var prioritiesWall = [
    [0],
    [1, 2, 4, 17, 18, 20, 19, 22, 23, 21, 3, 6, 5, 7, 24, 8],
    [2, 3, 1, 17, 19, 18, 23, 22, 24, 4, 5, 20, 21, 6, 8, 7],
    [3, 2, 5, 19, 18, 21, 17, 24, 23, 20, 1, 8, 4, 7, 22, 6],
    [4, 1, 6, 22, 17, 20, 21, 24, 19, 2, 7, 18, 23, 3, 8, 5],
    [5, 3, 8, 24, 19, 21, 20, 22, 17, 2, 7, 18, 23, 1, 6, 4],
    [6, 4, 7, 22, 20, 23, 17, 24, 18, 21, 1, 8, 2, 5, 19, 3],
    [7, 8, 6, 22, 24, 23, 18, 17, 19, 4, 5, 20, 21, 1, 3, 2],
    [8, 5, 7, 24, 21, 23, 19, 22, 18, 20, 3, 6, 2, 4, 17, 1]
  ];
  var prioritiesNoWall = [
    [9, 10, 11, 12, 13, 14, 15, 16, 0],
    [1, 2, 4, 9, 16, 10, 12, 3, 6, 11, 14, 5, 7, 13, 15, 8],
    [2, 3, 1, 10, 15, 14, 16, 4, 5, 12, 13, 9, 11, 6, 8, 7],
    [3, 2, 5, 11, 14, 10, 13, 1, 8, 9, 16, 4, 7, 12, 15, 6],
    [4, 1, 6, 12, 13, 16, 11, 2, 7, 10, 15, 9, 14, 3, 8, 5],
    [5, 3, 8, 13, 12, 14, 9, 2, 7, 10, 15, 11, 16, 1, 6, 4],
    [6, 4, 7, 14, 11, 12, 15, 1, 8, 9, 16, 2, 5, 10, 13, 3],
    [7, 8, 6, 15, 10, 9, 11, 4, 5, 12, 13, 14, 16, 1, 3, 2],
    [8, 5, 7, 16, 9, 13, 15, 3, 6, 11, 14, 2, 4, 10, 12, 1]
  ];

  var dir = dirs[direction(from.y, to.y) + 1][direction(from.x, to.x) + 1],
      method = from.hasWall ? prioritiesWall[dir] : prioritiesNoWall[dir];

  if(distanceTo(from.x, from.y, goal.x, goal.y) === 1){
    method.splice(1,2);
  }

  for(var i=0; i<method.length; i++){
    var attempt = method[i];
    if(checkMove(from, attempt)) return attempt;
  }
  return 0;
}

var numWalls = function(x, y, indexes){
  var allCoords = [
    [x - 1, y - 1],
    [x,     y - 1],
    [x + 1, y - 1],
    [x - 1, y    ],
    [x + 1, y    ],
    [x - 1, y + 1],
    [x,     y + 1],
    [x + 1, y + 1],
  ];
  var allTypes = allCoords.map(function(e){
    return grid(e[0], e[1]); // air = 0, wall = 1
  });
  var justWalls = allTypes.filter(function(e){
    return e === 1;
  }).length;

  return indexes ? allTypes : justWalls;
}

var checkMove = function(coords, moveCode){
  var x = coords.x, y = coords.y,
      baseX = [0, -1, 0, 1, -1, 1, -1, 0, 1],
      baseY = [0, -1, -1, -1, 0, 0, 1, 1, 1],
      targetX = x + baseX[(moveCode - 1) % 8 + 1],
      targetY = y + baseY[(moveCode - 1) % 8 + 1];

  if((targetX > 127 || targetX < 0 || targetY > 63 || targetY < 0) || // Don't bother if it's out of bounds
     (coords.timesStill > 2 && x == coords.lastX && y == coords.lastY && (moveCode == coords.lastMove || moveCode == coords.last2Move)))
    // Or is doing the same moves and not moving
    return false;

  var targetGrid = grid(targetX, targetY), enemyNear = false, couldStrandEnemy = false,
      eWallDirMove, hasNeighbor = numWalls(targetX, targetY) > 0;

  ebots.forEach(function(ebot){
    // Don't place a wall where an enemy can take it
    if(distanceTo(targetX, targetY, ebot.x, ebot.y) === 1 && !ebot.hasWall && (y != ebot.y || x != ebot.x))
      enemyNear = true;

    // Don't move if you can strand an enemy
    var eWallDir = numWalls(ebot.x, ebot.y, true).indexOf(1) + 1,
        wallX = ebot.x + baseX[eWallDir], wallY = ebot.y + baseY[eWallDir];

    if(!coords.hasWall && numWalls(ebot.x, ebot.y) === 1 &&
       distanceTo(x, y, wallX, wallY) === 1){
      eWallDirMove = dirs[direction(y, wallY) + 1][direction(x, wallX) + 1] + 8;
      couldStrandEnemy = true;
    }
  })

  if(targetX == goal.x && targetY == goal.y && targetGrid === 0){
    targetGrid = 2 // Don't place a wall in the goal
  } else {
    ebots.concat(bots).forEach(function(bot){
      // Ensure target cell doesn't have a bot in it
      if(bot.x == targetX && bot.y == targetY) targetGrid = 2;
    });
  }

  return ((moveCode < 9 && targetGrid !== 1 && hasNeighbor && !couldStrandEnemy) || // Move
          (moveCode > 8 && moveCode < 17 && targetGrid === 1 && !coords.hasWall && (!couldStrandEnemy || (couldStrandEnemy && eWallDirMove == moveCode))) || // Grab
          (moveCode > 16 && targetGrid === 0 && coords.hasWall && !enemyNear)) // Place
}

var goalClosest = {dist: Infinity}, rescuers = {};
bots.forEach(function(bot, index){

  // Check if bot is stranded
  bot.stranded = false;
  if(numWalls(bot.x, bot.y) / 8 == bot.hasWall){
    bot.stranded = true;
    rescuers[index] = -1;
  }
});

bots.forEach(function(bot, index){
  if(!bot.stranded){
    // Find which bot is closest to the goal
    var goalDist = distanceTo(bot.x, bot.y, goal.x, goal.y);

    if(goalDist < goalClosest.dist){
      goalClosest.dist = goalDist;
      goalClosest.index = index;
    }
  }
});

bots.forEach(function(bot, index){
  var destination = {
    x: 14 + (index % 4) * 32 + 3 * (index > 3),
    y: index > 3 ? 55 : 27
  }
  if(index == goalClosest.index){
    destination = goal;
  }

  moves[index] = moveTo(bot, destination);

  if(moves[index] == bot.lastMove || moves[index] == bot.last2Move) bot.timesStill++;

  newMem += moves[index].toString(36) +
    bot.lastMove.toString(36) +
    String.fromCharCode(bot.timesStill + 48) +
    String.fromCharCode(bot.x + 187) +
    String.fromCharCode(bot.y + 187);
});

setMem(newMem);

return moves;

ব্যাখ্যা

প্রতিটি বোটের জন্য কোন পদক্ষেপটি নির্ধারণ করা দুটি প্রধান কার্যে বিভক্ত করা যেতে পারে: কোথায় কোথায় যাবেন এবং কীভাবে সেখানে যাবেন তা নির্ধারণ করে।

কোথায় যেতে হবে

কোথায় যাবেন তা নির্ধারণের প্রাথমিক কাজটি সহজ: আপনি যদি নিকটতম হন তবে লক্ষের দিকে যান বা অন্যথায় সতীর্থ থেকে নিজেকে দূরে রাখার চেষ্টা করুন। এটি প্রথমে প্রতিটি বোটের মধ্য দিয়ে যায় এবং নির্ধারিত হয় যে এটি আটকা পড়েছে কিনা (অর্থাত্ এটির চারপাশে কোনও ব্লক নেই এবং এটি কোনও প্রাচীর ধারণ করছে না, বা এটি প্রাচীর দ্বারা বেষ্টিত এবং একটি প্রাচীর ধরেছে)। এরপরে লক্ষ্যটির নিকটে থাকা নন-স্ট্র্যান্ডড বটটি খুঁজে পেতে এটি আবার বটগুলির মধ্য দিয়ে যায়। অন্যান্য সমস্ত বটগুলি ব্লকগুলির পৃষ্ঠের নীচে সারি ( y=55) এবং উপরের সারিটি ব্যবধানে বিস্তৃত হওয়ার দিকে এগিয়ে যায় y=27। একবার কোথায় যেতে হবে তা জানার পরে, এটি এটি moveToফাংশনটির হাতে তুলে দেয়।

আমি সেখানে কিভাবে প্রবেশ করব

কীভাবে গন্তব্যে পৌঁছতে হবে তা সিদ্ধান্ত নেওয়া আরও বেশি কঠিন কারণ বটগুলি সরানোর জন্য সর্বদা প্রাচীরের সংলগ্ন থাকতে হবে। এটি প্রথমটির বর্তমান অবস্থানের তুলনায় গন্তব্যের দিকনির্দেশ কোড (1-8) বের করে। উদাহরণস্বরূপ, যদি একটি বট নীচে-বাম কোণে থাকে এবং এটি উপরের ডানদিকে যেতে চায়, তবে এটি নির্দেশ কোডটি 3 ব্যবহার করবে each প্রতিটি দিকের জন্য, আমি প্রথম দিকে আদর্শ, শীর্ষ সহ চালগুলির একটি তালিকা হার্ডকোড করেছি -প্রিয়িটিটি মুভ, এবং সর্বশেষটি শেষ অবলম্বন। বটের দেওয়াল রয়েছে কি না তা এটি দ্বারা পৃথক করা হয়েছে, কারণ আপনি প্রাচীর ব্যতীত কোনও স্থানের চালনা ব্যবহার করতে পারবেন না বা ইতিমধ্যে প্রাচীর থাকার সময় গ্র্যাভ মুভ ব্যবহার করতে পারবেন না।

অবশ্যই, আদর্শ পদক্ষেপটি ব্যবহার করা সবসময় কাজ করে না এবং এর ফলে প্রচুর ব্যর্থ ক্রিয়াকলাপ ঘটে। এটি এখানেই checkMoveআসে This উদাহরণস্বরূপ, বটটি সীমানা বা প্রাচীরের বাইরে যেতে বাধা দেওয়ার জন্য, প্রতিটি প্রয়োজনের বিরুদ্ধে এই কার্যকারিতাটি সম্ভাব্য পদক্ষেপগুলি পরীক্ষা করে। যদি কাছের কোনও শত্রু বট আটকে যেতে পারে (এটির সাথে কেবল একটি সংলগ্ন প্রাচীর রয়েছে যা বটটি ধরে নিতে পারে) এটি তার অগ্রাধিকার হয়ে ওঠে, সুতরাং ফাংশনটি falseঅন্যথায় বৈধ পদক্ষেপের জন্য ফিরে আসবে যাতে এটি দখল করার পদক্ষেপগুলি এড়িয়ে যেতে পারে এবং ফলস্বরূপ কার্যকর করতে পারে শত্রু. ফাংশনটি লক্ষ্য বা অন্য কোনও বোটে প্রাচীর স্থাপনের মতো আরও কয়েকটি বোকা পদক্ষেপগুলিকে বাধা দেয়।

মেমরি স্ট্রিং

কখনও কখনও বটটি আসলে আটকা পড়ে না তবে একই পদক্ষেপের চেষ্টা চালিয়ে যায় এবং চলন্ত শেষ হয় না (সাধারণত কোনও দেয়াল তোলা হয় এবং নীচে ফেলে দেয়, এটি তুলে নিয়ে যায় এবং ইত্যাদি)। এটি প্রতিরোধ করতে, এটি তার শেষ দুটি চাল, তার শেষ এক্স এবং ওয়াই অবস্থান এবং এটি এখনও কতবার হয়েছে তা স্মরণে রাখতে মেমরি স্ট্রিং ব্যবহার করে। প্রতিটি ডিটাম সহজে বিভাজনের জন্য একক অক্ষর হিসাবে এনকোড করা হয়। (স্ট্রিংটি 256 টি অক্ষর হতে হবে , বাইট নয়, তাই মাল্টিবাইট ইউনিকোড অক্ষর ব্যবহার করা কোনও সমস্যা নয়, কারণ এটি সাধারণ গল্ফিং চ্যালেঞ্জের সাথে))

উদাহরণস্বরূপ, বলুন যে একটি বট এই বাঁকটি তার বাঁ দিকে (কোড 12) দেয়ালটি ধরেছে 20এবং তার আগের বাঁকটিতে এটি তার বামে (কোড ) প্রতিস্থাপন করেছে এবং অতীতের বাঁকগুলির জন্য স্থানাঙ্কে ( 107, 3) ছিল 16। এই উদাহরণের জন্য মেমরি স্ট্রিং নীচে এনকোড করা হবে:

  • ck: দুটি সংখ্যার সংখ্যার একক অক্ষর তৈরি করতে দুটি সর্বশেষতম ক্রিয়া কোড বেস 36 এ রূপান্তরিত হয়।
  • @: অপ্রিন্টযোগ্য অক্ষরগুলি এড়িয়ে যাওয়ার জন্য + কোড সহ 48 বার এখনও এটি ASCII চরিত্র হিসাবে প্রদর্শিত হয়েছে এবং তাই প্রথম নয় বার এখনও প্রকৃত সংখ্যাটি দেখায় ( String.fromCharCode(0 + 48)0)।
  • Ħ¾: X এবং y স্থানাঙ্কগুলিও সেই মানটির সাথে চরিত্র হিসাবে উপস্থাপিত হয়, সমস্যাযুক্ত অক্ষরগুলি এড়াতে 187 এর কিছুটা নির্বিচার মান দ্বারা অফসেট করা হয়েছে।

গেমের সময় একটি সাধারণ মেমরি স্ট্রিং হতে পারে 53äÇØb7¼ðÌ00ßĉÖ7m±ĪÚ00ĝÌò00Ĝìò00ĖČò00ĈĬòআটটি বটের প্রত্যেকটির জন্য পাঁচটি অক্ষরের একটি গ্রুপ with


1
কোনও খেলোয়াড় যদি নিজের বিরুদ্ধে খেলায় থাকে তবে কোনও প্লেয়ার 1 বা প্লেয়ার 2 জিততে পারে, কোনও স্পষ্ট পক্ষপাতিত্ব না করে। এই উত্তরটি ব্যতিক্রম, কারণ প্লেয়ার 1 প্রায় সর্বদা একটি বড় ব্যবধানে জয়ী হয়। আমি এর কারণ দেখতে পাচ্ছি না - এটি আকর্ষণীয়।
ট্রাইকোপলাক্স

@ থ্রিচোপলাক্স আমি কল্পনা করেছি কারণ এটি পি 2 পি 2 এর আগে চলেছে, তাই পি 1 পি 2 এটি করার আগে স্ট্র্যান্ড করবে।
নিনজা বিয়ারমনকি

4
চ্যালেঞ্জ শেষ এবং ফলাফল আছে ! 30 রাউন্ডের পরে, ব্ল্যাক নাইটের 204 জয় ছিল, এবং পরবর্তী সেরা এন্ট্রি, সিকার্স কেবল 147 পেয়েছিল Ninja অভিনব নিনজাবার্মনকি ! আপনি নির্দিষ্ট চ্যালেঞ্জ উপায় হয়।
ক্যালভিনের শখ

একেবারে নিনজা! আপনাকে ধন্যবাদ
edc65

12

আউটপোস্ট

8 টি বট প্রত্যেকটি 32 বাই 32 স্কোয়ার নেয় এবং এটির কেন্দ্রের দিকে দৌড়ে যায় (আমি কেন্দ্রগুলি সামান্য অফসেট করি অন্যথায় তারা জুটি বাঁধতে শুরু করে এবং তাদের মধ্যে একটি প্রাচীরের ব্লক দিয়ে উল্লম্বভাবে ভ্রমণ করে, যার মধ্যে একটি আটকে যায়)।

প্রতিটি বট তার স্কোয়ারের কেন্দ্রে থাকবে যদি না লক্ষ্যটি তার নিজ কেন্দ্রে 32 টি কোষের মধ্যে থাকে তবে সেক্ষেত্রে এটি লক্ষ্যে চলে যাবে এবং তারপরে তার কেন্দ্রে ফিরে যাবে।

এটি এখনও তার লক্ষ্য (লক্ষ্য বা কেন্দ্র) পৌঁছানোর বেসলাইন পদ্ধতিটি ব্যবহার করে তাই তির্যকভাবে সরানো হয় না। মাত্র একটি সূচনা পয়েন্ট ...

var encodeAction = function(type, dx, dy) {
    var d
    if (dx === -1 && dy === -1) d = 1
    else if (dx === 0 && dy === -1) d = 2
    else if (dx === 1 && dy === -1) d = 3
    else if (dx === -1 && dy === 0) d = 4
    else if (dx === 1 && dy === 0) d = 5
    else if (dx === -1 && dy === 1) d = 6
    else if (dx === 0 && dy === 1) d = 7
    else if (dx === 1 && dy === 1) d = 8
    else return 0
    return 8 * type + d
}

var getNeighborCell = function(x, y, wallState) {
    if (x > 0 && y > 0 && grid(x - 1, y - 1) === wallState) return { x: x - 1, y: y - 1 }
    if (y > 0 && grid(x, y - 1) === wallState) return { x: x, y: y - 1 }
    if (x < 127 && y > 0 && grid(x + 1, y - 1) === wallState) return { x: x + 1, y: y - 1 }
    if (x > 0 && grid(x - 1, y) === wallState) return { x: x - 1, y: y }
    if (x < 127 && grid(x + 1, y) === wallState) return { x: x + 1, y: y }
    if (x > 0 && y < 63 && grid(x - 1, y + 1) === wallState) return { x: x - 1, y: y + 1 }
    if (y < 63 && grid(x, y + 1) === wallState) return { x: x, y: y + 1 }
    if (x < 127 && y < 63 && grid(x + 1, y + 1) === wallState) return { x: x + 1, y: y + 1 }
    return null
}

var moveBot = function(n) {
    var assignedX = (n % 4) * 32 + 14 + Math.floor(n/4) * 4
    var assignedY = (Math.floor(n / 4)) * 32 + 16
    if (Math.abs(goal.x - assignedX) < 33 && Math.abs(goal.y - assignedY) < 33) {
        assignedX = goal.x
        assignedY = goal.y
    }
    var b = bots[n], moveX = b.x !== assignedX, x = b.x, y = b.y, type
    if (moveX) {
        x += b.x < assignedX ? 1 : -1
    } else {
        y += b.y < assignedY ? 1 : -1
    }
    if (grid(x, y) === 1) {
        if (b.hasWall) {
            type = 2 //place
            var c = getNeighborCell(b.x, b.y, 0)
            if (!c) { //stuck holding wall with walls all around
                return 0
            }
            x = c.x
            y = c.y
        } else {
            type = 1 //grab
        }
    } else if (grid(x, y) === 0) {
        if (getNeighborCell(x, y, 1)) {
            type = 0 //move
        } else {
            if (b.hasWall) {
                type = 2 //place
                if (moveX) {
                    y += y > 0 ? -1 : 1
                } else {
                    x += x > 0 ? -1 : 1
                }
            } else {
                type = 1 //grab
                var c = getNeighborCell(b.x, b.y, 1)
                if (!c) { //stuck without wall in midair
                    return 0
                }
                x = c.x
                y = c.y
            }
        }
    } else {
        return 0 //should never get here
    }
    return encodeAction(type, x - b.x, y - b.y)
}

var actions = []
for (var i = 0; i < 8; i++) {
    actions[i] = moveBot(i)
}

return actions

1
আমি জানি এটি কেবল শুরু, তবে বেসলাইনটির সাথে (অসম) যুদ্ধ দেখার সময় একটি জিনিস আমি লক্ষ্য করেছি: লক্ষ্য যদি একাধিক কেন্দ্রের নাগালের মধ্যে থাকে তবে তারা সকলেই লক্ষ্যটির দিকে ধাবিত হয়। কেবলমাত্র নিকটতমটিকে বেছে নেওয়া এবং অন্যদের তাদের "আদর্শ" অবস্থানে রাখা কি আরও ভাল? মজা, বিটিডব্লিউ।
রেটো কোরাডি

ধন্যবাদ! হ্যাঁ এটি অবশ্যই একটি উন্নতি হবে। অন্যদের সম্পর্কেও ভাবার একটি দীর্ঘ তালিকা এবং ব্যবহারের জন্য বিভিন্ন কৌশল। অন্যরা কোন কৌশল বেছে নেয় এবং কীভাবে তারা ইন্টারঅ্যাক্ট করে তা দেখার অপেক্ষায়
রয়েছি

9

বেসলাইন

এটি আমি ভাবতে পারি সবচেয়ে সহজ ধারাবাহিকভাবে কাজ করা বট ফ্লক নিয়ন্ত্রক। এটি আমার একমাত্র অযোগ্য অযোগ্য উত্তর হবে এবং এর মাধ্যমে অন্যান্য উত্তরগুলির বিচার করার জন্য বেসলাইন হিসাবে কাজ করবে। টেকনিক্যালি এটি প্রতিযোগিতা জয়ের দৌড়ে, তবে এটির মারপিট করা কঠিন হওয়া উচিত নয়।

এখানে যে কোনও কোড অনুলিপি করে অন্য উত্তরে ব্যবহার করা যেতে পারে, কোনও অ্যাট্রিবিউশনের প্রয়োজন নেই।

var encodeAction = function(type, dx, dy) {
    var d
    if (dx === -1 && dy === -1) d = 1
    else if (dx === 0 && dy === -1) d = 2
    else if (dx === 1 && dy === -1) d = 3
    else if (dx === -1 && dy === 0) d = 4
    else if (dx === 1 && dy === 0) d = 5
    else if (dx === -1 && dy === 1) d = 6
    else if (dx === 0 && dy === 1) d = 7
    else if (dx === 1 && dy === 1) d = 8
    else return 0
    return 8 * type + d
}

var getNeighborCell = function(x, y, wallState) {
    if (x > 0 && y > 0 && grid(x - 1, y - 1) === wallState) return { x: x - 1, y: y - 1 }
    if (y > 0 && grid(x, y - 1) === wallState) return { x: x, y: y - 1 }
    if (x < 127 && y > 0 && grid(x + 1, y - 1) === wallState) return { x: x + 1, y: y - 1 }
    if (x > 0 && grid(x - 1, y) === wallState) return { x: x - 1, y: y }
    if (x < 127 && grid(x + 1, y) === wallState) return { x: x + 1, y: y }
    if (x > 0 && y < 63 && grid(x - 1, y + 1) === wallState) return { x: x - 1, y: y + 1 }
    if (y < 63 && grid(x, y + 1) === wallState) return { x: x, y: y + 1 }
    if (x < 127 && y < 63 && grid(x + 1, y + 1) === wallState) return { x: x + 1, y: y + 1 }
    return null
}

var moveBot = function(n) {
    var b = bots[n], moveX = b.x !== goal.x, x = b.x, y = b.y, type
    if (moveX) {
        x += b.x < goal.x ? 1 : -1
    } else {
        y += b.y < goal.y ? 1 : -1
    }
    if (grid(x, y) === 1) {
        if (b.hasWall) {
            type = 2 //place
            var c = getNeighborCell(b.x, b.y, 0)
            if (!c) { //stuck holding wall with walls all around
                return 0
            }
            x = c.x
            y = c.y
        } else {
            type = 1 //grab
        }
    } else if (grid(x, y) === 0) {
        if (getNeighborCell(x, y, 1)) {
            type = 0 //move
        } else {
            if (b.hasWall) {
                type = 2 //place
                if (moveX) {
                    y += y > 0 ? -1 : 1
                } else {
                    x += x > 0 ? -1 : 1
                }
            } else {
                type = 1 //grab
                var c = getNeighborCell(b.x, b.y, 1)
                if (!c) { //stuck without wall in midair
                    return 0
                }
                x = c.x
                y = c.y
            }
        }
    } else {
        return 0 //should never get here
    }
    return encodeAction(type, x - b.x, y - b.y)
}

var actions = []
for (var i = 0; i < 8; i++) {
    actions[i] = moveBot(i)
}

return actions

8 টি বটের প্রতিটি স্বতন্ত্রভাবে একই বুনিয়াদি পদ্ধতি অনুসরণ করে। বাহ্যিক কিছু দ্বারা পৃথক না হলে তারা এ কারণে একসাথে ঝাঁকুনির ঝোঁক রাখে। সতীর্থ বা শত্রুরা কোথায় থাকে সে সম্পর্কে বটরা কখনই চিন্তা করে না, তারা কেবল লক্ষের দিকে এগিয়ে যাওয়ার চেষ্টা করে। তারা কেবল orthogonally সরান, প্রথমে তাদের x এর সাথে গোল x এর সাথে মিলে যায়, তারপরে তাদের y। কখনই তির্যকভাবে চলার অর্থ তারা ভ্রমণের ক্ষেত্রে অনেক সময় নষ্ট করে।

প্রতিটি বটের চলন অ্যালগরিদম নিম্নরূপ:

If my X is not equal to the goal's X
    P = position to my left or right that is closer to the goal  
    Make a note that I'm trying to move horizontal  
Else  
    P = position above or below me that is closer to the goal  
    Make a note that I'm trying to move vertical  

If P is a wall  
    If I'm holding a wall  
        Place my wall in any neighboring air cell  
    Else  
        Grab the wall at P  
Else if P is air  
    If P has a wall neighboring it (i.e. if I can move to P)  
        Move to P  
    Else  
        If I'm holding a wall  
            If I'm trying to move horizontal  
                Place my wall above or below P  
            Else if I'm trying to move vertical  
                Place my wall to the left or right of P  
        Else  
            Grab wall from any neighboring wall cell   

6

Teamplayer

এই মুহুর্তে, এই জমাটি নিখুঁত। এটির আউটপোস্টগুলির মতো একই কৌশল রয়েছে তবে কেবল 6 বটগুলি "বাতাসে"। অন্য দুটি বট চুরি হয়ে গেলে তাদের দেয়াল সরবরাহ করে। সম্পাদনা করুন: সমর্থক বটগুলি এখন আরও ভাল পারফর্ম করে।

var outside = function(x,y) {
    return x < 0 || x > 127 || y < 0 || y > 127
}

var distance = function(x1, y1, x2, y2){
  return Math.sqrt(Math.pow(x1-x2, 2) + Math.pow(y1-y2, 2));
}

var isStuck = function(bot) {
    if (bot.hasWall) {
        for (var i=-1; i<=1; i++) {
            for (var j=-1; j<=1; j++) {
                if ((i != 0 || j != 0) && grid(bot.x+i,bot.y+j) == 0 && !outside(bot.x+i,bot.y+j))
                    return false
            }
        }
        return true
    }
    for (var i=-1; i<=1; i++) {
        for (var j=-1; j<=1; j++) {
            if (grid(bot.x+i, bot.y+j) == 1)
                return false
        }
    }
    return true
}

var isPlayer = function(x,y) {
    for (var i = 0; i < bots.length; i++) {
        if (bots[i].x == x && bots[i].y == y)
            return true
    }
    for (var i = 0; i < ebots.length; i++) {
        if (ebots[i].x == x && ebots[i].y == y)
            return true
    }
    return false
}

var encodeAction = function(type, dx, dy) {
    var d
    if (dx === -1 && dy === -1) d = 1
    else if (dx === 0 && dy === -1) d = 2
    else if (dx === 1 && dy === -1) d = 3
    else if (dx === -1 && dy === 0) d = 4
    else if (dx === 1 && dy === 0) d = 5
    else if (dx === -1 && dy === 1) d = 6
    else if (dx === 0 && dy === 1) d = 7
    else if (dx === 1 && dy === 1) d = 8
    else return 0
    return 8 * type + d
}

var surrounding = function(x,y) {
    var cell = {hasStone:false, cells: []}
    for (var i=-1; i<=1; i++) {
        for(var j=-1; j<=1; j++) {
            if ((i != 0 || j != 0) && !outside(x+i,y+j)) {
                cell.cells.push({x:x+i, y:y+j})
                if (grid(x+i,y+j) == 1) {
                    cell.hasStone = true
                }
            }
        }
    }
    return cell
}


var hunt = function(i, destination) {
    destination = destination || {x: 31+((i-2)%3)*32, y: 20+((i-2)%2)*21}, bot = bots[i]
    if (i < 5 && i > 1) {
        destination.x -= 2
    }
    if (bot.isStuck) {
        return 0
    }
    if ((p1 && destination.x >= move + i) || (!p1 && 127 - destination.x > move - i)) {
        destination.y = bot.y
    }
    if (i == bestBotId && move > 50) {
        destination.x = goal.x
        destination.y = goal.y
    }
    var dx = destination.x > bot.x ? 1 : destination.x == bot.x ? 0 : -1, newX = bot.x + dx
    var dy = destination.y > bot.y ? 1 : destination.y == bot.y ? 0 : -1, newY = bot.y + dy
    var surr = surrounding(newX, newY), botSurr = surrounding(bot.x, bot.y)
    if (grid(newX, newY) == 0) {
        if (surr.hasStone) {
            return encodeAction(0, dx, dy)
        } else {
            if (bot.hasWall) {
                for (var i=0; i<surr.cells.length; i++) {
                    var cell = surr.cells[i];
                    if (Math.abs(cell.x - bot.x) <= 1 && Math.abs(cell.y - bot.y) <= 1 && grid(cell.x, cell.y) == 0 && !isPlayer(cell.x, cell.y)) {
                        return encodeAction(2, cell.x - bot.x, cell.y - bot.y)
                    }
                }
            } else {
                if (bot.walls.length == 1) {
                    return encodeAction(1, bot.walls[0].x - bot.x, bot.walls[0].y - bot.y)
                } else {
                    for (var i=0; i<bot.walls.length; i++) {
                        var wall = bot.walls[i], canUseWall = true
                        for (var j=0; j<bots.length; j++) {
                            if (bots[j].walls.length == 1 && bots[j].walls[0].x == wall.x && bots[j].walls[0].y == wall.y) {
                                canUseWall = false
                            }
                        }
                        if (canUseWall) {
                            return encodeAction(1, wall.x - bot.x, wall.y - bot.y)
                        }
                    }
                }
            }
        }
    } else {
        if (bot.hasWall) {
            for (var i=0; i<botSurr.cells.length; i++) {
                var cell = botSurr.cells[i];
                if (grid(cell.x, cell.y) == 0 && !isPlayer(cell.x, cell.y) && !outside(cell.x, cell.y)) {
                    return encodeAction(2, cell.x - bot.x, cell.y - bot.y)
                }
            }
        } else {
            return encodeAction(1, dx, dy)
        }
    }
    return 0 //hopefully never happens
}

var help = function(i) {
    if (bots[i].isStuck) {
        return 0
    }
    var bot = bots[i], destination = helpDestinations[i]
    if (destination.stuckBot == -1) {
        if (bot.walls.length >= 2 || (bot.hasWall && bot.walls.length == 1)) {
            var stuckId = -1
            for (var j = 0; j < bots.length; j++) {
                if (j != helpDestinations[(i+1)%2].stuckBot && bots[j].isStuck)
                    stuckId = j
            }
            if (stuckId != -1) {
                destination.stuckBot = stuckId
                destination.x = bots[stuckId].x
                destination.y = bots[stuckId].y
                return 0
            } else {
                return hunt(i, destination)
            }
        } else if (bot.x == destination.x && bot.y == destination.y) {
            if (move % 2 == 0)
                destination.y += 1
            else
                destination.x -= 1
            return hunt(i, destination)
        } else {
            return hunt(i, destination)
        }
    } else if (bots[destination.stuckBot].isStuck) {
        if (bot.walls.length < 2 && !(bot.hasWall && bot.walls.length == 1)) {
            destination.stuckBot = -1
            destination.x = i == 0 ? 42 : 85
            destination.y = 55
            return hunt(i, destination)
        }
        var dx = destination.x > bot.x ? 1 : destination.x == bot.x ? 0 : -1, newX = bot.x + dx
        var dy = destination.y > bot.y ? 1 : destination.y == bot.y ? 0 : -1, newY = bot.y + dy
        var surr = surrounding(newX, newY), botSurr = surrounding(bot.x, bot.y), surrWalls = 0
        for (var i = 0; i < surr.cells.length; i++) {
            var cell = surr.cells[i]
            if (grid(cell.x,cell.y) == 1)
                surrWalls++
        }
        if (grid(newX, newY) == 0) {
            if (surrWalls >= 2 || (surr.hasWall && bot.hasWall)) {
                return encodeAction(0, dx, dy)
            } else {
                if (bot.hasWall) {
                    for (var i=0; i<surr.cells.length; i++) {
                        var cell = surr.cells[i];
                        if (Math.abs(cell.x - bot.x) <= 1 && Math.abs(cell.y - bot.y) <= 1 && grid(cell.x, cell.y) == 0 && !isPlayer(cell.x, cell.y)) {
                            return encodeAction(2, cell.x - bot.x, cell.y - bot.y)
                        }
                    }
                } else {
                    if (bot.walls.length == 1) {
                        return encodeAction(1, bot.walls[0].x - bot.x, bot.walls[0].y - bot.y)
                    } else {
                        for (var i=0; i<bot.walls.length; i++) {
                            var wall = bot.walls[i], canUseWall = true
                            for (var j=0; j<bots.length; j++) {
                                if (bots[j].walls.length == 1 && bots[j].walls[0].x == wall.x && bots[j].walls[0].y == wall.y) {
                                    canUseWall = false
                                }
                            }
                            for (var j=0; j<surr.cells.length; j++) {
                                if (surr.cells[j].x == wall.x && surr.cells[j].y == wall.y)
                                    canUseWall = false
                            }
                            if (canUseWall) {
                                return encodeAction(1, wall.x - bot.x, wall.y - bot.y)
                            }
                        }
                    }
                }
            }
        } else {
            if (bot.hasWall) {
                for (var i=0; i<botSurr.cells.length; i++) {
                    var cell = botSurr.cells[i];
                    if (grid(cell.x, cell.y) == 0 && !isPlayer(cell.x, cell.y)) {
                        return encodeAction(2, cell.x - bot.x, cell.y - bot.y)
                    }
                }
            } else {
                return encodeAction(1, dx, dy)
            }
        }
    } else {
        destination.stuckBot = -1
        destination.x = i == 0 ? 42 : 85
        destination.y = 55
        return hunt(i, destination)
    }
    return 0 //hopefully never happens
}

var moves = new Array(8)    
var mem = getMem(), helpDestinations = []
if (mem.length == 0) {
    mem = "42,55,-1 85,55,-1"
}
mem = mem.split(" ")
for (var i = 0; i < mem.length; i++) {
    var cell = mem[i].split(",")
    helpDestinations.push({x: parseInt(cell[0]), y: parseInt(cell[1]), stuckBot: parseInt(cell[2])})
}

for (var i = 0; i < 8; i++) {
    var bot = bots[i]
    var surr = surrounding(bot.x, bot.y)
    bot.walls = []
    for (var j = 0; j < surr.cells.length; j++) {
        if (grid(surr.cells[j].x, surr.cells[j].y) == 1) {
            bot.walls.push(surr.cells[j])
        }
    }
}

bots.forEach(function(bot, index) {
    if(isStuck(bot)) {
        bot.isStuck = true
    }
})

var bestDistance = 1000
var bestBotId = -1
for (var i=2; i<8; i++) {
    var dist = distance(bots[i].x, bots[i].y, goal.x, goal.y)
    if (dist < bestDistance && !bots[i].isStuck) {
        bestDistance = dist
        bestBotId = i
    }
}

for (var i=0; i<8; i++) {
    if (i < 2) {
        moves[i] = help(i)
    } else {
        moves[i] = hunt(i)  
    }
}

setMem(helpDestinations[0].x + "," + helpDestinations[0].y + "," + helpDestinations[0].stuckBot + " " + helpDestinations[1].x + "," + helpDestinations[1].y + "," + helpDestinations[1].stuckBot)

return moves

সমর্থক ধারণা (দুর্দান্ত) প্রয়োগ করা কঠিন বলে মনে হচ্ছে।
edc65

@ edc65 এটি মূলত কেবল একটিটির পরিবর্তে 2 টি দেয়াল নিয়ে চলছে। তবে দুটি সমর্থন বট এবং নতুন দেয়াল সন্ধানের মধ্যে যোগাযোগ বাস্তবায়ন করা বরং কঠিন ছিল :)
কমনগ্যুই

6

প্রার্থীদের

কাজ চলছে। আমার অনেক ধারণা আছে, তবে তাদের প্রায় কোনওটিই কাজ করে না।

সর্বোপরি, ব্যর্থ কর্মের সাথে বড় সমস্যা। মীমাংসিত!

var action=[], myGrid=[], goalSort=[], i, j, curBot, curAction, goalSeek;

var check = function(x,y) {
  return (myGrid[[x,y]] || (myGrid[[x,y]] = grid(x,y)))|0;
};

var setGrid = function(x,y,v) {
  myGrid[[x,y]] = v + '';
};

var orGrid = function(x,y,v) {
  myGrid[[x,y]] |= v;
};

var encodeDir = function(dx, dy) {
    return dx < 0 && dy < 0 ? 1
    : dx === 0 && dy < 0 ? 2
    : dx > 0 && dy < 0 ? 3
    : dx < 0 && dy === 0 ? 4
    : dx > 0 && dy === 0 ? 5
    : dx < 0 && dy > 0 ? 6
    : dx === 0 && dy > 0 ? 7
    : dx > 0 && dy > 0 ? 8
    : 0;
};

var distance = function(p1, p2) {
  return Math.max(Math.abs(p1.x-p2.x),Math.abs(p1.y-p2.y));
};

var cellNearWall = function(x,y)
{
  var r = check(x,y) == 1 ? 0
  : check(x-1,y-1) == 1 ? 1
  : check(x,y-1) == 1 ? 2
  : check(x+1,y-1) == 1 ? 3
  : check(x-1,y) == 1 ? 4
  : check(x+1,y) == 1 ? 5
  : check(x-1,y+1) == 1 ? 6
  : check(x,y+1) == 1 ? 7
  : check(x+1,y+1) == 1 ? 8
  : 0;
  return r;
};

var cellNearBot = function(x,y,m)
{
  return check(x-1,y-1) & m ? 1
  : check(x,y-1) & m ? 2
  : check(x+1,y-1) & m ? 3
  : check(x-1,y) & m ? 4
  : check(x+1,y) & m ? 5
  : check(x-1,y+1) & m ? 6
  : check(x,y+1) & m ? 7
  : check(x+1,y+1) & m ? 8
  : 0;
};


var tryGrabWall = function(x, y)
{
  var dx, dy, r = 8;
  for(dy = -1; dy < 2; ++dy)
  {
    for(dx = -1; dx < 2; ++dx)
    {
      if (dx|dy)
      {
        ++r;
        if (check(x+dx, y+dy) == 1)
        {
          setGrid(x+dx, y+dy, 0); // remember that the wall is not there anymore
          return r;
        }
      }
    }
  }
  return 0;
};

var tryDropWall= function(x, y)
{
  var dx, dy, r = 16;
  for(dy = -1; dy < 2; ++dy)
  {
    for(dx = -1; dx < 2; ++dx)
    {
      if (dx|dy)
      {
        ++r;
        if (x+dx>=0 & x+dx < 128 & y+dy >= 0 & y+dy < 64 && check(x+dx, y+dy) == 0)
        {
          setGrid(x+dx, y+dy, 1); // remember that the wall is there 
          return r;
        }
      }
    }
  }
  return 0;
};


var approach = function(bot, target)
{
  var dx, dy, tx, ty, r = 0, wallPos;

  var checkDrop = function(dx,dy)
  {
    var x = bot.x+dx, y = bot.y+dy;
    if (check(x,y) == 0 && cellNearBot(x,y,8) == 0)
    {
      setGrid(x, y, 1);
      return 16 + encodeDir(dx, dy);
    }
  };

  dy = target.y - bot.y;
  dy = dy < 0 ? -1 : dy > 0 ? 1 : 0;
  dx = target.x - bot.x;
  dx = dx < 0 ? -1 : dx > 0 ? 1 : 0;
  tx = bot.x+dx;
  ty = bot.y+dy;

  if ((dx|dy) === 0)
  {
    if (!bot.hasWall) {
      return tryGrabWall(bot.x, bot.y);
    }
    return 0;
  }


  if (cellNearWall(tx,ty))
  {
    setGrid(tx, ty, 2);
    return encodeDir(dx, dy);
  }

  if (dx === 0)
  {
    if (cellNearWall(bot.x-1,ty))
    {
      setGrid(bot.x-1, ty, 2);
      return encodeDir(-1, dy);
    }
    if (cellNearWall(bot.x+1,ty))
    {
      setGrid(bot.x+1, ty, 2);
      return encodeDir(1, dy);
    }
    if (bot.hasWall) 
    {
      if (wallPos = checkDrop(1,dy)) { return wallPos; }
      if (wallPos = checkDrop(-1,dy)) { return wallPos; }
      if (wallPos = checkDrop(1,0)) { return wallPos; }
      if (wallPos = checkDrop(-1,0)) { return wallPos; }
    }
  }
  else if (dy === 0) 
  {
    if (cellNearWall(tx,bot.y-1))
    {
      setGrid(tx, bot.y-1, 2);
      return encodeDir(dx, -1);
    }
    if (cellNearWall(tx,bot.y+1))
    {
      setGrid(tx, bot.y+1, 2);
      return encodeDir(dx, 1);
    }
    if (bot.hasWall) 
    {
      if (wallPos = checkDrop(dx,1)) { return wallPos; }
      if (wallPos = checkDrop(dx,-1)) { return wallPos; }
      if (wallPos = checkDrop(0,1)) { return wallPos; }
      if (wallPos = checkDrop(0,-1)) { return wallPos; }
    }
  }
  else
  {
    if (cellNearWall(tx,bot.y))
    {
      setGrid(tx, bot.y, 2);
      return encodeDir(dx, 0);
    }
    if (cellNearWall(bot.x,ty))
    {
      setGrid(bot.x, ty, 2);
      return encodeDir(0,dy);
    }
    if (bot.hasWall) {
      if (wallPos = checkDrop(dx,0)) { return wallPos; }
      if (wallPos = checkDrop(0,dy)) { return wallPos; }
      if (wallPos = checkDrop(dx,dy)) { return wallPos; }
    }
  }

  if (!bot.hasWall)
  {
  if (check(tx, ty) == 1)
  {
      setGrid(tx, ty, 0); // remember that the wall is not there anymore
      return 8 + encodeDir(dx, dy);
    };
    return tryGrabWall(bot.x, bot.y);
  }
  else
  {
    return tryDropWall(bot.x, bot.y);
  }
};

for (i=0; curBot=ebots[i]; i++)
{
  setGrid(curBot.x, curBot.y, curBot.hasWall ? 4 : 8);
}

var goalDistance=[]

for (i=0; curBot=bots[i]; i++)
{
  orGrid(curBot.x, curBot.y, 2);
  goalDistance[i] = distance(curBot, goal);
}
var sorted = goalDistance.slice().sort(function(a,b){return a-b})
var ranks = goalDistance.slice().map(function(v){ return sorted.indexOf(v)});

var tt = p1 
? [ { x:32, y:20 },{ x:32, y:55 },{ x:64, y:20 },{ x:64, y:55 },
   { x:96, y:20 },{ x:96, y:55 },{ x:16, y:30 },{ x:112, y:30 }]
: [ { x:96, y:20 },{ x:96, y:55 },{ x:64, y:20 },{ x:64, y:55 },
   { x:32, y:20 },{ x:32, y:55 },{ x:112, y:30 },{ x:16, y:30 }]

var goalSeek = 3;

for (i=0; curBot=bots[i]; i++)
{
  if (ranks[i] < goalSeek)
  {
    curAction = approach(curBot, goal);
    if (curAction == 0) goalSeek += 1;
  }
  else
    curAction = approach(curBot, tt[i]);

  action[i] = curAction;
}

return action;
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.