আমি কীভাবে কার্ড গেমের জন্য কার্ডগুলিকে সাফ করব?


13

আমি অ্যান্ড্রয়েডের জন্য একটি কার্ড গেম বিকাশের চেষ্টা করছি যে কেউ কীভাবে আমাকে কার্যকরভাবে প্লে কার্ডগুলি বদলানোর জন্য কোড লিখতে পরামর্শ দিতে পারেন?

উত্তর:


21

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

এখানে সরল ইংরেজিতে প্রাথমিক ধারণাটি দেওয়া হয়েছে:

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

আমরা ডেকের "অবস্থান" সম্পর্কে কথা বলতে যাচ্ছি, যেখানে "অবস্থান" হ'ল সেই অবস্থানের কার্ডের চেয়ে ডেকের মধ্যে কতগুলি কার্ড বেশি। উদাহরণস্বরূপ, ডেকের উপরের কার্ডটি 0 পজিশনে রয়েছে, নীচে কার্ডটি পজিশনে রয়েছে 1 (কারণ এটির তুলনায় 1 টি কার্ড বেশি রয়েছে - শীর্ষ কার্ড), এবং একটি স্ট্যান্ডার্ড 52-কার্ড ডেকের নীচে কার্ডটি 51 পজিশনে রয়েছে, কেননা ডেকের চেয়ে 51 টি কার্ড বেশি।

এখন, আমরা ডেকে প্রতিটি অবস্থান বিবেচনা করি, একবারে একবারে নীচ থেকে শুরু করে এবং শীর্ষে পৌঁছে যাওয়ার পথে কাজ করি।

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

যখন আমরা এলোমেলো নির্বাচন করি, আমরা কার্ডটি বর্তমানে যে অবস্থানটি আমরা এলোমেলোভাবে বাছাই করেছি তার সাথে আমরা বিবেচনা করছি at যদি আমরা এলোমেলোভাবে কার্ডটি নির্বাচন করে যা ইতিমধ্যে সেই অবস্থানে ছিল, তবে কোনও অদলবদল করা হয় না।

অদলবদল করার পরে (বা অদলবদল না করে, আমরা যদি এলোমেলোভাবে কার্ডটি বেছে নিয়েছিলাম যা ইতিমধ্যে আমরা বিবেচনা করছি এমন অবস্থানে ছিল), আমরা ডেকের পরবর্তী অবস্থানে চলেছি এবং চালিয়ে যাচ্ছি।

Pseudocode মধ্যে, সঙ্গে এন ডেক কার্ড সংখ্যা হচ্ছে, এবং একটি একটি অ্যারের ডেক, ভালো অ্যালগরিদম সৌন্দর্য প্রতিনিধিত্বমূলক হচ্ছে:

for each i in [n .. 1] do
     j  random integer in [ 0 .. i ]
     exchange a[j] and a[i]

1
অ্যালগরিদমটি এখানে খুব সুন্দরভাবে ভিজ্যুয়ালাইজড হয়েছে: bost.ocks.org/mike/algorithms/#shuffling
Felsir

9

আপনি প্রথমে যে সমস্ত কার্ডটি বদল করতে চান তার ক্রমটি নির্ধারণ করুন:

List<Card> shuffled = new ArrayList<Card>();
shuffled.addAll(allCards);

তারপরে আপনি ক্রমানুসারে প্রতিটি অবস্থানের মধ্য দিয়ে চলুন এবং এলোমেলোভাবে এটিকে একটি কার্ড নির্ধারণ করুন।

Random random = new Random();
for (int i = shuffled.size() - 1; i >= 0; i--) {
    int j = random.nextInt(i + 1);

    /* swap cards i,j */
    Card card = shuffled.get(i);
    shuffled.set(i, shuffled.get(j));
    shufflet.set(j, card);
}

এখন shuffledআপনার সমস্ত কার্ডের একটি এলোমেলো ক্রম।


3
: এই Knuth এর এলোমেলো হিসাবে পরিচিত হয় en.wikipedia.org/wiki/Knuth_shuffle
krolth

2

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

মূলত আপনার কাছে যা ছিল তা হ'ল একটি এনক্রিপশন অ্যালগরিদম যা 0 থেকে 51 এর মান এবং একটি কী (শ্যাফেল বীজ) নেয় এবং 0 থেকে 51 পর্যন্ত মান বের করে দেয় Since যেহেতু এনক্রিপশন সংজ্ঞা অনুসারে বিপরীত হয় যার অর্থ কোনও 2 ইনপুট সংখ্যা এতে এনক্রিপ্ট করতে পারে না একই আউটপুট নম্বর, যার অর্থ আপনি যদি 0 থেকে 51 এনক্রিপ্ট করেন তবে আপনি বিভিন্ন ক্রমে 0 থেকে 51 আউটপুট হিসাবে পেতে পারেন। অন্য কথায় আপনার আপনার এলোমেলো অবস্থা রয়েছে এবং এমনকি কোনও আসল শিফলিং করার দরকার নেই।

