Splix.io - দেশের রাজা


37

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

আপনি যদি ইতিমধ্যে এটি চেষ্টা না করে থাকেন তবে স্প্লিক্স.আইওতে যান এবং একটি গেমটি চেষ্টা করুন। আপনার চলাচল নিয়ন্ত্রণ করতে তীর কীগুলি ব্যবহার করুন।

জিআইএফ

এখানে চিত্র বর্ণনা লিখুন

ক্রেডিট: http://splix.io/

সুনির্দিষ্ট

সমস্ত খেলোয়াড় 200x200 বোর্ডে এলোমেলো অবস্থান থেকে শুরু করে। (আমি এটি পরিবর্তন করার অধিকার সংরক্ষণ করি :)। সম্ভব সর্বাধিক সংখ্যক পয়েন্ট সংগ্রহ করতে আপনার কাছে একটি নির্দিষ্ট পরিমাণের পদক্ষেপ থাকবে। পয়েন্টগুলি দ্বারা দীর্ঘ করা:

  • আপনি খেলোয়াড়ের সংখ্যা 300 বার মারা গেছেন
  • রাউন্ড শেষে আপনার নিজের পরিমাণ জমির পরিমাণ

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

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

মৃত্যু মামলা

হেড বাট

মাথা বাট

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

মাথা বাট

তবে, যখন খেলোয়াড়দের মধ্যে একটি তার জমিতে থাকে, তখন অন্য খেলোয়াড় মারা যায়।

এখানে চিত্র বর্ণনা লিখুন

লাইন ক্রস

এখানে চিত্র বর্ণনা লিখুন

এই ক্ষেত্রে, শুধুমাত্র বেগুনি প্লেয়ার মারা যায়।

আপনি নিজের লাইনটি অতিক্রম করতে পারবেন না।

এখানে চিত্র বর্ণনা লিখুন

বোর্ড থেকে বের হচ্ছে

খেলোয়াড় বোর্ড থেকে যাচ্ছে

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

ক্যাপচারিং অঞ্চল

কোনও খেলোয়াড় যখন একটি ট্রেইল পেলে সে অঞ্চলটি দখল করবে এবং সে তার নিজের জমিতে আবার প্রবেশ করবে।

এখানে চিত্র বর্ণনা লিখুন

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

নিয়ামক বিশদ

নিয়ামক এখানে আছেন । এটি মূল গেমের সাথে খুব মিল, তবে কোটএইচের জন্য এবং প্রযুক্তিগত কারণে এটি আরও ভাল ফিট করার জন্য ছোট ছোট পরিবর্তন করা হয়েছে। এটা দিয়ে তৈরি করা হয়েছে @NathanMerrill এর KotHComm গ্রন্থাগার @NathanMerrill থেকে সারগর্ভ সাহায্যে পাশাপাশি, এবং। চ্যাট রুমের নিয়ামকটিতে আপনি যে কোনও বাগ খুঁজে পান সে সম্পর্কে দয়া করে আমাকে জানান । কোটএইচকমের সাথে সামঞ্জস্য বজায় রাখার জন্য, আমি নিয়ামক জুড়ে ইলিপেস সংগ্রহগুলি ব্যবহার করেছি, তবে কেবল জাভা সংগ্রহ লাইব্রেরি ব্যবহার করে বটগুলি লেখা যেতে পারে।

গিথুব প্রকাশের পৃষ্ঠায় একটি উবারজারে সবকিছু প্যাকেজ করা আছে । এটি ব্যবহার করতে, এটি ডাউনলোড করুন এবং এটি আপনার প্রকল্পের সাথে সংযুক্ত করুন যাতে আপনি এটি অটো-কমপ্লিট ( ইন্টেলিজিজ , ইক্লিপসের নির্দেশাবলী ) এর জন্য ব্যবহার করতে পারেন । আপনার জমাগুলি পরীক্ষা করার জন্য, আপনি জারটি দিয়ে চালান java -jar SplixKoTH-all.jar -d path\to\submissions\folder। নিশ্চিত করুন যে path\to\submissions\folderএর নামে একটি সাবফোলার রয়েছে javaএবং আপনার সমস্ত ফাইল সেখানে রাখবে । আপনার বটগুলিতে প্যাকেজের নামগুলি ব্যবহার করবেন না (যদিও এটি কোটকমকমের মাধ্যমে সম্ভব হতে পারে, এটি কেবল খানিকটা বেশি সমস্যা)। সমস্ত বিকল্প দেখতে, ব্যবহার করুন --help। সমস্ত বট লোড করতে, ব্যবহার করুন --question-id 126815

