ফেলোশিপদের লড়াই


45

এই চ্যালেঞ্জটিতে আপনি যুদ্ধে অন্য সমস্ত ফেলোশিপকে পরাস্ত করার লক্ষ্য নিয়ে ফেলোশিপ তৈরি করতে যাচ্ছেন ।

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

চরিত্রগুলির ক্ষমতা রয়েছে। আপনার অক্ষরগুলির কী কী ক্ষমতা রয়েছে তা চয়ন করা এই কোটএইচটির একটি অত্যন্ত গুরুত্বপূর্ণ (এবং মজাদার) অংশ । এগুলি সকলেই শক্তিশালী এবং আপনার শত্রুকে নিশ্চিহ্ন করার সম্ভাবনা রয়েছে।

চরিত্রগুলির স্বাস্থ্য পয়েন্টস (এইচপি) থাকে এবং যখন তাদের এইচপি হিট হয় (বা নীচে যায়) তখন তারা মারা যায় । যদি আপনার প্রতিপক্ষের দলের সমস্ত অক্ষর মারা যায়, তবে আপনি জিতবেন!

চরিত্রের মন আছে। বেশিরভাগ ক্রিয়াগুলির জন্য মনকে সম্পাদন করা প্রয়োজন , এবং যদি আপনার পর্যাপ্ত পরিমাণ না থাকে তবে সেই ক্রিয়াটি আপনার কাছে উপলব্ধ নয়।

চরিত্রগুলির একটি টার্ন বিলম্ব রয়েছে । এটি প্রতিটি টার্নের মধ্যে টিক্সের সংখ্যা নির্ধারণ করে (100 থেকে শুরু হয়)। স্বল্পতা ভালো.

চরিত্রের বৈশিষ্ট্য রয়েছে । প্রতিটি চরিত্রের প্রতিটি অ্যাট্রিবিউটে 5 টি বেস থাকে এবং আপনাকে বিভাজনে 20 টি অতিরিক্ত গুণাবলী দেওয়া হয়। অ্যাট্রিবিউট পয়েন্টগুলি বরাদ্দের পরে, আপনার প্রাথমিক বৈশিষ্ট্যটি আপনার সর্বোচ্চ বৈশিষ্ট্য হিসাবে সেট করা আছে।

উপলব্ধ বৈশিষ্ট্যগুলি হ'ল:

  • শক্তি: পালা প্রতি 10 সর্বোচ্চ এইচপি এবং .5 এইচপি দেয়
  • বুদ্ধিমত্তা: 7 ম্যাক্স মান এবং প্রতিমুখে .1 মান দেয়
  • তত্পরতা: টার্নের বিলম্বকে 1 দ্বারা হ্রাস করে

আন্দোলন, দৃষ্টি, ব্যাপ্তি
সীমাগুলি নীচে রয়েছে (0 টি কেন্দ্র করে) কিছু রেঞ্জগুলি কার্ডিনাল হয় , যার অর্থ তারা কেবল সরাসরি উপরে, বাম, ডান বা নীচে যেতে পারে।

    444
   43334
  4322234
 432111234
 432101234
 432111234
  4322234
   43334
    444

অক্ষরগুলির সূচনা ভিশন 2 থাকে the একই ফেলোশিপের খেলোয়াড়দের মধ্যে দৃষ্টি ভাগ করা হয়।

কিভাবে খেলতে হবে

নির্মাণ
খেলোয়াড়রা তাদের ফেলোশিপ তৈরি করবে। আপনাকে নিম্নলিখিত পদক্ষেপগুলি করতে হবে :

  1. প্রতিটি অক্ষর বৈশিষ্ট্য বিন্দু দিন । প্রতিটি অক্ষরে প্রতিটি স্ট্যাটে 5 দিয়ে শুরু হয়, 3 এর মধ্যে বিতরণ করার জন্য অতিরিক্ত 20 দিয়ে।

  2. প্রতিটি চরিত্রের ক্ষমতা দিন । প্রতিটি অক্ষর 4 টি দক্ষতার স্লট দিয়ে শুরু হয় এবং ক্ষমতাগুলি ডিফল্টরূপে 1 স্লট নেয়। কিছু ক্ষমতা পুনরাবৃত্তিযোগ্য , এবং একাধিকবার কোনও চরিত্রকে দেওয়া যেতে পারে। মালিকের অনুমতি ব্যতীত অন্য জমা দেওয়ার একটি সক্ষম সেট ব্যবহার করার অনুমতি নেই।

  3. আপনার বট জন্য কিছু কোড লিখুন । কোডটি অবশ্যই জাভাতে হবে এবং লড়াইয়ের জন্য ব্যবহার করা হবে (পরবর্তী ধাপ)

ক্রিয়াকলাপ

সমস্ত অক্ষর 3 টি স্ট্যান্ডার্ড ক্রিয়া দিয়ে শুরু হয়:

  1. পদক্ষেপ : আপনার চরিত্রটিকে 1 এর কার্ডিনাল সীমার মধ্যে নিয়ে যান
  2. স্লাইস : প্রাইমারিঅ্যাট্রিবিউটের জন্য একটি শত্রুটিকে 1 এর মূল সীমার মধ্যে আক্রমণ করুন
  3. হাসি : কিছুই করিস না

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

ক্ষমতা
প্রতিটি চরিত্রের 4 টি ক্ষমতা স্লট রয়েছে। যদি কোনও ক্ষমতা তির্যক থাকে তবে এটি একটি ক্রিয়া।

ক্ষমতা

নাম বর্ণনা মন কোলডাউন 
                                                     গতিশীলতা                                                     

ব্লিংক         একটি স্কোয়ারে সরান, 4 5 2 
          টার্গেট 5 5 টেলিপোর্টের সাথে অদলবদল অদলবদল করুন 2 5 
      কোথাও 20 5 এ যান

ড্যাশ পদক্ষেপের পরিধি 1 দ্বারা বৃদ্ধি করুন Rep পুনরাবৃত্তিযোগ্য                                               
মোবাইল স্টেপ 8 টি দিকের যে কোনও জায়গায় যেতে পারে                                                  
                                                    অ্যাটাকিং                                                    

কুইক         স্লাইস দুইবার 3 0 
 বুনা         স্লাইস একবার 15 10 সকল দৃশ্যমান শত্রু

প্রতিটি স্লাইস আপনার লক্ষ্যমাত্রার প্রাথমিক গুণাবলী 1 টি চুরি করে als 20 টার্ন থাকে                    
ক্লিভ প্রতিটি স্লাইস সংলগ্ন শত্রুদের 1/2 টির ক্ষতি করে                                           
ক্রিটাল 200% ক্ষতির জন্য স্লাইসের 30% সুযোগ যুক্ত করে। repeatable                               
প্রতি স্লাইস ভোজ আপনার এইচপি 3 দ্বারা বাড়িয়ে তোলে। পুনরাবৃত্তিযোগ্য                                             
8 দিকের যে কোনও একটিতে নমনীয় ক্যান স্লাইস                                                      
মন চুরি স্লাইস চুরি 2 মন। repeatable                                                           
0 3 কেটে ফেলা হলে রিফ্লেক্সিভ স্লাইস 
স্লাইসের পরিসীমাতে রেঞ্জযুক্ত 1 টি যুক্ত হয়                                                              
একই টার্গেটে প্রতিটি টানা প্রতিটি স্লাইপ শেষের চেয়ে 3 টি বেশি ক্ষতির सौदा করে               
                                                    স্থিতিগুলিকে                                                     

ডিসপেল        একটি লক্ষ্য থেকে সমস্ত স্ট্যাটাস সরিয়ে দেয়। পরিসীমা 2. 20 10 
 ডুয়েল          আপনাকে এবং আপনার টার্গেটকে স্থির করে দেয় যতক্ষণ না আপনার একজন মারা যায়। পরিসীমা 1 25 0 
 নকআউট      আপনি এবং টার্গেট পরবর্তী 1000 টিকের জন্য স্তব্ধ হয়ে গেছেন 10 10 
 উল্কা        সমস্ত শত্রু পরের 100 টি টিক্সের জন্য স্তব্ধ হয়ে যায় 25 10 
 লিশ         টার্গেট তাদের 2 পরবর্তী টার্নের জন্য হিমায়িত হয় 4 6 পোয়েজন        পোয়েসন 5 টি 
 টার্নের জন্য 1 এইচপি জন্য শত্রু 5 0 
 নীরবতা      লক্ষ্যটি 5 টার্নের জন্য 5 নীরব হয়ে যায় 7 7 ধীর          লক্ষ্যটি তাদের পরবর্তী 3 টার্নের জন্য 40 টি টিক দিয়ে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে 
 ধীরে এগিয়ে যায় 5 
          পরবর্তী স্ট্যান্ড 10 পরবর্তী 10 টির জন্য স্টান লক্ষ্য স্তম্ভিত হয়

ঠান্ডা 2 পরিসরের মধ্যে অন্যান্য সমস্ত অক্ষর 10 টিক দ্বারা ধীর হয়                                
ইমিউন আপনার জন্য কোনও স্ট্যাটাস প্রয়োগ করা যাবে না                                                           
                                                    আত্মরক্ষামূলক                                                    

ফোর্স ফিল্ড   ব্লক ক্ষতি পরবর্তী 5 উত্স। না স্ট্যাকের 15 5 করে 
 গোস্ট         একটি মোড় জন্য, সমস্ত ক্ষতি হিলস 10 10 
 সারিয়ে          20 জন্য উদ্দিষ্ট সারিয়ে এইচপি 10 3 
 পুনরুদ্ধার করুন       সব ইউনিট সম্পূর্ণ স্বাস্থ্য 20 থেকে 40 ফিরে পুনরুদ্ধার করা হয়েছে 
 শিল্ড        আপনি স্লাইসড আপনার পরবর্তী পালা পর্যন্ত হতে পারে না 3 0

একটি স্লাইস আপনাকে আঘাত না করার 25% সুযোগের ক্ষতিকারক সুযোগ। repeatable                                         
কেবল পিলারটি একবার ঘুরে একবার কাটা যায়                                                            
পুনরুত্থান মারা গেলে পুরো এইচপি (এবং কোনও স্ট্যাটাস নেই) 0 40 দিয়ে ফিরে আসুন 
স্পাইকস যখন ক্ষতির মুখোমুখি হয়, তখন ক্ষতিটির অর্ধেক ভাগ করে ফেলি                                           
                                                     দৃষ্টি                                                      

ক্লোক         টিম 5 টি 20 টির জন্য অদৃশ্য হয়ে যায় 20 20 
 লুকান          আপনি 5 টার্নের জন্য অদৃশ্য হন 4 7 
 ধাপ         1 টার্নের জন্য অদৃশ্য হয়ে যান 0 3 
 ট্র্যাক         টার্গেট অদৃশ্য হতে পারে না, এবং আরও 10% ক্ষতি নেয়। 10 টার্ন থাকে। 5 5

অন্ধকার শত্রু দর্শনীয় পরিসীমা ১. হ্রাস পেয়েছে তবে 1 এর নিচে যেতে পারে না।                                 
দূরদৃষ্টির দর্শনীয় স্থানের পরিধি ২. বৃদ্ধি পেয়েছে Rep                                                    
অদৃশ্য আপনি যদি শত্রু দৃষ্টি থেকে আপনার পালা শুরু করেন তবে আপনি অদৃশ্য                               
সত্যিকারের দর্শন শুরু হওয়ার পরে 2 টি পরিসরের মধ্যে সমস্ত লুকানো ইউনিট প্রকাশ করে                                     
                                                     ক্ষতি                                                      

ড্রেনটি         টার্গেটের 5 টি ক্ষতি করে এবং 5 টি এইচপি-র জন্য নিজেকে নিরাময় করে যখন তারা 1 রেঞ্জে থাকে 5 5 
 বিদ্যুত্     ডিল 15 সমস্ত শত্রুদের ক্ষতি 15 10 
 কে / হে           কিল লক্ষ্য যদি 20% এইচপি 20 0 এর নিচে থাকে তবে 
 ট্র্যাজ          একটি অদৃশ্য ফাঁদ রাখুন। পদক্ষেপ নেওয়ার সময় ট্র্যাপ 15 টি ক্ষতি করে। স্ট্যাক। 10 2 
 জ্যাপ           ডিল 30 টি লক্ষ্যমাত্রা 30 টির ক্ষতি

স্ট্যাটিক ডিলস 5 প্রতিটি শত্রুকে 1 সীমার মধ্যেই ক্ষতি করে। repeatable                       
                                                      পরিসংখ্যান                                                      

ওয়েভল্ফ      5 টি 30 25 এর জন্য সমস্ত পরিসংখ্যানে 10 যোগ করুন

বাফ আপনার এইচপি পুল দ্বিগুণ। repeatable                                                           
চতুর ক্রিয়াকলাপগুলিতে 20% কম কন্ডাউনডাউন রয়েছে। repeatable                                             
কেন্দ্রীভূত আপনার মান প্রজনন হার ইন্ট / 10 দ্বারা বৃদ্ধি করে। repeatable                                  
পুনঃজেনার ক্ষমতা / 2 দ্বারা আপনার পুনর্বিবেচনার হার বাড়ায়। repeatable                                 
স্মার্ট অ্যাকশনগুলির দাম 2 কম মন cost repeatable                                                      
শক্তিশালী আপনি 10 গুণাবলী পয়েন্ট অর্জন। repeatable                                                  
দুর্বল আপনি 15 গুণাবলী পয়েন্ট হারাবেন। আপনি ২ টি দক্ষতার স্লট অর্জন করেছেন (এটি এর মধ্যে একটি লাগে)                  
                                                      অন্যান্য                                                      

বিয়ার          ক্যান একটি ভালুক যা প্রতিটি পরিসংখ্যান 8 10 5 হয়েছে তলব 
 ক্লোন         ক্লোন নিজেকে। দুটি দক্ষতার স্লট নেয়। 100 100 
 চুরি         এই ক্রিয়াটি সর্বশেষ ব্যবহৃত শত্রু লক্ষ্য ব্যবহার করে প্রতিস্থাপন করুন। 10 দশকে 5 বছর স্থায়ী হয়েছে 0 
 ওয়াল          লক্ষ্যযুক্ত খালি বর্গক্ষেত্র, 6 10 10 রেঞ্জের একটি দুর্গম প্রাচীর তৈরি করুন 

স্থিতিগুলিকে:

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

সমস্ত স্ট্যাটাস (বিষের বিষয় বাদে) একে অপরের থেকে স্বাধীনভাবে কাজ করে।

পার্শ্ব নোট:

  • প্রাথমিক বৈশিষ্ট্যের জন্য যদি টাই থাকে তবে এটি এসটিআর> এজিআই> আইএনটি হিসাবে সমাধান করা হবে।
  • আপনি একটি 10x10 গ্রিড খেলেন। দলগুলি বিপরীত দিকে স্থাপন করা হবে।
  • শতাংশগুলি চতুর ব্যতীত বহুগুণে স্ট্যাক করে।

জমা দেওয়ার নিয়ম

আপনার 2 টি ফাংশন বাস্তবায়ন করতে হবে:

// Create *exactly* 3 Character templates.  You must return the same templates every time
public List<CharacterTemplate> createCharacters();

// Choose an action for a character.  If the action requires a target or location, it must be set.
public ReadonlyAction choose(Set<ReadonlyAction> actions, ReadonlyCharacter character);

আপনার কাছে তিনটি ভেরিয়েবল (সদস্য ভেরিয়েবল) অ্যাক্সেস থাকবে:

Set<ReadonlyCharacter> team;
Set<EnemyCharacter> enemies;
Map<Point2D, EnemyCharacter> visibleEnemies;

এটাই. বর্ণানুক্রমিক ক্রমে নীচে আপনি একটি সম্পূর্ণ API খুঁজে পেতে পারেন:

class Ability and ReadonlyAbility
    int getNumSlots() returns the number of slots it takes up
    boolean repeatable() returns true if the ability can be repeated
    String name()
class Action and ReadonlyAction
    Set<Point2D> availableLocations()
    Set<ReadonlyCharacter> availableTargets()
    boolean basicAction() returns true if the action is Smile, Step, or Slice
    boolean breaksInvisibiliby()      
    int getCooldown() returns the cooldown cost (not the cooldown remaining)
    int getManaCost()
    String getName()
    int getRemainingCooldown()
    boolean isAvailable() returns true if the action can be performed
    boolean movementAction() returns true if the action is prevented when Frozen
    boolean needsLocation()
    boolean needsTarget()
    void setTarget(ReadonlyCharacter target)
    void setLocation(Point2D location)
class CharacterTemplate
    void addAbility(Ability)
    boolean canAddAbility(Ability)
    List<Ability> currentAbilities()
    Map<Stat, Integer> currentAttributes()
    int getRemainingPoints() returns the total number of ability points you have left to assign
    int getRemainingSlots() returns the total number of slots you have to assign
    int getStat(Stat stat)
    boolean isValid() returns true if your character template is complete and valid
class Point2D
    getX()
    getY()
class Range
    boolean isCardinal() returns true if the range only extends in the 4 cardinal directions
    int getRange() returns the distance of the range
class ReadonlyCharacter and EnemyCharacter
    Class characterClass()
    int cleverness()
    List<ReadonlyAbility> getAbilities()
    Point2D getLocation()   Not on EnemyCharacter
    double getHealth()
    double getMana()
    int getMaxHealth()
    int getMaxMana()
    Range getSightRange()
    Range getSliceRange()
    int getStat(Stat stat)
    Range getStepRange()
    ReadonlyAction getLastAction()
    boolean isFrozen()
    boolean isStunned()
    boolean isPoisoned()
    int getPoisonAmount()
    boolean isSilenced()
    boolean isInvisible()
    boolean isDead()
    Stat primaryStat()
    int smartness()
enum Stat
    INT, STR, AGI

উপরের সমস্ত বৈশিষ্ট্য যা আপনার সম্ভবত আপনার জমা দেওয়ার প্রয়োজন হতে পারে। প্রতিবিম্ব অনুমোদিত নয়। যদি কোনও কারণে কোনও জমাটি অবৈধ হয় তবে দয়া করে এটি সরান বা হেডারটিতে "অবৈধ" যুক্ত করুন। আপনার জমা দেওয়ার কোনও প্যাকেজ ঘোষণা থাকা উচিত নয় । আপনার জমাটি প্রথম মাল্টি-লাইন কোড ব্লকে থাকা উচিত এবং প্রথম লাইনে অবশ্যই ফাইলের নাম থাকা উচিত।

প্রকল্পটি কীভাবে পরিচালনা করবেন:

বিভিন্ন উপায় আছে:

  1. জার ফাইলটি ডাউনলোড করুন এবং চালান java -jar Fellowship.jar। আপনি যদি অন্যান্য জমাগুলি ডাউনলোড করতে চান তবে পাস করুন -q 99744java আবশ্যক JDK না JRE নির্দেশ।
  2. গিট রেপো ক্লোন করুন , এবং চালান gradle run। আপনার গ্রেড ইনস্টল করা দরকার এবং আপনি যদি যুক্তিগুলি পাস করতে চান তবে ব্যবহার করুন-PappArgs="['arg1', 'args2']"
  3. গিট রেপো ক্লোন করুন এবং এটি নিজেই সংকলন করুন। আপনি নিম্নলিখিত লাইব্রেরি প্রয়োজন হবে: org.eclipse.collections:eclipse-collections-api:8.0.0, org.eclipse.collections:eclipse-collections:8.0.0, com.beust:jcommander:1.48, com.google.code.gson:gson:2.7,org.jsoup:jsoup:1.9.2

যদি আপনি ক্লোন করে থাকেন তবে অবশ্যই --recursiveপতাকাটি ব্যবহার করতে হবে এবং আপনি যখন আপডেটগুলি টানেন,--recurse-submodules উপরের যে কোনওটির জন্য অন্তর্ভুক্ত করুন , আপনার শ্রেণীর submissions/javaফোল্ডারে যেতে হবে । আপনি যদি গ্রেড ব্যবহার করছেন, বা নিজেই এটি সংকলন করছেন, আপনি প্রকল্পটি নিজেই ক্লাসে রাখতে পারেন। আপনার প্রধান ফাংশনে কিছু লাইনকে অসুবিধে করতে হবে এবং আপনার শ্রেণিতে নির্দেশ করার জন্য সেগুলি আপডেট করতে হবে।

স্কোরবোর্ড:

+------+-------------------+-------+
| Rank | Name              | Score |
+------+-------------------+-------+
|    1 | TheWalkingDead    | 738.0 |
|    2 | RogueSquad        | 686.0 |
|    3 | Spiky             | 641.0 |
|    4 | Invulnerables     | 609.0 |
|    5 | Noob              | 581.0 |
|    6 | Railbender        | 561.0 |
|    7 | Vampire           | 524.0 |
|    8 | LongSword         | 508.0 |
|    9 | SniperSquad       | 456.0 |
|   10 | BearCavalry       | 430.0 |
|   11 | StaticCloud       | 429.0 |
|   12 | PlayerWerewolf    | 388.0 |
|   13 | LongSwordv2       | 347.0 |
|   14 | Derailer          | 304.0 |
|   15 | Sorcerer          | 266.0 |
|   16 | CowardlySniperMk2 | 262.0 |
|   17 | TemplatePlayer    |  59.0 |
+------+-------------------+-------+

আপনার যদি কোনও প্রশ্ন থাকে, বা সাহায্যের প্রয়োজন হয় তবে নীচে মন্তব্য করুন বা চ্যাটরুমে যোগদান করুন ! গুড লাক এবং মজা আছে


1
মন্তব্যগুলি বর্ধিত আলোচনার জন্য নয়; এই কথোপকথন চ্যাটে সরানো হয়েছে ।
ডেনিস

বাজ হিসাবে তালিকাবদ্ধ করা হয় Deal 15 damage to all enemies, কিন্তু অদৃশ্য শত্রুরা বাজ দ্বারা প্রভাবিত হয় না। এটি কি বাগ? অন্যথায়, অদৃশ্যতা আমার কাছে বেশ শক্তিশালী বলে মনে হচ্ছে ...
CommonGuy

1
এই চ্যালেঞ্জটি আগের মতো চ্যালেঞ্জগুলির চেয়ে ব্যতিক্রমী জটিল। আমি এখানে একটি ফর্ম্যাট যে দীর্ঘমেয়াদে এই ধরনের কিছু আরো প্রতিযোগিতামূলক তৈরি করতে চান।
স্পার

2
হ্যাঁ, -g বিকল্পগুলি কিনা তা জানি না, তবে আমি যখন আমার বটটি বিকাশ করছিলাম তখন আমার এটি ব্যবহারযোগ্য অবস্থায় ছিল না তাই আমি একটি বিকল্প তৈরি করা শুরু করি। এটি এই মুহুর্তে খুব উদ্দীপনাজনক তবে এটি দৃশ্যমান দর্শনীয় ব্যাসার্ধ। এখানে বিয়ার ক্যাভালারি বনাম টেম্পলেট প্লেয়ারের ক্যাপচার দেওয়া হচ্ছে! ক্যাপচার
মোগি

1
আপনি নতুন অক্ষর পরীক্ষা করতে এবং স্কোর আপডেট করতে পারেন?
ধ্বংসাত্মক লেবু

উত্তর:


10

StaticCloud

একটি সংবেদনশীল ক্রমবর্ধমান মেঘ যা কাছাকাছি আসার কারও কাছে স্থির ক্ষতি করে। ইহা গঠিত:

  • 1/3 অদৃশ্য অংশ
    • এসআরটি: 5; এজিআই: 5; INT: 25
    • ক্লোন , অদৃশ্য , স্থিতিশীল
  • 2/3 দৃশ্যমান অংশ
    • এসআরটি: 5; এজিআই: 5; INT: 25
    • ক্লোন , স্ট্যাটিক , স্ট্যাটিক

আপনি নিজের দলে এখান থেকে একক অক্ষর পুনরায় ব্যবহার করতে পারেন, যতক্ষণ না আপনি অন্তত আরও একটি চরিত্র যোগ করেন যা এখানে উপস্থিত নেই।

StaticCloud.java
import java.util.Arrays;
import java.util.List;

import org.eclipse.collections.api.set.ImmutableSet;
import org.eclipse.collections.impl.factory.Sets;

import com.nmerrill.kothcomm.game.maps.Point2D;

import fellowship.abilities.ActionAbility;
import fellowship.abilities.damage.Static;
import fellowship.abilities.vision.Invisible;
import fellowship.actions.ReadonlyAction;
import fellowship.actions.other.Clone;
import fellowship.characters.CharacterTemplate;
import fellowship.characters.ReadonlyCharacter;

public class StaticCloud extends SleafarPlayer {
    private CharacterTemplate invisibleTemplate() {
        return new CharacterTemplate(0, 0, 20,
                new ActionAbility(Clone::new), new Invisible(), new Static());
    }

    private CharacterTemplate visibleTemplate() {
        return new CharacterTemplate(0, 0, 20,
                new ActionAbility(Clone::new), new Static(), new Static());
    }

    @Override
    public List<CharacterTemplate> createCharacters() {
        return Arrays.asList(visibleTemplate(), invisibleTemplate(), visibleTemplate());
    }

    private class InvisibleCloud extends Character {
        protected InvisibleCloud(ReadonlyCharacter delegate) {
            super(delegate);
        }

        @Override
        protected ReadonlyAction choose() {
            ReadonlyAction clone = getAction(Clone.class);
            if (clone != null && (isVisible() || !isInEnemySightRange())) {
                int invisibleCount = countCharacters(InvisibleCloud.class);
                if (invisibleCount > 8 && setClosestSafeLocation(clone, getStaticLocations())) {
                    return clone;
                } else if (setCloneLocation(clone, invisibleCount < 3 ? 3 : 1)) {
                    return clone;
                }
            }
            if (step != null && isVisible() && isInEnemySliceRange() &&
                    setClosestSafeLocation(step, getStaticLocations())) {
                return step;
            }
            if (slice != null && isVisible() && setSliceTarget(slice, 0.01)) {
                return slice;
            }
            if (step != null) {
                ImmutableSet<Point2D> avoidLocations = !isVisible() || isInEnemySliceRange() ?
                        Sets.immutable.empty() : getEnemySliceLocations();
                if ((isVisible() || clone != null) && !getEnemyHiddenLocations().isEmpty() &&
                        setClosestLocation(step, avoidLocations, getEnemyHiddenLocations())) {
                    return step;
                }
                if (!getStaticLocations().contains(getLocation()) &&
                        setClosestLocation(step, avoidLocations, getStaticLocations())) {
                    return step;
                }
            }
            return smile;
        }
    }

    private class VisibleCloud extends Character {
        protected VisibleCloud(ReadonlyCharacter delegate) {
            super(delegate);
        }

        @Override
        protected ReadonlyAction choose() {
            ReadonlyAction clone = getAction(Clone.class);
            if (clone != null) {
                int visibleCount = countCharacters(VisibleCloud.class);
                if (visibleCount > 5 && setClosestSafeLocation(clone, getStaticLocations())) {
                    return clone;
                } else if (setCloneLocation(clone, visibleCount < 3 ? 2 : 1)) {
                    return clone;
                }
            }
            if (step != null && isInEnemySliceRange() && setClosestSafeLocation(step, getStaticLocations())) {
                return step;
            }
            if (slice != null && setSliceTarget(slice, 0.01)) {
                return slice;
            }
            if (step != null && !getStaticLocations().contains(getLocation())) {
                if (isInEnemySliceRange() ? setClosestLocation(step, getStaticLocations()) :
                        setClosestSafeLocation(step, getStaticLocations())) {
                    return step;
                }
            }
            return smile;
        }
    }

    @Override
    protected Character createCharacter(ReadonlyCharacter delegate) {
        if (hasAbility(delegate, Invisible.class)) {
            return new InvisibleCloud(delegate);
        } else {
            return new VisibleCloud(delegate);
        }
    }
}

3
এটি আকর্ষণীয় কারণ স্ট্যাটিক অদৃশ্যতা ভঙ্গ করে না।
Draco18s

7

টেমপ্লেট প্লেয়ার

ব্যবহার সীমাকৃত , নমনীয় , ঝটকা এবং KO । আপনি যদি চান তবে এই ক্ষমতা সেটটি ব্যবহার করার অনুমতি আপনার রয়েছে।

আপনার নিজের তৈরি করার জন্য এই বটটিকে একটি টেম্পলেট হিসাবে নির্দ্বিধায় ব্যবহার করুন।

মনে রাখবেন যে আপনাকে প্রথম লাইনে ফাইলের নাম পরিবর্তন করতে হবে, পাশাপাশি নিজের নিজস্ব ক্ষমতা সেটটিও নির্বাচন করতে হবে।

TemplatePlayer.java
import com.nmerrill.kothcomm.game.maps.Point2D;
import fellowship.abilities.ActionAbility;
import fellowship.abilities.attacking.Flexible;
import fellowship.abilities.attacking.Ranged;
import fellowship.actions.ReadonlyAction;
import fellowship.actions.damage.KO;
import fellowship.actions.damage.Zap;
import fellowship.characters.CharacterTemplate;
import fellowship.characters.ReadonlyCharacter;
import fellowship.Player;
import org.eclipse.collections.api.set.MutableSet;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

public class TemplatePlayer extends Player{
    private final double CRITICAL_HEALTH = 20;
    @Override
    public List<CharacterTemplate> createCharacters() {
        List<CharacterTemplate> templates = new ArrayList<>();
        for (int i = 0; i < 3; i++) {
            templates.add(new CharacterTemplate(10, 5, 5,
                    new Ranged(),
                    new Flexible(),
                    new ActionAbility(KO::new),
                    new ActionAbility(Zap::new)));
        }
        return templates;
    }

    @Override
    public ReadonlyAction choose(Set<ReadonlyAction> actions, ReadonlyCharacter character) {
        int minPriority = Integer.MAX_VALUE;
        ReadonlyAction chosen = null;
        for (ReadonlyAction action: actions){
            int priority = getPriorityFor(action, character);
            if (priority < minPriority){
                chosen = action;
                minPriority = priority;
            }
        }
        if (chosen == null){
            throw new RuntimeException("No valid actions");
        }
        if (chosen.needsLocation()){
            chosen.setLocation(chooseLocationFor(chosen, character));
        } else if (chosen.needsTarget()){
            chosen.setTarget(chooseTargetFor(chosen));
        }
        return chosen;
    }

    private Point2D chooseLocationFor(ReadonlyAction action, ReadonlyCharacter character){
        if (action.movementAction()){
            if (character.getHealth() < CRITICAL_HEALTH){
                return fromEnemy(action.availableLocations());
            } else {
                return toEnemy(action.availableLocations());
            }
        }
        return toTeam(action.availableLocations());
    }

    private Point2D toEnemy(MutableSet<Point2D> availableLocations){
        if (visibleEnemies.isEmpty()){
            return availableLocations.iterator().next();
        }
        return availableLocations.minBy(p1 ->
                p1.cartesianDistance(visibleEnemies.keysView().minBy(p1::cartesianDistance))
        );
    }

    private Point2D fromEnemy(MutableSet<Point2D> availableLocations){
        if (visibleEnemies.isEmpty()){
            return availableLocations.iterator().next();
        }
        return availableLocations.maxBy(p1 ->
                p1.cartesianDistance(visibleEnemies.keysView().minBy(p1::cartesianDistance))
        );
    }

    private Point2D toTeam(MutableSet<Point2D> availableLocations){
        if (team.isEmpty()){
            return availableLocations.iterator().next();
        }
        return availableLocations.minBy(p1 ->
                p1.cartesianDistance(team.collect(ReadonlyCharacter::getLocation).minBy(p1::cartesianDistance))
        );
    }

    private ReadonlyCharacter chooseTargetFor(ReadonlyAction action){
        return action.availableTargets().minBy(ReadonlyCharacter::getHealth);
    }

    private int getPriorityFor(ReadonlyAction action, ReadonlyCharacter character){
        if (character.isInvisible() && action.breaksInvisibility()){
            return 1000;
        }
        if (action.getName().equals("Smile")){
            return 999;
        }
        if (action.movementAction()){
            if (character.getHealth() < 20){
                return 0;
            }
            return 998;
        }
        if (action.needsTarget()) {
            return ((int) action.availableTargets().minBy(ReadonlyCharacter::getHealth).getHealth());
        }
        return 997;
    }
}

7

CowardlySniperMk2

ব্যবহার ঝটকা , FarSight * 2, এবং লুকান

এই বটটি কাপুরুষ is এটির সর্বোচ্চ অগ্রাধিকার লক্ষ্য নয়। সে লক্ষ্যে শত্রুরা কোথায় তা দেখার জন্য তিনি তার উচ্চতর দৃষ্টি ব্যবহার করেন। শত্রুকে অনুসরণ করা / অনুসরণ করা দেখা না দেওয়া অবস্থায় এটি এ জ্ঞানটি ব্যবহার করে। যদি এটি দেখা হয়, বা পরের দিকে দেখা যায় তবে বটটি একটি সময়ের জন্য অদৃশ্য হয়ে উঠবে hide

ট্র্যাকিং মোডে, এবং যথেষ্ট মানা এবং কোলডাউন রিসেট রয়েছে, তারপরে দুর্বলতম দৃশ্যমান শত্রু 'জ্যাপ' করবে।

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

দ্রষ্টব্য যেহেতু 'জ্যাপ' অসীম পরিসীমা, তাই টিপ মেম্বাররা জ্যাপিংয়ের সময় সকলেই একই বটকে লক্ষ্য করবে।

আমার এই একই বুনিয়াদি ধারণার অন্যান্য রূপ রয়েছে যা আমি উত্তর হিসাবে যুক্ত করতে পারি: তাদের সকলের পৃথক পৃথক সুবিধা / ক্ষতিকারক রয়েছে যা উপস্থিত বিরোধীদের উপর নির্ভর করে শোষণ / উন্মুক্ত করা হয়।

CowardlySniperMk2.java

import com.nmerrill.kothcomm.game.maps.Point2D;
import fellowship.abilities.ActionAbility;
import fellowship.abilities.vision.FarSight;
import fellowship.actions.ReadonlyAction;
import fellowship.actions.damage.Zap;
import fellowship.actions.vision.Hide;
import fellowship.characters.CharacterTemplate;
import fellowship.characters.ReadonlyCharacter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
import fellowship.*;

public class CowardlySniperMk2 extends Player{

    private final static boolean DEBUG=false; 
    private static Point2D lastAttackedEnemyLocation = null;
    private static HashMap<ReadonlyCharacter, Boolean> rechargingManaMap = new HashMap<>();
    private final double STANDARD_VISION_MOVEMENT_BUFFER = 3;
    private final double MIN_VISION_DISTANCE = 2;

    @Override
    public List<CharacterTemplate> createCharacters() {
        List<CharacterTemplate> templates = new ArrayList<>();
        for (int i = 0; i < 3; i++) {
            templates.add(new CharacterTemplate(8, 8, 4,
                    new ActionAbility(Zap::new),
                    new FarSight(),
                    new FarSight(),
                    new ActionAbility(Hide::new)));
        }
        return templates;
    }

    @Override
    public ReadonlyAction choose(Set<ReadonlyAction> actions, ReadonlyCharacter character) {

        // get last flag for recharging mana
        Boolean rechargingMana = rechargingManaMap.get(character);
        if (rechargingMana == null || rechargingMana)
        {
            rechargingMana = !(character.getMana()>0.90*character.getMaxMana());
        }
        else
        {
            rechargingMana = character.getMana()<0.10*character.getMaxMana();
        }

        rechargingManaMap.put(character,rechargingMana);

        HashMap<Integer, ReadonlyAction> validActions = new HashMap<>();
        HashMap<Integer, String> actionString = new HashMap<>();

        // see if we have arrived at the last attack location of the enemy
        if (character.getLocation().equals(lastAttackedEnemyLocation))
        {
            lastAttackedEnemyLocation = null;
        }

        double closestEnemyVisionDistance = Double.MAX_VALUE;
        for ( Point2D enemyLocation : visibleEnemies.keySet())
        {
            final int enemyVisibiltyRange = visibleEnemies.get(enemyLocation).getSightRange().getRange();
            double visionDistanceDiff = character.getLocation().diagonalDistance(enemyLocation)-enemyVisibiltyRange;
            if (visionDistanceDiff< closestEnemyVisionDistance)
            {
                closestEnemyVisionDistance = visionDistanceDiff;
            }
        }

        for (ReadonlyAction action: actions){

            int priority=-1;
            String message = "";
            switch (action.getName())
            {
                case "Hide":
                    // are we, or will we be within sight range of an enemy
                    if (closestEnemyVisionDistance < STANDARD_VISION_MOVEMENT_BUFFER )
                    {
                        if (!character.isInvisible())
                        {
                            message = ""+closestEnemyVisionDistance;
                            priority = 1000;
                        }
                    }
                    break;

                case "Step":

                    Point2D chosenLocation = null;

                    // are we within sight range of an enemy or are we recharging mana?
                    if (closestEnemyVisionDistance < MIN_VISION_DISTANCE || rechargingMana)
                    {
                        message = "Fleeing (Seen) "+ closestEnemyVisionDistance;
                        priority = 800;

                        if (character.isInvisible())
                        {
                            message = "Fleeing (UnSeen) "+ closestEnemyVisionDistance;
                            priority = 500;
                        }

                        // simple enemy avoidance... chose location that is farthest away from closest enemy
                        double furthestDistance = 0;

                        for ( Point2D enemyLocation : visibleEnemies.keySet())
                        {
                            for (Point2D location : action.availableLocations())
                            {
                                if (location.diagonalDistance(enemyLocation) > furthestDistance)
                                {
                                    furthestDistance = location.diagonalDistance(enemyLocation);
                                    chosenLocation = location;
                                }
                            }
                        }

                        if (chosenLocation == null)
                        {
                            // no moves are better than staying in current location
                            priority = -1;
                            break;
                        }
                    }
                    // are we "tracking" an enemy?
                    else if (lastAttackedEnemyLocation !=null)
                    {
                        priority = 20;
                        message = "Tracking "+ closestEnemyVisionDistance;

                        // head toward last attacked enemy location
                        double distance = Integer.MAX_VALUE;
                        for (Point2D location : action.availableLocations())
                        {
                            if (location.diagonalDistance(lastAttackedEnemyLocation) < distance)
                            {
                                distance = location.diagonalDistance(lastAttackedEnemyLocation);
                                chosenLocation = location;
                            }
                        }
                    }
                    // are we outside the sight range of all enemies?
                    else if (closestEnemyVisionDistance > STANDARD_VISION_MOVEMENT_BUFFER)
                    {
                        // scout for an enemy

                        priority = 10;
                        message = "Scouting "+ closestEnemyVisionDistance;

                        // dumb random location selection... not optimal but is sufficent.
                        int index = getRandom().nextInt(action.availableLocations().size());
                        for (Point2D location : action.availableLocations())
                        {
                            chosenLocation= location;
                            if (--index == 0)
                            {
                                break;
                            }
                        }
                    }
                    else
                    {
                        // we are in the sweet zone... just out of enemy sight range but within our sight range
                        break;
                    }

                    action.setLocation(chosenLocation);
                    break;

                case "Zap":
                    message = ""+closestEnemyVisionDistance;
                    ReadonlyCharacter chosenTarget = null;
                    double chosenTargetHealth = Double.MAX_VALUE;

                    // target the weakest enemy
                    for (ReadonlyCharacter target : action.availableTargets())
                    {
                        if (target.getHealth() < chosenTargetHealth)
                        {
                            chosenTargetHealth = target.getHealth();
                            chosenTarget = target;
                        }
                    }

                    if (chosenTarget != null)
                    {
                        priority = 100;
                        action.setTarget(chosenTarget);
                        lastAttackedEnemyLocation = chosenTarget.getLocation();
                    }
                    else
                    {
                        // nothing to target
                    }

                    break;

                case "Smile":
                    priority = 0;
                    break;
            }

            // add the action to the collection of valid actions to perform
            if (priority >-1)
            {
                validActions.put(priority, action);
                actionString.put(priority, message);
            }

        }


        int highestPriority = -1;
        ReadonlyAction chosen = null;

        // choose the highest priority action
        for (Integer priority : validActions.keySet())
        {
            if (priority > highestPriority)
            {
                highestPriority = priority;
                chosen = validActions.get(priority);
            }
        }
        String message = actionString.get(highestPriority);

        if (chosen == null){
            throw new RuntimeException("No valid actions");
        }

        if (DEBUG) System.out.println(this+"("+System.identityHashCode(character)+"): "+chosen.getName()+ (rechargingMana?" Mana_charge":" Mana_usable")+" H: "+character.getHealth()+" M: "+character.getMana() +(character.isInvisible()?" InVis":" Vis") +" x: "+character.getLocation().getX()+" y: "+character.getLocation().getY()+" "+message);
        return chosen;
    }
}

ফাইলের নামটি কাপর্ডলি স্নিপারমেক 2 হওয়া উচিত :)
নাথান মেরিল