এই ক্ষেত্রে আপনাকে একটি এনক্রিপশন অ্যালগরিদম তৈরি করতে বা খুঁজে পেতে হবে যা 6 টি বিট নিয়েছিল এবং 6 টি বিট (0-63) থুথু ফেলবে। ডেক থেকে পরবর্তী কার্ডটি আঁকতে আপনার শূন্য থেকে শুরু হওয়া একটি সূচক ভেরিয়েবল থাকবে, আপনি সেই সূচীটি এনক্রিপ্ট করবেন, সূচকে বাড়িয়ে তুলবেন এবং সিফার থেকে বেরিয়ে আসা মানটি দেখুন। যদি মান> = 52 হয় তবে আপনি এটিকে এড়িয়ে যান এবং একটি নতুন সংখ্যা উত্পন্ন করেন (এবং অবশ্যই সূচকে আবার বৃদ্ধি করুন)। যেহেতু 0-63 এনক্রিপ্ট করার ফলে 0-63 ফলাফল আউটপুট হিসাবে দেখাবে, আপনি অন্য কোনও ক্রম হিসাবে বেরিয়ে আসছেন> = 52 যাতে আপনার নিজের অ্যালগরিদম থাকে যা 0-51 লাগে এবং 0-51 কে আলাদা করে দেয়।

ডেকে রদবদল করতে, সূচকটি শূন্যে ফিরে সেট করুন এবং এনক্রিপশন কী (শফল বীজ) পরিবর্তন করুন।

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

আরও বিস্তারিত তথ্য এবং উত্স কোডের জন্য আমার ব্লগ পোস্টটি দেখুন: http://blog.demofox.org/2013/07/06/ ব্রেকফাস্ট-light વજન-random-shuffle-functionality-fixed/


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

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

1

জাভা 1.5 enum টিউটোরিয়াল , ডেক তৈরী অদলবদল এবং তার আচরণ তাসের তাড়ার বাস্তবায়ন একটি আকর্ষণীয় উপায় রয়েছে। সমস্ত খুব enumএস ব্যবহার করে এবংCollections

public class Card {
    public enum Rank { DEUCE, THREE, FOUR, FIVE, SIX,
        SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING, ACE }

    public enum Suit { CLUBS, DIAMONDS, HEARTS, SPADES }

    private final Rank rank;
    private final Suit suit;
    private Card(Rank rank, Suit suit) {
        this.rank = rank;
        this.suit = suit;
    }

    public Rank rank() { return rank; }
    public Suit suit() { return suit; }
    public String toString() { return rank + " of " + suit; }

    private static final List<Card> protoDeck = new ArrayList<Card>();

    // Initialize prototype deck
    static {
        for (Suit suit : Suit.values())
            for (Rank rank : Rank.values())
                protoDeck.add(new Card(rank, suit));
    }

    public static ArrayList<Card> newDeck() {
        return new ArrayList<Card>(protoDeck); // Return copy of prototype deck
    }
}

এবং ডেক পরিচালনা করার জন্য ক্লাস।

public class Deal {
    public static void main(String args[]) {
        int numHands = Integer.parseInt(args[0]);
        int cardsPerHand = Integer.parseInt(args[1]);
        List<Card> deck  = Card.newDeck();
        Collections.shuffle(deck);
        for (int i=0; i < numHands; i++)
            System.out.println(deal(deck, cardsPerHand));
    }

    public static ArrayList<Card> deal(List<Card> deck, int n) {
         int deckSize = deck.size();
         List<Card> handView = deck.subList(deckSize-n, deckSize);
         ArrayList<Card> hand = new ArrayList<Card>(handView);
         handView.clear();
         return hand;
     }
}

0

পাইথনে সেখানে কেবল ইটারটোলের মতো কোনও ফাংশন ব্যবহার করুন। জাভা চেষ্টা "" তে একই ফাংশনটির নাম সম্পর্কে আমি অবগত নই " http://code.google.com/p/neoitertools/ "

"কার্ড" নামক বস্তুর সমস্ত ক্রিয়াকলাপ সন্ধান করুন


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