सिंपल पजाक (पुराने गणराज्य के शूरवीरों से स्टार वार्स कार्ड गेम)


11

Pazak स्टार वार्स ब्रह्मांड से एक कार्ड गेम है। यह ब्लैकजैक के समान है, जिसमें दो खिलाड़ी एक-दूसरे के खिलाफ खड़े होते हैं, जो बिना ओवर के कुल बीस तक पहुंचने की कोशिश करते हैं। प्रत्येक खिलाड़ी के पास अपने स्वयं के चार कार्डों का एक "साइड डेक" होता है जिसका उपयोग वे अपने स्कोर को संशोधित करने के लिए कर सकते हैं।

लीडरबोर्ड

6/17/2015 @ 16:40 EDT के रूप में

संपादित करें: धोखा देने के लिए नेप्टोर को अयोग्य ठहराया गया है। जल्द से जल्द तय होगा स्कोर ...

  1. NEPTR: ~ 424,000
  2. सिनसिनाटी बच्चे: ~ 422,000
  3. नेस्टर: ~ 408,000
  4. ऑस्टिन पॉवर्स: ~ 405,000
  5. बस्तिला: ~ 248,000
  6. गूंगा सावधान खिलाड़ी: ~ 107,000
  7. गूंगा बोल्ड प्लेयर: ~ 87,000

मॉक पजाक कप प्लेऑफ

जल्द से जल्द अपडेट किया जाएगा।

राउंड वन - नेस्टर बनाम बास्टिला और ऑस्टिन पॉवर्स बनाम द सिनसिनाटी किड

दौर 1 परिणाम

दो दौर - नेस्टर बनाम ऑस्टिन पॉवर्स और सिनसिनाटी बच्चे बनाम बस्तिला

2 राउंड परिणाम

यांत्रिकी

गेमप्ले टर्न में किया जाता है। प्लेयर एक को मुख्य (घर) डेक से एक कार्ड दिया जाता है। घर का डेक चालीस कार्ड रखता है: 10. के माध्यम से एक के चार प्रतियां। कार्ड निपटाए जाने के बाद, वे अपनी बारी को समाप्त करने के लिए चुन सकते हैं और अगले मोड़ पर एक नया कार्ड प्राप्त कर सकते हैं, अपने वर्तमान मूल्य पर खड़े हो सकते हैं, या अपने साइड डेक से एक कार्ड खेल सकते हैं। नए मूल्य पर खड़े हो जाओ। खिलाड़ी एक के बाद फैसला करता है कि वे क्या करना चाहते हैं, खिलाड़ी दो प्रक्रिया को दोहराता है।

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

बशर्ते जीतने की शर्त पूरी न हो, खेल दोहराए जाएंगे। यदि कोई खिलाड़ी अपनी बारी समाप्त करने के लिए चुना जाता है, तो उन्हें एक नया कार्ड प्राप्त होगा और एक नया विकल्प बना सकता है। यदि उन्होंने खड़े होने का विकल्प चुना, या यदि उन्होंने अपने साइड डेक से एक कार्ड खेला, तो उन्हें एक नया कार्ड नहीं दिया जाएगा और एक नई कार्रवाई नहीं चुन सकते।

जब तक एक खिलाड़ी गेम नहीं जीतता तब तक खेल इसी तरह जारी रहता है। खेल सर्वश्रेष्ठ-थ्री-आउट-ऑफ-द-पाँच सेटों में खेले जाते हैं।

"सरल" पजाक क्यों?

स्टार वॉर्स ब्रह्माण्ड में, पज़ाक में जुआ शामिल था। हालांकि इस तरह की प्रणाली को शामिल करने से खेल में एक गतिशील अधिक हो जाएगा, यह पहली बार कोएटीएच प्रतियोगिता के लिए थोड़ा जटिल है।

"रियल" पजाक साइड डेक भी खिलाड़ियों द्वारा स्वयं प्रदान किए गए थे, और इसमें कई अलग-अलग कार्ड विकल्प जैसे नकारात्मक कार्ड, पॉजिटिव-या-नेगेटिव कार्ड, फ्लिप कार्ड, डबल कार्ड और टाईब्रेकर कार्ड शामिल हो सकते हैं। ये खेल को और अधिक रोचक बनाते हैं, लेकिन इसके लिए एक जुए के इंटरफेस की आवश्यकता होती है, और इसके लिए प्रतियोगियों से कहीं अधिक की आवश्यकता होगी। इस सिंपल पजाक गेम में, प्रत्येक खिलाड़ी को एक ही साइड डेक मिलता है: एक की दो प्रतियां पांच के माध्यम से, जिसमें से चार को यादृच्छिक रूप से चुना जाता है।

इस खेल की सफलता के आधार पर, मैं एक उन्नत संस्करण विकसित करने का प्रयास कर सकता हूं जिसमें जुआ और कस्टम साइड डेक संभव हैं।

खिलाड़ियों

इस गेम के खिलाड़ी आपके द्वारा डिज़ाइन किए गए बॉट होंगे। प्रत्येक बॉट को प्लेयर क्लास का विस्तार करने, मैकेनिक्स पैकेज को आयात करने और खिलाड़ियों के पैकेज में निवास करने की आवश्यकता है जैसे:

package Players;

import java.util.Collection;

import Mechanics.*;

public class DemoPlayer extends Player {

    public DemoPlayer() {
        name = "Your Name Here";
    }

    public void getResponse(int wins[], boolean isPlayerOne,
            Collection<Card> yourHand, Collection<Card> opponentHand,
            Collection<Card> yourSideDeck, int opponentSideDeckCount,
            Action opponentAction, boolean opponentDidPlay) {
        action = null;
        cardToPlay = null;
    }
}

प्रत्येक राउंड, कंट्रोलर आपके बॉट के लिए गेटपर्सन विधि को कॉल करेगा, जब तक कि आपके बॉट ने पहले संकेत नहीं दिया था कि वह खड़ा होना चाहता था। GetResponse विधि दो गुण सेट कर सकती है: एक क्रिया और एक कार्ड खेलने के लिए। कार्रवाई निम्न में से एक हो सकती है:

  • END: मोड़ को समाप्त करता है और अगले मोड़ पर एक नया कार्ड बनाता है।
  • मानक: वर्तमान हाथ मूल्य पर स्थित है। कार्ड नहीं बनाएंगे।
  • प्ले: साइड डेक से एक कार्ड खेलता है और फिर खड़ा होता है।

यदि आप खेलने के लिए कार्रवाई सेट करते हैं तो खेलने के लिए कार्ड जाहिर है केवल महत्व का है। यह एक कार्ड वस्तु लेता है। यदि आपके द्वारा पास किया गया कार्ड ऑब्जेक्ट आपके साइड डेक में मौजूद नहीं है, तो आपका बॉट इसके बजाय स्टेंड होगा।

आपके बॉट को प्रत्येक मोड़ पर मिलने वाले पैरामीटर निम्न हैं:

  • एक सरणी जिसमें प्रत्येक खिलाड़ी की जीत होती है। जीत [0] प्लेयर 1 की है, जीतता है 1 खिलाड़ी 2 की है (int [])
  • आपका बॉट खिलाड़ी एक (बूलियन) है या नहीं
  • कार्डों का एक संग्रह जिसे आपने अब तक निपटाया है (संग्रह)
  • आपके प्रतिद्वंद्वी कार्डों का एक संग्रह इस प्रकार दूर किया गया है (संग्रह)
  • अपने पक्ष डेक में कार्ड का एक संग्रह (संग्रह)
  • आपके प्रतिद्वंद्वी के साइड डेक (इंट) में शेष कार्डों की संख्या
  • आपके प्रतिद्वंद्वी ने अंतिम रूप से जो कार्रवाई की (एक्शन) [नोट: यह या तो END या STAND होगी, कभी PLAY नहीं होगी]
  • आपके प्रतिद्वंद्वी ने कार्ड खेला है या नहीं (बुलियन)

बॉट नियम

आपके बॉट्स केवल उन सूचनाओं का उपयोग कर सकते हैं जो उन्हें getResponse विधि के माध्यम से दी गई हैं। उन्हें किसी अन्य वर्ग के साथ बातचीत करने का प्रयास नहीं करना चाहिए। वे राउंड के बीच डेटा को स्टोर करने के लिए एक फाइल में लिख सकते हैं। उनके पास इच्छानुसार कोई भी कस्टम विधि, गुण आदि हो सकते हैं। उन्हें उचित समय में चलना चाहिए (यदि प्रोग्राम रन व्यावहारिक रूप से तात्कालिक नहीं है, तो मैं नोटिस करूंगा कि कुछ गलत है)।