উফফ: পি কেটে পেস্ট করা আমাকে বোকাদের মতো দেখাচ্ছে!
মোগি

আমাকে মারিওকার্ট ওয়াইয়ের বি ড্যাশার এমকে 2 এর স্মরণ করিয়ে দেয় :)
ক্রিটিক্সী লিথোস

@ ক্রিটিক্সিলিথস আমাকে স্প্লাটুনের বাঁশজুলার 14 এম কে II এর স্মরণ করিয়ে দেয়। ;)
টিএনটি

7

TheWalkingDead

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

  • 1 এক্স বোকচন্দর # 1 (সবচেয়ে শক্তিশালী এবং তাই আলফা জম্বি)
    • এসআরটি: 25; এজিআই: 5; INT: 15
    • ক্লোন , পুনরুত্থান , শক্তিশালী
  • 2 এক্স বোকচন্দর # 2 (সমাপ্তি জমাগুলিতে কেউ # 3 বোকচন্দর হতে চায়নি, সুতরাং উভয়ই একই নম্বর পেয়েছে)
    • এসআরটি: 15; এজিআই: 5; INT: 15
    • ক্লোন , পুনরুত্থান , শোষণকারী

আপনি নিজের দলে এখান থেকে একক অক্ষর পুনরায় ব্যবহার করতে পারেন, যতক্ষণ না আপনি অন্তত আরও একটি চরিত্র যোগ করেন যা এখানে উপস্থিত নেই।

TheWalkingDead.java
import java.util.Arrays;
import java.util.List;

import fellowship.abilities.ActionAbility;
import fellowship.abilities.attacking.Absorb;
import fellowship.abilities.defensive.Resurrect;
import fellowship.abilities.stats.Strong;
import fellowship.actions.ReadonlyAction;
import fellowship.actions.other.Clone;
import fellowship.characters.CharacterTemplate;
import fellowship.characters.ReadonlyCharacter;

public class TheWalkingDead extends SleafarPlayer {
    private CharacterTemplate zombie1Template() {
        return new CharacterTemplate(20, 0, 10, new ActionAbility(Clone::new), new Resurrect(), new Strong());
    }

    private CharacterTemplate zombie2Template() {
        return new CharacterTemplate(10, 0, 10, new ActionAbility(Clone::new), new Resurrect(), new Absorb());
    }

    @Override
    public List<CharacterTemplate> createCharacters() {
        return Arrays.asList(zombie1Template(), zombie2Template(), zombie2Template());
    }

    private class Zombie extends Character {
        private int resurrectCountdown = 0;
        private double oldHealth;

        protected Zombie(ReadonlyCharacter delegate) {
            super(delegate);
            this.oldHealth = getHealth();
        }

        @Override
        protected ReadonlyAction choose() {
            if (getHealth() > oldHealth + getHealthRegen() + 0.1) {
                resurrectCountdown = 40;
            }
            if (resurrectCountdown > 0) {
                --resurrectCountdown;
            }
            oldHealth = getHealth();

            ReadonlyAction clone = getAction(Clone.class);
            if (resurrectCountdown > 0) {
                if (step != null && isInEnemySliceRange() && setAvoidEnemiesLocation(step)) {
                    return step;
                }
                if (clone != null && !getSliceLocations().isEmpty() && setClosestLocation(clone, getSliceLocations())) {
                    return clone;
                }
                if (clone != null && setCloneLocation(clone, 1)) {
                    return clone;
                }
                if (slice != null && setSliceTarget(slice, 0.01)) {
                    return slice;
                }
                if (step != null && setAvoidEnemiesLocation(step)) {
                    return step;
                }
            } else {
                if (clone != null && !getSliceLocations().isEmpty() && setClosestLocation(clone, getSliceLocations())) {
                    return clone;
                }
                if (clone != null && setCloneLocation(clone, 1)) {
                    return clone;
                }
                if (slice != null && setSliceTarget(slice, 0.01)) {
                    return slice;
                }
                if (step != null && !getSliceLocations().isEmpty() && setClosestLocation(step, getSliceLocations())) {
                    return step;
                }
            }
            return smile;
        }
    }

    @Override
    protected Character createCharacter(ReadonlyCharacter delegate) {
        return new Zombie(delegate);
    }
}

আমি ... Sleafar বেস বর্গ আমদানির একটি fellowship.characters.CharacterInterface সর্বশেষ মাস্টার শাখায় হবে বলে মনে হচ্ছে না ... কাজ করার জন্য আপনার বট পেতে পারে না
Moogie


7

অদম্য

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

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

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

দ্য ম্যাজিক ইন দ্য এক্সক্লিয়াস গোলক

  • এসআরটি : 5; এজিআই : 5; INT : 25

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

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

দ্য জায়েন্ট ক্লিফটপ ফ্যালকোনার

  • এসআরটি : 35; এজিআই : 5; INT : 5

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

ফ্যালকনারের চাকরির বিরুদ্ধে আক্রমণাত্মক শত্রুদের শিকার করা এবং শত্রুদের দৃষ্টিশক্তি বজায় রাখা যাতে ম্যাগেজ তাদের বিষাক্ত রাখতে পারে, শত্রুর জলাবদ্ধ দলগুলির সাথে কাজ করার জন্য মাঝেমধ্যে 35 এর জন্য বুনন করার ক্ষমতা কী; এইভাবে প্রচুর শত্রুদের আঘাত করা সম্ভব হবে এবং দলের বাকি অংশের জন্য শেষ পর্যাপ্ত পর্যায়ে এগুলি যথেষ্ট রেখে দিন (আদর্শভাবে অন্য ওয়েভ দিয়ে)। এই নিয়মের অধীনে জলাবদ্ধতা একটি অতিশক্তিযুক্ত কৌশল এবং ওয়েভ এটির কয়েকটি আসল কাউন্টারগুলির মধ্যে একটি। তারপরেও, এটি নিজে থেকে যথেষ্ট ভাল নয় not

ট্রোলবোন স্কুলারেন্ডার

  • এসআরটি : 25; এজিআই : 5; INT : 5

ট্রলবোনের কাজ হ'ল শত্রুদের সৈন্যদলকে দমন করা এবং অন্য ইউনিটগুলি তাদের কাজটি করতে পারে। শুধু পুরোনো যাদুকর মতো Trollbone মধ্যে অসীম পরিসরের বানান হয়েছে নকআউট । এই কম্বোটিসটি ম্যাগেজের বিষের সাথে খুব ভাল; যদি একে অপরকে শত্রুর মুখোমুখি করা সম্ভব হয় (এবং অনেক দলের বিপক্ষে, এটি হ'ল), ফ্যালকোনার দৃষ্টি অর্জন করবে, ট্রলবোন তাদের স্তম্ভিত করবে, তারপরে দ্য দ্য ম্যাগেজ তাদের উপর বিষ ছড়িয়ে দেবে এবং তারা মারা যাবে'll কিছু করার ক্ষমতা ছাড়াই (নকআউট লক্ষ্যভেদে 1000 টি টিক্ টিকিয়ে রাখে এবং ট্রলবোন এর চেয়ে সামান্য দ্রুত তার জন্য কলডাউনটিকে পুনরায় জেনারেট করে)। ট্রোলবোনকে একক শক্তিশালী শত্রুদের বিরুদ্ধে রক্ষা করার ক্ষেত্রে এটি খুব ভাল; তারা সচেতন না হলে তারা তাকে কিছু করতে পারে না। অবশ্যই, কোনও শত্রুর সাথে মস্তকগুলি ভেঙে ফেলা উভয়কেই অবাক করে দেওয়া দায়,স্টান এবং বিষ (এবং অন্যান্য স্ট্যাটাসগুলির একগুচ্ছ কেউই যত্ন করে না) to মন্ত্র-কেন্দ্রিক চরিত্র হিসাবে যিনি তবুও খুব জাদুকরীভাবে ঝোঁক নন, ট্রলবোন বুদ্ধির মাধ্যমে নয়, তাঁর শত্রুদের রক্ত ​​পান করে, প্রতিটি হিট দিয়ে একটি মান স্টিল করে যাদুটিকে পুনরুত্পাদন করে; এটি এমপি পুনর্জন্মের বেশ ভাল হার দেয় (এবং স্তব্ধ শত্রুরা এমপি থেকে চুরি করার সহজ টার্গেট তৈরি করে)) অবশেষে, Trollbone কখনও তা ছোটাছুটি যায় হবে বুনা শত্রু পদমর্যাদার মাধ্যমে যখন মাথা মর্মান্তিক এবং তাদের রক্ত পান। যথেষ্ট পরিমাণে শত্রুদের বিপক্ষে, এটি আসলে মন ফিরে আসে এবং ফ্যালকনার দুর্বল হয়ে পড়ে এমন একটি ঝাঁক শেষ করতে পারে (25 + 35 হ'ল 60 এমনকি শত্রুদের মাঝে কিছুটা হলেও পুনরায় জেনারেট হলেও এটি কাজ করে)।

কৌশল

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

Invulnerables.java
import com.nmerrill.kothcomm.game.maps.Point2D;
import fellowship.abilities.*;
import fellowship.abilities.attacking.*;
import fellowship.abilities.defensive.*;
import fellowship.abilities.vision.*;
import fellowship.abilities.stats.*;
import fellowship.abilities.statuses.*;
import fellowship.actions.*;
import fellowship.actions.attacking.*;
import fellowship.actions.damage.*;
import fellowship.actions.defensive.*;
import fellowship.actions.statuses.*;
import fellowship.characters.CharacterTemplate;
import fellowship.characters.ReadonlyCharacter;
import fellowship.characters.EnemyCharacter;
import fellowship.*;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

public class Invulnerables extends Player {
  @Override
  public List<CharacterTemplate> createCharacters() {
    List<CharacterTemplate> templates = new ArrayList<>();

    templates.add(new CharacterTemplate(0, 0, 20,
                                        new ActionAbility(Poison::new),
                                        new ActionAbility(ForceField::new),
                                        new Focused(),
                                        new Pillar()));

    templates.add(new CharacterTemplate(30, 0, 0,
                                        new ActionAbility(Weave::new),
                                        new Strong(),
                                        new FarSight(),
                                        new TrueSight()));

    templates.add(new CharacterTemplate(20, 0, 0,
                                        new ActionAbility(Weave::new),
                                        new ActionAbility(Knockout::new),
                                        new ManaSteal(),
                                        new Immune()));

    return templates;
  }

  private String lastIdentifier(String s) {
    String[] split = s.split("\\W");
    return split[split.length - 1];
  }

  private boolean hasAbility(ReadonlyCharacter character, String abilityName) {
    for (ReadonlyAbility ability : character.getAbilities()) {
      if (lastIdentifier(ability.name()).equals(abilityName))
        return true;
    }
    return false;
  }

  private boolean hasAbility(EnemyCharacter character, String abilityName) {
    for (ReadonlyAbility ability : character.getAbilities()) {
      if (lastIdentifier(ability.name()).equals(abilityName))
        return true;
    }
    return false;
  }

  private int getSquareDanger(ReadonlyCharacter character, Point2D square) {
    /* A square's danger is basically equal to the number of hits we'd
       expect to take when standing there. Each hit is worth 1; a hit of
       25 damage or more is worth 2. */
    int sliceDanger = 0;
    int otherDanger = 0;
    int cx = square.getX();
    int cy = square.getY();
    for (Point2D enemyLocation : visibleEnemies.keysView()) {
      EnemyCharacter enemy = visibleEnemies.get(enemyLocation);
      if (enemy.isStunned())
        continue; /* approaching stunned enemies is a good thing */
      int dx = enemyLocation.getX() - cx;
      int dy = enemyLocation.getY() - cy;
      if (dx < 0)
        dx = -dx;
      if (dy < 0)
        dy = -dy;
      if (dx + dy <= 1) {
        /* We're in Static range. */
        if (hasAbility(enemy, "Static"))
          otherDanger++;
      }
      if (dx + dy <= enemy.getSliceRange().getRange() &&
          (dx * dy == 0 || !enemy.getSliceRange().isCardinal())) {
        int sliceMultiplier = 1;
        if (hasAbility(enemy, "Quick") && !hasAbility(character, "Pillar"))
          sliceMultiplier *= 2;
        if (enemy.getStat(enemy.primaryStat()) >= 25)
          sliceMultiplier *= 2;
        if (hasAbility(character, "Pillar")) {
          if (sliceDanger >= sliceMultiplier)
            continue;
          sliceDanger = 0;
        }
        sliceDanger += sliceMultiplier;
      }
    }
    return sliceDanger + otherDanger;
  }

  private ReadonlyAction[] forceFieldAction = new ReadonlyAction[3];
  private int goalX = 5;
  private int goalY = 5;

  @Override
  public ReadonlyAction choose(Set<ReadonlyAction> actions, ReadonlyCharacter character) {

    /* Which character are we? */
    int characterNumber;
    if (hasAbility(character, "Focused"))
      characterNumber = 0;
    else if (hasAbility(character, "Immune"))
      characterNumber = 1;
    else if (hasAbility(character, "TrueSight"))
      characterNumber = 2;
    else
      throw new RuntimeException("Unrecognised character!");

    /* If we're at the goal square, pick a new one. */
    if (goalX == character.getLocation().getX() &&
        goalY == character.getLocation().getY()) {
      int i = getRandom().nextInt(5);
      goalX = i < 2 ? 1 : i > 2 ? 9 : 5;
      goalY = i == 2 ? 5 : (i % 2) == 1 ? 1 : 9;
    }

    /* If there are a lot of visible enemies, try to group up in a corner in order
       to prevent being surrounded. */
    if (visibleEnemies.size() > 3) {
      int xVotes = 0;
      int yVotes = 0;
      for (ReadonlyCharacter ally : team) {
        xVotes += ally.getLocation().getX() >= 5 ? 1 : -1;
        yVotes += ally.getLocation().getY() >= 5 ? 1 : -1;
      }
      goalX = xVotes > 0 ? 9 : 0;
      goalY = yVotes > 0 ? 9 : 0;
    }

    /* We need to know our Force Field cooldowns even between turns, so store the
       actions in a private field for later use (they aren't visible via the API) */
    for (ReadonlyAction action : actions) {
      if (action.getName().equals("ForceField"))
        forceFieldAction[characterNumber] = action;
    }

    /* If we know Force Field, ensure we always hang on to enough mana to cast it, and
       never allow our mana to dip low enough that it wouldn't regenerate in time. */
    double mpFloor = 0.0;
    if (forceFieldAction[characterNumber] != null) {
      double mpRegen = character.getStat(Stat.INT) / 10.0;
      if (hasAbility(character, "Focused"))
        mpRegen *= 2;
      mpFloor = forceFieldAction[characterNumber].getManaCost();
      mpFloor -= forceFieldAction[characterNumber].getRemainingCooldown() * mpRegen;
    }
    if (mpFloor > character.getMana())
      mpFloor = character.getMana();

    /* We use a priority rule for actions. */
    int bestPriority = -2;
    ReadonlyAction bestAction = null;
    for (ReadonlyAction action : actions) {
      int priority = 0;
      if (lastIdentifier(action.getName()).equals("ForceField"))
        priority = 20; /* top priority */
      else if (character.getMana() - action.getManaCost() < mpFloor) {
        continue; /* never spend mana if it'd block a force field */
      } else if (lastIdentifier(action.getName()).equals("Quick") ||
                 lastIdentifier(action.getName()).equals("Slice")) {
        int damagePotential =
          lastIdentifier(action.getName()).equals("Quick") ? 50 : 25;
        /* We use these abilities with very high priority to /kill/ an enemy
           who's weak enough to die from the damage. If they wouldn't die,
           we're much more wary about attacking; we do it only if we have
           nothing better to do and it's safe. */
        ReadonlyCharacter chosenTarget = null;
        for (ReadonlyCharacter target : action.availableTargets()) {
          if (!isEnemy(target))
            continue;
          if (target.getHealth() <= damagePotential) {
            chosenTarget = target;
            priority = (damagePotential == 25 ? 19 : 18);
            break; /* can't do beter than this */
          }
          if (hasAbility(target, "Spikes") ||
              hasAbility(target, "Reflexive"))
            /*  (target.getLastAction() != null &&
                target.getLastAction().getName().equals("Ghost")) */
            continue; /* veto the target */
          priority = (damagePotential == 25 ? 3 : 4);
          chosenTarget = target;
        }
        if (chosenTarget == null)
          continue;
        action.setTarget(chosenTarget);
      } else if (lastIdentifier(action.getName()).equals("Weave")) {
        priority = visibleEnemies.size() >= 3 ? 14 :
          visibleEnemies.size() >= 1 ? 6 : -1;
      } else if (lastIdentifier(action.getName()).equals("Smile")) {
        /* If there's a stunned or poisoned enemy in view, we favour Smile
           as the idle action, rather than exploring, so that we don't
           move it out of view. Exception: if they're the only enemy;
           in that case, hunt them down. Another exception: if we're
           running into a corner. */
        for (EnemyCharacter enemy : visibleEnemies) {
          if (enemy.isStunned() || enemy.isPoisoned())
            if (visibleEnemies.size() > 1 && visibleEnemies.size() < 4)
              priority = 2;
        }
        /* otherwise we leave it as 0, and Smile only as a last resort */
      } else if (lastIdentifier(action.getName()).equals("Knockout")) {
        /* Use this only on targets who have more than 50 HP. It doesn't
           matter where they are: if we can see them now, knocking them
           out will guarantee we can continue to see them. Of course, if
           they're already knocked out, don't use it (although this case
           should never come up). If there's only one enemy target in
           view, knocking it out has slightly higher priority, because
           we don't need to fear enemy attacks if all the enemies are
           knocked out.

           Mildly favour stunning poisoned enemies; this reduces the
           chance that they'll run out of sight and reset the poison. */
        ReadonlyCharacter chosenTarget = null;
        for (ReadonlyCharacter target : action.availableTargets())
          if ((target.getHealth() > 50 || target.isPoisoned()) &&
              !target.isStunned() && isEnemy(target)) {
            chosenTarget = target;
            if (target.isPoisoned())
              break;
          }
        if (chosenTarget == null)
          continue;
        action.setTarget(chosenTarget);
        priority = visibleEnemies.size() == 1 ? 17 : 15;
      } else if (lastIdentifier(action.getName()).equals("Poison")) {
        /* Use this preferentially on stronger enemies, and preferentially
           on enemies who are more poisoned. We're willing to poison
           almost anyone, although weak enemies who aren't poisoned
           are faster to kill via slicing. The cutoff is at 49, not 50,
           so that in the case of evasive enemies who we can't hit any
           other way, we can wear them one at a time using poison. */
        ReadonlyCharacter chosenTarget = null;
        int chosenTargetPoisonLevel = -1;
        for (ReadonlyCharacter target : action.availableTargets()) {
          int poisonLevel = 0;

          if (!isEnemy(target))
            continue;
          if (target.isPoisoned())
            poisonLevel = target.getPoisonAmount() + 1;
          if (poisonLevel < chosenTargetPoisonLevel)
            continue;
          if (poisonLevel == 0 && target.getHealth() <= 49)
            continue; /* prefer stronger targets */
          if (poisonLevel == 0 && target.getHealth() == 50 &&
              chosenTarget != null)
            continue; /* we poison at 50, but not with other options */
          chosenTarget = target;
          chosenTargetPoisonLevel = poisonLevel;
          priority = 12;
        }
        if (chosenTarget == null)
          continue;
        action.setTarget(chosenTarget);
      } else if (action.movementAction()) {
        /* A move to a significantly safer square is worth 16.
           A move to a mildly safer square is worth 8.
           Otherwise, move to group, either with the enemy,
           the team, or the goal, at priority 1, if we
           safely can; that's our "idle" action. */
        int currentSquareDanger =
          getSquareDanger(character, character.getLocation());
        int bestSquareDanger = currentSquareDanger;
        int bestGroupiness = 0;
        Point2D bestLocation = null;
        priority = 1;
        for (Point2D location :
               action.availableLocations().toList().shuffleThis(getRandom())) {
          int danger = getSquareDanger(character, location);
          if (danger > bestSquareDanger)
            continue;
          else if (danger < bestSquareDanger) {
            priority = (currentSquareDanger - danger > 2)
              ? 16 : 8;
            bestSquareDanger = danger;
            bestLocation = location;
            bestGroupiness = 0; /* reset the tiebreak */
          }

          int cx = character.getLocation().getX();
          int xDelta = location.getX() - cx;
          int cy = character.getLocation().getY();
          int yDelta = location.getY() - cy;
          int groupiness = 0;
          /* Always hunt down a visible enemy when they're the only
             remaining enemy and doing so is safe. Otherwise, still
             favour hunting them down, but in that situation also
             consider factors like grouping and exploration. */
          for (Point2D enemyLocation : visibleEnemies.keysView())
            if (xDelta * (enemyLocation.getX() - cx) > 0 ||
                yDelta * (enemyLocation.getY() - cy) > 0)
              groupiness += (visibleEnemies.size() == 1 ? 99 : 5);
          /* If there are 4 or more visible enemies, then grouping is
             vitally important (so as to not get surrounded).
             Otherwise, it's more minor. */
          for (ReadonlyCharacter ally : team)
            if (xDelta * (ally.getLocation().getX() - cx) > 0 ||
                yDelta * (ally.getLocation().getY() - cy) > 0)
              groupiness += (visibleEnemies.size() > 3 ? 99 : 3);
          /* When exploring, we bias towards random map locations,
             changing location when we reach them. This helps us beat
             enemies that hide in the corners. When there are a lot
             of visible enemies, this changes to a bias to hide in a
             corner. */
          if (xDelta * (goalX - cx) > 0 ||
              yDelta * (goalY - cy) > 0)
            groupiness += (visibleEnemies.size() > 3 ? 99 : 4);
          if (groupiness >= bestGroupiness) {
            bestLocation = location;
            bestGroupiness = groupiness;
            /* leave priority, safety untouched */
          }
        }
        if (bestLocation == null)
          continue;
        action.setLocation(bestLocation);
      } else
        throw new RuntimeException("unknown action" + action.getName());

      if (priority > bestPriority) {
        bestPriority = priority;
        bestAction = action;
      }
    }
    if (bestAction == null)
      throw new RuntimeException("no action?");

    return bestAction;
  }
}