একটি বট লেখা

বট লেখা শুরু করার জন্য আপনাকে অবশ্যই প্রসারিত করতে হবে SplixPlayer

  • Direction makeMove(ReadOnlyGame game, ReadOnlyBoard board)
    • আপনার বটটি কোন পদক্ষেপটি তৈরি করতে চান তা এখানেই স্থির করুন। নাল ফিরে না।
  • HiddenPlayer getThisHidden()
    • এর HiddenPlayerসংস্করণ পান this। আপনার বটকে বোর্ডের সাথে তুলনা করার জন্য দরকারী।

enum Direction

  • মানগুলি
    • East (x = 1; y = 0)
    • West (x = -1; y = 0)
    • North (x = 0; y = 1)
    • South (x = 0; y = -1)
  • Direction leftTurn()
    • আপনি Directionযদি একটি বাম পালা তৈরি করেন তবে তা পাবেন Get
  • Direction RightTurn()
    • আপনি Directionযদি সঠিক বাঁক তৈরি করেন তবে যা পাবেন তা পান ।

ReadOnlyBoard

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

  • SquareRegion getBounds()
    • বোর্ডের আকারটি পুনরুদ্ধার করুন।
  • MutableMap<com.nmerrill.kothcomm.game.maps.Point2D,ReadOnlySplixPoint> getGlobal()
    • বোর্ডের একটি বৈশ্বিক মানচিত্র পান।
  • MutableMap<com.nmerrill.kothcomm.game.maps.Point2D,ReadOnlySplixPoint> getView()
    • যেমনটি getGlobal()এটি আপনার প্লেয়ারের চারপাশে একটি 20x20 অঞ্চলে সীমাবদ্ধ এবং এটি খেলোয়াড়ের অবস্থান প্রদর্শন করে except
  • Point2D getPosition(SplixPlayer me)
    • আপনার প্লেয়ারের অবস্থান পান। হিসাবে ব্যবহার করুন board.getPosition(this)
  • Point2D getSelfPosition(ReadOnlyBoard)
    • বোর্ডে আপনার অবস্থান পান। ব্যবহার:Point2D mypos = getSelfPosition(board)

ReadOnlyGame

ReadOnlyGameকেবলমাত্র খেলাগুলির মধ্যে থাকা বাঁকগুলির সংখ্যাটিতে অ্যাক্সেস সরবরাহ করে int getRemainingIterations()

ReadOnlySplixPoint

  • HiddenPlayer getClaimer()
    • HiddenPlayerকে দাবী করছে দাবি করছে - দাবী করা = একটি ট্রেইলের সংস্করণ পান ।
  • HiddenPlayer getOwner()
    • কার পয়েন্টের মালিক তা পান।
  • HiddenPlayer getWhosOnSpot()
    • যদি প্লেয়ারটি এই স্থানে থাকে তবে এর লুকানো সংস্করণটি ফিরিয়ে দিন। শুধুমাত্র কাজ করে getLocal()

Point2D

এখানে অন্যান্য ক্লাসগুলির মতো নয়, Point2Dকোটকমকম লাইব্রেরিতে রয়েছে।com.nmerrill.kothcomm.game.maps.Point2D

  • Point2D(int x, int y)
  • int getX()
  • int getY()
  • Point2D moveX(int x)
  • Point2D moveY(int y)
  • Point2D wrapX(int maxX)
    • xএর ব্যাপ্তির মধ্যে থাকা মানটি মোড়ানো maxX
  • Point2D wrapY(int maxY)
    • yএর ব্যাপ্তির মধ্যে থাকা মানটি মোড়ানো maxY
  • int cartesianDistance(Point2D other)
    • এটি খেলোয়াড়কে বিন্দু থেকে বিন্দু বিতে সরতে যে কতটা মোড় নিতে পারে তা অনুবাদ করে।

ক্লোজার সমর্থন

ক্লোজার সংকলকটি এর সাথে বান্ডিল রয়েছে SplixKoTH-all.jar, যাতে আপনি আপনার বটের জন্য ক্লোজার ব্যবহার করতে পারেন! random_botএটি কীভাবে ব্যবহার করতে হয় তা দেখতে আমার উল্লেখ করুন ।