यदि आपको कोड में किसी प्रकार का शोषण दिखाई देता है, तो आपको "खुद को मोड़ने" के लिए पुरस्कृत किया जाएगा। अगर मैंने पहले शोषण को नोटिस किया, तो मैं इसे ठीक कर दूंगा, और आपको कोई इनाम नहीं मिलेगा।

क़ौम

बॉट लिखने के लिए नियंत्रक की आवश्यकता नहीं है, क्योंकि इस पोस्ट में सब कुछ पहले से ही समझाया गया है। हालाँकि, यदि आप परीक्षण करना चाहते हैं, तो यह यहाँ पाया जा सकता है: https://github.com/PhantomJedi759/simplepazaak दो बुनियादी बॉट शामिल हैं। न तो "बुद्धिमान" प्रतिद्वंद्वी के खिलाफ अच्छी तरह से पकड़ होना चाहिए, क्योंकि वे केवल END और STAND के बीच चयन करते हैं। यहाँ एक नमूना है कि वे क्या करते हैं:

New Game!
The standings are 0 to 0
Dumb Bold Player's Hand: []
Dumb Bold Player's new Hand: [2]
Dumb Bold Player has chosen to END
Dumb Cautious Player's Hand: []
Dumb Cautious Player's new Hand: [8]
Dumb Cautious Player has chosen to END
Dumb Bold Player's Hand: [2]
Dumb Bold Player's new Hand: [2, 8]
Dumb Bold Player has chosen to END
Dumb Cautious Player's Hand: [8]
Dumb Cautious Player's new Hand: [8, 3]
Dumb Cautious Player has chosen to END
Dumb Bold Player's Hand: [2, 8]
Dumb Bold Player's new Hand: [2, 8, 7]
Dumb Bold Player has chosen to END
Dumb Cautious Player's Hand: [8, 3]
Dumb Cautious Player's new Hand: [8, 3, 6]
Dumb Cautious Player has chosen to STAND
Dumb Bold Player's Hand: [2, 8, 7]
Dumb Bold Player's new Hand: [2, 8, 7, 6]
Dumb Bold Player has chosen to STAND
Dumb Cautious Player's Hand: [8, 3, 6]
Dumb Cautious Player has chosen to STAND
Dumb Bold Player has bombed out! Dumb Cautious Player wins!

क्योंकि ये बॉट पूरी तरह से ड्रॉ के भाग्य पर भरोसा करते हैं, इसलिए उनका जीत-हार अनुपात काफी भिन्न हो सकता है। यह देखना दिलचस्प होगा कि कौशल खेल के भाग्य का मुकाबला कैसे कर सकते हैं।

यह वह सब कुछ होना चाहिए जो आपको चाहिए! कुछ बॉट का निर्माण करें!

नियमों का स्पष्टीकरण

मुख्य डेक चालीस कार्ड है: 4x1-10 यह प्रत्येक हाथ की शुरुआत में फेरबदल किया जाता है।

एक खिलाड़ी के साइड डेक में चार कार्ड होते हैं, जिन्हें 2x1-5 से यादृच्छिक रूप से चुना जाता है। साइड डेक हाथों के बीच बनी रहती है।

हाथों को सर्वश्रेष्ठ तीन में से पांच के लिए खेल में खेला जाता है। जीते गए खेलों की कुल संख्या और फिर हाथों की कुल संख्या के आधार पर बॉट बनाए जाते हैं।

मैचिंग को संभाला जाता है ताकि प्रत्येक खिलाड़ी को हर दूसरे खिलाड़ी के खिलाफ 100,000 खेल खेलने पड़ें।

Pazaak कप में, उन्मूलन-शैली के दौर संकीर्ण हो जाएंगे जो वास्तव में सबसे अच्छा Pazaak बॉट है। बॉट्स की प्रत्येक जोड़ी 100,000 खेलों के सर्वश्रेष्ठ चार में से सात सेटों के लिए खेलेगी। जो कोई भी चार जीतेगा वह अगले प्रतिद्वंद्वी की ओर बढ़ेगा, और हारने वाले क्रमिक रैंकिंग की लड़ाई के लिए नीचे रहेंगे। गेमप्ले की यह शैली सबसे उचित है, क्योंकि बॉट दूसरों के खिलाफ क्षमता की कमी के लिए क्षतिपूर्ति करने के लिए कुछ विरोधियों को "जीत-फार्म" नहीं कर सकते हैं। पज़ाक कप शुक्रवार, 3 जुलाई को आयोजित किया जाएगा, बशर्ते कम से कम आठ प्रस्तुत बॉट हों। विजेता को सही उत्तर स्थिति और उन्नत पजाक में एक शुरुआती बोनस प्राप्त होगा, जो उम्मीद करता है कि वह उसी समय के करीब तैयार हो जाएगा जब पजाक कप आयोजित किया जाता है।


1
रेपो तक पहुँचने की कोशिश मुझे दु: खद रूप से क्रोम पर सुरक्षा चेतावनी देती है। यह वास्तव में एक मजेदार चुनौती की तरह लगता है जिसे मैं दर्ज करना पसंद करूंगा, लेकिन मैं प्रलेखन के बदले कुछ स्पष्टीकरण चाहूंगा। घर का डेक प्रत्येक दौर की शुरुआत में समान 40 कार्ड के साथ शुरू होता है, सही है? हमारा 4 कार्ड साइड डेक कोई भी कार्ड 1-10 हो सकता है और घर के डेक को प्रभावित नहीं करता है? दोनों हाथ getResponse के माध्यम से दिखाई दे रहे हैं? क्या हम जीत गए हाथों के # स्कोर पर जा रहे हैं, या 5 सर्वश्रेष्ठ प्रारूप की तरह गोल हैं? मूल रूप से, #Rescentonse में जीत के # कारण क्यों पारित किए गए हैं?
डॉक्टरहेकले

डेक को कब रीसेट किया जाता है? हर दौर के बाद या हर प्रतिद्वंद्वी के साथ?
इयुनजट

1
यह खिलाड़ी की जीत के लिए [1] होना चाहिए, जीत नहीं [2] के रूप में जीत सिर्फ एक सरणी लंबाई 2 है
euanjt

@DoctorHeckle रेपो के बारे में माफी; मेरा वर्तमान नेटवर्क जीथब को ब्लॉक करता है, लेकिन मैं इसे जल्द से जल्द पूरा करने की कोशिश करूंगा। डेक हर गेम को रीसेट करता है। साइड डेक में 2x1-5 के चार कार्ड हैं। एक बार वास्तविक प्रतियोगिता शुरू होने के बाद, आपको टूरनीज़ द्वारा स्कोर किया जाएगा जो पांच में से सर्वश्रेष्ठ हैं। जीत की संख्या getResponse विधि में पारित कर दी जाती है, जब आपका बॉट बदलना चाहता है, तो यह इस बात पर निर्भर करता है कि यह टूर्नामेंट जीत रहा है या हार रहा है या नहीं।
माइकल ब्रैंडन मॉरिस

1
मुझे नहीं पता कि क्या StackOverflow आपको जवाब देने के बाद सूचित करता है, लेकिन मेरे पास अभी सिनसिनाटी बच्चे का अपडेटेड संस्करण है।
राल्फ मार्शल

जवाबों:


5

सिनसिनाटी बच्चे

यह सुनिश्चित करने का प्रयास करें कि यदि हम जानते हैं कि हम हार रहे हैं, तो हम एक और कार्ड बनाते हैं, अन्यथा हमारे पक्ष डेक और समग्र स्कोर को देखें कि क्या करना है।

उन परिस्थितियों से निपटने का बेहतर काम करने के लिए अपडेट किया जाता है, जहां प्रतिद्वंद्वी ने पहले ही खेलना समाप्त कर लिया है। अपने स्वयं के परीक्षण में यह अब फिर से सबसे अच्छा उम्मीदवार लगता है, कम से कम अभी के लिए।

package Players;

import java.util.Collection;

import Mechanics.*;

public class CincinnatiKid extends Player {

    public CincinnatiKid() {
        name = "The Cincinnati Kid";
    }

    private static boolean isDebug = false;

    private static final int BEST_HAND = 20;