খুব কার্যকর :) অত্যাশ্চর্য একটি কার্যকর কৌশল মত দেখাচ্ছে!
মোগি

ফোর্সফিল্ডের সাথে আপনার চরিত্রটি আমার নুবস দ্বারা পরাস্ত করা যাবে না, যদিও এর মাত্র 50 টি স্বাস্থ্য রয়েছে!
ক্রিটসি লিথোস

@ স্লেফার ইঙ্গিত করে একটি বাগ ঠিক করেছেন।

আমি মনে করি আপনার ফ্যালকনার এবং ট্রলবোনটিতে আপনার কয়েকটি খুব বেশি দক্ষতা রয়েছে
Eumel

স্থিরও। এটি বর্ণনায় কেবল একটি টাইপ ছিল, কোডটি সঠিক ছিল।

7

RogueSquad

একটি দুর্বৃত্ত দল রয়েছে:

  • 1 স্কাউট (মানচিত্র অন্বেষণ করার সময় ছায়ায় থেকে যায়)
    • এসআরটি: 5; এজিআই: 5; INT: 25
    • ক্লোন , অদৃশ্য , দূরদর্শন
  • 2 অ্যাসাসিন (মারাত্মক বিষ দিয়ে শত্রুদের আক্রমণ)
    • এসআরটি: 5; এজিআই: 5; INT: 25
    • ক্লোন , বিষ , কেন্দ্রীভূত

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

আপনি নিজের দলে এখান থেকে একক অক্ষর পুনরায় ব্যবহার করতে পারেন, যতক্ষণ না আপনি অন্তত আরও একটি চরিত্র যোগ করেন যা এখানে উপস্থিত নেই।

RogueSquad.java
import java.util.Arrays;
import java.util.List;

import fellowship.abilities.ActionAbility;
import fellowship.abilities.stats.Focused;
import fellowship.abilities.vision.FarSight;
import fellowship.abilities.vision.Invisible;
import fellowship.actions.ReadonlyAction;
import fellowship.actions.other.Clone;
import fellowship.actions.statuses.Poison;
import fellowship.characters.CharacterTemplate;
import fellowship.characters.ReadonlyCharacter;

public class RogueSquad extends SleafarPlayer {
    private CharacterTemplate scoutTemplate() {
        return new CharacterTemplate(0, 0, 20,
                new ActionAbility(Clone::new), new Invisible(), new FarSight());
    }

    private CharacterTemplate assasinTemplate() {
        return new CharacterTemplate(0, 0, 20,
                new ActionAbility(Clone::new), new ActionAbility(Poison::new), new Focused());
    }

    @Override
    public List<CharacterTemplate> createCharacters() {
        return Arrays.asList(assasinTemplate(), scoutTemplate(), assasinTemplate());
    }

    private class Scout extends Character {
        protected Scout(ReadonlyCharacter delegate) {
            super(delegate);
        }

        @Override
        protected ReadonlyAction choose() {
            ReadonlyAction clone = getAction(Clone.class);
            if (clone != null && (isVisible() || !isInEnemySightRange()) && setCloneLocation(clone, 3)) {
                return clone;
            }
            if (step != null && isVisible() && isInEnemySliceRange() && setAvoidEnemiesLocation(step)) {
                return step;
            }
            if (slice != null && isVisible() && setSliceTarget(slice, 0.01)) {
                return slice;
            }
            if (step != null && isVisible() && setAvoidEnemiesLocation(step)) {
                return step;
            }
            if (step != null && !isVisible() && setExploreLocation(step)) {
                return step;
            }
            return smile;
        }
    }

    private class Assasin extends Character {
        protected Assasin(ReadonlyCharacter delegate) {
            super(delegate);
        }

        @Override
        protected ReadonlyAction choose() {
            ReadonlyAction clone = getAction(Clone.class);
            ReadonlyAction poison = getAction(Poison.class);
            if (clone != null && setCloneLocation(clone, 1)) {
                return clone;
            }
            if (step != null && isInEnemySliceRange() && setAvoidEnemiesLocation(step)) {
                return step;
            }
            if (slice != null && setSliceTarget(slice, 0.01)) {
                return slice;
            }
            if (poison != null && setPoisonTarget(poison)) {
                return poison;
            }
            if (step != null && setAvoidEnemiesLocation(step)) {
                return step;
            }
            return smile;
        }
    }

    @Override
    protected Character createCharacter(ReadonlyCharacter delegate) {
        if (hasAbility(delegate, Invisible.class)) {
            return new Scout(delegate);
        } else if (hasAbility(delegate, Poison.class)) {
            return new Assasin(delegate);
        } else {
            throw new IllegalArgumentException();
        }
    }
}

আমার সমস্ত বট জন্য বেস ক্লাস

SleafarPlayer.java
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.collections.api.RichIterable;
import org.eclipse.collections.api.map.ImmutableMap;
import org.eclipse.collections.api.map.MutableMap;
import org.eclipse.collections.api.set.ImmutableSet;
import org.eclipse.collections.api.set.MutableSet;
import org.eclipse.collections.api.tuple.Pair;
import org.eclipse.collections.impl.factory.Maps;
import org.eclipse.collections.impl.factory.Sets;
import org.eclipse.collections.impl.list.primitive.IntInterval;
import org.eclipse.collections.impl.tuple.Tuples;

import com.nmerrill.kothcomm.game.maps.Point2D;

import fellowship.Player;
import fellowship.Range;
import fellowship.abilities.ReadonlyAbility;
import fellowship.abilities.attacking.Critical;
import fellowship.abilities.attacking.Reflexive;
import fellowship.abilities.defensive.Spikes;
import fellowship.abilities.statuses.Immune;
import fellowship.actions.ReadonlyAction;
import fellowship.actions.attacking.Quick;
import fellowship.actions.attacking.Slice;
import fellowship.actions.mobility.Step;
import fellowship.actions.other.Smile;
import fellowship.characters.CharacterInterface;
import fellowship.characters.EnemyCharacter;
import fellowship.characters.ReadonlyCharacter;

public abstract class SleafarPlayer extends Player {
    private static final ImmutableSet<Point2D> MAP_LOCATIONS = IntInterval.fromTo(0, 9)
            .collect(x -> IntInterval.fromTo(0, 9).collect(y -> new Point2D(x, y))).flatCollect(t -> t).toSet()
            .toImmutable();
    protected static final Comparator<CharacterInterface> HEALTH_COMPARATOR = (o1, o2) ->
            Double.compare(o1.getHealth(), o2.getHealth());
    private static final Range BLOCKING_RANGE = new Range(1, true);
    private static final Range STATIC_RANGE = new Range(1);

    protected static boolean hasAbility(CharacterInterface character, Class<?> ability) {
        return character.getAbilities().anySatisfy(a -> a.abilityClass().equals(ability));
    }

    protected static boolean isBear(CharacterInterface character) {
        return character.getAbilities().isEmpty();
    }

    protected static double calcSliceDamage(CharacterInterface character) {
        return character.getStat(character.primaryStat()) * (hasAbility(character, Quick.class) ? 2.0 : 1.0);
    }

    protected static boolean setLocation(ReadonlyAction action, Point2D location) {
        if (location != null) {
            action.setLocation(location);
        }
        return location != null;
    }

    protected static boolean setTarget(ReadonlyAction action, ReadonlyCharacter target) {
        if (target != null) {
            action.setTarget(target);
        }
        return target != null;
    }

    protected abstract class Character {
        protected final ReadonlyCharacter delegate;

        protected Character(ReadonlyCharacter delegate) {
            super();
            this.delegate = delegate;
        }

        protected abstract ReadonlyAction choose();

        protected double getHealth() {
            return delegate.getHealth();
        }

        protected double getHealthRegen() {
            return delegate.getHealthRegen();
        }

        protected double getMana() {
            return delegate.getMana();
        }

        protected double getManaRegen() {
            return delegate.getManaRegen();
        }

        protected Point2D getLocation() {
            return delegate.getLocation();
        }

        protected boolean isVisible() {
            return !delegate.isInvisible();
        }

        protected double getSliceDamage() {
            return delegate.getStat(delegate.primaryStat());
        }

        protected boolean isInEnemySliceRange() {
            return getEnemySliceLocations().contains(delegate.getLocation());
        }

        protected boolean isInEnemySightRange() {
            return getEnemySightLocations().contains(delegate.getLocation());
        }

        protected boolean isInEnemyStepSightRange() {
            return getEnemyStepSightLocations().contains(delegate.getLocation());
        }

        protected double calcSliceRetaliationDamage(CharacterInterface character) {
            double result = 0.0;
            double ownDamage = getSliceDamage();
            for (ReadonlyAbility ability : character.getAbilities()) {
                if (ability.abilityClass().equals(Critical.class)) {
                    ownDamage = ownDamage * 2;
                }
            }
            for (ReadonlyAbility ability : character.getAbilities()) {
                if (ability.abilityClass().equals(Spikes.class)) {
                    result += ownDamage / 2.0;
                } else if (ability.abilityClass().equals(Reflexive.class)) {
                    result += character.getStat(character.primaryStat());
                }
            }
            return result;
        }

        protected double calcSpellRetaliationDamage(CharacterInterface character, double ownDamage) {
            double result = 0.0;
            for (ReadonlyAbility ability : character.getAbilities()) {
                if (ability.abilityClass().equals(Spikes.class)) {
                    result += ownDamage / 2.0;
                }
            }
            return result;
        }

        protected boolean setRandomLocation(ReadonlyAction action) {
            return setLocation(action, chooseRandom(action.availableLocations()));
        }

        protected boolean setRandomLocation(ReadonlyAction action, ImmutableSet<Point2D> avoidLocations) {
            return setLocation(action, chooseRandom(action.availableLocations().difference(avoidLocations)));
        }

        protected boolean setClosestLocation(ReadonlyAction action, ImmutableSet<Point2D> targetLocations) {
            return setLocation(action, chooseClosest(action.availableLocations(), targetLocations));
        }

        protected boolean setClosestLocation(ReadonlyAction action, ImmutableSet<Point2D> avoidLocations,
                ImmutableSet<Point2D> targetLocations) {
            return setLocation(action, chooseClosest(action.availableLocations().difference(avoidLocations),
                    targetLocations));
        }

        protected boolean setClosestHiddenLocation(ReadonlyAction action, ImmutableSet<Point2D> preferredLocations) {
            return setClosestLocation(action, getEnemySightLocations(), preferredLocations);
        }

        protected boolean setClosestSafeLocation(ReadonlyAction action, ImmutableSet<Point2D> preferredLocations) {
            return setClosestLocation(action, getEnemySliceLocations(), preferredLocations);
        }

        protected boolean setFarthestLocation(ReadonlyAction action, ImmutableSet<Point2D> targetLocations) {
            return setLocation(action, chooseFarthest(action.availableLocations(), targetLocations));
        }

        protected boolean setFarthestLocation(ReadonlyAction action, ImmutableSet<Point2D> avoidLocations,
                ImmutableSet<Point2D> targetLocations) {
            return setLocation(action, chooseFarthest(action.availableLocations().difference(avoidLocations),
                    targetLocations));
        }

        public boolean setCloneLocation(ReadonlyAction action, int distance) {
            ImmutableSet<Point2D> cloneLocations = distance < 2 ? team.collect(t -> t.getLocation()).toImmutable() :
                team.flatCollect(t -> t.rangeAround(new Range(distance))).difference(
                team.flatCollect(t -> t.rangeAround(new Range(distance - 1)))).toImmutable();
            if (cloneLocations.isEmpty()) {
                return setRandomLocation(action, getEnemySightLocations()) ||
                        setRandomLocation(action, getEnemySliceLocations()) ||
                        setRandomLocation(action);
            } else {
                return setClosestLocation(action, getEnemySightLocations(), cloneLocations) ||
                        setClosestLocation(action, getEnemySliceLocations(), cloneLocations) ||
                        setClosestLocation(action, cloneLocations);
            }
        }

        protected boolean setAvoidEnemiesLocation(ReadonlyAction action) {
            Point2D location = chooseFarthest(Sets.mutable.ofAll(action.availableLocations())
                    .with(delegate.getLocation()).difference(getEnemySliceLocations()), getEnemyLocations());
            if (location == null || location.equals(delegate.getLocation())) {
                return false;
            } else {
                return setLocation(action, location);
            }
        }

        protected boolean setBlockEnemiesLocation(ReadonlyAction action) {
            return setLocation(action, chooseRandom(action.availableLocations().intersect(getEnemyBlockingLocations())));
        }

        protected boolean setExploreLocation(ReadonlyAction action) {
            return visibleEnemies.size() < enemies.size() && getTeamHiddenLocations().notEmpty() &&
                    setClosestLocation(action, getEnemyStepSightLocations(), getTeamHiddenLocations());
        }

        protected boolean setSliceTarget(ReadonlyAction action, double minHealthReserve) {
            MutableSet<Pair<ReadonlyCharacter, Double>> pairs = action.availableTargets()
                    .collect(t -> Tuples.pair(t, calcSliceRetaliationDamage(t)));
            Pair<ReadonlyCharacter, Double> smallest = chooseSmallest(pairs, (o1, o2) -> {
                int c = Double.compare(o1.getTwo(), o2.getTwo());
                return c == 0 ? Double.compare(o1.getOne().getHealth(), o2.getOne().getHealth()) : c;
            });
            if (smallest == null || smallest.getTwo() > delegate.getHealth() - minHealthReserve) {
                return false;
            } else {
                return setTarget(action, smallest.getOne());
            }
        }

        protected boolean setPoisonTarget(ReadonlyAction action) {
            return setTarget(action, chooseSmallest(action.availableTargets().reject(c -> hasAbility(c, Immune.class)),
                    HEALTH_COMPARATOR));
        }

        protected final ImmutableSet<Point2D> getEnemyLocations() {
            if (enemyLocations == null) {
                enemyLocations = visibleEnemies.keysView().toSet().toImmutable();
            }
            return enemyLocations;
        }

        protected final ImmutableSet<Point2D> getEnemySliceLocations() {
            if (enemySliceLocations == null) {
                enemySliceLocations = visibleEnemies.keyValuesView()
                        .flatCollect(c -> c.getTwo().rangeAround(c.getTwo().getSliceRange(), c.getOne())).toSet()
                        .toImmutable();
            }
            return enemySliceLocations;
        }

        protected final ImmutableSet<Point2D> getEnemySightLocations() {
            if (enemySightLocations == null) {
                enemySightLocations = visibleEnemies.keyValuesView()
                        .flatCollect(c -> c.getTwo().rangeAround(c.getTwo().getSightRange(), c.getOne())).toSet()
                        .toImmutable();
            }
            return enemySightLocations;
        }

        protected final ImmutableSet<Point2D> getEnemyStepSightLocations() {
            if (enemyStepSightLocations == null) {
                enemyStepSightLocations = visibleEnemies.keyValuesView()
                        .flatCollect(c -> Sets.mutable.ofAll(c.getTwo().rangeAround(c.getTwo().getStepRange(), c.getOne()))
                                .with(c.getOne()).flatCollect(r -> c.getTwo().rangeAround(c.getTwo().getSightRange(), r)))
                        .toSet().toImmutable();
            }
            return enemyStepSightLocations;
        }

        protected final ImmutableSet<Point2D> getEnemyHiddenLocations() {
            if (enemyHiddenLocations == null) {
                enemyHiddenLocations = MAP_LOCATIONS.difference(getEnemySightLocations());
            }
            return enemyHiddenLocations;
        }

        protected final ImmutableSet<Point2D> getEnemyBlockingLocations() {
            if (enemyBlockingLocations == null) {
                enemyBlockingLocations = visibleEnemies.keyValuesView()
                        .flatCollect(c -> c.getTwo().rangeAround(BLOCKING_RANGE, c.getOne())).toSet().toImmutable();
            }
            return enemyBlockingLocations;
        }

        protected final ImmutableSet<Point2D> getTeamHiddenLocations() {
            if (teamHiddenLocations == null) {
                teamHiddenLocations = MAP_LOCATIONS.difference(team.flatCollect(c -> c.rangeAround(c.getSightRange())));
            }
            return teamHiddenLocations;
        }

        protected final ImmutableSet<Point2D> getTeamBlockingLocations() {
            if (teamBlockingLocations == null) {
                teamBlockingLocations = team.flatCollect(c -> c.rangeAround(BLOCKING_RANGE)).toImmutable();
            }
            return teamBlockingLocations;
        }

        protected final ImmutableSet<Point2D> getSliceLocations() {
            if (sliceLocations == null) {
                sliceLocations = visibleEnemies.keyValuesView()
                        .flatCollect(c -> c.getTwo().rangeAround(delegate.getSliceRange(), c.getOne())).toSet().toImmutable();
            }
            return sliceLocations;
        }

        protected final ImmutableSet<Point2D> getStaticLocations() {
            if (staticLocations == null) {
                staticLocations = visibleEnemies.keyValuesView()
                        .flatCollect(c -> c.getTwo().rangeAround(STATIC_RANGE, c.getOne())).toSet().toImmutable();
            }
            return staticLocations;
        }

        protected final ImmutableMap<Point2D, Double> getEnemySliceDamage() {
            if (enemySliceDamage == null) {
                MutableMap<Point2D, Double> tmp = MAP_LOCATIONS.toMap(l -> l, l -> 0.0);
                for (Pair<Point2D, EnemyCharacter> p : visibleEnemies.keyValuesView()) {
                    double damage = calcSliceDamage(p.getTwo());
                    for (Point2D l : p.getTwo().rangeAround(p.getTwo().getSliceRange(), p.getOne())) {
                        tmp.put(l, tmp.get(l) + damage);
                    }
                }
                enemySliceDamage = tmp.toImmutable();
            }
            return enemySliceDamage;
        }
    }

    protected ImmutableMap<ReadonlyCharacter, Character> characters = Maps.immutable.empty();

    private ImmutableMap<Class<?>, ReadonlyAction> actions = null;
    protected ReadonlyAction step = null;
    protected ReadonlyAction slice = null;
    protected ReadonlyAction smile = null;

    private ImmutableSet<Point2D> enemyLocations = null;
    private ImmutableSet<Point2D> enemySliceLocations = null;
    private ImmutableSet<Point2D> enemySightLocations = null;
    private ImmutableSet<Point2D> enemyStepSightLocations = null;
    private ImmutableSet<Point2D> enemyHiddenLocations = null;
    private ImmutableSet<Point2D> enemyBlockingLocations = null;
    private ImmutableSet<Point2D> teamHiddenLocations = null;
    private ImmutableSet<Point2D> teamBlockingLocations = null;
    private ImmutableSet<Point2D> sliceLocations = null;
    private ImmutableSet<Point2D> staticLocations = null;
    private ImmutableMap<Point2D, Double> enemySliceDamage = null;