একটি বট ডিবাগিং

নিয়ন্ত্রক পরীক্ষার কৌশলগুলিতে সহায়তা করতে একটি ডিবাগার নিয়ে আসে। এটি শুরু করতে, --guiবিকল্পটি দিয়ে জারটি চালান ।

পাত্রীটি কি তবে ডিবাগার সংযুক্ত করতে, অনুসরণ এই নির্দেশাবলী IntelliJ, অথবা এই নির্দেশাবলী অন্ধকার জন্য (অন্ধকার সংস্করণ অপরীক্ষিত)।

এখানে চিত্র বর্ণনা লিখুন

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

এখানে চিত্র বর্ণনা লিখুন

এখন, এটি সব একসাথে রাখার জন্য:

চলমান বট

অন্যদের সাথে আপনার বট চালানোর জন্য আপনাকে প্রকাশের পৃষ্ঠায় জার চালাতে হবে। পতাকাগুলির তালিকা এখানে রয়েছে:

  • --iterations( -i) <= int(ডিফল্ট 500)
    • চলমান গেমের সংখ্যা উল্লেখ করুন।
  • --test-bot( -t) <=String
    • বট অন্তর্ভুক্ত কেবলমাত্র গেমগুলি চালান।
  • --directory( -d) <= পথ
    • থেকে জমা দেওয়ার জন্য ডিরেক্টরি run আপনার বট চালানোর জন্য এটি ব্যবহার করুন। নিশ্চিত করুন যে আপনার বট নামে পাথ একটি subfolder একটি হয় java
  • --question-id( -q) <= int(কেবল ব্যবহার 126815)
    • সাইট থেকে অন্যান্য জমাগুলি ডাউনলোড করুন এবং সংকলন করুন।
  • --random-seed( -r) <= int(একটি এলোমেলো সংখ্যায় ডিফল্ট)
    • রানারকে একটি বীজ দিন যাতে এলোমেলোভাবে ব্যবহার করা বটগুলি পুনরায় উত্পাদন করতে পারে।
  • --gui( -g)
    • কোনও টুর্নামেন্ট চালানোর পরিবর্তে ডিবাগার ইউআই চালান। সঙ্গে সেরা ব্যবহার --test-bot
  • --multi-thread( -m) <= boolean(ডিফল্ট true)
    • মাল্টি-থ্রেড মোডে একটি টর্নোমেন্ট চালান। আপনার কম্পিউটারে একাধিক কোর থাকলে এটি একটি দ্রুত ফলাফল সক্ষম করে।
  • --thread-count( -c) <= int(ডিফল্ট 4)
    • মাল্টি-থ্রেড অনুমোদিত হলে চালানোর জন্য থ্রেডের সংখ্যা।
  • --help( -h)
    • এটির মতো একটি সহায়তা বার্তা প্রিন্ট করুন।

এই পৃষ্ঠায় সমস্ত জমা চালাতে, ব্যবহার করুন java -jar SplixKoTH-all.jar -q 126815

আপনার পোস্ট ফর্ম্যাট করা হচ্ছে

কন্ট্রোলার সমস্ত বট ডাউনলোড করতে পারে তা নিশ্চিত করতে আপনার এই ফর্ম্যাটটি অনুসরণ করা উচিত।

[BotName], Java                     // this is a header
                                    // any explanation you want
[BotName].java                      // filename, in the codeblock
[code]

এছাড়াও, প্যাকেজ ঘোষণার ব্যবহার করবেন না।


স্কোরবোর্ড

+------+--------------+-----------+
| Rank | Name         |     Score |
+------+--------------+-----------+
|    1 | ImNotACoward | 8940444.0 |
|    2 | TrapBot      |  257328.0 |
|    3 | HunterBot    |  218382.0 |
+------+--------------+-----------+

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

আনন্দ কর!


আরে, এই অবশেষে পোস্ট হয়েছে! আমি ভাবছিলাম: ডি
এমডি এক্সএফ

কতক্ষন আপনি অপেক্ষা করছেন? ;) আপনি কি জমা দেওয়ার পরিকল্পনা করছেন?
জে আতকিন