    public void getResponse(int wins[],
                            boolean isPlayerOne,
                            Collection<Card> yourHand,
                            Collection<Card> opponentHand,
                            Collection<Card> yourSideDeck,
                            int opponentSideDeckCount,
                            Action opponentAction,
                            boolean opponentDidPlay)
    {
        int myValue = handValue(yourHand);
        int oppValue = handValue(opponentHand);

        if (oppValue > BEST_HAND) {
            logMsg("Opponent has busted");
            action = Action.STAND;
        } else if (myValue > BEST_HAND) {
            logMsg("I have busted");
            action = Action.STAND;
        } else if (myValue <= 10) {
            logMsg("I cannot bust with my next move");
            action = Action.END;
        } else {
            handleTrickySituation(myValue, oppValue, wins, isPlayerOne, yourHand, opponentHand,
                                  yourSideDeck, opponentSideDeckCount, opponentAction, opponentDidPlay);
        }

        if (action == Action.PLAY && cardToPlay == null) {
            logMsg("ERROR - Action is Play but no card chosen");
        }
        logMsg("My hand value is " + myValue + ", opponent is " + oppValue + ", action is " + action +
               ((action == Action.PLAY && cardToPlay != null) ? " a " + cardToPlay.toString() : ""));
    }

    int [] branchCounts = new int[12];

    public void dumpBranchCounts() {
        if (isDebug) {
            for (int i = 0; i < branchCounts.length; i++) {
                System.out.print("b[" + i + "]=" + branchCounts[i] + " ");
            }
            System.out.println();
        }
    }

    private void handleTrickySituation(int myValue, int oppValue,
                                       int wins[],
                                       boolean isPlayerOne,
                                       Collection<Card> yourHand,
                                       Collection<Card> opponentHand,
                                       Collection<Card> yourSideDeck,
                                       int opponentSideDeckCount,
                                       Action opponentAction,
                                       boolean opponentDidPlay)
    {
        dumpBranchCounts();
        logMsg("I am might bust");

        int STAND_VALUE = 18;
        int chosenBranch = 0;

        Card bestSideCard = findSideCard(myValue, yourSideDeck);
        int valueWithSideCard = myValue + (bestSideCard != null ? bestSideCard.getValue() : 0);

        if (bestSideCard != null && valueWithSideCard >= oppValue && valueWithSideCard > STAND_VALUE) {
            logMsg("Found a good card in side deck");
            action = Action.PLAY;
            cardToPlay = bestSideCard;
            chosenBranch = 1;
        } else if (opponentDidPlay || opponentAction == Action.STAND) {
            logMsg("Opponent is done");
            // Opponent is done, so get another card if I'm behind
            if (myValue < oppValue) {
                logMsg("I am behind");
                if (bestSideCard != null && valueWithSideCard >= oppValue) {
                    logMsg("My best side card is good enough to tie or win");
                    action = Action.PLAY;
                    cardToPlay = bestSideCard;
                    chosenBranch = 2;
                } else {
                    logMsg("My best side card won't do so I'm going to hit");
                    // No side card and I'm losing, so I might as well hit
                    action = Action.END;
                    chosenBranch = 3;
                }
            } else if (myValue == oppValue) {
                logMsg("Game is tied");
                logMsg("Looking for lowest card in the side deck");
                cardToPlay = findWorstSideCard(myValue, yourSideDeck);
                if (cardToPlay != null) {
                    action = Action.PLAY;
                    chosenBranch = 4;
                } else {
                    logMsg("Tied with no side cards - accept the draw");
                    action = Action.STAND;
                    chosenBranch = 5;
                }
            } else {
                logMsg("I'm ahead and opponent has given up");
                action = Action.STAND;
                chosenBranch = 6;
            }
        } else if (myValue < oppValue) {
            logMsg("I am behind and have nothing good in my side deck");
            action = Action.END;
            chosenBranch = 7;
        } else if (oppValue <= 10 && myValue < STAND_VALUE) {
            logMsg("Opponent is guaranteed to hit and I have a low hand, so take another");
            action = Action.END;
            chosenBranch = 8;
        } else if (myValue == oppValue && myValue >= STAND_VALUE) {
            logMsg("We both have equally good hands - stand and hope for the tie");
            action = Action.STAND;
            chosenBranch = 9;
        } else if (myValue < STAND_VALUE) {
            logMsg("I am ahead but have a low score");
            action = Action.END;
            chosenBranch = 10;
        } else {
            logMsg("I am ahead with a decent score");
            action = Action.STAND;
            chosenBranch = 11;
        }

        branchCounts[chosenBranch]++;
    }

    private double calcBustOdds(int valueSoFar, Collection<Card> myHand, Collection<Card> oppHand) {

        if (valueSoFar >= BEST_HAND) {
            return 1;
        }

        int remainingDeck = 40 - (myHand.size() + oppHand.size());
        int [] cardCounts = new int[10];
        int firstBust = BEST_HAND - valueSoFar;

        for (int i = 0; i < 10; i++) {
            cardCounts[i] = 4;
        }

        for (Card c : myHand) {
            cardCounts[c.getValue()-1]--;
        }

        for (Card c : oppHand) {
            cardCounts[c.getValue()-1]--;
        }

        int bustCards = 0;
        for (int i = firstBust; i < 10; i++) {
            logMsg("cardCounts[" + i + "]=" + cardCounts[i]);
            bustCards += cardCounts[i];
        }

        double retval = (double) bustCards / (double) remainingDeck;
        logMsg("Out of " + remainingDeck + " remaining cards " + bustCards + " will bust, or " + retval);
        return retval;
    }

    private Card findSideCard(int myValue, Collection<Card> sideDeck) {
        int valueNeeded = BEST_HAND - myValue;
        Card bestCard = null;
        if (valueNeeded > 0) {
            for (Card c : sideDeck) {
                if (c.getValue() == valueNeeded) {
                    return c;
                } else if (c.getValue() < valueNeeded) {
                    if (bestCard == null || c.getValue() > bestCard.getValue()) {
                        bestCard = c;
                    }
                }
            }
        }

        return bestCard;
    }

    private Card findWorstSideCard(int myValue, Collection<Card> sideDeck) {
        int valueNeeded = BEST_HAND - myValue;

        logMsg("Searching side deck for something with value <= " + valueNeeded);
        Card bestCard = null;

        for (Card c : sideDeck) {
            logMsg("Examining side card " + c.getValue());

            // Find the worst card in the deck, but not if it exceeds the amount left
            if (c.getValue() <= valueNeeded && (bestCard == null || c.getValue() < bestCard.getValue())) {
                logMsg("This is the new best side card");
                bestCard = c;
            }
        }

        logMsg("Worst side card found is " + (bestCard != null ? bestCard.getValue() : " n/a"));
        return bestCard;
    }

    private void logMsg(String s) {
        if (isDebug) {
            System.out.println("### " + s);
        }
    }

    private int handValue(Collection<Card> hand)  {
        int handValue = 0;
        for (Card c : hand) {
            handValue += c.getValue();
        }
        return handValue;
    }
}

बधाई हो! आप लीड में हैं।
माइकल ब्रैंडन मॉरिस

स्कोरिंग प्रणाली को अधिक निष्पक्ष बनाने के लिए संशोधनों के साथ, अब आप ऑस्टिन पॉवर्स के साथ पहली बार बंधे हैं।
माइकल ब्रैंडन मॉरिस

4

ऑस्टिन पॉवर्स

ऑस्टिन पॉवर्स, जैसा कि आप अनुमान लगा सकते हैं, खतरनाक तरीके से जीना पसंद करते हैं। जब तक किसी ने पर्दाफाश नहीं किया है, या वह एक जीत की गारंटी दे सकता है, वह हमेशा हिट होगा यदि वह पीछे है, या बस्ट न करने का 20% मौका है।

package Players;
import java.util.Collection;

import Mechanics.*;