    protected final <T> T chooseRandom(Collection<T> collection) {
        if (!collection.isEmpty()) {
            int i = getRandom().nextInt(collection.size());
            for (T t : collection) {
                if (i == 0) {
                    return t;
                }
                --i;
            }
        }
        return null;
    }

    protected final <T> T chooseSmallest(Collection<T> collection, Comparator<? super T> comparator) {
        if (!collection.isEmpty()) {
            List<T> list = new ArrayList<>();
            for (T t : collection) {
                if (list.isEmpty()) {
                    list.add(t);
                } else {
                    int c = comparator.compare(t, list.get(0));
                    if (c < 0) {
                        list.clear();
                    }
                    if (c <= 0) {
                        list.add(t);
                    }
                }
            }
            return list.get(getRandom().nextInt(list.size()));
        }
        return null;
    }

    protected final Point2D chooseClosest(Collection<Point2D> available, RichIterable<Point2D> targets) {
        if (targets.isEmpty()) {
            return chooseRandom(available);
        } else {
            Map<Point2D, Integer> map = new HashMap<>();
            for (Point2D a : available) {
                map.put(a, targets.collect(t -> t.cartesianDistance(a)).min());
            }
            return chooseSmallest(available, (o1, o2) -> Integer.compare(map.get(o1), map.get(o2)));
        }
    }

    protected final Point2D chooseFarthest(Collection<Point2D> available, RichIterable<Point2D> targets) {
        if (targets.isEmpty()) {
            return chooseRandom(available);
        } else {
            Map<Point2D, Integer> map = new HashMap<>();
            for (Point2D a : available) {
                map.put(a, targets.collect(t -> t.cartesianDistance(a)).min());
            }
            return chooseSmallest(available, (o1, o2) -> Integer.compare(map.get(o2), map.get(o1)));
        }
    }

    protected int countCharacters(Class<?> clazz) {
        return characters.count(c -> c.getClass().equals(clazz));
    }

    protected ReadonlyAction getAction(Class<?> clazz) {
        return actions.get(clazz);
    }

    protected abstract Character createCharacter(ReadonlyCharacter delegate);

    @Override
    public final ReadonlyAction choose(Set<ReadonlyAction> actions, ReadonlyCharacter character) {
        characters = team.collect(c -> characters.getIfAbsentWith(c, this::createCharacter, c))
                .groupByUniqueKey(c -> c.delegate).toImmutable();

        this.actions = Sets.immutable.ofAll(actions).groupByUniqueKey(ReadonlyAction::actionClass);
        step = getAction(Step.class);
        slice = getAction(Slice.class);
        smile = getAction(Smile.class);

        enemyLocations = null;
        enemySliceLocations = null;
        enemySightLocations = null;
        enemyStepSightLocations = null;
        enemyHiddenLocations = null;
        enemyBlockingLocations = null;
        teamHiddenLocations = null;
        teamBlockingLocations = null;
        sliceLocations = null;
        staticLocations = null;
        enemySliceDamage = null;

        return characters.get(character).choose();
    }
}

সুন্দরভাবে সম্পন্ন. হারানোর জন্য একটি শক্ত দল ... চ্যালেঞ্জ গ্রহণ করা হয়েছে: পি
মোগি

6

রক্তচোষা

আমি এটিতে নতুন এবং আমি নিশ্চিত যে আমি কী করছি তা আমি নিশ্চিত নই, তবে আমি ভেবেছিলাম এটি আকর্ষণীয় বলে মনে হয়েছিল, তাই আমার চেষ্টা এখানে।

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

ব্যবহার শোষণ , ফিস্ট , পুনর্জাত , স্ট্রং সবকিছু সঙ্গে STR

Vampire.java

import com.nmerrill.kothcomm.game.maps.Point2D;
import fellowship.abilities.ActionAbility;
import fellowship.abilities.attacking.Absorb;
import fellowship.abilities.attacking.Feast;
import fellowship.abilities.stats.Strong;
import fellowship.abilities.stats.Regenerate;
import fellowship.actions.ReadonlyAction;
import fellowship.characters.CharacterTemplate;
import fellowship.characters.ReadonlyCharacter;
import fellowship.Player;
import org.eclipse.collections.api.set.MutableSet;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

public class Vampire extends Player{
    private final double CRITICAL_HEALTH = 5;
    @Override
    public List<CharacterTemplate> createCharacters() {
        List<CharacterTemplate> templates = new ArrayList<>();
        for (int i = 0; i < 3; i++) {
            templates.add(new CharacterTemplate(30, 0, 0,
                    new Absorb(),
                    new Feast(),
                    new Regenerate(),
                    new Strong()));
        }
        return templates;
    }

    @Override
    public ReadonlyAction choose(Set<ReadonlyAction> actions, ReadonlyCharacter character) {
        int minPriority = Integer.MAX_VALUE;
        ReadonlyAction chosen = null;
        for (ReadonlyAction action: actions){
            int priority = getPriorityFor(action, character);
            if (priority < minPriority){
                chosen = action;
                minPriority = priority;
            }
        }
        if (chosen == null){
            throw new RuntimeException("No valid actions");
        }
        if (chosen.needsLocation()){
            chosen.setLocation(chooseLocationFor(chosen, character));
        } else if (chosen.needsTarget()){
            chosen.setTarget(chooseTargetFor(chosen));
        }
        return chosen;
    }

    private Point2D chooseLocationFor(ReadonlyAction action, ReadonlyCharacter character){
        if (action.movementAction()){
            if (character.getHealth() <= CRITICAL_HEALTH){
                return fromEnemy(action.availableLocations());
            } else {
                return toEnemy(action.availableLocations());
            }
        }
        return toTeam(action.availableLocations());
    }

    private Point2D toEnemy(MutableSet<Point2D> availableLocations){
        if (visibleEnemies.isEmpty()){
            return availableLocations.iterator().next();
        }
        return availableLocations.minBy(p1 ->
                p1.cartesianDistance(visibleEnemies.keysView().minBy(p1::cartesianDistance))
        );
    }

    private Point2D fromEnemy(MutableSet<Point2D> availableLocations){
        if (visibleEnemies.isEmpty()){
            return availableLocations.iterator().next();
        }
        return availableLocations.maxBy(p1 ->
                p1.cartesianDistance(visibleEnemies.keysView().minBy(p1::cartesianDistance))
        );
    }

    private Point2D toTeam(MutableSet<Point2D> availableLocations){
        if (team.isEmpty()){
            return availableLocations.iterator().next();
        }
        return availableLocations.minBy(p1 ->
                p1.cartesianDistance(team.collect(ReadonlyCharacter::getLocation).minBy(p1::cartesianDistance))
        );
    }

    private ReadonlyCharacter chooseTargetFor(ReadonlyAction action){
        return action.availableTargets().minBy(ReadonlyCharacter::getHealth);
    }

    private int getPriorityFor(ReadonlyAction action, ReadonlyCharacter character){
        if (action.getName().equals("Smile")){
            return 1000;
        }
        if (action.movementAction()){
            if (character.getHealth() <= CRITICAL_HEALTH){
                return 0;
            }
            return 999;
        }
        if (action.needsTarget()) {
            return ((int) action.availableTargets().minBy(ReadonlyCharacter::getHealth).getHealth());
        }
        return 998;
    }
}

আমি সমস্ত প্যাসিভ ক্রিয়া ব্যবহার পছন্দ করি! সুন্দর.
মোগি

6

বিয়ার ক্যাভালারি

শোষণ , ক্লোন এবং ভাল্লুক ব্যবহার করে ; পরিসংখ্যানগুলি (+9, +0, +11)

প্রথম ঘুরে, প্রত্যেকে নিজের মতো করে একটি ক্লোন তৈরি করে, যাতে মাঠে দলের 6 টি অক্ষর থাকে। তারপরে তারা শত্রুকে চার্জ করে, স্প্যামিং ভাল্লুকরা যখনই পারে, এবং তাদের শত্রুদেরকে স্ট্যাট-শোষণকারী আক্রমণ দিয়ে দুর্বল করে।

কোডটি একটি জগাখিচুড়ি, তবে এটি কাজ করে বলে মনে হচ্ছে। আমি টেমপ্লেট প্লেয়ার থেকে এর অংশগুলি অনুলিপি করেছি।

আপনি এই দলের চরিত্রগুলি যে কোনও উপায়ে আপনার পছন্দ মতো ব্যবহার করতে পারেন।

BearCavalry.java

import com.nmerrill.kothcomm.game.maps.Point2D;
import fellowship.abilities.ActionAbility;
import fellowship.abilities.attacking.Absorb;
import fellowship.actions.ReadonlyAction;
import fellowship.actions.other.Clone;
import fellowship.actions.other.Bear;
import fellowship.characters.CharacterTemplate;
import fellowship.characters.ReadonlyCharacter;
import fellowship.Player;
import org.eclipse.collections.api.set.MutableSet;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

public class BearCavalry extends Player{
    @Override
    public List<CharacterTemplate> createCharacters() {
        List<CharacterTemplate> templates = new ArrayList<>();
        for (int i = 0; i < 3; i++) {
            templates.add(new CharacterTemplate(9, 0, 11,
                        new Absorb(),
                        new ActionAbility(Clone::new),
                        new ActionAbility(Bear::new)));
        }
        return templates;
    }

    @Override
    public ReadonlyAction choose(Set<ReadonlyAction> actions, ReadonlyCharacter character) {
    for(ReadonlyAction action: actions){
        if (action.getName().equals("Clone") && action.isAvailable()){
        action.setLocation(toTeam(action.availableLocations(), character));
        return action;
        }
    }
    for(ReadonlyAction action: actions){
        if (action.getName().equals("Bear") && action.isAvailable()){
        action.setLocation(toEnemy(action.availableLocations(), character));
        return action;
        }
    }
    for(ReadonlyAction action: actions){
        if (action.getName().equals("Slice") && action.isAvailable()){
        action.setTarget(action.availableTargets().minBy(ReadonlyCharacter::getHealth));
        return action;
        }
    }
    for(ReadonlyAction action: actions){
        if (action.getName().equals("Step") && action.isAvailable()){
        action.setLocation(toEnemy(action.availableLocations(), character));
        return action;
        }
    }
    for(ReadonlyAction action: actions){
        if (action.getName().equals("Smile")){
        return action;
        }
    }
    return null;
    }

    private Point2D toTeam(MutableSet<Point2D> availableLocations, ReadonlyCharacter character){
        if (team.isEmpty()){
            return availableLocations.minBy(p1 ->
                        p1.diagonalDistance(character.getLocation())
                        );
        }
        return availableLocations.minBy(p1 ->
                    p1.diagonalDistance(team.collect(ReadonlyCharacter::getLocation).minBy(p1::cartesianDistance))
                    );
    }

    private Point2D toEnemy(MutableSet<Point2D> availableLocations, ReadonlyCharacter character){
        if (visibleEnemies.isEmpty()){
            return toTeam(availableLocations, character);
        }
        return availableLocations.minBy(p1 ->
                    p1.diagonalDistance(visibleEnemies.keyValuesView().minBy(p -> p.getTwo().getHealth()).getOne())
                    );
    }
}

আপনার ভালুকগুলি আমার কাপুরুষ স্নাইপারের বিরুদ্ধে কার্যকর কৌশল :) জ্যাপ করা শুরু করার জন্য আমার বটের পক্ষে খুব বেশি লক্ষ্যবস্তু! ভাল হয়েছে
মোগি

5

খোঁটাযুক্ত

স্পিকি তার নামগুলি থেকে বোঝা যায়, অন্ধভাবে আক্রমণ করা উচিত নয়। সে টাঙ্কি, পুরো এইচপি পুরোপুরি জেনারেট করতে পারে এবং ট্রাকের মতো আঘাত করে। তিনি মানচিত্রের কেন্দ্রে ঘুরে বেড়াবেন, কেউ কাছে আসার অপেক্ষায়।

স্ট্রং (এসটিআর +10) এক্স 2 ব্যবহার করে , পুনঃজেনারেট , স্পাইকস এবং পুরো এসআরটি (+40, 0, 0) চলছে।

Spiky.java

import fellowship.*;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ThreadLocalRandom;

import com.nmerrill.kothcomm.game.maps.Point2D;

import fellowship.abilities.defensive.Spikes;
import fellowship.abilities.stats.Regenerate;
import fellowship.abilities.stats.Strong;
import fellowship.actions.ReadonlyAction;
import fellowship.characters.CharacterTemplate;
import fellowship.characters.ReadonlyCharacter;

public class Spiky extends Player {

    @Override
    public List<CharacterTemplate> createCharacters() {
        List<CharacterTemplate> templates = new ArrayList<>();
        for (int i = 0; i < 3; i++) {
            templates.add(new CharacterTemplate(40, 0, 0,
                    new Strong(),
                    new Strong(),
                    new Regenerate(),
                    new Spikes()));
        }
        return templates;
    }

    @Override
    public ReadonlyAction choose(Set<ReadonlyAction> actions, ReadonlyCharacter character) {

        ReadonlyAction chosen = null;
        Boolean canSlice = false;
        for (ReadonlyAction action: actions) {
            if (action.getName().equals("Slice")) {
                canSlice = true;
            }
        }

        for (ReadonlyAction action: actions) {
             if (action.getName().equals("Slice")) {
                 chosen = action;
                 chosen.setTarget(action.availableTargets().minBy(ReadonlyCharacter::getHealth));
             }
             if (!canSlice && action.getName().equals("Step")){
                 int x = ThreadLocalRandom.current().nextInt(3, 6 + 1);
                 int y = ThreadLocalRandom.current().nextInt(3, 6 + 1);
                 chosen = action;
                 Point2D destination = null;
                 if (visibleEnemies.isEmpty()){
                     destination = action.availableLocations().minBy(p1 -> p1.cartesianDistance(new Point2D(x, y)));
                 } else {
                     destination = action.availableLocations().minBy(p1 -> p1.cartesianDistance(visibleEnemies.keysView().minBy(p1::cartesianDistance)));
                 }
                 chosen.setLocation(destination);
             }
        }
        if (chosen == null){
            for (ReadonlyAction action: actions){
                if (action.getName().equals("Smile")){
                    chosen = action;
                }
            }
        }

        return chosen;
    }

}

> আপনার জমা দেওয়ার কোনও প্যাকেজ ঘোষণা হওয়া উচিত নয়। আপনার জমাটি প্রথম মাল্টি-লাইন কোড ব্লকে থাকা উচিত এবং প্রথম লাইনে অবশ্যই ফাইলের নাম থাকা উচিত।
ক্রিটসি লিথোস

আমি পোস্টে যা বলা হয়েছিল তা স্রেফ জানিয়েছি।
ক্রিটসি লিথোস

@ ক্রিটিক্সিলিথোস অনুমান করুন আমি কেবল এটিই করেছি। ধন্যবাদ।
থ্রাক্স

চমৎকার বট! স্পিকি আমার বটগুলির মধ্যে সেরাকে পরাজিত করেছিল।
ক্রিটসি লিথোস

আপনি কি পরিবর্তন ThreadLocalRandom.current()করতে পারেন getRandom()? এটি গেমসকে নির্বিচারক করার অনুমতি দেয়।
নাথান মেরিল

5

মায়াবী