আমি মূলত ইওস্ল্যাংগুলিতে প্রোগ্রাম লিখি বলে আমি এর মতো একটি চ্যালেঞ্জ সমাধান করতে সক্ষম হবো কিনা তা আমি জানি না। তবে আমি এটি স্যান্ডবক্সে দেখেছি এবং এটি দুর্দান্ত চ্যালেঞ্জের মতো দেখাচ্ছে!
এমডি এক্সএফ

@ হাইপারনেট্রিনো আমি সম্পাদনাটি দেখেছি, এটি কি আপনাকে সত্যিই বিরক্ত করে? রাজনৈতিক সঠিকতা এই পোস্টের পরিধি হিসাবে কোথাও নেই, এবং এটি সম্পূর্ণভাবে সঠিক ইংরেজি ব্যাকরণ ...
জে আতকিন

2
0.o ছোট পৃথিবী? আমি splix.io এর বিকাশকারী (এর) জানি। (এটি @ তাকে টুইট করেছেন)
CAD97

উত্তর:


2

ইমনোটাকোয়ার্ড, জাভা

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

ImNotACoward.java
import org.eclipse.collections.api.map.MutableMap;
import org.eclipse.collections.api.set.MutableSet;
import org.eclipse.collections.impl.factory.Lists;
import org.eclipse.collections.impl.factory.Maps;
import org.eclipse.collections.impl.factory.Sets;

import com.jatkin.splixkoth.ppcg.game.Direction;
import com.jatkin.splixkoth.ppcg.game.SplixPlayer;
import com.jatkin.splixkoth.ppcg.game.readonly.HiddenPlayer;
import com.jatkin.splixkoth.ppcg.game.readonly.ReadOnlyBoard;
import com.jatkin.splixkoth.ppcg.game.readonly.ReadOnlyGame;
import com.jatkin.splixkoth.ppcg.game.readonly.ReadOnlySplixPoint;
import com.nmerrill.kothcomm.game.maps.Point2D;
import com.nmerrill.kothcomm.game.maps.graphmaps.bounds.point2D.SquareRegion;

public class ImNotACoward extends SplixPlayer {
    private static final MutableSet<Direction> DIRECTIONS = Sets.mutable.of(Direction.values());

    private static class Board {
        public MutableSet<Point2D> allPoints = null;
        private SquareRegion globalBounds = null;
        private SquareRegion viewBounds = null;
        private MutableMap<Point2D, ReadOnlySplixPoint> global = null;
        private MutableMap<Point2D, ReadOnlySplixPoint> view = null;

        public void update(ReadOnlyBoard readOnlyBoard) {
            if (this.allPoints == null) {
                this.allPoints = readOnlyBoard.getGlobal().keysView().toSet();
                this.globalBounds = readOnlyBoard.getBounds();
            }
            this.viewBounds = readOnlyBoard.viewingArea;
            this.global = readOnlyBoard.getGlobal();
            this.view = readOnlyBoard.getView();
        }

        public boolean inBounds(Point2D point) {
            return globalBounds.inBounds(point);
        }

        public boolean inView(Point2D point) {
            return viewBounds.inBounds(point);
        }

        public ReadOnlySplixPoint getSplixPoint(Point2D point) {
            return inView(point) ? view.get(point) : global.get(point);
        }

        public MutableSet<Point2D> getNeighbors(Point2D point) {
            return DIRECTIONS.collect(d -> point.move(d.vector.getX(), d.vector.getY())).select(this::inBounds);
        }

        public MutableSet<Point2D> getNeighbors(MutableSet<Point2D> points) {
            return points.flatCollect(this::getNeighbors);
        }

        public MutableSet<Point2D> getBorders(SquareRegion region) {
            return allPoints.select(p -> region.inBounds(p) &&
                    (p.getX() == region.getLeft() || p.getX() == region.getRight() ||
                    p.getY() == region.getTop() || p.getY() == region.getBottom() ||
                    p.getX() == globalBounds.getLeft() || p.getX() == globalBounds.getRight() ||
                    p.getY() == globalBounds.getTop() || p.getY() == globalBounds.getBottom()));
        }
    }

    private class Player {
        public final HiddenPlayer hiddenPlayer;
        public MutableSet<Point2D> owned = Sets.mutable.empty();
        private MutableSet<Point2D> unowned = null;
        private MutableSet<Point2D> oldClaimed = Sets.mutable.empty();
        public MutableSet<Point2D> claimed = Sets.mutable.empty();
        private MutableSet<Point2D> oldPos = Sets.mutable.empty();
        public MutableSet<Point2D> pos = Sets.mutable.empty();