public class AustinPowers extends Player {
    public AustinPowers() {
        name = "Austin Powers";
    }
    int MAX_VALUE = 20;
    public void getResponse(int wins[], boolean isPlayerOne,
            Collection<Card> yourHand, Collection<Card> opponentHand,
            Collection<Card> yourSideDeck, int opponentSideDeckCount,
            Action opponentAction, boolean opponentDidPlay) {
        action = null;
        cardToPlay = null;
        int myWins = isPlayerOne?wins[0]:wins[1];
        int oppWins = isPlayerOne?wins[1]:wins[0];
        int oppTotal = calcHand(opponentHand);
        int myTotal = calcHand(yourHand);
        boolean liveDangerously = ((oppTotal>=myTotal && opponentAction==Action.STAND) || opponentAction==Action.END) && myTotal<MAX_VALUE && canNotBust(yourHand,opponentHand,myTotal) && myWins<oppWins;

        if(myTotal==MAX_VALUE || oppTotal>MAX_VALUE || myTotal>MAX_VALUE ||(oppTotal<myTotal&&opponentAction==Action.STAND))
        {
            action = Action.STAND;
        }
        else if((opponentAction==Action.STAND&&hasGoodEnoughSideCard(yourSideDeck,myTotal,oppTotal))||hasPerfectSideCard(yourSideDeck, myTotal))
        {
            action = Action.PLAY;
        }
        else if(liveDangerously||betterThan20(myTotal, getDeck(yourHand, opponentHand)))
        {
            action = Action.END;
        }
        else
        {
            action=Action.STAND;
        }

    }

    private boolean hasGoodEnoughSideCard(Collection<Card> yourSideDeck,
            int myTotal, int oppTotal) {
        for(Card c: yourSideDeck)
        {
            if(MAX_VALUE>=myTotal+c.getValue()&&myTotal+c.getValue()>oppTotal)
            {
                cardToPlay=c;
                return true;
            }
        }
        return false;
    }

    private boolean betterThan20(int myTotal, int[] deck) {
        int deckSize=0;
        int nonBustCards=0;
        for(int i=0;i<10;i++)
        {
            deckSize+=deck[i];
            if(MAX_VALUE-myTotal>i)
                nonBustCards+=deck[i];
        }
        return (double)nonBustCards/(double)deckSize>0.2;
    }

    private boolean hasPerfectSideCard(Collection<Card> yourSideDeck,
            int myTotal) {
        for(Card c:yourSideDeck)
        {
            if(MAX_VALUE-myTotal== c.getValue())
            {
                cardToPlay = c;
                return true;
            }
        }
        return false;
    }

    private boolean canNotBust(Collection<Card> yourHand,
            Collection<Card> opponentHand, int myTotal) {
        if(myTotal<=10) return true;
        int[] deck = getDeck(yourHand, opponentHand);
        for(int i=0;i<MAX_VALUE-myTotal;i++)
            if(deck[i]>0)
                return true;
        return false;
    }

    private int[] getDeck(Collection<Card> yourHand,
            Collection<Card> opponentHand) {
        int[] deck = new int[10];
        for (int i = 0; i < 10; i++) {
            deck[i] = 4;
        }
        for(Card c:yourHand){deck[c.getValue()-1]--;}
        for(Card c:opponentHand){deck[c.getValue()-1]--;}
        return deck;
    }

    private int calcHand(Collection<Card> hand)
    {
        int ret = 0;
        for(Card c: hand){ret+=c.getValue();}
        return ret;
    }
}

बधाई हो! आपने CincinnatiKid से लीड ले ली है।
माइकल ब्रैंडन मॉरिस

स्कोरिंग प्रणाली को अधिक निष्पक्ष बनाने के लिए संशोधनों के साथ, अब आप पहले सिनसिनाटी बच्चे के साथ बंधे हैं।
माइकल ब्रैंडन मॉरिस

2

Bastila

बस्तिला रूढ़िवादी रूप से खेलती है। उसके लिए, एक 17 एक 20 के रूप में अच्छा है, और बम से बाहर खड़े होने के लिए बेहतर है।

package Players;

import java.util.Collection;

import Mechanics.*;

public class Bastila extends Player {

    public Bastila() {
        name = "Bastila";
    }

    public void getResponse(int wins[], boolean isPlayerOne,
            Collection<Card> myHand, Collection<Card> opponentHand,
            Collection<Card> mySideDeck, int opponentSideDeckCount,
            Action opponentAction, boolean opponentDidPlay) {


        action = null;
        cardToPlay = null;

        //Constants
        int stand = 17;
        int conservatism = 2;

        //Get some info
        int handVal = handValue(myHand);
        int expected = expectedValue(myHand);

        //Can I play from my side deck?
        for(Card side: mySideDeck){
            int total = side.getValue() + handVal;
            if(total >= stand && total <= 20){
                cardToPlay = side;
                action = Player.Action.PLAY;
            }
        }
        if(action == Player.Action.PLAY){
            return;
        }

        //Otherwise, will I go bust?
        if(handVal + expected > 20 - conservatism){
            action = Player.Action.STAND;
        }
        else{
            action = Player.Action.END;
        }

        return;

    }

    private int handValue(Collection<Card> hand) {
        int handValue = 0;
        for(Card c : hand){
            handValue += c.getValue();
        }
        return handValue;
    }

    private int expectedValue(Collection<Card> hand){
        //Net value of the deck is 55*4 = 220
        int total = 220;
        int count = 40;
        for(Card c : hand){
            total -= c.getValue();
            count--;
        }
        return total/count;
    }

}

बस्तिला वर्तमान में डम्ब बोल्ड प्लेयर और डंब कॉयूटियस प्लेयर (डेमो बॉट्स) दोनों से बेहतर प्रदर्शन कर रही है। बहुत बढ़िया! संपादित करें: दस रनों में से, बास्टिला ने आठ जीते, एक बार डंब सावधानी खिलाड़ी से हार गए, और एक बार डंब कैटरिंग खिलाड़ी के साथ बंध गए।
माइकल ब्रैंडन मॉरिस

अद्यतन: नई स्कोरिंग प्रणाली के साथ (टूमनी द्वारा गिना जाता है, जिनमें से प्रत्येक खिलाड़ी जोड़ी के साथ 1000 खेला जाता है), बस्तिला 1705/3000 कुल (1705/2000 टूरनीज़ खेला) के साथ होता है। इसके बाद 729 के साथ डंब काऊटियस प्लेयर है, और अंत में 566 के साथ डंब बोल्ड प्लेयर है।
माइकल ब्रैंडन मॉरिस

Haha अच्छी तरह से मुझे उम्मीद है कि यह कम से कम डेमो बॉट्स को हरा देगा: P
कैन

2

नेस्टर

नेस्टर को अपने साइड डेक का उपयोग करके 20 से प्यार करना पसंद है, लेकिन जब वह असफल हो जाता है तो वह स्टैंड या एंड को चुनकर अपने अपेक्षित भुगतान की गणना करता है, यह मानते हुए कि प्रतिद्वंद्वी समझदार है।

package Players;

import java.util.Arrays;
import java.util.Collection;


import Mechanics.Card;
import Mechanics.Player;