ক্লোনের যোগান দেয় নিজেকে দিয়ে সম্ভব হিসাবে সব শত্রুদের অনেক তাত্ক্ষণিক ক্ষতি যেমন মোকাবেলা করতে বুনা (এটা বাজ পূর্বে ছিল, কিন্তু বুনা আরো ক্ষতি করে এবং একটি নিম্ন Mana খরচ হয়েছে।

Sorcerer.java

import com.nmerrill.kothcomm.game.maps.Point2D;
import fellowship.Player;
import fellowship.abilities.ActionAbility;
import fellowship.abilities.vision.TrueSight;
import fellowship.actions.ReadonlyAction;
import fellowship.actions.attacking.Slice;
import fellowship.actions.attacking.Weave;
import fellowship.actions.mobility.Step;
import fellowship.actions.other.Clone;
import fellowship.actions.other.Smile;
import fellowship.characters.CharacterTemplate;
import fellowship.characters.ReadonlyCharacter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.collections.api.set.MutableSet;

public class Sorcerer extends Player {

    @Override
    public List<CharacterTemplate> createCharacters() {
        List<CharacterTemplate> templates = new ArrayList<>();
        for (int i = 0; i < 3; i++) {
            templates.add(new CharacterTemplate(0, 0, 20,
                    new ActionAbility(Clone::new),
                    new TrueSight(),
                    new ActionAbility(Weave::new)));
        }
        return templates;
    }

    @Override
    public ReadonlyAction choose(Set<ReadonlyAction> actions, ReadonlyCharacter character) {
        ReadonlyAction chosen = getBestAction(actions, character);
        if (chosen == null){
            throw new RuntimeException("No valid actions");
        }
        if (chosen.needsLocation()){
            chosen.setLocation(toEnemy(chosen.availableLocations()));
        } else if (chosen.needsTarget()){
            chosen.setTarget(chooseTargetFor(chosen));
        }
        return chosen;
    }

    private Point2D toEnemy(MutableSet<Point2D> availableLocations){
        if (visibleEnemies.isEmpty()){
            return availableLocations.minBy(p1 ->
                    p1.cartesianDistance(team.minBy(x -> p1.cartesianDistance(x.getLocation())).getLocation())
            );
        }

        return availableLocations.maxBy(p1 ->
                p1.cartesianDistance(visibleEnemies.keysView().maxBy(p1::cartesianDistance))
        );
    }

    private ReadonlyCharacter chooseTargetFor(ReadonlyAction action){
        return action.availableTargets().minBy(ReadonlyCharacter::getHealth);
    }

    private ReadonlyAction getBestAction(Set<ReadonlyAction> actions, ReadonlyCharacter character) {
        Map<Class<?>, ReadonlyAction> actionMap = new HashMap<>();
        for (ReadonlyAction action : actions) {
            actionMap.put(action.actionClass(), action);
        }

        ReadonlyAction clone = actionMap.get(Clone.class);
        if (clone != null && clone.isAvailable() && !clone.availableLocations().isEmpty()) {
            return clone;
        }

        ReadonlyAction weave = actionMap.get(Weave.class);
        if (weave != null && weave.isAvailable() && (clone == null || clone.getRemainingCooldown() > 0)) {
            return weave;
        }

        ReadonlyAction slice = actionMap.get(Slice.class);
        if (slice != null && slice.isAvailable() && !slice.availableLocations().isEmpty() && !character.isInvisible()) {
            return slice;
        }

        ReadonlyAction step = actionMap.get(Step.class);
        if (step != null && step.isAvailable()) {
            return step;
        }

        return actionMap.get(Smile.class);        
    }
}

ক্লোনিং বটগুলির কাছে একটি জনপ্রিয় পছন্দ বলে মনে হচ্ছে ... আমার আপনার বটটি অনুপ্রেরণা হিসাবে ব্যবহার করা উচিত।
মোগি

4

LongSword

ব্যবহার সীমাকৃত (স্লাইস পরিসীমা যোগ 1), নমনীয় (can স্লাইস 8 দিকনির্দেশ কোনো), কুইক (: 3, Cooldown: স্লাইস দুইবার, Mana থেকে 0), স্ট্রং (আপনি আরও 10 গুণ পয়েন্ট লাভ)

স্ট্যাটাস

শুরু 5 পয়েন্ট বেস হয়

  • এসটিআর: 5 + 20 + 10
  • এজিআই: 5 + 0
  • INT: 5 + 0

প্রথমত, আমি সত্যিই এই বটটি তৈরি করে উপভোগ করেছি এবং আমি সত্যিই এই কোটএইচকে পছন্দ করি (এটি কোনও কোটএইচ চ্যালেঞ্জের কাছে আমার প্রথম জমা!)। (আমি আরও বট পোস্ট করতে পারি)

বট

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

একটি NetHack ভূমিকা সঙ্গে এই বট তুলনা করতে, আমি বলতে হবে এটি ঘনিষ্ঠভাবে বর্ণনার অনুরূপ ভ্যাল্কিরি "LongSword" এবং গড় স্বাস্থ্যের ধারণা কারণে।

NAME এর

এই বটটির স্বাভাবিক বটের চেয়ে কিছুটা দীর্ঘ পরিসীমা থাকে এবং এটি যে কোনও দিকে আক্রমণ করতে পারে। এটি নেটহ্যাকের বেশিরভাগ লম্বা তরোয়ালকে মনে করিয়ে দিয়েছে, তাই আমি আমার বটটির নাম রাখলাম।

আচরণ

চরিত্রটি যদি শত্রু চরিত্রটি দেখতে না পারে, তবে শত্রু চরিত্রগুলি খুঁজতে এটি ক্ষেত্রের বিপরীত দিকে (শত্রুর স্পোন অঞ্চল / শত্রুর "বেস") যাবে। যদি এটি শত্রুদের সন্ধান করে তবে তা দ্রুত, স্লাইস (অগ্রাধিকার হ্রাসে) দিয়ে তাদের আক্রমণ করবে। যদি এটি শত্রুদের লক্ষ্যবস্তু করতে না পারে, তবে বট শত্রু অক্ষরগুলির ধ্বংস করতে তাদের দিকে যাবে।

যদি চরিত্রটি কোনও শত্রু চরিত্র দেখতে না পারে এবং তার স্বাস্থ্য কম থাকে, তবে এটি "বেস" / স্পোন অঞ্চলের দিকে পিছিয়ে যাবে।

দ্রষ্টব্য: বট যুদ্ধের মাঝে কখনও পিছপা হবে না। এই বট কখনই হাসবে না।

আমি নিম্নলিখিত ব্যবহৃত Regex regexr.com একটি ফরম্যাট কোড ব্লক মধ্যে আমার জাভা কোড রূপান্তর করবে।

নীচের কোডটি মন্তব্য করা হয়েছে যাতে এটি বুঝতে সহজ হওয়া উচিত। এটি কীভাবে কাজ করে সে সম্পর্কে আপনার যদি কোনও প্রশ্ন বা স্পষ্টতা থাকে তবে ফেলোশিপস চ্যাটরুমের যুদ্ধে আমাকে বিনা দ্বিধায় পড়ুন !

সম্পাদনা: বটের আন্দোলনটি যেখানে শুরু হয়েছিল তার উপর নির্ভর করে (অগ্রবর্তী | পিছনের দিকে) মানিয়ে নেওয়ার জন্য আমি আমার প্রোগ্রামে একটি ছোট্ট ভুল স্থির করেছি। আমি এটি করতে ভুলে গেছি, তাই এখনই এটি সম্পাদনা করেছি।

LongSword.java

import fellowship.*;
import com.nmerrill.kothcomm.game.maps.Point2D;
import fellowship.abilities.ActionAbility;
import fellowship.abilities.attacking.Flexible;
import fellowship.abilities.attacking.Ranged;
import fellowship.abilities.stats.Strong;
import fellowship.actions.ReadonlyAction;
import fellowship.actions.attacking.Quick;
import fellowship.characters.CharacterTemplate;
import fellowship.characters.ReadonlyCharacter;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

public class LongSword/*Closest NetHack Role: Valkyrie*/ extends Player{

    //debugging
    private boolean debug = false;
    private void println(String text) {
        if(debug)
            System.out.println(text);
    }

    //variables use to hold the start Y coordinate of the bot
    private boolean started = false;
    private int startY = 5;

    @Override
    public List<CharacterTemplate> createCharacters() {
        List<CharacterTemplate> templates = new ArrayList<>();
        for (int i = 0; i < 3; i++) {
            templates.add(new CharacterTemplate(30, 0, 0,
                    new Ranged(), //Adds 1 to the range of Slice
                    new Flexible(), //Can Slice in any of the 8 directions
                    new ActionAbility(Quick::new), //Slice twice, Mana: 3, Cooldown: 0
                    new Strong())); //You gain 10 attribute points
        }
        return templates;
    }

    @Override
    public ReadonlyAction choose(Set<ReadonlyAction> actions, ReadonlyCharacter character) {
        if(!started) {
            startY = character.getLocation().getY(); //giving startY the value of the bot's starting y-value
            started = true; //do this only once, that's why there is the if statement
        }

        ReadonlyAction current = null;

        //choosing action depending on priority
        int priority = Integer.MAX_VALUE;
        for(ReadonlyAction action:actions) {
            int priorityLocal = getPriority(action, character);
            if(priorityLocal < priority) {
                current = action;
                priority = priorityLocal;
            }
        }

        if (current == null){
            throw new RuntimeException("No valid actions");
        }

        println(current.getName());

        if(current.needsLocation()) {
            if(visibleEnemies.isEmpty()) {
                if (character.getHealth() < 100) {
                    //if has low health, go backwards towards "base"
                    //println("lowHealth");
                    current.setLocation(move(current, character, "backward"));
                } else {
                    //else go forwards to enemy's "base"
                    current.setLocation(move(current, character, "forward"));
                }
            }else{
                //go towards closest enemy
                current.setLocation(current.availableLocations().minBy(p1->p1.cartesianDistance(visibleEnemies.keysView().minBy(p1::cartesianDistance))));
            }
        }
        if(current.needsTarget()) {
            //get closest target
            current.setTarget(current.availableTargets().minBy(p1 -> 0));
        }

        return current;
    }

    //move backwards or forwards
    private Point2D move(ReadonlyAction readonlyAction, ReadonlyCharacter character, String direction) {
        Point2D location = null;

        //move direction depending on Y coordinate of point
        for(Point2D point2D:readonlyAction.availableLocations()) {
            switch (direction) {
                case "forward":
                    if(startY > 5) { //bot started at bottom
                        if (point2D.getY() < character.getLocation().getY())
                            location = point2D;
                    }else{ //bot started at top
                        if (point2D.getY() > character.getLocation().getY())
                            location = point2D;
                    }
                    break;
                case "backward":
                    if(startY > 5) { //bot started at bottom
                        if (point2D.getY() > character.getLocation().getY())
                            location = point2D;
                    }else{ //bot started at top
                        if (point2D.getY() < character.getLocation().getY())
                            location = point2D;
                    }
                    break;
            }

        }

        //if no available locations, just choose the first available location
        if(location == null) {
            location = readonlyAction.availableLocations().iterator().next();
        }

        println(location.getY()+","+character.getLocation().getY());

        return location;
    }

    private int getPriority(ReadonlyAction action, ReadonlyCharacter character) {
        if(visibleEnemies.isEmpty()) {
            //if there are no visible enemies, Step. In the choose function, this becomes move forward or backward depending on health
            if(action.getName().equals("Step")) {
                return 100;
            }
        }else {
            /*
             * PRIORITIES:
             *  1. Quick (Slice twice)
             *  2. Slice
             *  3. Step (when enemy is not in range --> move towards enemy)
             */
            if (action.getName().equals("Quick")) {
                return 1;
            }else if(action.getName().equals("Slice")) {
                return 10;
            }else if(action.getName().equals("Step")) {
                return 50;
            }
        }
        //Kids, don't Smile, instead Step or Slice
        return 1000;
    }
}

2
আমার কাপুরুষদের লজ্জায় ফেলেছে। ভাল কাজ
মোগি

4

Derailer

আমার একগুচ্ছ লজিক ত্রুটি থাকার কারণে এটি দুটি বার মুছতে হয়েছিল। : P: P

এটি অবশ্যই আপনার পরিকল্পনাগুলি লেনদেন করতে পারে। ;)

দলটি:

  • পরাজিত করা খুব কঠিন হয়ে ওঠার সাথে সাথে শত্রুদের দ্রুত বের করতে দ্রুত সমালোচনামূলক , বাফ , স্ট্রং এবং দ্রুত সহ 1 টি চরিত্র । +25 স্ট্র্যাট, +2 এজিআই, +3 আইএনটি
  • চালাক , চালাক , পুনরুদ্ধার এবং জ্যাপ সহ 1 টি চরিত্র । সমর্থন হিসাবে পিছনে থাকে এবং এইচপির উপর কম চলমান যে কোনও সতীর্থের স্বাস্থ্য পুনরুদ্ধার করে এবং আক্রমণ করে নিজেকে প্রয়োজনীয় রক্ষা করতে পারে। +14 স্ট্র্যাট, +3 এজিআই, +3 আইএনটি
  • সঙ্গে 1 টি অক্ষর TrueSight , Spikes , অসরল , এবং বুনা । আঘাত করা এত সহজ নয়, এবং আপনি যদি করেন তবে বা আপনি খুব কাছের হয়ে গেলে এটি আপনাকে দেখবে এবং ধর্মঘট করবে। +13 স্ট্রাট, +3 এজিআই, +4 আইএনটি
Derailer.java

import com.nmerrill.kothcomm.game.maps.Point2D;
import fellowship.Player;
import fellowship.abilities.ActionAbility;
import fellowship.abilities.ReadonlyAbility;
import fellowship.abilities.attacking.Critical;
import fellowship.abilities.defensive.Evasive;
import fellowship.abilities.defensive.Spikes;
import fellowship.abilities.stats.Buff;
import fellowship.abilities.stats.Clever;
import fellowship.abilities.stats.Strong;
import fellowship.abilities.vision.TrueSight;
import fellowship.actions.ReadonlyAction;
import fellowship.actions.attacking.Quick;
import fellowship.actions.attacking.Weave;
import fellowship.actions.damage.Zap;
import fellowship.actions.defensive.Restore;
import fellowship.characters.CharacterTemplate;
import fellowship.characters.ReadonlyCharacter;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Set;
import java.util.function.BinaryOperator;
import java.util.stream.Collectors;

public class Derailer extends Player {
    private static final double CRITICAL_HEALTH_PCT = .175;

    @Override
    public List<CharacterTemplate> createCharacters() {
        List<CharacterTemplate> list = new ArrayList<>();

        list.add(new CharacterTemplate(14, 3, 3,
                                       new Clever(),
                                       new Clever(),
                                       new ActionAbility(Restore::new),
                                       new ActionAbility(Zap::new)));

        list.add(new CharacterTemplate(25, 2, 3,
                                       new Critical(),
                                       new Buff(),
                                       new ActionAbility(Quick::new),
                                       new Strong()));

        list.add(new CharacterTemplate(13, 3, 4,
                                       new TrueSight(),
                                       new Spikes(),
                                       new Evasive(),
                                       new ActionAbility(Weave::new)));
        return list;
    }

    @Override
    public ReadonlyAction choose(Set<ReadonlyAction> actions, ReadonlyCharacter character) {
        List<ReadonlyAbility> abilities = character.getAbilities();
        ReadonlyAction action = null;

        for (ReadonlyAbility a : abilities) {
            String s = a.name();
            int i = s.lastIndexOf(".");
            if (i == -1)
                continue;
            s = s.substring(i+1, s.length());
            if (s.equals("Clever")) {
                action = getActionForChar1(character, actions);
                break;
            }
            else if (s.equals("Buff")) {
                action = getActionForChar2(character, actions);
                break;
            }
            else if (s.equals("Evasive")) {
                action = getActionForChar3(character, actions);
                break;
            }
        }

        return action;
    }

    private ReadonlyAction getActionForChar1(ReadonlyCharacter character, Set<ReadonlyAction> actions) {
        int members = (int) team.stream().filter(c -> !c.isDead()).count();

        List<ReadonlyAction> list = actions.stream()
                                           .sorted(Comparator.comparingInt(this::getPriority))
                                           .collect(Collectors.toList());

        for (ReadonlyAction a : list) {
            String name = a.getName();
            if (name.equals("Restore")) {
                for (ReadonlyCharacter teammate : team) {
                    if (teammate.getHealth() / teammate.getMaxHealth() < CRITICAL_HEALTH_PCT * (4 - members))
                        return a;
                }
            }
            else if (name.equals("Zap") && !a.availableTargets().isEmpty()) {
                a.setTarget(a.availableTargets()
                             .stream()
                             .reduce(
                                 BinaryOperator.minBy(
                                     Comparator.<ReadonlyCharacter>comparingDouble(e -> e.getHealth())
                                 )
                             )
                             .get()
                );
                return a;
            }
            else if (name.equals("Slice") && !a.availableTargets().isEmpty()) {
                a.setTarget(a.availableTargets().iterator().next());
                return a;
            }
            else if (name.equals("Smile"))
                return a;
        }
        throw new RuntimeException("No available actions");
    }

    private ReadonlyAction getActionForChar2(ReadonlyCharacter character, Set<ReadonlyAction> actions) {
        List<ReadonlyAction> list = actions.stream()
                                           .sorted(Comparator.comparingInt(this::getPriority))
                                           .collect(Collectors.toList());

        for (ReadonlyAction a : list) {
            String name = a.getName();
            if (name.equals("Quick") && !a.availableTargets().isEmpty()) {
                a.setTarget(a.availableTargets().minBy(ReadonlyCharacter::getHealth));
                return a;
            }
            else if (name.equals("Slice") && !a.availableTargets().isEmpty()) {
                a.setTarget(a.availableTargets().minBy(ReadonlyCharacter::getHealth));
                return a;
            }
            else if (name.equals("Step") && !a.availableLocations().isEmpty()) {
                Point2D e = getClosestEnemyPoint(character);
                if (e == null) {
                    Point2D p = character.getLocation();
                    if (p.getY() > 5) {
                        a.setLocation(a.availableLocations()
                                       .stream()
                                       .filter(x -> x.getY() < p.getY())
                                       .findFirst()
                                       .orElse(a.availableLocations().iterator().next()));
                    }
                    else if (p.getY() < 4) {
                        a.setLocation(a.availableLocations()
                                       .stream()
                                       .filter(x -> x.getY() > p.getY())
                                       .findFirst()
                                       .orElse(a.availableLocations().iterator().next()));
                    }
                    else
                        a.setLocation(randomLocation(new ArrayList<>(a.availableLocations())));
                }
                else {
                    int currentDistance = character.getLocation().cartesianDistance(e);
                    a.setLocation(a.availableLocations()
                                   .stream()
                                   .filter(x -> x.cartesianDistance(e) < currentDistance)
                                   .findFirst()
                                   .orElse(randomLocation(new ArrayList<>(a.availableLocations()))));
                }
                return a;
            }
            else if (name.equals("Smile"))
                return a;
        }
        throw new RuntimeException("No available actions");
    }

    private ReadonlyAction getActionForChar3(ReadonlyCharacter character, Set<ReadonlyAction> actions) {
        List<ReadonlyAction> list = actions.stream()
                                           .sorted(Comparator.comparingInt(this::getPriority))
                                           .collect(Collectors.toList());

        for (ReadonlyAction a : list) {
            String name = a.getName();
            if (name.equals("Weave") && visibleEnemies.keySet().size() > 1)
                return a;
            else if (name.equals("Slice") && !a.availableTargets().isEmpty()) {
                a.setTarget(a.availableTargets().iterator().next());
                return a;
            }
            else if (name.equals("Smile"))
                return a;
            else if (name.equals("Step")) {
                Point2D p = character.getLocation();
                if (!visibleEnemies.keySet().isEmpty()) {
                    Point2D e = getClosestEnemyPoint(character);
                    int currentDistance = character.getLocation().cartesianDistance(e);
                    a.setLocation(a.availableLocations()
                                   .stream()
                                   .filter(x -> x.cartesianDistance(e) < currentDistance)
                                   .findAny()
                                   .orElse(randomLocation(new ArrayList<>(a.availableLocations()))));
                }
                else if (p.getY() > 5) {
                    a.setLocation(a.availableLocations()
                                   .stream()
                                   .filter(x -> x.getY() < p.getY())
                                   .findFirst()
                                   .orElse(randomLocation(new ArrayList<>(a.availableLocations()))));
                }
                else if (p.getY() < 4) {
                    a.setLocation(a.availableLocations()
                                   .stream()
                                   .filter(x -> x.getY() > p.getY())
                                   .findFirst()
                                   .orElse(randomLocation(new ArrayList<>(a.availableLocations()))));
                }
                else
                    a.setLocation(randomLocation(new ArrayList<>(a.availableLocations())));
                return a;
            }
        }
        throw new RuntimeException("No available actions");
    }

    private Point2D getClosestEnemyPoint(ReadonlyCharacter c) {
        return visibleEnemies.keySet()
                             .stream()
                             .reduce(
                                 BinaryOperator.minBy(
                                     Comparator.comparingInt(x -> x.cartesianDistance(c.getLocation()))
                                 )
                             )
                             .orElse(null);
    }

    private int getPriority(ReadonlyAction action) {
        switch (action.getName()) {
            case "Quick":
            case "Restore":
            case "Weave":
                return 1;
            case "Zap": return 2;
            case "Slice": return 3;
            case "Step": return 4;
            case "Smile": return 5;
        }
        throw new IllegalArgumentException(String.valueOf(action));
    }

    private Point2D randomLocation(List<Point2D> l) {
        return l.get((int) (Math.random() * l.size()));
    }
}

আকর্ষণীয় দলের গতিশীলতা! আমাকে আরও কিছু উন্নত টিম অ্যাকশনের জন্য চেষ্টা করতে বাধ্য করে :)
মোগি

ধন্যবাদ। আমি দলের মধ্যে সমন্বয় অন্তর্ভুক্ত করার চেষ্টা করেছি, তবে তৃতীয় চরিত্রটি জায়গা থেকে একটু দূরে বলে মনে হচ্ছে। ভবিষ্যতের বোটে সম্ভবত আমি এই কৌশলটি উন্নত করব।
টিএনটি

মজার বিষয় হল, প্রথমটির একটি অনুলিপি সহ তৃতীয় চরিত্রটি প্রতিস্থাপনের ফলে আরও ভাল ফলাফল হয়েছে।
টিএনটি

4

SniperSquad