        public Player(HiddenPlayer hiddenPlayer) {
            super();
            this.hiddenPlayer = hiddenPlayer;
        }

        public void nextMove() {
            owned.clear();
            unowned = null;
            oldClaimed = claimed;
            claimed = Sets.mutable.empty();
            oldPos = pos;
            pos = Sets.mutable.empty();
        }

        public MutableSet<Point2D> getUnowned() {
            if (unowned == null) {
                unowned = board.allPoints.difference(owned);
            }
            return unowned;
        }

        public void addOwned(Point2D point) {
            owned.add(point);
        }

        public void addClaimed(Point2D point) {
            claimed.add(point);
        }

        public void setPos(Point2D point) {
            pos.clear();
            pos.add(point);
        }

        public void calcPos() {
            if (pos.isEmpty()) {
                MutableSet<Point2D> claimedDiff = claimed.difference(oldClaimed);
                if (claimedDiff.size() == 1) {
                    pos = board.getNeighbors(claimedDiff).select(p -> !claimed.contains(p) && !board.inView(p));
                } else if (!oldPos.isEmpty()) {
                    pos = board.getNeighbors(oldPos).select(p -> owned.contains(p) && !board.inView(p));
                } else {
                    pos = owned.select(p -> !board.inView(p));
                }
            }
        }
    }

    private Board board = new Board();
    private Point2D myPos = null;
    private final Player nobody = new Player(new HiddenPlayer(null));
    private final Player me = new Player(new HiddenPlayer(this));
    private MutableMap<HiddenPlayer, Player> enemies = Maps.mutable.empty();
    private MutableMap<HiddenPlayer, Player> players = Maps.mutable.of(nobody.hiddenPlayer, nobody, me.hiddenPlayer, me);
    private MutableSet<Point2D> path = Sets.mutable.empty();

    private Player getPlayer(HiddenPlayer hiddenPlayer) {
        Player player = players.get(hiddenPlayer);
        if (player == null) {
            player = new Player(hiddenPlayer);
            players.put(player.hiddenPlayer, player);
            enemies.put(player.hiddenPlayer, player);
        }
        return player;
    }

    private Direction moveToOwned() {
        MutableSet<Point2D> targets = me.owned.difference(me.pos);
        if (targets.isEmpty()) {
            return moveTo(myPos);
        } else {
            return moveTo(targets.minBy(myPos::cartesianDistance));
        }
    }

    private Direction moveTo(Point2D target) {
        return DIRECTIONS.minBy(d -> {
            Point2D p = myPos.move(d.vector.getX(), d.vector.getY());
            return !board.inBounds(p) || me.claimed.contains(p) ? Integer.MAX_VALUE : target.cartesianDistance(p);
        });
    }

    @Override
    protected Direction makeMove(ReadOnlyGame readOnlyGame, ReadOnlyBoard readOnlyBoard) {
        board.update(readOnlyBoard);
        myPos = readOnlyBoard.getPosition(this);
        path.remove(myPos);

        for (Player e : players.valuesView()) {
            e.nextMove();
        }
        for (Point2D point : board.allPoints) {
            ReadOnlySplixPoint splixPoint = board.getSplixPoint(point);
            getPlayer(splixPoint.getOwner()).addOwned(point);
            getPlayer(splixPoint.getClaimer()).addClaimed(point);
            getPlayer(splixPoint.getWhosOnSpot()).setPos(point);
        }
        for (Player e : players.valuesView()) {
            e.calcPos();
        }

        if (me.owned.contains(myPos) && path.allSatisfy(p -> me.owned.contains(p))) {
            path.clear();
        }

        if (path.isEmpty()) {
            MutableSet<Point2D> enemyPositions = enemies.valuesView().flatCollect(e -> e.pos).toSet();
            int enemyDistance = enemyPositions.isEmpty() ? Integer.MAX_VALUE :
                    enemyPositions.minBy(myPos::cartesianDistance).cartesianDistance(myPos);

            if (enemyDistance < 20) {
                MutableSet<Point2D> enemyClaimed = enemies.valuesView().flatCollect(e -> e.claimed).toSet();
                if (!enemyClaimed.isEmpty()) {
                    Point2D closestClaimed = enemyClaimed.minBy(myPos::cartesianDistance);
                    if (closestClaimed.cartesianDistance(myPos) < enemyDistance) {
                        return moveTo(closestClaimed);
                    } else if (enemyDistance < 10) {
                        return moveToOwned();
                    }
                }
            }

            if (me.owned.contains(myPos)) {
                if (!me.getUnowned().isEmpty()) {
                    Point2D target = me.getUnowned().minBy(myPos::cartesianDistance);
                    if (target.cartesianDistance(myPos) > 2) {
                        return moveTo(target);
                    }
                }

                int safeSize = Math.max(1, Math.min(enemyDistance / 6, readOnlyGame.getRemainingIterations() / 4));
                SquareRegion region = Lists.mutable
                        .of(new SquareRegion(myPos, myPos.move(safeSize, safeSize)),
                                new SquareRegion(myPos, myPos.move(safeSize, -safeSize)),
                                new SquareRegion(myPos, myPos.move(-safeSize, safeSize)),
                                new SquareRegion(myPos, myPos.move(-safeSize, -safeSize)))
                        .maxBy(r -> me.getUnowned().count(p -> r.inBounds(p)));
                path = board.getBorders(region);
            } else {
                return moveToOwned();
            }
        }

        if (!path.isEmpty()) {
            return moveTo(path.minBy(myPos::cartesianDistance));
        }

        return moveToOwned();
    }
}