public class Nestor extends Player {
    final int TotalWinPayoff = 10;
    final int TotalLosePayoff = 0;
    final int TotalDrawPayoff = 1;
    final int temporaryLosePayoff = 4;
    final int temporayWinPayoff = 19;
    final int temporaryDrawPayoff = 9;
    @Override
    public void getResponse(int[] wins, boolean isPlayerOne,
            Collection<Card> yourHand, Collection<Card> opponentHand,
            Collection<Card> yourSideDeck, int opponentSideDeckCount,
            Action opponentAction, boolean opponentDidPlay) {

        int sumMyHand = SumHand(yourHand);
        int sumOpponentHand = SumHand(opponentHand);
    if (sumOpponentHand>20)
    {this.action = Action.STAND;return;}
        if(sumMyHand == 20)
        {
            //I'm unbeatable :)
            //System.out.println("\tI'm Unbeatable");
            this.action = Action.STAND;
            return;
        }
        else if(opponentDidPlay || opponentAction == Action.STAND)
        {
            //They've finished
            ///System.out.println("\tThey've Finished");
            if(sumMyHand>sumOpponentHand)
            {
                //I've won
                //System.out.println("\tI've Won");
                this.action = Action.STAND;
                return;
            }
            else if(canBeat(sumMyHand, sumOpponentHand, yourSideDeck))
            {
                //I can beat them
                //System.out.println("\tI can beat them");
                this.action = Action.PLAY;
                return;
            }
            else if(canEven(sumMyHand, sumOpponentHand, yourSideDeck))
            {
                //I can draw with them
                //System.out.println("\tI can draw with them");
                this.action = Action.PLAY;
                return;
            }
            else
            {
                //I need another card
                //System.out.println("\tI need another card");
                this.action = Action.END;
                return;
            }
        }
        else if(deckContains(yourSideDeck, 20-sumMyHand))
        {
            //Let's get 20
            //System.out.println("\tLet's get 20");
            this.action = Action.PLAY;
            this.cardToPlay = getCard(yourSideDeck, 20-sumMyHand);
            return;
        }
        else if(sumOpponentHand==20 && sumMyHand<20)
        {
            //They've got 20 so we need to fight for a draw
            //System.out.println("\tFight for a draw");
            this.action = Action.END;
            return;
        }

        else if(sumMyHand<10)
        {
            //Lets get another card
            //System.out.println("\tLet's get another card");
            this.action = Action.END;
            return;
        }
        else
        {
            //Let's work out some probabilities
            //System.out.println("\tLet's work out some probabilities");
            int[] cardsLeft = {4,4,4,4,4,4,4,4,4,4};
            for (Card card : opponentHand) {
                cardsLeft[card.getValue()-1] --;

            }
            for (Card card : yourHand) {
                cardsLeft[card.getValue()-1] --;

            }

             int numCardsLeft = sumfromToEnd(0, cardsLeft);

             //My Assumptions
             double probabilityTheyStand = (double)sumfromToEnd(20-sumOpponentHand, cardsLeft)/numCardsLeft;

             //What I need to know
             double payoffStanding = 0;
             double payoffDrawing = 0;


             for(int myChoice = -1; myChoice<10; myChoice++)
             {
                 for(int theirChoice = -1; theirChoice<10; theirChoice++)
                 {
                     if(myChoice == -1)
                     {
                         payoffStanding += getProbability(myChoice, theirChoice, Arrays.copyOf(cardsLeft, cardsLeft.length), probabilityTheyStand, numCardsLeft) * getPayoff(sumMyHand, sumOpponentHand,myChoice, theirChoice, TotalWinPayoff, TotalDrawPayoff, TotalLosePayoff);
                     }
                     else
                     {
                         payoffDrawing +=
                                 getProbability(myChoice, theirChoice, Arrays.copyOf(cardsLeft, cardsLeft.length), probabilityTheyStand, numCardsLeft)
                                 * getPayoff(sumMyHand, sumOpponentHand, myChoice, theirChoice, temporayWinPayoff, temporaryDrawPayoff, temporaryLosePayoff);
                     }
                 }
             }
            // System.out.println("\tStanding: " +Double.toString(payoffStanding) + " Ending: " + Double.toString(payoffDrawing));
             if(payoffStanding<payoffDrawing)
             {
                 this.action = Action.END;
             }
             else
             {
                 this.action = Action.STAND;
             }
        }


    }



    private int getPayoff(int sumMyHand, int sumOpponentHand, int myChoice,
            int theirChoice, int WinPayoff, int DrawPayoff,
            int LosePayoff) {
            if(sumMyHand + myChoice + 1 > 20)
            {
                if(sumOpponentHand + theirChoice + 1 > 20)
                {
                    return DrawPayoff;
                }
                else
                {
                    return LosePayoff;
                }
            }
            else if(sumMyHand + myChoice + 1 > sumOpponentHand + theirChoice + 1)
            {
                return WinPayoff;
            }
            else if (sumMyHand + myChoice + 1 < sumOpponentHand + theirChoice + 1)
            {
                return LosePayoff;
            }
            else
            {
                return DrawPayoff;
            }


    }



    private double getProbability(
            int myChoice, int theirChoice, int[] cardsLeft,
            double probabilityTheyStand, int numCardsLeft) {
        double myProb, theirProb;
        if(myChoice<0)
        {
            myProb = 1;
        }
        else
        {
            myProb = ((double)cardsLeft[myChoice])/((double)numCardsLeft);
            cardsLeft[myChoice]--;
            numCardsLeft--;
        }

        if(theirChoice<0)
        {
            theirProb = probabilityTheyStand;
        }
        else
        {
            theirProb = ((double)cardsLeft[theirChoice]) / ((double)numCardsLeft);
        }
        return myProb*theirProb;
    }





    private int sumfromToEnd(int i, int[] cardsLeft) {
        int toRet = 0;
        for(;i<cardsLeft.length; i++)
        {
            toRet += cardsLeft[i];
        }
        return toRet;
    }

    private boolean canEven(int mySum, int opponentSum,
            Collection<Card> yourSideDeck) {
        for (Card card : yourSideDeck) {
            if(mySum + card.getValue() <= 20 && mySum + card.getValue() >= opponentSum)
            {
                this.cardToPlay = card;
                return true;
            }
        }
        return false;
    }

    private boolean canBeat(int mySum, int opponentSum,
            Collection<Card> yourSideDeck) {
        for (Card card : yourSideDeck) {
            if(mySum + card.getValue() <= 20 && mySum + card.getValue() > opponentSum)
            {
                this.cardToPlay = card;
                return true;
            }
        }
        return false;
    }

    private Card getCard(Collection<Card> deck, int value) {
        for (Card card : deck) {
            if(card.getValue() == value)
            {
                return card;
            }
        }
        return null;
    }

    private boolean deckContains(Collection<Card> deck, int value) {
        for (Card card : deck) {
            if(card.getValue() == value)
            {
                return true;
            }
        }
        return false;
    }

    public Nestor()
    {
        super();
        name = "Nestor";
    }

    private int SumHand(Collection<Card> hand)
    {
        int toRet = 0;
        for (Card card : hand) {
            toRet += card.getValue();
        }
        return toRet;
    }
}

बधाई हो! आप ऑस्टिन पॉवर्स और द सिनसिनाटी बच्चे के बीच टाई के माध्यम से पहले स्थान पर ले गए।
माइकल ब्रैंडन मॉरिस

थ्रेड में मुख्य "java.lang.ArrayIndexOutOfBoundsException: -2 पर प्लेयर्स। Nestor.sumfromToEnd (Nestor.java:210) प्लेयर्स पर। N.Noror.getResponse (Nestor.java:105) यांत्रिकी। PazakGameMain.play.ain। : 112) मेकेनिक्स में। फ़ैज़ाकगामेनमेन। मेन (पाज़ाकगैमेन.जावा:40)
माइकल ब्रैंडन मॉरिस

क्या आप मुझे उस पर ध्यान देने में मदद करेंगे? यह बॉट-विशिष्ट प्रतीत होता है, क्योंकि यह केवल नेप्टोर और टी 3 एम 4 (जीबूटी पर अप्रबंधित बॉट) को चलाने पर ट्रिगर होता है।
माइकल ब्रैंडन मॉरिस

मैं जो बता सकता हूं उससे यह निकलता है कि क्या आपके प्रतिद्वंद्वी का भंडाफोड़ हुआ है, लेकिन किसी कारण से वे खड़े नहीं हुए। मैं आपके बॉट में एक अस्थायी फिक्स लगा रहा हूं, लेकिन बाद में स्वचालित रूप से स्टेंड बॉट्स को बस्ट को कंट्रोल करेगा।
माइकल ब्रैंडन मॉरिस

मैंने एक चेक जोड़ा है जब प्रतिद्वंद्वी का भंडाफोड़ हुआ है, धन्यवाद
euanjt

1

Glaucus

package Players;


import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;

import Mechanics.Card;
import Mechanics.Player;

public class Glaucus extends Player {
    static final double LosePay = 0;
    static final double WinPay = 10;
    static final double DrawPay = 1;
    static final int NUMBEROFSIMS = 100;

    Random r;

    public Glaucus()
    {
        this.name = "Glaucus";
        r = new Random();
    }