একটি স্নিপার স্কোয়াড নিয়ে গঠিত:

  • 1 স্পোটার (প্রায় পুরো মানচিত্রের ওভারভিউকে মঞ্জুরি দেয়, সেরা স্পটিং গিয়ার উপলভ্য)
    • এসআরটি: 25; এজিআই: 5; INT: 5
    • দূরে দৃষ্টিশক্তি , দূরে দৃষ্টিশক্তি , দূরে দৃষ্টিশক্তি , দূরে দৃষ্টিশক্তি
  • শ্যুটার (নতুন মাল্টি টার্গেট স্নিপার রাইফেলস দিয়ে সজ্জিত, একমাত্র ব্যর্থতা হ'ল ফায়ার রেট)
    • এসআরটি: 25; এজিআই: 5; INT: 5
    • বুনা , সমালোচক , সমালোচক , সমালোচক

আপনি নিজের দলে এখান থেকে একক অক্ষর পুনরায় ব্যবহার করতে পারেন, যতক্ষণ না আপনি অন্তত আরও একটি চরিত্র যোগ করেন যা এখানে উপস্থিত নেই।

SniperSquad.java
import java.util.Arrays;
import java.util.List;

import fellowship.abilities.ActionAbility;
import fellowship.abilities.attacking.Critical;
import fellowship.abilities.vision.FarSight;
import fellowship.actions.ReadonlyAction;
import fellowship.actions.attacking.Weave;
import fellowship.characters.CharacterTemplate;
import fellowship.characters.ReadonlyCharacter;

public class SniperSquad extends SleafarPlayer {
    private static CharacterTemplate spotterTemplate() {
        return new CharacterTemplate(20, 0, 0,
                new FarSight(), new FarSight(), new FarSight(), new FarSight());
    }

    private static CharacterTemplate shooterTemplate() {
        return new CharacterTemplate(20, 0, 0,
                new ActionAbility(Weave::new), new Critical(), new Critical(), new Critical());
    }

    @Override
    public List<CharacterTemplate> createCharacters() {
        return Arrays.asList(shooterTemplate(), spotterTemplate(), shooterTemplate());
    }

    private class Spotter extends Character {
        protected Spotter(ReadonlyCharacter delegate) {
            super(delegate);
        }

        @Override
        protected ReadonlyAction choose() {
            if (slice != null && setSliceTarget(slice, 100.0)) {
                return slice;
            }
            if (step != null && isInEnemyStepSightRange() && setAvoidEnemiesLocation(step)) {
                return step;
            }
            if (slice != null && setSliceTarget(slice, 0.01)) {
                return slice;
            }
            if (step != null && setExploreLocation(step)) {
                return step;
            }
            return smile;
        }
    }

    private class Shooter extends Character {
        protected Shooter(ReadonlyCharacter delegate) {
            super(delegate);
        }

        @Override
        protected ReadonlyAction choose() {
            ReadonlyAction weave = getAction(Weave.class);
            if (weave != null && !visibleEnemies.isEmpty() &&
                    visibleEnemies.collectDouble(e -> calcSliceRetaliationDamage(e)).sum() < getHealth()) {
                return weave;
            }
            if (slice != null && setSliceTarget(slice, 100.0)) {
                return slice;
            }
            if (step != null && setAvoidEnemiesLocation(step)) {
                return step;
            }
            if (slice != null && setSliceTarget(slice, 0.01)) {
                return slice;
            }
            return smile;
        }
    }

    @Override
    protected Character createCharacter(ReadonlyCharacter delegate) {
        if (hasAbility(delegate, FarSight.class)) {
            return new Spotter(delegate);
        } else if (hasAbility(delegate, Weave.class)) {
            return new Shooter(delegate);
        } else {
            throw new IllegalArgumentException();
        }
    }
}


3

ওয়্যারউলভস

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

ব্যবহার সীমাকৃত , সোয়াইপ , স্ট্রং , এবং নেকড়ে বাঘে পরিণত মানুষ এবং অন্যথায় হিসাবে একই এআই যুক্তিবিজ্ঞান ব্যবহার LongSword , যদিও সামান্য বদলে দিয়েছিলেন।

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

PlayerWerewolf.java

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import com.nmerrill.kothcomm.game.maps.Point2D;

import fellowship.Player;
import fellowship.abilities.ActionAbility;
import fellowship.abilities.attacking.Ranged;
import fellowship.abilities.attacking.Swipe;
import fellowship.abilities.stats.Strong;
import fellowship.actions.ReadonlyAction;
import fellowship.actions.stats.Werewolf;
import fellowship.characters.CharacterTemplate;
import fellowship.characters.ReadonlyCharacter;
import fellowship.characters.EnemyCharacter;

public class PlayerWerewolf extends Player {
    //variables use to hold the start Y coordinate of the bot
    private boolean started = false;
    private int startY = 5;

    @Override
    public List<CharacterTemplate> createCharacters() {
        List<CharacterTemplate> templates = new ArrayList<>();
        for (int i = 0; i < 3; i++) {
            templates.add(new CharacterTemplate(30, 0, 0,
                    new Ranged(), //Adds 1 to the range of Slice
                    new Swipe(), //Deal increasing damage
                    new ActionAbility(Werewolf::new), //Turn into a werewolf for 5 turns
                    new Strong())); //You gain 10 attribute points
        }
        return templates;
    }

    @Override
    public ReadonlyAction choose(Set<ReadonlyAction> actions, ReadonlyCharacter character) {
        if(!started) {
            startY = character.getLocation().getY(); //giving startY the value of the bot's starting y-value
            started = true; //do this only once, that's why there is the if statement
        }

        ReadonlyAction current = null;

        //choosing action depending on priority
        int priority = Integer.MAX_VALUE;
        for(ReadonlyAction action:actions) {
            int priorityLocal = getPriority(action, character);
            if(priorityLocal < priority) {
                current = action;
                priority = priorityLocal;
            }
        }

        if (current == null){
            throw new RuntimeException("No valid actions");
        }

        if(current.needsLocation()) {
            if(visibleEnemies.isEmpty()) {
                if (character.getHealth() < 50) {
                    //if has low health, go backwards towards "base"
                    //println("lowHealth");
                    current.setLocation(move(current, character, "backward"));
                } else {
                    //else go forwards to enemy's "base"
                    current.setLocation(move(current, character, "forward"));
                }
            }else{
                //go towards closest enemy
                current.setLocation(current.availableLocations().minBy(p1->p1.cartesianDistance(visibleEnemies.keysView().minBy(p1::cartesianDistance))));
            }
        }
        if(current.needsTarget()) {
            //get closest target
            current.setTarget(current.availableTargets().minBy(p1 -> 0));
        }

        return current;
    }

    //move backwards or forwards
    private Point2D move(ReadonlyAction readonlyAction, ReadonlyCharacter character, String direction) {
        Point2D location = null;

        //move direction depending on Y coordinate of point
        for(Point2D point2D:readonlyAction.availableLocations()) {
            switch (direction) {
            case "forward":
                if(startY > 5) { //bot started at bottom
                    if (point2D.getY() < character.getLocation().getY())
                        location = point2D;
                }else{ //bot started at top
                    if (point2D.getY() > character.getLocation().getY())
                        location = point2D;
                }
                break;
            case "backward":
                if(startY > 5) { //bot started at bottom
                    if (point2D.getY() > character.getLocation().getY())
                        location = point2D;
                }else{ //bot started at top
                    if (point2D.getY() < character.getLocation().getY())
                        location = point2D;
                }
                break;
            }

        }

        //if no available locations, just choose the first available location
        if(location == null) {
            location = readonlyAction.availableLocations().iterator().next();
        }

        return location;
    }

    private int getPriority(ReadonlyAction action, ReadonlyCharacter character) {
        if(visibleEnemies.isEmpty()) {
            //if there are no visible enemies, Step. In the choose function, this becomes move forward or backward depending on health
            if(action.getName().equals("Step")) {
                return 100;
            }
        }else {
            /*
             * PRIORITIES:
             *  1. If near an enemy, and not a werewolf, turn into a werewolf
             *  2. Slice
             *  3. Step (when enemy is not in range --> move towards enemy)
             */
            if (action.getName().equals("Werewolf") && action.isAvailable()) {
                EnemyWrapper wrap = getNearestEnemy(character);
                //don't turn into a werewolf unless we're close to an enemy
                if(wrap.location.diagonalDistance(character.getLocation()) < 3) {
                    return 1;
                }
            }else if(action.getName().equals("Slice")) {
                return 10;
            }else if(action.getName().equals("Step")) {
                return 50;
            }
        }
        //Kids, don't Smile, instead Step or Slice
        return 1000;
    }

    private EnemyWrapper getNearestEnemy(ReadonlyCharacter character) {
        double closestEnemyDistance = Double.MAX_VALUE;
        Point2D closestEnemy = null;
        for ( Point2D enemyLocation : visibleEnemies.keySet()) {
            double visionDistanceDiff = character.getLocation().diagonalDistance(enemyLocation);
            if (visionDistanceDiff< closestEnemyDistance)
            {
                closestEnemyDistance = visionDistanceDiff;
                closestEnemy = enemyLocation;
            }
        }
        return new EnemyWrapper(visibleEnemies.get(closestEnemy), closestEnemy);
    }
    private static class EnemyWrapper {
        public final EnemyCharacter enemy;
        public final Point2D location;

        EnemyWrapper(EnemyCharacter e, Point2D l) {
            enemy = e;
            location = l;
        }
    }
}

বেশ কয়েকটি সমস্যা ছিল (একটি প্যাকেজ ঘোষণা, পাশাপাশি ফাইলের নামটি প্রথম লাইনে না লাগানো) এবং আমি সেগুলি স্থির করেছিলাম। এটি বলেছিল, আমি আমার সংকলকটি পাস করার জন্য স্থির শ্রেণি পেতে পারি না ... এটি খতিয়ে দেখছি।
নাথান মেরিল

আমি এটি বের করেছিলাম: আপনি একটি আমদানি মিস করছেন:import fellowship.characters.EnemyCharacter;
নাথান মেরিল

@ নাথানম্যারিল আমি মাধ্যমিক শ্রেণিটিকে একিপ্সের বাইরে একটি অভ্যন্তরীণ শ্রেণিতে সংযুক্ত করার চেষ্টা করেছি, সম্ভবত এটিই ছিল।
Draco18s

নিস! আপনি লংসওয়ার্ড থেকে আমার নিজস্ব আন্দোলনের কাজগুলি ব্যবহার করেছেন!
ক্রিটসি লিথোস

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

2

Railbender

এই বটটি কেবল ডেরিলারের একটি সংস্করণ যা এর তৃতীয় অক্ষরটি প্রথমটির অনুলিপি দ্বারা প্রতিস্থাপিত হয়েছিল। এটি ডেরিলারের সাথে তুলনা করে আরও অনেক ভাল ফলাফল দেয়।

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

Railbender.java

import com.nmerrill.kothcomm.game.maps.Point2D;
import fellowship.Player;
import fellowship.abilities.ActionAbility;
import fellowship.abilities.ReadonlyAbility;
import fellowship.abilities.attacking.Critical;
import fellowship.abilities.stats.Buff;
import fellowship.abilities.stats.Clever;
import fellowship.abilities.stats.Strong;
import fellowship.actions.ReadonlyAction;
import fellowship.actions.attacking.Quick;
import fellowship.actions.damage.Zap;
import fellowship.actions.defensive.Restore;
import fellowship.characters.CharacterTemplate;
import fellowship.characters.ReadonlyCharacter;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Set;
import java.util.function.BinaryOperator;
import java.util.stream.Collectors;

public class Railbender extends Player {
    private static final double CRITICAL_HEALTH_PCT = .175;

    @Override
    public List<CharacterTemplate> createCharacters() {
        List<CharacterTemplate> list = new ArrayList<>();

        list.add(new CharacterTemplate(14, 3, 3,
                                       new Clever(),
                                       new Clever(),
                                       new ActionAbility(Restore::new),
                                       new ActionAbility(Zap::new)));

        for (int k = 0; k < 2; k++) {
            list.add(new CharacterTemplate(25, 2, 3,
                                           new Critical(),
                                           new Buff(),
                                           new ActionAbility(Quick::new),
                                           new Strong()));
        }
        return list;
    }

    @Override
    public ReadonlyAction choose(Set<ReadonlyAction> actions, ReadonlyCharacter character) {
        List<ReadonlyAbility> abilities = character.getAbilities();
        ReadonlyAction action = null;

        for (ReadonlyAbility a : abilities) {
            String s = a.name();
            int i = s.lastIndexOf(".");
            if (i == -1)
                continue;
            s = s.substring(i+1, s.length());
            if (s.equals("Clever")) {
                action = getActionForChar1(character, actions);
                break;
            }
            else if (s.equals("Buff")) {
                action = getActionForChar2(character, actions);
                break;
            }
        }

        return action;
    }

    private ReadonlyAction getActionForChar1(ReadonlyCharacter character, Set<ReadonlyAction> actions) {
        int members = (int) team.stream().filter(c -> !c.isDead()).count();

        List<ReadonlyAction> list = actions.stream()
                                           .sorted(Comparator.comparingInt(this::getPriority))
                                           .collect(Collectors.toList());

        Point2D closestEnemy = getClosestEnemyPoint(character);

        for (ReadonlyAction a : list) {
            String name = a.getName();
            if (name.equals("Restore")) {
                for (ReadonlyCharacter teammate : team) {
                    if (teammate.getHealth() / teammate.getMaxHealth() < CRITICAL_HEALTH_PCT * (4 - members))
                        return a;
                }
            }
            else if (name.equals("Zap") && !a.availableTargets().isEmpty() && closestEnemy != null &&
                     character.getLocation().cartesianDistance(closestEnemy) <= 4) {
                a.setTarget(a.availableTargets()
                             .stream()
                             .reduce(
                                 BinaryOperator.minBy(
                                     Comparator.<ReadonlyCharacter>comparingDouble(e -> e.getHealth())
                                 )
                             )
                             .get()
                );
                return a;
            }
            else if (name.equals("Slice") && !a.availableTargets().isEmpty()) {
                a.setTarget(a.availableTargets().iterator().next());
                return a;
            }
            else if (name.equals("Smile"))
                return a;
        }
        throw new RuntimeException("No available actions");
    }

    private ReadonlyAction getActionForChar2(ReadonlyCharacter character, Set<ReadonlyAction> actions) {
        List<ReadonlyAction> list = actions.stream()
                                           .sorted(Comparator.comparingInt(this::getPriority))
                                           .collect(Collectors.toList());

        for (ReadonlyAction a : list) {
            String name = a.getName();
            if (name.equals("Quick") && !a.availableTargets().isEmpty()) {
                a.setTarget(a.availableTargets().minBy(ReadonlyCharacter::getHealth));
                return a;
            }
            else if (name.equals("Slice") && !a.availableTargets().isEmpty()) {
                a.setTarget(a.availableTargets().minBy(ReadonlyCharacter::getHealth));
                return a;
            }
            else if (name.equals("Step") && !a.availableLocations().isEmpty()) {
                Point2D e = getClosestEnemyPoint(character);
                if (e == null) {
                    Point2D p = character.getLocation();
                    if (p.getY() > 5) {
                        a.setLocation(a.availableLocations()
                                       .stream()
                                       .filter(x -> x.getY() < p.getY())
                                       .findFirst()
                                       .orElse(a.availableLocations().iterator().next()));
                    }
                    else if (p.getY() < 4) {
                        a.setLocation(a.availableLocations()
                                       .stream()
                                       .filter(x -> x.getY() > p.getY())
                                       .findFirst()
                                       .orElse(a.availableLocations().iterator().next()));
                    }
                    else
                        a.setLocation(randomLocation(new ArrayList<>(a.availableLocations())));
                }
                else {
                    int currentDistance = character.getLocation().cartesianDistance(e);
                    a.setLocation(a.availableLocations()
                                   .stream()
                                   .filter(x -> x.cartesianDistance(e) < currentDistance)
                                   .findFirst()
                                   .orElse(randomLocation(new ArrayList<>(a.availableLocations()))));
                }
                return a;
            }
            else if (name.equals("Smile"))
                return a;
        }
        throw new RuntimeException("No available actions");
    }

    private Point2D getClosestEnemyPoint(ReadonlyCharacter c) {
        return visibleEnemies.keySet()
                             .stream()
                             .reduce(
                                 BinaryOperator.minBy(
                                     Comparator.comparingInt(x -> x.cartesianDistance(c.getLocation()))
                                 )
                             )
                             .orElse(null);
    }

    private int getPriority(ReadonlyAction action) {
        switch (action.getName()) {
            case "Quick":
            case "Restore":
                return 1;
            case "Zap": return 2;
            case "Slice": return 3;
            case "Step": return 4;
            case "Smile": return 5;
        }
        throw new IllegalArgumentException(String.valueOf(action));
    }

    private Point2D randomLocation(List<Point2D> l) {
        return l.get((int) (Math.random() * l.size()));
    }
}

অ্যামেজিং! এটি ডেরিলারের চেয়ে আরও বেশি শক্ত
ক্রিতিক্সী লিথোস

2

Noob/*Destroyer*/

ব্যবহার স্ট্রং * 2, পুনর্জাত এবং অচেতন (পরবর্তী 300 এঁটেল পোকা জন্য Stuns লক্ষ্য)

স্ট্যাটাস

  • এসটিআর : 5 + 40
  • এজিআই : 5 + 0
  • INT : 5 + 0

এআই

নুব-এর বেশিরভাগ কোড আমার লংসওয়ার্ড থেকে নেওয়া হয়েছে।

কৌশল

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

Noob.java
import fellowship.*;
import com.nmerrill.kothcomm.game.maps.Point2D;
import fellowship.Stat;
import fellowship.abilities.ActionAbility;
import fellowship.abilities.stats.Regenerate;
import fellowship.abilities.stats.Strong;
import fellowship.actions.ReadonlyAction;
import fellowship.actions.defensive.Shield;
import fellowship.actions.statuses.Silence;
import fellowship.actions.statuses.Stun;
import fellowship.characters.CharacterTemplate;
import fellowship.characters.ReadonlyCharacter;
import fellowship.Player;
import org.eclipse.collections.api.set.MutableSet;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

public class Noob/*Destroyer*/ extends Player {

    private boolean debug = false;
    private void println(String text) {
        if(debug)
            System.out.println(text);
    }

    private boolean started = false;
    private int startY = 5;

    @Override
    public List<CharacterTemplate> createCharacters() {
        List<CharacterTemplate> templates = new ArrayList<>();
        for (int i = 0; i < 3; i++) {
            templates.add(new CharacterTemplate(40, 0, 0,
                    new Regenerate(),
                    new ActionAbility(Stun::new),
                    new Strong(),
                    new Strong()));
        }
        return templates;
    }

    @Override
    public ReadonlyAction choose(Set<ReadonlyAction> actions, ReadonlyCharacter character) {
        if(!started) {
            startY = character.getLocation().getY();
            started = true;
        }

        ReadonlyAction readonlyAction = null;

        //get priority of action
        int priority = Integer.MAX_VALUE;

        for(ReadonlyAction action:actions) {
            int priorityLocal = getPriority(action, character);
            if(priorityLocal < priority) {
                readonlyAction = action;
                priority = priorityLocal;
            }
        }

        if (readonlyAction == null){
            println("NULL!");
            throw new RuntimeException("No valid actions");
        }

        //movement
        if(readonlyAction.needsLocation()) {
            if(visibleEnemies.isEmpty()) {
                if (character.getHealth() < 100) {
                    readonlyAction.setLocation(move(readonlyAction, character, "backward"));
                } else {
                    readonlyAction.setLocation(move(readonlyAction, character, "forward")); //enemy base is "forward"
                }
            }else{
                readonlyAction.setLocation(readonlyAction.availableLocations().minBy(p1->p1.cartesianDistance(visibleEnemies.keysView().minBy(p1::cartesianDistance))));
            }
        }

        if(readonlyAction.needsTarget()) {
            readonlyAction.setTarget(readonlyAction.availableTargets().minBy(p1 -> 0));
        }

        return readonlyAction;
    }

    private Point2D move(ReadonlyAction readonlyAction, ReadonlyCharacter character, String direction) {
        Point2D location = null;

        for(Point2D point2D:readonlyAction.availableLocations()) {
            switch (direction) {
                case "forward":
                    if(startY > 5) { //bot starts at bottom
                        if (point2D.getY() < character.getLocation().getY())
                            location = point2D;
                    }else{ //bot starts at top
                        if (point2D.getY() > character.getLocation().getY())
                            location = point2D;
                    }
                    break;
                case "backward":
                    if(startY > 5) { //bot starts at bottom
                        if (point2D.getY() > character.getLocation().getY())
                            location = point2D;
                    }else{ //bot starts at top
                        if (point2D.getY() < character.getLocation().getY())
                            location = point2D;
                    }
                    break;
            }

        }

        if(location == null) {
            location = readonlyAction.availableLocations().iterator().next();
        }
        return location;
    }

    private int getPriority(ReadonlyAction action, ReadonlyCharacter character) {
        if(visibleEnemies.isEmpty()) {
            if(action.getName().equals("Step")) {
                return 100;
            }
        }else {
            if (action.getName().equals("Slice")) {
                return 10;
            }else if(action.getName().equals("Step")) {
                return 50;
            }else if(action.getName().equals("Stun") && !action.availableTargets().minBy(p1->0).isStunned()) {
                //if target is not stunned, stun 'em
                return 1;
            }
        }
        return 1000;
    }
}

2

লিভিং ওয়াল

যুদ্ধের ময়দানে হাঁটতে পারে এমন এক কাঠের প্রাচীর, যে কোনও শত্রু এসে পড়তে পারে এবং তার সর্বোচ্চ স্বাস্থ্যকে আরও শক্তিশালী করার জন্য সেগুলির মধ্য থেকে স্যাপটি বের করে দেয় strong এর মূল সিস্টেমটি কম্পনগুলি সনাক্ত করতে পারে, এমনকি এটি অদৃশ্য শত্রুদের কাছেও মারতে পারে। ইহা গঠিত:

  • 2 শাখা : এসটিআর 35, এজিআই 5, আইএনটি 5, স্ট্রং , বাফ , বাফ , শোষণকারী
  • 1 রুট : স্ট্রেট 25, এজিআই , 5, আইএনটি , 5, ট্রু দর্শন , বাফ , বাফ , শোষণ

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

দলটি অবিশ্বাস্যভাবে ভাল করে; সিমুলেশনগুলিতে, একমাত্র দল (এটি লেখার সময় উপস্থিত রয়েছে) এটি পরাজিত করতে পারে তা হ'ল রোগু স্কোয়াড এবং তারপরেও সবসময় না (কখনও কখনও এমনকি রোগোগুয়াডও দেয়ালের শক্তিতে মারা যায়)। অদম্য ব্যক্তিরা মাঝে মাঝে একটি ড্র স্ক্র্যাপ করার ব্যবস্থা করে।

দলের সাফল্যের মূল কারণ বাফ × 2 এবং অ্যাবসার্বের কম্বো; এর অর্থ হ'ল প্রতিবার যখন আমরা একটি এসটিআর-প্রাথমিক শত্রুকে আঘাত করি তখন আমরা কার্যকরভাবে স্বল্প মেয়াদে 40 এইচপি অর্জন করি (চুরি হওয়া এসআরটি থেকে পুনর্বার বৃদ্ধির কারণে দীর্ঘ মেয়াদে মাত্র 10 এইচপি, তবে ততক্ষণে লড়াইটি শেষ করা উচিত) এবং আমাদের প্রাকৃতিক পুনর্গঠনটি আমাদেরকে আরও জোয়ার করে তুলতে পারে) এবং তার উপরে প্রাকৃতিক পুনর্জন্মের হার 12.5 বা 17.5 এর উপরে দেওয়া হয়, পুনর্জন্মটির সাথে তাল মিলিয়ে রাখার জন্য যথেষ্ট দ্রুত ক্ষতি করা সম্ভব নয় (একটি এজিআই দল সম্ভবত হিট- এর সাহায্যে এটি করতে পারে এবং চালিত কৌশলগুলি, কিন্তু কেউ এখনও সেগুলির মধ্যে একটি তৈরি করেনি)। { আপডেট : আপাতদৃষ্টিতে এই কম্বোটি আসলে কাজ করে না (শোষণ করে কেবল 10 এইচপি খালি করে), তবে দলটি কোনওভাবেই জিততে পারে} এদিকে, শত্রু না হলেএসটিআর-প্রাথমিক, তারা বার বার 25- বা 35-ক্ষতি হিটগুলি গ্রহণ করতে পছন্দ করবে না (এবং সম্ভবত সম্ভবত তাদের কোনও একের মধ্যে ফোকাস করা যেতে পারে); এবং যদি শত্রু INT- প্রাথমিক হয় এবং তাদের আত্মরক্ষার জন্য মন্ত্র ব্যবহার করে (হাই অলক্ষণযোগ্য!), অবসরেব তাদের মন্ত্রীকে অবশেষে নীচে নামিয়ে দেবে যেখানে তারা আর মন্ত্র ফেলতে পারে না। (অতিরিক্তভাবে, আমাদের বেশিরভাগ মন্ত্র থেকে ভয় পাওয়ার মূলত কিছুই নেই; তাদের কুলডাউনগুলি আমাদের পুনর্জন্মকে ছাড়িয়ে যাওয়ার ক্ষতির জন্য খুব দীর্ঘ। মূল ব্যতিক্রমগুলি ট্র্যাপ, যা এখনও কেউ চলছে না, এবং পয়জন, যা 1000 বা 1400 এর মধ্যে যুগে যুগে সময় কাটাতে সময় নেয় takes এইচপি, তবে ওয়াল যদি প্রথমে কাস্টারকে পরাজিত না করে তবে কাজ করে True) সত্য সত্য এখনও অদৃশ্য শত্রুদের পরাস্ত করতে কার্যত দক্ষভাবে একমাত্র ক্ষমতা (ট্র্যাক করেনি '

LivingWall.java
import com.nmerrill.kothcomm.game.maps.Point2D;
import fellowship.abilities.*;
import fellowship.abilities.attacking.*;
import fellowship.abilities.defensive.*;
import fellowship.abilities.vision.*;
import fellowship.abilities.stats.*;
import fellowship.abilities.statuses.*;
import fellowship.actions.*;
import fellowship.actions.attacking.*;
import fellowship.actions.damage.*;
import fellowship.actions.defensive.*;
import fellowship.actions.statuses.*;
import fellowship.characters.CharacterTemplate;
import fellowship.characters.ReadonlyCharacter;
import fellowship.characters.EnemyCharacter;
import fellowship.*;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

public class LivingWall extends Player {
  @Override
  public List<CharacterTemplate> createCharacters() {
    List<CharacterTemplate> templates = new ArrayList<>();

    for (int i = 0; i < 2; i++)
      templates.add(new CharacterTemplate(30, 0, 0,
                                          new Absorb(),
                                          new Strong(),
                                          new Buff(),
                                          new Buff()));
    templates.add(new CharacterTemplate(20, 0, 0,
                                        new Absorb(),
                                        new TrueSight(),
                                        new Buff(),
                                        new Buff()));

    return templates;
  }

  private String lastIdentifier(String s) {
    String[] split = s.split("\\W");
    return split[split.length - 1];
  }

  private boolean hasAbility(ReadonlyCharacter character, String abilityName) {
    for (ReadonlyAbility ability : character.getAbilities()) {
      if (lastIdentifier(ability.name()).equals(abilityName))
        return true;
    }
    return false;
  }

  private boolean hasAbility(EnemyCharacter character, String abilityName) {
    for (ReadonlyAbility ability : character.getAbilities()) {
      if (lastIdentifier(ability.name()).equals(abilityName))
        return true;
    }
    return false;
  }

  private int goalX = 5;
  private int goalY = 5;

  @Override
  public ReadonlyAction choose(Set<ReadonlyAction> actions, ReadonlyCharacter character) {

    /* If we're at the goal square, pick a new one. */
    if (goalX == character.getLocation().getX() &&
        goalY == character.getLocation().getY()) {
      int i = getRandom().nextInt(5);
      goalX = i < 2 ? 1 : i > 2 ? 9 : 5;
      goalY = i == 2 ? 5 : (i % 2) == 1 ? 1 : 9;
    }

    {
      int bestDistance = 99999;
      /* If there are visible enemies, place the goal square under the closest enemy to
         the team. */
      for (Point2D enemyLocation : visibleEnemies.keysView()) {
        int distance = 0;
        for (ReadonlyCharacter ally : team) {
          Point2D allyLocation = ally.getLocation();
          distance +=
            (allyLocation.getX() - enemyLocation.getX()) *
            (allyLocation.getX() - enemyLocation.getX()) +
            (allyLocation.getY() - enemyLocation.getY()) *
            (allyLocation.getY() - enemyLocation.getY());
        }
        if (distance < bestDistance) {
          goalX = enemyLocation.getX();
          goalY = enemyLocation.getY();
          bestDistance = distance;
        }
      }
    }

    /* We use a priority rule for actions. */
    int bestPriority = -2;
    ReadonlyAction bestAction = null;
    for (ReadonlyAction action : actions) {
      int priority = 0;
      if (lastIdentifier(action.getName()).equals("Slice")) {
        int damagePotential = 35;
        /* We use these abilities with very high priority to /kill/ an enemy
           who's weak enough to die from the damage. If they wouldn't die,
           we still want to attack them, but we might prefer to attack
           other enemies instead. The enemy on the goal square (if any)
           is a slightly preferred target, to encourage the team to focus
           on a single enemy. */
        ReadonlyCharacter chosenTarget = null;
        for (ReadonlyCharacter target : action.availableTargets()) {
          if (!isEnemy(target))
            continue;
          chosenTarget = target;
          if (target.getHealth() <= damagePotential) {
            priority = 18;
          } else
            priority = 14;
          if (target.getLocation().getX() == goalX &&
              target.getLocation().getY() == goalY)
            priority++;
        }
        if (chosenTarget == null)
          continue;
        action.setTarget(chosenTarget);
      } else if (lastIdentifier(action.getName()).equals("Smile")) {
        priority = 0;
      } else if (action.movementAction()) {
        /* Move towards the goal location. */
        int bestDistance = 99999;
        Point2D bestLocation = null;
        priority = 1;
        for (Point2D location :
               action.availableLocations().toList().shuffleThis(getRandom())) {
          int distance =
            (location.getX() - goalX) * (location.getX() - goalX) +
            (location.getY() - goalY) * (location.getY() - goalY);
          if (distance < bestDistance) {
            bestDistance = distance;
            bestLocation = location;
          }
        }
        if (bestLocation == null)
          continue;
        action.setLocation(bestLocation);
      } else
        throw new RuntimeException("unknown action" + action.getName());

      if (priority > bestPriority) {
        bestPriority = priority;
        bestAction = action;
      }
    }
    if (bestAction == null)
      throw new RuntimeException("no action?");

    return bestAction;
  }
}

2

DarkAbsorbers

অন্ধকার শোষণকারীরা হলেন 2 ভাই, যা তাদের ক্ষতিগ্রস্থদের জীবনশক্তি শোষণ করে:

  • ওরাকল অ্যাবসার্বার (অদৃশ্য শত্রু দেখতে পারেন)
    • এসআরটি: 25; এজিআই: 5; INT: 5
    • TrueSight , নমনীয় , সীমাকৃত , শোষণ
  • দ্রুত শোষণকারী (তার ভাইয়ের চেয়ে আরও দ্রুত শোষিত করতে পারে)
    • এসআরটি: 25; এজিআই: 5; INT: 5
    • দ্রুত , নমনীয় , রেঞ্জযুক্ত , শোষণকারী

তারা সর্বদা বর্ধমান অন্ধকার মেঘের সাথে থাকে। এটি একবার সমালোচনামূলক ভর পৌঁছালে শত্রুদের হত্যা করতে শুরু করে kill

  • অন্ধকার মেঘ
    • এসআরটি: 5; এজিআই: 5; INT: 25
    • ক্লোন , জ্যাপ , অন্ধকার

আপনি নিজের দলে এখান থেকে একক অক্ষর পুনরায় ব্যবহার করতে পারেন, যতক্ষণ না আপনি অন্তত আরও একটি চরিত্র যোগ করেন যা এখানে উপস্থিত নেই।

DarkAbsorbers.java
import java.util.Arrays;
import java.util.List;

import org.eclipse.collections.api.map.ImmutableMap;
import org.eclipse.collections.api.set.ImmutableSet;

import com.nmerrill.kothcomm.game.maps.Point2D;

import fellowship.abilities.ActionAbility;
import fellowship.abilities.ReadonlyAbility;
import fellowship.abilities.attacking.Absorb;
import fellowship.abilities.attacking.Flexible;
import fellowship.abilities.attacking.Ranged;
import fellowship.abilities.vision.Darkness;
import fellowship.abilities.vision.TrueSight;
import fellowship.actions.ReadonlyAction;
import fellowship.actions.attacking.Quick;
import fellowship.actions.damage.Zap;
import fellowship.actions.defensive.ForceField;
import fellowship.actions.other.Clone;
import fellowship.characters.CharacterTemplate;
import fellowship.characters.ReadonlyCharacter;

public class DarkAbsorbers extends SleafarPlayer {
    private ReadonlyCharacter zapTarget = null;

    private CharacterTemplate oracleAbsorberTemplate() {
        return new CharacterTemplate(20, 0, 0,
                new TrueSight(), new Flexible(), new Ranged(), new Absorb());
    }

    private CharacterTemplate quickAbsorberTemplate() {
        return new CharacterTemplate(20, 0, 0,
                new ActionAbility(Quick::new), new Flexible(), new Ranged(), new Absorb());
    }

    private CharacterTemplate darknessCloudTemplate() {
        return new CharacterTemplate(0, 0, 20,
                new ActionAbility(Clone::new), new ActionAbility(Zap::new), new Darkness());
    }

    @Override
    public List<CharacterTemplate> createCharacters() {
        return Arrays.asList(oracleAbsorberTemplate(), quickAbsorberTemplate(), darknessCloudTemplate());
    }

    private class Absorber extends Character {
        protected Absorber(ReadonlyCharacter delegate) {
            super(delegate);
        }

        @Override
        protected ReadonlyAction choose() {
            ReadonlyAction quick = getAction(Quick.class);

            if (quick != null && setSliceTarget(quick, 100.0)) {
                return quick;
            }
            if (slice != null && setSliceTarget(slice, 100.0)) {
                return slice;
            }

            ImmutableMap<Point2D, Double> damage = getEnemySliceDamage();
            ImmutableSet<Point2D> above5Damage = damage.select((k, v) -> v > 5.0).keysView().toSet().toImmutable();

            if (step != null && (above5Damage.contains(getLocation()) ||
                    (getHealth() <= 5.0 && isInEnemySliceRange())) && setAvoidEnemiesLocation(step)) {
                return step;
            }
            if (quick != null && setSliceTarget(quick, 0.01)) {
                return quick;
            }
            if (slice != null && setSliceTarget(slice, 0.01)) {
                return slice;
            }
            if (step != null && getSliceLocations().notEmpty() && setClosestLocation(step, getSliceLocations())) {
                return step;
            }
            if (step != null && setExploreLocation(step)) {
                return step;
            }
            return smile;
        }
    }

    private class DarknessCloud extends Character {
        private int zapCooldown = 0;
        private boolean zapNow = false;
        private boolean zapLater = false;

        protected DarknessCloud(ReadonlyCharacter delegate) {
            super(delegate);
        }

        private void updateZapFlags(double mana) {
            zapNow = zapCooldown == 0 && mana >= 15.0;
            zapLater = mana + 5 * getManaRegen() >= (zapNow ? 30.0 : 15.0);
        }

        private boolean isZappable(ReadonlyCharacter c, int zapNowCount, int zapLaterCount) {
            int forceFieldNow = 0;
            int forceFieldLater = 0;
            for (ReadonlyAbility a : c.getAbilities()) {
                if (a.abilityClass().equals(ForceField.class)) {
                    forceFieldNow = a.getRemaining();
                    forceFieldLater = 5;
                }
            }
            return c.getHealth() + c.getHealthRegen() <= (zapNowCount - forceFieldNow) * 30.0 ||
                    c.getHealth() + c.getHealthRegen() * 6 <= (zapNowCount + zapLaterCount - forceFieldNow - forceFieldLater) * 30.0;
        }

        @Override
        protected ReadonlyAction choose() {
            ReadonlyAction clone = getAction(Clone.class);
            ReadonlyAction zap = getAction(Zap.class);

            zapCooldown = zapCooldown > 0 ? zapCooldown - 1 : 0;
            updateZapFlags(getMana());
            int zapNowCount = characters.count(c -> c instanceof DarknessCloud && ((DarknessCloud) c).zapNow);
            int zapLaterCount = characters.count(c -> c instanceof DarknessCloud && ((DarknessCloud) c).zapLater);

            if (zap != null) {
                if (zapTarget != null && (!zap.availableTargets().contains(zapTarget) || zapTarget.isDead() ||
                        !isZappable(zapTarget, zapNowCount, zapLaterCount))) {
                    zapTarget = null;
                }
                if (zapTarget == null) {
                    zapTarget = chooseSmallest(zap.availableTargets().reject(c ->
                            isBear(c) || !isZappable(c, zapNowCount, zapLaterCount)), HEALTH_COMPARATOR);
                }
                if (zapTarget != null) {
                    zapCooldown = 5;
                    zapNow = false;
                    zap.setTarget(zapTarget);
                    return zap;
                }
            }

            ImmutableMap<Point2D, Double> damage = getEnemySliceDamage();
            ImmutableSet<Point2D> above5Damage = damage.select((k, v) -> v > 5.0).keysView().toSet().toImmutable();

            if (clone != null) {
                if (visibleEnemies.isEmpty()) {
                    if (setFarthestLocation(clone, getTeamHiddenLocations())) {
                        updateZapFlags(getMana() - 100.0);
                        return clone;
                    }
                } else {
                    if (setFarthestLocation(clone, above5Damage, getEnemyLocations()) ||
                            setLocation(clone, chooseSmallest(clone.availableLocations(),
                            (o1, o2) -> Double.compare(damage.get(o1), damage.get(o2))))) {
                        updateZapFlags(getMana() - 100.0);
                        return clone;
                    }
                }

                return clone;
            }
            if (step != null && (above5Damage.contains(getLocation()) ||
                    (getHealth() <= 5.0 && isInEnemySliceRange())) && setAvoidEnemiesLocation(step)) {
                return step;
            }
            if (slice != null && setSliceTarget(slice, 0.01)) {
                return slice;
            }
            if (step != null && !visibleEnemies.isEmpty() &&
                    setFarthestLocation(step, getEnemySliceLocations(), getEnemyLocations())) {
                return step;
            }
            return smile;
        }
    }

    @Override
    protected Character createCharacter(ReadonlyCharacter delegate) {
        if (hasAbility(delegate, Absorb.class)) {
            return new Absorber(delegate);
        } else if (hasAbility(delegate, Darkness.class)) {
            return new DarknessCloud(delegate);
        } else {
            throw new IllegalArgumentException();
        }
    }
}

0

LongSwordv2

"আপনি চালাতে পারেন, তবে আপনি লুকিয়ে রাখতে পারবেন না ..." - লংসওয়ার্ডভি 2

ব্যবহার সীমাকৃত , নমনীয় , দ্রুত , TrueSight

এই বট হয় ঠিক ব্যতীত এটি TrueSight পরিবর্তে ব্যবহার স্ট্রং এর LongSwordv2 হিসাবে একই।

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

LongSwordv2.java
import fellowship.*;
import com.nmerrill.kothcomm.game.maps.Point2D;
import fellowship.abilities.ActionAbility;
import fellowship.abilities.attacking.Flexible;
import fellowship.abilities.attacking.Ranged;
import fellowship.abilities.stats.Strong;
import fellowship.abilities.vision.Darkness;
import fellowship.abilities.vision.TrueSight;
import fellowship.actions.ReadonlyAction;
import fellowship.actions.attacking.Quick;
import fellowship.characters.CharacterTemplate;
import fellowship.characters.ReadonlyCharacter;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

public class LongSwordv2 extends Player{
    //debugging
    private boolean debug = false;
    private void println(String text) {
        if(debug)
            System.out.println(text);
    }

    //variables use to hold the start Y coordinate of the bot
    private boolean started = false;
    private int startY = 5;

    private boolean together = false;

    @Override
    public List<CharacterTemplate> createCharacters() {
        List<CharacterTemplate> templates = new ArrayList<>();
        for (int i = 0; i < 3; i++) {
            templates.add(new CharacterTemplate(20, 0, 0,
                    new Ranged(), //Adds 1 to the range of Slice
                    new Flexible(), //Can Slice in any of the 8 directions
                    new ActionAbility(Quick::new), //Slice twice, Mana: 3, Cooldown: 0
                    new TrueSight())); //Reveals all hidden units within range 2 at turn start
        }
        return templates;
    }

    @Override
    public ReadonlyAction choose(Set<ReadonlyAction> actions, ReadonlyCharacter character) {
        if(!started) {
            startY = character.getLocation().getY(); //giving startY the value of the bot's starting y-value
            started = true; //do this only once, that's why there is the if statement
        }

        ReadonlyAction current = null;

        //choosing action depending on priority
        int priority = Integer.MAX_VALUE;
        for(ReadonlyAction action:actions) {
            int priorityLocal = getPriority(action, character);
            if(priorityLocal < priority) {
                current = action;
                priority = priorityLocal;
            }
        }

        if (current == null){
            throw new RuntimeException("No valid actions");
        }

        println(current.getName());

        if(current.needsLocation()) {
            if(visibleEnemies.isEmpty()) {
                if (character.getHealth() < 100) {
                    //if has low health, go backwards towards "base"
                    //println("lowHealth");
                    current.setLocation(move(current, character, "backward"));
                } else {
                    //else go forwards to enemy's "base"
                    current.setLocation(move(current, character, "forward"));
                }
            }else{
                //go towards closest enemy
                current.setLocation(current.availableLocations().minBy(p1->p1.cartesianDistance(visibleEnemies.keysView().minBy(p1::cartesianDistance))));
            }
        }
        if(current.needsTarget()) {
            //get closest target
            current.setTarget(current.availableTargets().minBy(p1 -> 0));
        }

        Iterator<ReadonlyCharacter> iterator = current.availableTargets().iterator();

        while(iterator.hasNext()) {
            Point2D loc = iterator.next().getLocation();
            println(loc.getX()+","+loc.getY());
        }

        return current;
    }

    //move backwards or forwards
    private Point2D move(ReadonlyAction readonlyAction, ReadonlyCharacter character, String direction) {
        Point2D location = null;

        //move direction depending on Y coordinate of point
        for(Point2D point2D:readonlyAction.availableLocations()) {
            switch (direction) {
                case "forward":
                    if(startY > 5) { //bot started at bottom
                        if (point2D.getY() < character.getLocation().getY())
                            location = point2D;
                    }else{ //bot started at top
                        if (point2D.getY() > character.getLocation().getY())
                            location = point2D;
                    }
                    break;
                case "backward":
                    if(startY > 5) { //bot started at bottom
                        if (point2D.getY() > character.getLocation().getY())
                            location = point2D;
                    }else{ //bot started at top
                        if (point2D.getY() < character.getLocation().getY())
                            location = point2D;
                    }
                    break;
            }

        }

        //if no available locations, just choose the first available location
        if(location == null) {
            location = readonlyAction.availableLocations().iterator().next();
        }

        println(location.getY()+","+character.getLocation().getY());

        return location;
    }

    private int getPriority(ReadonlyAction action, ReadonlyCharacter character) {
        if(visibleEnemies.isEmpty()) {
            //if there are no visible enemies, Step. In the choose function, this becomes move forward or backward depending on health
            if(action.getName().equals("Step")) {
                return 100;
            }
        }else {
            /*
             * PRIORITIES:
             *  1. Quick (Slice twice)
             *  2. Slice
             *  3. Step (when enemy is not in range --> move towards enemy)
             */
            if (action.getName().equals("Quick")) {
                return 1;
            }else if(action.getName().equals("Slice")) {
                return 10;
            }else if(action.getName().equals("Step")) {
                return 50;
            }
        }
        //Kids, don't Smile, instead Step or Slice
        return 1000;
    }
}

এই বটটি ডাউনলোড করা ব্যর্থ হয়েছে, কারণ শিরোনামটি অনুপস্থিত।
স্লিফার

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