মজাদার. খুব সুন্দর! আমি আরও আশ্চর্য হই যে এটি আরও কতটা ভাল তৈরি করা যায় ...
জে আতকিন

1

ট্র্যাপবট, জাভা

TrapBot.java

import com.jatkin.splixkoth.ppcg.game.Direction;
import com.jatkin.splixkoth.ppcg.game.SplixPlayer;
import com.jatkin.splixkoth.ppcg.game.readonly.ReadOnlyBoard;
import com.jatkin.splixkoth.ppcg.game.readonly.ReadOnlyGame;
import com.jatkin.splixkoth.ppcg.game.readonly.ReadOnlySplixPoint;
import com.nmerrill.kothcomm.game.maps.Point2D;
import com.nmerrill.kothcomm.game.maps.graphmaps.bounds.point2D.SquareRegion;
import javafx.util.Pair;
import org.eclipse.collections.api.map.MutableMap;
import org.eclipse.collections.impl.factory.Lists;

import java.util.Comparator;

/**
 * Trap bot goes to the wall and traces the entirety around. Hopes that
 * the players in the middle die and that nobody challenges him. Nearly 
 * all turns are left turns.
 */
public class TrapBot extends SplixPlayer {

    /**
     * Mode when the bot is attempting to reach the wall from it's original spawn
     * location.
     */
    public static final int MODE_GOING_TO_WALL = 1;

    /**
     * Mode when we have reached the wall and are now going around the board.
     */
    public static final int MODE_FOLLOWING_WALL = 2;

    private int mode = MODE_GOING_TO_WALL;

    public static int WALL_EAST = 1;
    public static int WALL_NORTH = 2;
    public static int WALL_WEST = 3;
    public static int WALL_SOUTH = 4;


    /**
     * How long the bot would like to go before he turns around to go back home.
     */
    private static final int PREFERRED_LINE_DIST = 5;

    private int distToTravel = 0;

    private Direction lastMove = Direction.East;// could be anything that's not null
    private int lastTrailLength = 0;

    @Override
    protected Direction makeMove(ReadOnlyGame game, ReadOnlyBoard board) {
        Direction ret = null;
        MutableMap<Point2D, ReadOnlySplixPoint> view = board.getView();
        int trailLength = getTrailLength(board, view);

        if (trailLength == 0) {

            int closestWall = getClosestWall(board);
            Direction directionToWall = getDirectionToWall(closestWall);

            if (lastTrailLength != 0) {
                ret = lastMove.leftTurn();
                // move to the other half of 2 width line so we can start without shifting to the left
            }

            if (mode == MODE_GOING_TO_WALL && ret == null) {
                int distCanTravel = getDistCanTravel(
                        getSelfPosition(board), board.getBounds(), directionToWall);
                if (distCanTravel == 0) mode = MODE_FOLLOWING_WALL;
                else ret = directionToWall;
                distToTravel = distCanTravel;

            }

            if (mode == MODE_FOLLOWING_WALL && ret == null) {
                int distCanTravel = 0;
                ret = directionToWall;
                while (distCanTravel == 0) {// keep turning left until we can get somewhere
                    ret = ret.leftTurn();
                    distCanTravel = getDistCanTravel(
                            getSelfPosition(board), board.getBounds(), ret);
                }

                distToTravel = distCanTravel;
            }
        }

        // once we have started we are on auto pilot (can't run after the before block)
        else if (trailLength == distToTravel || trailLength == (distToTravel + 1))
            ret = lastMove.leftTurn();

        if (ret == null)// if we don't have a move otherwise, we must be on our trail. ret same as last time
            ret = lastMove;

        lastTrailLength = trailLength;
        lastMove = ret;
        return ret;
    }