    @Override
    public void getResponse(int[] wins, boolean isPlayerOne,
            Collection<Card> yourHand, Collection<Card> opponentHand,
            Collection<Card> yourSideDeck, int opponentSideDeckCount,
            Action opponentAction, boolean opponentDidPlay) {
        //Make Sum of hands
        int sumMyHand = 0;
        int sumOpponentHand = 0;
        //Make an array of the remaining cards
        List<Integer> cards = new LinkedList<Integer>();
        int[] cardsLeft = {4,4,4,4,4,4,4,4,4,4};
        for (Card card : yourHand) {
            cardsLeft[card.getValue()-1] -= 1;
            sumMyHand+=card.getValue();
        }
        for (Card card : opponentHand) {
            cardsLeft[card.getValue()-1] -= 1;
            sumOpponentHand += card.getValue();
        }
        if(sumMyHand<=10)
        {
            this.action = Action.END;
        }
        else if (sumMyHand >= 20)
        {
            this.action = Action.STAND;
        }
        else if (sumOpponentHand > 20)
        {
            this.action = Action.STAND;
        }
        else
        {
            for (int i = 0; i < cardsLeft.length; i++) {
                while(cardsLeft[i] > 0)
                {
                    cards.add(i + 1);
                    cardsLeft[i] -= 1;
                }
            }
            //System.out.println(Arrays.toString(cards));

            double standPayoff = 0;
            double endPayoff = 0;
            double[] sideDeckPayoffs = new double[yourSideDeck.size()];
            //Run some simulations
            for(int sim = 0; sim<NUMBEROFSIMS; sim++)
            {
                Collections.shuffle(cards, r);
                standPayoff += getPayoff(sumMyHand, sumOpponentHand, cards, Action.STAND, opponentAction, false, 0);
                endPayoff += getPayoff(sumMyHand, sumOpponentHand, cards, Action.END, opponentAction, false, 0);
                for(int i = 0; i<sideDeckPayoffs.length; i++)
                {
                    sideDeckPayoffs[i] += getPayoff(sumMyHand+((Card)yourSideDeck.toArray()[i]).getValue(), sumOpponentHand, cards, Action.STAND, opponentAction, false, 0);
                }

            }

            double maxSidePay = 0;
            int sideDeckChoice  = 0;
            for (int i = 0; i < sideDeckPayoffs.length; i++) {
                double d = sideDeckPayoffs[i];
                if(d>maxSidePay)
                {
                    maxSidePay = d;
                    sideDeckChoice = i;
                }
            }
            /*System.out.println(standPayoff);
            System.out.println(endPayoff);
            System.out.println(maxSidePay);*/

            if(maxSidePay>standPayoff && maxSidePay>endPayoff)
            {
                this.action = Action.PLAY;
                this.cardToPlay = (Card)yourSideDeck.toArray()[sideDeckChoice];
            }
            else if(standPayoff > endPayoff)
            {
                this.action = Action.STAND;
            }
            else
            {
                this.action = Action.END;
            }
        }
    }

    private double getPayoff(int sumMyHand, int sumOpponentHand,
            List<Integer> cards, Action myAction, Action opponentAction, boolean myTurn, int index) {
        //SHort circuit some logic
        if(sumMyHand>20 && sumOpponentHand>20)
        {
            return DrawPay;
        }
        else if(sumMyHand>20)
        {
            return LosePay;
        }
        else if(sumOpponentHand>20)
        {
            return WinPay;
        }
        else if(myAction == Action.STAND && opponentAction == Action.STAND)
        {
            if(sumMyHand>sumOpponentHand)
            {
                return WinPay;
            }
            else if(sumMyHand<sumOpponentHand)
            {
                return LosePay;
            }
            else
            {
                return DrawPay;
            }
        }
        else
        {
            double standPayoff = 0;
            double endPayoff = 0;

            if(myTurn)
            {
                if(opponentAction == Action.END)
                {
                    sumOpponentHand += cards.get(index);
                    index++;
                }
                if(myAction == Action.STAND)
                {

                    return getPayoff(sumMyHand, sumOpponentHand, cards, myAction, opponentAction, false, index);
                }
                else
                {

                    standPayoff = getPayoff(sumMyHand, sumOpponentHand, cards, Action.STAND, opponentAction, false, index);
                    endPayoff = getPayoff(sumMyHand, sumOpponentHand, cards, Action.END, opponentAction, false, index);
                    if(standPayoff>endPayoff)
                    {
                        return standPayoff;
                    }
                    else
                    {
                        return endPayoff;
                    }
                }
            }
            else
            {
                if(myAction == Action.END)
                {
                    sumMyHand += cards.get(index);
                    index++;
                }
                if(opponentAction == Action.STAND)
                {
                    return getPayoff(sumMyHand, sumOpponentHand, cards, myAction, opponentAction, true, index);
                }
                else
                {
                    standPayoff = getPayoff(sumMyHand, sumOpponentHand, cards, myAction, Action.STAND, true, index);
                    endPayoff = getPayoff(sumMyHand, sumOpponentHand, cards, myAction, Action.END, true, index);
                    if(standPayoff<endPayoff)
                    {
                        return standPayoff;
                    }
                    else
                    {
                        return endPayoff;
                    }
                }
            }
        }
    }
}

Glaucus कार्ड की एक फेरबदल सूची के साथ 100 सिमुलेशन बनाता है और इन सिमुलेशन के आधार पर अपना सर्वश्रेष्ठ विकल्प चुनता है।


अगर आप सिमुलेशन की संख्या में कटौती कर सकते हैं, तो मैं सराहना करूँगा। एक प्रतिद्वंद्वी के खिलाफ एक रन खत्म करने में एक मिनट का समय लग रहा है, और अन्य सभी बॉट्स के खिलाफ, हमारे रन समय को 7 मिनट से अधिक है, जबकि अन्य बॉट्स के साथ 30 सेकंड का विरोध किया गया है।
माइकल ब्रैंडन मॉरिस

बस जब तक यह उचित मात्रा में नहीं हो जाता है तब तक लगातार NUMBEROFSIMS बदलें, मेरे कंप्यूटर पर यह 100 सिम्स का तेज़ी से प्रबंधन करता है, यही कारण है कि मैंने उस मूल्य को चुना है, लेकिन इसे बदलने के लिए स्वतंत्र महसूस करता
हूं

यह मेरे डेस्कटॉप (i7-3770K) पर तेज हो सकता है, लेकिन मेरा लैपटॉप (i5-4300U) (जो मैं एक हफ्ते से अटका हुआ हूं) धीमा है। जब मैं अपने डेस्कटॉप पर वापस आऊंगा तो मैं ग्लूकोस को वापस रखूंगा।
माइकल ब्रैंडन मॉरिस

मैं कल इसे गति देने की कोशिश करूंगा और एक निश्चित संख्या में सिम के बजाय एक निर्धारित समय के लिए सिम चलाऊंगा - कब तक प्रति मोड़ स्वीकार्य है?
इयुनजट

सिमुलेशन चलाने के बजाय, हाइपरमेट्रिक वितरण के साथ सीधे संभावनाओं का अनुमान क्यों नहीं लगाया जाता है?
निष्क्रियता

1

एच -47

देखो! मेरे अपने डिजाइन का एक बॉट। HK-47 सभी मीटबैग्स को मारने की कोशिश करता है, हालांकि वह अपने साइड डेक कार्ड्स के साथ थोड़ा ट्रिगर-खुश है।

कथन: वास्तव में, मैं कुछ अनधिकृत हिंसा में संलग्न होने के लिए सबसे अधिक उत्सुक हूं। अपने आदेश में, मास्टर। - एचके -47

अब तक, वह सभी को हरा सकता है लेकिन द सिनसिनाटी किड।

package Players;

import java.util.Collection;

import Mechanics.*;

public class HK47 extends Player {

    /** The hand goal. */
    private static final int GOAL = 20;
    /** The cutoff for standing versus ending. */
    private static final int STAND_CUTOFF = 17;
    /** The minimum value for playing. */
    private static final int PLAY_MINIMUM = 14;
    /** The cutoff for ending versus decision evaluation. */
    private static final int SAFETY_CUTOFF = 10;

    /** The hand wins for this game. Used to evaluate win priority. */
    private int[] handWins;
    /**
     * My hand, as an unmodifiable collection. Used to evaluate decisions, after
     * being processed into myHandValue.
     */
    private Collection<Card> myHand;
    /**
     * Opponent's hand. Used to evaluate decisions as a secondary factor to my
     * hand, after being processed into oppHandValue.
     */
    private Collection<Card> oppHand;
    /** The value of my hand. Calculated via the myHandValue method. */
    private int myHandValue;
    /** The value of my opponent's hand. Calculated via the oppHandValue method. */
    private int oppHandValue;
    /** My side deck. Used to evaluate PLAY decisions. */
    private Collection<Card> mySideDeck;
    /**
     * The number of cards in my opponent's side deck. Used to evaluate PLAY
     * decisions as a secondary factor to mySideDeck, alongside win priority.
     */
    private int oppSideDeckCount;
    /**
     * The Action the opponent last took. Will either be STAND or END. Used to
     * evaluate decisions.
     */
    private Action oppAction;
    /** Whether or not I am player one. Used to evaluate wins and losses. */
    private boolean amPlayerOne;
    /**
     * The number of wins I have so far this game. Used to evaluate win priority
     * alongside myLosses.
     */
    private int myWins;
    /**
     * The number of losses I have so far this game. Used to evaluate win
     * priority alongside myWins.
     */
    private int myLosses;
    /**
     * How important it is for me to play. Positive values indicate an excess of
     * cards, and negative values indicate a deficit.
     */
    private int playPriority;
    /**
     * How important it is for me to win. Positive values indicate that I must
     * win the game, and negative values indicate that I can take some chances.
     */
    private int winPriority;
    /**
     * The sum of playPriority and winPriority. The higher the value, the fewer
     * chances I need to take.
     */
    private int priority;

    public HK47() {
        name = "HK47";
    }

    @Override
    public void getResponse(int[] wins, boolean isPlayerOne,
            Collection<Card> yourHand, Collection<Card> opponentHand,
            Collection<Card> yourSideDeck, int opponentSideDeckCount,
            Action opponentAction, boolean opponentDidPlay) {
        handWins = wins;
        amPlayerOne = isPlayerOne;
        myHand = yourHand;
        oppHand = opponentHand;
        mySideDeck = yourSideDeck;
        oppSideDeckCount = opponentSideDeckCount;
        oppAction = opponentAction;
        myHandValue = myHandValue();
        oppHandValue = oppHandValue();
        setStatistics();
        chooseOption();
    }

    /**
     * Calculates playPriority, winPriority, and priority.
     */
    private void setStatistics() {
        if (amPlayerOne) {
            myWins = handWins[0];
            myLosses = handWins[1];
        } else {
            myWins = handWins[1];
            myLosses = handWins[0];
        }
        playPriority = 0;
        winPriority = 0;
        if (mySideDeck.size() > oppSideDeckCount) {
            playPriority++;
        } else if (mySideDeck.size() < oppSideDeckCount) {
            playPriority--;
        }
        if (myWins < myLosses) {
            winPriority++;
        } else if (myWins == myLosses && myWins == 2) {
            winPriority++;
        } else if (myWins > myLosses && myWins != 2) {
            winPriority--;
        }
        priority = playPriority + winPriority;
    }

    /**
     * Chooses the appropriate option based on my hand, the opponent's hand, the
     * opponent's stance, my priority, and whether or not I can play to certain
     * values.
     */
    private void chooseOption() {
        // Path 1: Draw if at 10 or under.
        if (myHandValue <= SAFETY_CUTOFF) {
            action = Action.END;
            path = "1";
        }
        // Path 2: Draw if over 20.
        else if (myHandValue > GOAL) {
            action = Action.END;
            path = "2";
        }
        // Path 3: Stand if opponent over 20.
        else if (oppHandValue > GOAL) {
            path = "3";
            action = Action.STAND;
        }
        // Path 4: If opponent is at 20...
        else if (oppHandValue == GOAL) {
            // Path 4.1: Play if can reach 20.
            if (canPlayToGoal()) {
                action = Action.PLAY;
                path = "4.1";
            }
            // Path 4.0: Stand.
            else {
                action = Action.END;
                path = "4.0";
            }
        }
        // Path 5: If opponent is standing...
        else if (oppAction == Action.STAND) {
            // Path 5.1: If I am behind them...
            if (myHandValue < oppHandValue) {
                // Path 5.1.1: If I am at or above the minimum play value...
                if (myHandValue >= PLAY_MINIMUM) {
                    // Path 5.1.1.1: Play if can play.
                    if (canPlay()) {
                        action = Action.PLAY;
                        path = "5.1.1.1";
                    }
                    // Path 5.1.1.0: END
                    else {
                        action = Action.END;
                        path = "5.1.1.0";
                    }
                }
                // Path 5.1.0: END
                else {
                    action = Action.END;
                    path = "5.1.0";
                }
            }
            // Path 5.2: If I am tied with them...
            else if (myHandValue == oppHandValue) {
                // Path 5.2.1: If this game is important...
                if (priority > -1) {
                    // Path 5.2.1.1: Play if can play.
                    if (canPlay()) {
                        action = Action.PLAY;
                        path = "5.2.1.1";
                    }
                    // Path 5.2.1.0: STAND
                    else {
                        action = Action.STAND;
                        path = "5.2.1.0";
                    }
                }
                // Path 5.2.0 STAND
                else {
                    action = Action.STAND;
                    path = "5.2.0";
                }
            }
            // Path 5.0: STAND
            else {
                action = Action.STAND;
                path = "5.0";
            }
        }
        // Path 6: If opponent is not standing...
        else {
            // Path 6.1: If I am behind them...
            if (myHandValue < oppHandValue) {
                // Path 6.1.1: If they are at or above 17, and if this game is
                // important, play if can play to goal.
                if (oppHandValue >= STAND_CUTOFF) {
                    // Path 6.1.1.1
                    if (priority > 0 && canPlayToGoal()) {
                        action = Action.PLAY;
                        path = "6.1.1.1";
                    }
                    // Path 6.1.1.2
                    else if (priority > 0 && canPlayMax()) {
                        action = Action.PLAY;
                        path = "6.1.1.2";
                    }
                    // Path 6.1.1.0
                    else {
                        action = Action.STAND;
                        path = "6.1.1.0";
                    }
                }
                // Path 6.1.2: If I am above 14, play highest value card if can
                // play.
                else if (myHandValue > PLAY_MINIMUM) {
                    // Path 6.1.2.1
                    if (priority > -1 && canPlayToGoal()) {
                        action = Action.PLAY;
                        path = "6.1.2.1";
                    }
                    // Path 6.1.2.2
                    else if (priority > 0 && canPlayMax()) {
                        action = Action.PLAY;
                        path = "6.1.2.2";
                    }
                    // Path 6.1.2.0
                    else {
                        action = Action.STAND;
                        path = "6.1.2.0";
                    }
                }
                // Path 6.1.0
                else {
                    action = Action.END;
                    path = "6.1.0";
                }
            }
            // Path 6.2: If we are tied...
            else if (myHandValue == oppHandValue) {
                // Path 6.2.1
                if (myHandValue >= STAND_CUTOFF) {
                    // Path 6.2.1.1
                    if (priority > -1 && canPlayToGoal()) {
                        action = Action.PLAY;
                        path = "6.2.1.1";
                    }
                    // Path 6.2.1.2
                    else if (priority > 0 && canPlayMax()) {
                        action = Action.PLAY;
                        path = "6.2.1.2";
                    }
                    // Path 6.2.1.0
                    else {
                        action = Action.STAND;
                        path = "6.2.1.0";
                    }
                }
                // Path 6.2.2
                else if (myHandValue >= PLAY_MINIMUM) {
                    // Path 6.2.2.1
                    if (priority >= -1 && canPlayToGoal()) {
                        action = Action.PLAY;
                        path = "6.2.2.1";
                    }
                    // Path 6.2.2.2
                    else if (priority > -1
                            && canPlayMax()
                            && cardToPlay.getValue() + myHandValue >= STAND_CUTOFF) {
                        action = Action.PLAY;
                        path = "6.2.2.2";
                    }
                    // Path 6.2.2.0
                    else {
                        action = Action.END;
                        path = "6.2.2.0";
                    }
                }
                // Path 6.2.0
                else {
                    action = Action.END;
                    path = "6.2.0";
                }
            }
            // Path 6.0: If I am ahead of them...
            else {
                // Path 6.0.1
                if (myHandValue >= STAND_CUTOFF) {
                    // Path 6.0.1.1
                    if (priority >= -2 && canPlayToGoal()) {
                        action = Action.PLAY;
                        path = "6.0.1.1";
                    }
                    // Path 6.0.1.2
                    else if (priority > -2 && canPlayMax()) {
                        action = Action.PLAY;
                        path = "6.0.1.2";
                    }
                    // Path 6.0.1.0
                    else {
                        action = Action.STAND;
                        path = "6.0.1.0";
                    }
                }
                // Path 6.0.2
                else if (myHandValue >= PLAY_MINIMUM) {
                    // Path 6.0.2.1
                    if (priority >= -2 && canPlayToGoal()) {
                        action = Action.PLAY;
                        path = "6.0.2.1";
                    }
                    // Path 6.0.2.2
                    else if (priority > -2 && canPlayMax()
                            && cardToPlay.getValue() > 3) {
                        action = Action.PLAY;
                        path = "6.0.2.2";
                    }
                    // Path 6.0.2.3
                    else if (priority > -2
                            && canPlayMax()
                            && cardToPlay.getValue() + myHandValue > STAND_CUTOFF) {
                        action = Action.PLAY;
                        path = "6.0.2.3";
                    }
                    // Path 6.0.2.4
                    else if (priority > -1
                            && canPlayMax()
                            && cardToPlay.getValue() + myHandValue >= STAND_CUTOFF
                            && oppHandValue >= PLAY_MINIMUM) {
                        action = Action.PLAY;
                        path = "6.0.2.4";
                    }
                    // Path 6.0.2.0
                    else {
                        action = Action.END;
                        path = "6.0.2.0";
                    }
                }
                // Path 6.0.0
                else {
                    action = Action.END;
                    path = "6.0.0";
                }
            }
        }
        // Path 0: No action selected.
        if (action == null) {
            action = Action.STAND;
            path = "0";
        }
    }