    int getClosestWall(ReadOnlyBoard board) {
        Point2D thisPos = getSelfPosition(board);
        return Lists.mutable.of(
                new Pair<>(WALL_NORTH, board.getBounds().getTop() - thisPos.getY()),
                new Pair<>(WALL_SOUTH, thisPos.getY()), 
                new Pair<>(WALL_EAST, board.getBounds().getRight() - thisPos.getX()),
                new Pair<>(WALL_WEST, thisPos.getX())
        ).min(Comparator.comparingInt(Pair::getValue)).getKey();
    }

    /**
     * This goes around some intended behavior in the controller to get the correct result. When a player goes outside
     * his territory the land under him is converted to a trail -- on the next step of the game. So a trail length may
     * be the count of the trail locations plus one. That is what this function calculates. Depends on the whole trail
     * being contained inside the view passed to it.
     * @return
     */
    int getTrailLength(ReadOnlyBoard board, MutableMap<Point2D, ReadOnlySplixPoint> view) {
        boolean isPlayerOutsideHome = !view.get(getSelfPosition(board)).getOwner().equals(getThisHidden());
        int trailLength = view.count(rop -> rop.getClaimer().equals(getThisHidden()));
        return trailLength + (isPlayerOutsideHome? 1 : 0);
    }

    /**
     * Calculate how far we can travel in the direction before we hit the wall.
     * @return
     */
    int getDistCanTravel(Point2D currPos, SquareRegion bounds, Direction direction) {
        for (int i = 1; i <= PREFERRED_LINE_DIST; i++) {
            if (!bounds.inBounds(currPos.move(direction.vector.getX()*i, direction.vector.getY()*i)))
                return i-1;
        }
        return PREFERRED_LINE_DIST;
    }

    /**
     * Get which direction needs to be traveled to reach the specified wall.
     * Requires that neither Direction nor the values of `WALL_...` change.
     * @param targetWall
     * @return
     */
    Direction getDirectionToWall(int targetWall) {
        return Direction.values()[targetWall-1];
    }
}

এটি সম্ভবত সবচেয়ে সহজ বট। এটি কেবল বোর্ডের প্রান্তটি সন্ধান করা, নিহত হওয়ার ঝুঁকি হ্রাস করতে নিজেই দ্বিগুণ হয়ে যাওয়া।


আপনি Eclipse সংগ্রহ ব্যবহার করেছেন তা দেখতে শীতল। ইসিতে একটি জুড়ি ইন্টারফেস রয়েছে। আপনি একটি জোড় উদাহরণ পেতে Tuples.pair () ব্যবহার করতে পারেন। জোড়ায় মান দুটি বা উভয়ই আদিম হলে একটি প্রিমিটিভআপস ক্লাসও রয়েছে।
ডোনাল্ড রাব

1

র্যান্ডম_বোট, ক্লোজার

এটি র‌্যান্ডমবট , তবে নামকরণের সম্মেলনে আমাকে আটকে থাকতে হয়েছিল এবং কিছু সমস্যা আমাকে হাইফেনটি ব্যবহার করতে বাধা দেয়, তাই রাজত্বকে আন্ডারস্কোর করে! make-moveFN প্রথম আইটেম হচ্ছে একটি গ্রাম শক্তি সমিতির ফেরৎ Directionআপনি স্থানান্তর করতে চান, এবং দ্বিতীয় হচ্ছে রাষ্ট্র যদি আপনি চান পরবর্তী বাঁক উপর আপনাকে ফেরত পাস করতে হবে। কোনও বাহ্যিক পরমাণু ব্যবহার করবেন না, যেহেতু এই কোডটি সমান্তরালভাবে একাধিক গেমগুলি চালাচ্ছে।

 random_bot.clj
 (ns random-bot
     (:import
      [com.jatkin.splixkoth.ppcg.game Direction]))

 (defn make-move [game board state]
       [(rand-nth [Direction/East
                   Direction/West
                   Direction/North
                   Direction/South])
        nil])