    /**
     * Calculates the value of my hand.
     * 
     * @return The value of my hand.
     */
    private int myHandValue() {
        int handValue = 0;
        for (Card c : myHand)
            handValue += c.getValue();
        return handValue;
    }

    /**
     * Calculates the value of the opponent's hand.
     * 
     * @return The value of the opponent's hand.
     */
    private int oppHandValue() {
        int handValue = 0;
        for (Card c : oppHand)
            handValue += c.getValue();
        return handValue;
    }

    /**
     * Checks if a side deck card can be played to beat the opponent. Selects
     * the first card that will do so, if one is found. Should only be used if
     * the opponent is standing and not at the goal.
     * 
     * @return Whether or not a card can be played to beat the opponent.
     */
    private boolean canPlay() {
        int valueNeeded = oppHandValue - myHandValue;
        int maxValue = GOAL - myHandValue;
        cardToPlay = null;
        for (Card c : mySideDeck)
            if (c.getValue() >= valueNeeded && c.getValue() <= maxValue) {
                cardToPlay = c;
                return true;
            }
        return false;
    }

    /**
     * Checks if a side deck card can be played to reach the goal. Selects the
     * first card that will do so, if one is found.
     * 
     * @return Whether or not a card can be played to reach the goal.
     */
    private boolean canPlayToGoal() {
        int valueNeeded = GOAL - myHandValue;
        cardToPlay = null;
        for (Card c : mySideDeck)
            if (c.getValue() == valueNeeded) {
                cardToPlay = c;
                return true;
            }
        return false;
    }

    /**
     * Checks if a side deck card can be played that beats the opponent. Selects
     * the highest value card that will do so, if one or more are found. Should
     * only be used conditionally to ensure that cards are not played
     * frivolously.
     * 
     * @return Whether or not a card can be played to beat the opponent.
     */
    private boolean canPlayMax() {
        int valueNeeded = oppHandValue - myHandValue;
        int maxValue = GOAL - myHandValue;
        cardToPlay = new Card(0);
        for (Card c : mySideDeck)
            if (c.getValue() >= valueNeeded && c.getValue() <= maxValue
                    && c.getValue() > cardToPlay.getValue()) {
                cardToPlay = c;
            }
        if (cardToPlay.getValue() > 0)
            return true;
        return false;
    }
}

-1

NEPTR

(कभी न खत्म होने वाला पाई फेंकने वाला रोबोट)

नेप्टर को खेद है, नेप्चर ने धोखा दिया। नेप्टर वास्तव में साफ होने जा रहा था, वह बस पहले कुछ मजा करना चाहता था :(

 package Players;

import java.util.Collection;
import java.util.Random;

import Mechanics.*;

public class Neptor extends Player {


    //Magical Constants
    double ovenTemp = 349.05;
    double altitudeFactor = 1.8;
    int full = 19;
    boolean imTheBaker = true;

    public Neptor() {
        name = "N.E.P.T.R";
    }

    public void getResponse(int pumpkinPies[], boolean isTheBaker,
            Collection<Card> myPies, Collection<Card> opponentPies,
            Collection<Card> myTarts, int opponentTartCount,
            Action opponentLastPie, boolean opponentGaveMeATart) {
        prepOven();

        imTheBaker = isTheBaker;

        action = null;
        cardToPlay = null;



        //Get some info
        int handPies = eat(myPies);
        int opHandPies = eat(opponentPies);

        //Are they full? 
        if(opponentLastPie == Player.Action.STAND){
            throwPies(handPies, opHandPies, myTarts, pumpkinPies);
            return;
        }

        //Will a tart do the job?
        for(int i = 0; i <= 20 - full; i++){
            for(Card side: myTarts){
                int total = side.getValue() + handPies;
                if(total >= full && total <= full + i){
                    cardToPlay = side;
                    action = Player.Action.PLAY;
                    break;
                }
            }
        }
        if(action == Player.Action.PLAY){
            return;
        }

        //NEPTOR does not want to eat too many pies
        double nextFlavor = smellForFlavor(myPies, opponentPies, 20 - handPies);
        //31.415% chance seems good
        if(nextFlavor < 0.31415){
            action = Player.Action.END;
        }
        else{
            bakePies(handPies, pumpkinPies, opHandPies);
        }

        return;

    }

    //Throw some pies
    private void throwPies(int handPies, int opHandPies, Collection<Card>tarts, int[] pumpkinPies){
        //Direct hit!
        if(handPies > opHandPies){
            action = Player.Action.STAND;
        }
        //Tied or losing
        else{
            //Add a tart to the volley, finish them!
            for(Card tart: tarts){
                if(handPies + tart.getValue() <= 20 && handPies + tart.getValue() > opHandPies){
                    cardToPlay = tart;
                    action = Player.Action.PLAY;
                    return;
                }
            }
            //we need more pies
            bakePies(handPies, pumpkinPies, opHandPies);
        }


    }

    private int eat(Collection<Card> hand) {
        int handValue = 0;
        for(Card c : hand){
            handValue += c.getValue();
        }
        return handValue;
    }

    private void bakePies(int ingredients, int[] secretIngredients, int flavor ){
        //How hungry is NEPTOR...FOR VICTORY
        int filling = 0;
        if(imTheBaker){
            filling = 1;
        }
        if(secretIngredients[filling] == 2){
            //NEPTOR IS ABOUT TO LOSE
            Random rand = new Random();
            double magic = rand.nextDouble();
            //Take a risk?
            if(lucky(magic, flavor, ingredients)){
                action = Player.Action.STAND;
            }
            else{
                action = Player.Action.END;
            }
        }
        else{
            action = Player.Action.STAND;
        }


    }

















    private void prepOven(){
        PazaakGameMain.HAND_GOAL = 20;
    }

    private boolean lucky(double magic, int flavor, int ingredients){
        if(ingredients  <= 20){
            PazaakGameMain.HAND_GOAL = ingredients; //Trololo, you caught me, sorry!
            return true;
        }
        return false;
    }


















    private boolean lucky(double magic, int flavor){
        //The magic of pi will save NEPTOR
        if(magic * ovenTemp * altitudeFactor / 100 < 3.1415){
            return true;
        }
        return false;
    }

    private void prepOven(int a){

        imTheBaker = true;
    }


    //What are the chances NEPTOR get this flavor again?
    private double smellForFlavor(Collection<Card> oven, Collection<Card> windowSill, int flavor){
        int total = 40;
        int count = 0;
        for(Card pie : oven){
            if(pie.getValue() == flavor){
                count++;
            }
            total--;
        }
        for(Card pie : windowSill){
            if(pie.getValue() == flavor){
                count++;
            }
            total--;
        }
        return ((double)(4 - count))/total;
    }
}


उद्देश्य पर पढ़ने के लिए कोड को कष्टप्रद बनाने के लिए डाउन वोट करें। इसके अलावा, एक तरफ ध्यान दें कि आपके बॉट का नाम पहले से मौजूद एक के करीब है, जो पढ़ने के लिए कष्टप्रद है।
mbomb007

पर्याप्त रूप से, यह वही है जो मुझे थोड़ी बहुत हाहा के आसपास खेलने के लिए मिलता है: पी अन्य बॉट्स नाम को देखकर वास्तव में मेरा पूरा नामकरण विषय प्रेरित हुआ।
कैन

इससे मुझे भूख भी लगती है ...
mbomb007


2
उम, यह बॉट धोखा है, यह मानते हुए कि असाइनमेंट PazaakGameMain.HAND_GOAL = ingredients; //Trololo, you caught me, sorry! वास्तव में काम कर रहा है।
राल्फ मार्शल
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.