0

হান্টারবট, জাভা

HunterBot.java

import com.jatkin.splixkoth.ppcg.game.Direction;
import com.jatkin.splixkoth.ppcg.game.SplixPlayer;
import com.jatkin.splixkoth.ppcg.game.readonly.HiddenPlayer;
import com.jatkin.splixkoth.ppcg.game.readonly.ReadOnlyBoard;
import com.jatkin.splixkoth.ppcg.game.readonly.ReadOnlyGame;
import com.jatkin.splixkoth.ppcg.game.readonly.ReadOnlySplixPoint;
import com.nmerrill.kothcomm.game.maps.Point2D;
import org.eclipse.collections.api.map.MutableMap;
import org.eclipse.collections.api.set.ImmutableSet;
import org.eclipse.collections.impl.factory.Sets;

import java.util.Comparator;

/**
 * This bot looks for any trail points left behind by another player and sets that as his target. If the target ever
 * disappears, it will continue on in hopes that the player will return soon, or if another target appears, it will
 * go towards that one. Works best when the other player repeatedly goes in the same general direction.
 */
public class HunterBot extends SplixPlayer {

    private Point2D lastTarget;

    private Direction lastMove = Direction.East;

    @Override
    protected Direction makeMove(ReadOnlyGame game, ReadOnlyBoard board) {
        Point2D thisPos = getSelfPosition(board);
        MutableMap<Point2D, ReadOnlySplixPoint> global = board.getGlobal();
        MutableMap<Point2D, ReadOnlySplixPoint> targets = global.select((pt, rosp) ->
                !rosp.getClaimer().equals(getThisHidden()) 
                        && !rosp.getClaimer().equals(new HiddenPlayer(null)));

        if (targets.size() == 0 && lastTarget == null) {
            lastMove = lastMove.leftTurn();
            return lastMove;
        }

        Point2D target = null;
        if (targets.size() == 0) target = lastTarget;
        else target = targets.keysView().min(Comparator.comparingInt(thisPos::cartesianDistance));
        if (target.equals(thisPos)) {
            lastTarget = null;
            if (global.get(thisPos).getOwner().equals(getThisHidden())) {
                lastMove = lastMove.leftTurn();
                return lastMove;
            } else 
            // time to go home
            target = global.select((z_, x) -> getThisHidden().equals(x.getOwner())).keySet().iterator().next();

        }

        lastTarget = target;
        lastMove = makeSafeMove(target, global, board, thisPos);
        return lastMove;
    }

    private Direction makeSafeMove(Point2D targetLocation, MutableMap<Point2D, ReadOnlySplixPoint> map, ReadOnlyBoard board, Point2D currLoc) {
        Point2D dist = targetLocation.move(-currLoc.getX(), -currLoc.getY());
        ImmutableSet<Direction> possibleMoves = Sets.immutable.of(Direction.values())
                .select(x -> {
                    Point2D pos = currLoc.move(x.vector.getX(), x.vector.getY());
                    return !board.getBounds().outOfBounds(pos) && !getThisHidden().equals(map.get(pos).getClaimer());
                });
        Direction prefMove;
        if (Math.abs(dist.getX()) > Math.abs(dist.getY()))
            prefMove = getDirectionFroPoint(new Point2D(normalizeNum(dist.getX()), 0));
        else
            prefMove = getDirectionFroPoint(new Point2D(0, normalizeNum(dist.getY())));

        if (possibleMoves.contains(prefMove)) return prefMove;
        if (possibleMoves.contains(prefMove.leftTurn())) return prefMove.leftTurn();
        if (possibleMoves.contains(prefMove.rightTurn())) return prefMove.rightTurn();
        return prefMove.leftTurn().leftTurn();
    }

    private Direction getDirectionFroPoint(Point2D dir) {
        return Sets.immutable.of(Direction.values()).select(d -> d.vector.equals(dir)).getOnly();
    }

    private int normalizeNum(int n) { if (n < -1) return -1; if (n > 1) return 1; else return n;}

}

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

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