उत्तरजीविता खेल - अपनी वुल्फ बनाएँ


238

बोर्ड

बोर्ड कोशिकाओं के एक दो आयामी सरणी है। सेल जानवरों द्वारा आबादी वाले हैं । हर दिन, बोर्ड के सभी पशु एक साथ एक चाल चलते हैं। यदि दो या अधिक पशु एक ही सेल में जाते हैं, तो वे तब तक लड़ते हैं जब तक कि एक ही रहता है। संभावित चाल और हमले इस प्रकार हैं:

  • चाल - { Move.UP, Move.RIGHT, Move.DOWN, Move.LEFT, Move.HOLD}
  • हमलों - { Attack.ROCK, Attack.PAPER, Attack.SCISSORS, Attack.SUICIDE}

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

खिलाड़ियों

पशु व्यवहार और उपस्थिति इस प्रकार है।

  • सिंह
    • चरित्र द्वारा प्रस्तुत किया गया L। चलता है DOWN, RIGHTफिर दोहराता है। Pseudorandomly के साथ PAPERया पर हमला करता है SCISSORS
  • भालू
    • चरित्र द्वारा प्रस्तुत किया गया B। चालें DOWNएक्स 4, RIGHTएक्स 4, UPएक्स 4, LEFTएक्स 4, फिर दोहराया जाता है। के साथ हमलों PAPER
  • पत्थर
    • चरित्र द्वारा प्रस्तुत किया गया S। चलती है HOLD। के साथ हमलों ROCK
  • भेड़िया
    • केवल भेड़ियों को जवाब के रूप में प्रस्तुत किया जाएगा। 'डब्ल्यू' द्वारा प्रस्तुत। किसी भी चाल के साथ चलता है। किसी भी हमले के साथ हमलों

आप निम्न टेम्पलेट में रिक्त स्थान को भरकर वुल्फ को लागू करेंगे। सभी प्रस्तुतियाँ जावा में होनी चाहिए और एक ही फाइल में होनी चाहिए। वैकल्पिक रूप से, @ProgrammerDan ने एक रैपर क्लास लिखा है जो प्रतियोगिता को गैर-जावा सबमिशन तक बढ़ाता है।

// Optional code here
public class Wolf extends Animal {
    // Optional code here
    public Wolf() { super('W'); /* Optional code here */ }
    public Attack fight(char opponent) { /* Required code here. Must return an Attack. */ }
    public Move move() { /* Required code here. Must return a Move. */ }
    // Optional code here
}

1,000 पुनरावृत्तियों की जीत के साथ पाँच परीक्षणों के बाद जीवित भेड़ियों की सबसे अधिक औसत संख्या के साथ जमा। जब भी कोई नया उत्तर पोस्ट किया जाएगा (लेकिन पहले 24 घंटों के भीतर) मैं विजेता को अपडेट करूंगा।

उपकरण

  • आपको निम्नलिखित रूप में अपने तत्काल परिवेश के एक छोटे से नक्शे के साथ प्रदान किया जाता है।
    • char[][] surroundingsएक शून्य अनुक्रमित, 3 द्वारा 3 वर्णों के मैट्रिक्स जो आस-पास के जानवरों का प्रतिनिधित्व करते हैं। खाली टाइलों को एक अंतरिक्ष वर्ण ('') द्वारा दर्शाया जाता है। आप पर हैं surroundings[1][1]। उदाहरण के लिए, आपके दाईं ओर surroundings[1][2], और ऊपर आप हैं surroundings[0][1]। स्थानांतरित होने के लिए कहने से पहले आपका परिवेश अपडेट किया जाता है, लेकिन लड़ने के लिए कहने पर यह पुराना हो सकता है।
  • आप अपने वुल्फ के चालन, अनुरोधों और आक्रमण अनुरोधों के बीच डेटा को बनाए रख सकते हैं। आप किसी अन्य वुल्फ वर्ग द्वारा बनाई गई फ़ाइलों को न तो पढ़ सकते हैं और न ही संशोधित कर सकते हैं।
  • आपको निम्न रूप में नक्शे के आकार के साथ प्रदान किया जाता है
    • int MAP_SIZE

मान्यताओं

  • सभी सबमिशन अन्य सभी सबमिशन के साथ-साथ लायंस, बियर और स्टोन्स के खिलाफ एक ही बोर्ड पर प्रतिस्पर्धा करेंगे
  • बोर्ड एक वर्ग होता है जिसकी लंबाई लंबाई होती है sqrt(n+3)*20जहां nसबमिशन की संख्या होती है। सभी पक्ष लपेटते हैं, इसलिए आप सुरक्षित रूप से किसी भी दिशा में असीम रूप से आगे बढ़ सकते हैं।
  • सिमुलेशन शुरू होता है ~ 25% बोर्ड क्षमता 100 प्रत्येक पशु के छद्म रूप से बोर्ड भर में वितरित की जाती है।
  • यदि किसी पशु को स्थानांतरित करने के लिए कहा जाए तो वह जानवर फेंकता है HOLD
  • अगर किसी जानवर को लड़ने के लिए कहने पर अपवाद फेंकता है, तो वह जानवर करेगा SUICIDE
  • यदि किसी पशु के पास कोई पत्र नहीं है जब नियंत्रक जांच करता है, तो पशु तुरंत मर जाएगा

आरंभ और परीक्षण निर्देश

आपके प्रस्तुत करने का परीक्षण करने के लिए आवश्यक उपकरण यहां मिल सकते हैं । निम्न फ़ाइलें उस लिंक पर उपलब्ध होनी चाहिए।

  • ExampleRun.gif - चल रहे प्रोग्राम का 5-10 सेकंड का GIF।
  • स्कोरबोर्ड - प्रतियोगिता के नवीनतम परिणाम।
  • Wild.jar - एक निष्पादन योग्य जिसे आप प्रीमियर जानवरों को देखने के लिए चला सकते हैं।
  • Wild.zip - NetBeans प्रोजेक्ट जिसमें कुछ प्रीमियर जानवरों के साथ नियंत्रक कार्यक्रम शामिल है। अपने सबमिशन को विकसित करने के लिए इसका उपयोग करें।
  • WildPopulated.zip - ऊपर के समान, लेकिन आपके खिलाफ परीक्षण करने के लिए लगभग 40 सबमिशन जोड़े गए। प्रदर्शन के मुद्दों के कारण GUI को भी हटा दिया गया है। आपके दौड़ने के कुछ ही समय बाद परिणाम दिखाई देंगे। गैर-जावा सबमिशन में टिप्पणी की जाती है क्योंकि उन्हें अतिरिक्त डाउनलोड और प्रयास की आवश्यकता होती है। क्षेत्र के खिलाफ अपनी अधीनता का परीक्षण करने के लिए इसका उपयोग करें।
  • Wolf.txt - जावा में वुल्फ वर्ग का एक भोली कार्यान्वयन। आप उस कार्यान्वयन का उपयोग और विस्तार कर सकते हैं, बिना मुझे बताए।

अपनी कक्षा का परीक्षण करने के लिए:

  • डाउनलोड Wild.zip
  • कुछ अनोखा करने के लिए अपने वुल्फ.जवा और वुल्फ वर्ग का नाम बदलें
  • अपने UniquelyNamedWolf.java फ़ाइल को Wild \ src \ जानवरों में जोड़ें
  • वाइल्ड क्लास में, अपनी क्लास को classesइस तरह से अरेंज करें।
    • Class[] classes = { UniquelyNamedWolf.class, Bear.class, Lion.class, Stone.class, Wolf.class };
  • पुनर्निर्माण और भागो

मैंने परीक्षण प्रयोजनों के लिए सभी प्रस्तुतियाँ वाले एक अन्य प्रोजेक्ट को भी शामिल किया। मैंने रचनात्मक रूप से इसे "वाइल्डपोपाइटल" नाम दिया है। तीन या चार गैर-जावा भेड़ियों की टिप्पणी की गई, क्योंकि उन्हें चलाने के लिए अतिरिक्त काम और डाउनलोड की बहुत आवश्यकता होती है। जिसे मैंने पोस्ट किया है उसे शून्य अतिरिक्त काम के साथ चलना चाहिए । जीयूआई की गति के लिए भी टिप्पणी की गई थी।

स्कोरबोर्ड 22 अप्रैल 2014

स्कोरबोर्ड को Google ड्राइव में ले जाया गया है। इसे यहाँ देखें। यह एक आकस्मिक आधार पर अद्यतन किया जाएगा (यानी, जब मैं इसे प्राप्त करता हूं) जैसे ही नई प्रस्तुतियाँ आती हैं।

साइड चैलेंज - NoHOLD

हटा दिया गया क्योंकि नहीं (शून्य के रूप में) भागीदारी। यह वैसे भी मूल चुनौती का हिस्सा नहीं था।


5
@Rusher जो भयानक लगता है। मैं सिर्फ समुदाय को अपना जवाब दे सकता हूं जिसमें रैपर शामिल है। संकलक / दुभाषिया मुद्दे के लिए, मुझे लगता है कि यह आपको उपयोग पर स्पष्ट निर्देश प्रदान करने के लिए सबमिट करने के लिए होगा, और यदि निर्देश अस्पष्ट या बहुत जटिल हैं, तो आप सबमिशन को अस्वीकार कर सकते हैं :)
प्रोग्रामर

4
* "आपको निम्नलिखित रूप में नक्शे के आकार के साथ प्रदान किया जाता है: int MAP_SIZE" मुझे यह पता लगाने में परेशानी हो रही है कि इसका उपयोग कैसे करें। Netbeans का कहना है कि MAP_SIZEइस परियोजना में किसी भी फाइल में स्ट्रिंग का कोई उदाहरण नहीं है ।
अंडरग्राउंडोरेल

6
कागज दिखाने वाले पेड़ों के बारे में कैसे?
मुकुल कुमार

3
@Rusher, मुझे लगता है कि कुछ लोग पहले से ही ऐसा कर रहे हैं, लेकिन अंतर-भेड़िया संचार स्थिर सदस्यों (आपकी अपनी नस्ल के भीतर) के माध्यम से अनुमति है?
मार्टिन एंडर

10
@ m.buettner अनुमति है। आगे बढ़ो और अपने छत्ते के दिमाग वाले भेड़िये का निर्माण करो।
रेनबोल्ट

जवाबों:


47

HerjanWolf

15:00-2014 को 15:00 बजे अपडेट किया गया

100 राउंड का लाभ, 1000 पुनरावृत्तियों:

मानक स्तन:

class animals.Bear - 2.2600002
class animals.Lion - 41.21
class animals.Stone - 20.159998
class animals.HerjanWolf - 99.99 <-- kind of flawless

20+ प्रजाति (ध्यान रखें, जब तक हम अपने भेड़ियों के सर्वश्रेष्ठ स्कोर को प्राप्त नहीं करते, तब तक इन स्कोर पर भरोसा न करें!)

class animals.Bear - 0.1
class animals.Lion - 0.0
class animals.Stone - 1.5
class animals.AlphaWolf - 75.5
class animals.HerjanWolf - 86.4 <-- #1
class animals.GatheringWolf - 39.5
class animals.OmegaWolf - 85.4 <-- #2
class animals.ShadowWolf - 71.1
class animals.MOSHPITFRENZYWolf - 8.8
class animals.WolfWithoutFear - 11.5
class animals.MimicWolf - 0.5
class animals.LazyWolf - 52.8
class animals.Sheep - 38.3
class animals.HonorWolf - 80.7
class animals.CamperWolf - 52.8
class animals.GamblerWolf - 14.7
class animals.WolfRunningWithScissors - 0.0
class animals.LionHunterWolf - 27.6
class animals.StoneEatingWolf - 70.8
class animals.Wion - 0.1
class animals.ProAlpha - 79.3
class animals.HybridWolf - 83.2

मेरा भेड़िया:

package animals;

public class HerjanWolf extends Animal {

    private boolean lionTopLeft = false, lionTopLeftReady = false;
    private boolean lionRight = false, lionRightReady = false;
    private boolean lionBot = false, lionBotReady = false;
    private boolean lionDanger = false, careful = true, firstmove = true;
    private final int hold = 0, down = 1, right = 2, left = 3, up = 4;

    public HerjanWolf() {
        super('W');
    }

    public Attack fight(char c){
        switch (c) {
            case 'B':
                return Attack.SCISSORS;
            case 'L':
                return Attack.SCISSORS;
            case 'S':
                return Attack.PAPER;
            default:
                int rand = (int) (Math.random()*3);
                if(rand < 1)
                    return Attack.PAPER;
                else if(rand < 2)
                    return Attack.SCISSORS;
                else
                    return Attack.ROCK;
        } 

    }
    public Move move() { //surroundings[y][x]

        checkLions();

        if(firstmove){
            if(surroundings[2][0] == 'L')
                lionBotReady = true;
            if(surroundings[0][2] == 'L')
                lionRightReady = true;
            firstmove = false;
        }

        int[] dang = new int[4]; // 0 is left side, 1 is top side, 2 is right side, 3 is down side

        for(int y = 0; y < 3; y++){
            for(int x = 0; x < 3; x++){
                if(surroundings[y][x] == 'W'){
                    if(y == 0){
                        dang[1]++;
                        if(x == 1)
                            dang[1]+=2;
                    }if(y == 2){
                        dang[3]++;
                        if(x == 1)
                            dang[3]+=2;
                    }if(x == 0){
                        dang[0]++;
                        if(y == 1)
                            dang[0]+=2;
                    }if(x == 2){
                        dang[2]++;
                        if(y == 1)
                            dang[2]+=2;
                    }
                }
            }
        }

        int maxIndex = 0, minIndex = 0, minIndex2 = 0;
        for(int i = 1; i < dang.length; i++){
            if(dang[i] > dang[maxIndex])
                maxIndex = i;
            if(dang[i] <= dang[minIndex]){
                minIndex2 = minIndex;
                minIndex = i;
            }
        }

        if(lionDanger || surroundings[1][0] == 'L' && lionTopLeftReady || surroundings[0][1] == 'L' && lionTopLeftReady || dang[maxIndex] >= 3){

            switch(minIndex){
            case 0:
                if (isSafe(1, 0)){
                    newMove(left);
                    return Move.LEFT;
                }
            case 1:
                if (isSafe(0, 1)){
                    newMove(up);
                    return Move.UP;
                }
            case 2:
                if(isSafe(1,2)){
                    newMove(right);
                    return Move.RIGHT;
                }

            case 3:
                if (isSafe(2, 1)){
                    newMove(down);
                    return Move.DOWN;
                } 
            }

            switch(minIndex2){
            case 0:
                if (isSafe(1, 0)){
                    newMove(left);
                    return Move.LEFT;
                }
            case 1:
                if (isSafe(0, 1)){
                    newMove(up);
                    return Move.UP;
                }
            case 2:
                if(isSafe(1,2)){
                    newMove(right);
                    return Move.RIGHT;
                }

            case 3:
                if (isSafe(2, 1)){
                    newMove(down);
                    return Move.DOWN;
                } 
            }

            if(dang[maxIndex]<3){ //if that was not the reason its really obligated (because of lions)
                if (isSafe(2, 1)){
                    newMove(down);
                    return Move.DOWN;
                }else if(isSafe(1,2)){
                    newMove(right);
                    return Move.RIGHT;
                }else if (isSafe(0, 1)){
                    newMove(up);
                    return Move.UP;
                }else{
                    newMove(left);
                    return Move.LEFT;
                }
            }
        }

        return Move.HOLD;
    }

    boolean isSafe(int y, int x){
        if(y <= 1){
            if(x <= 1){
                if(surroundings[y][x] != 'W' && !lionTopLeft)
                    return true;
            }else if(surroundings[1][2] != 'W' && !lionRightReady)
                    return true;
        }else if(surroundings[2][1] != 'W' && !lionBotReady)
            return true;

        return false;
    }

    public void checkLions(){
        int y = 0, x = 0;

        if(lionTopLeft)
            lionTopLeftReady = true;
        else
            lionTopLeftReady = false;

        if(surroundings[y][x] == 'L')
            lionTopLeft = true;
        else
            lionTopLeft = false;

        if(lionRight)
            lionRightReady = true;
        else
            lionRightReady = false;

        if(surroundings[y][x+1] == 'L') // && !lionTopLeftReady
            lionRight = true;
        else
            lionRight = false;

        if(lionBot)
            lionBotReady = true;
        else
            lionBotReady = false;

        if(surroundings[y+1][x] == 'L' && !lionTopLeftReady)
            lionBot = true;
        else
            lionBot = false;

        if(careful){
            if(surroundings[y+1][x] == 'L'){
                lionDanger = true;
            }else if(surroundings[y][x+1] == 'L'){
                lionDanger = true;
            }

            careful = false;
        }
    }

    public void newMove(int move){
        lionTopLeft = false;
        lionRight = false;
        lionBot = false;

        lionTopLeftReady = false;
        lionRightReady = false;
        lionBotReady = false;

        lionDanger = false;

        if(move == down){
            if(surroundings[1][0] == 'L')
                lionTopLeft = true;
            if(surroundings[2][0] == 'L')
                lionBot = true;

        }else if(move == right){
            if(surroundings[0][1] == 'L')
                lionTopLeft = true;
            if(surroundings[0][2] == 'L')
                lionRight = true;

        }else
            careful = true;
    }
}

केवल "शीर्ष" भेड़ियों में परीक्षण रन शामिल हैं, जो सामान्य रूप से संख्याओं को रोकते हैं। मैदान पर 30+ प्रजातियों के साथ, संख्या नाटकीय रूप से बदल सकती है। यदि आपने अभी तक नहीं किया है, तो मैं यह भी परीक्षण की सिफारिश करेंगे।
जियोबिट्स

1
@ user20220 यह सिद्धांत में बहुत अच्छा है (और अपेक्षाकृत कम भेड़ियों के साथ व्यवहार में)।
user3188175

1
इस भेड़िया के पास सबसे अच्छी शेर-विरोधी रणनीति है: chat.stackexchange.com/transcript/message/14837616#14837616
जस्टिन

2
@ user20220 भेड़िया-टकराव अधिक बार होता है, इसलिए आपको एक और भेड़िया जोड़ना चाहिए। इसके अलावा, क्या आप यह बता सकते हैं कि यह भेड़िया कैसे काम करता है?
जस्टिन

3
@ अन्याय ठीक है, यह बेहतर नहीं है, यह तब अच्छा है। मेरे भेड़िये ने सभी शेरों को भी चकमा दिया, मैंने भेड़िया-चकमा देने से पहले अपनी भेड़िये को 100% शेरनी बना लिया। अंतर यह है कि मेरा भेड़िया शेरों (कम आंदोलन, बेहतर) से बचने की कोशिश करता है। तो यह शेर के रूप में शेर-चकमा देने वाले के रूप में अच्छा है, दोनों 100% शेरोनप्रूफ हैं, लेकिन चूंकि मेरा भेड़िया शेरों से बचने की कोशिश करता है, न कि उबाऊ रूप से शेर की तरह चलता है, मैं अभी भी भेड़िये को चकमा दे सकता हूं और साथ ही, यह सिर्फ तरीका है अधिक जटिल।
हरजन

153

EmoWolf

EmoWolf जावा से नफरत करता है, और भाग लेने के बजाय खुद को मार देगा। EmoWolf ने खुद को भूखा रखा है, लेकिन अभी भी उसका वजन 177 बाइट्स है।

package animals;public class EmoWolf extends Animal{public EmoWolf(){super('W');}public Attack fight(char opponent){return Attack.SUICIDE;}public Move move(){return Move.HOLD;}}

34
lol आप कुछ बाइट्स को शेव कर सकते हैं: " यदि किसी पशु के पास कोई पत्र नहीं है जब नियंत्रक जांच करता है, कि पशु तुरंत मर जाएगा "।
भूत

112
इसके बारे में सबसे अच्छी बात यह है कि यह लगातार सबसे खराब नहीं है । यह सामान्य रूप से कम से कम 2-3 अन्य लोगों के लिए धड़कता है।
ज्योबिट्स

51
"केवल जीतने वाला कदम नहीं खेलना है।"
तदमन

38
+1 छोटा और आत्मघाती होने के लिए और अभी भी 4 अन्य भेड़ियों की पिटाई कर रहा है।
puggsoy

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

52

LazyWolf

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

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

बस। मुझे उम्मीद है कि सादगी के बावजूद यह बहुत अच्छा करेगा।

package animals;    
public class LazyWolf extends Animal{    
    static int last = 0;
    static final Attack[] attacks = Attack.values();

    public LazyWolf() {super('W');}

    @Override
    public Attack fight(char other) {
        switch(other){
        case 'B':
        case 'L':
            return Attack.SCISSORS;
        case 'S': 
            return Attack.ROCK; // faker!
        default:
            return attacks[last++%3];
        }
    }

    @Override
    public Move move() {
        if(surroundings[0][1] == 'L')
            return Move.LEFT;
        if(surroundings[1][0] == 'L')
            return Move.UP;
        return Move.HOLD;
    }

}

अपडेट करें:

कैमोवुल्फ मुझे हाथ से पीट रहा था। चूंकि मेरा भेड़िया इतना आलसी है, इसलिए वह आम तौर पर असली पत्थर में नहीं चलता। इसलिए, यदि कोई पत्थर हमला करता है, तो यह स्पष्ट रूप से एक नकली है और इसके चेहरे पर फेंकने वाली चट्टान की जरूरत है।


जब आप एक से बचने की कोशिश करते हैं, तो आपके पास दूसरे शेर में जाने की संभावना होती है। आप इसे ट्रैक करके निकाल सकते हैं कि वहां कितनी चालें हैं, इसलिए आप जानते हैं कि क्या शेर वास्तव में आपके वर्ग में आ रहा है। यदि यह है, तो शेर की तरह ही दिशा को आगे बढ़ाएं, और कोई भी शेर आपको नहीं मिल सकता क्योंकि वे भी उसी दिशा में आगे बढ़ रहे हैं।
उघौवगफह

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

1
आपको क्या लगता है कि यह भेड़िया कभी असली पत्थरों में नहीं चलता है? मुझे लगता है कि जब भी यह शेर से दूर भागता है तो ऐसा हो सकता है।
बजे क्रिस्टोफर क्रेतुज़िग

6
@ChristopherCreutzig यह शेर से चलता है जहां शेर था । अगर एक शेर था वहाँ, एक पत्थर वहाँ नहीं हो सकता अब
Geobits

1
यहां तक ​​कि अगर यह हो सकता है, कोई "अनंत लूप" नहीं है। यदि कोई हमला एक टाई है, तो एक या दूसरे की मौत सिक्का द्वारा (सिक्का टॉस द्वारा चुनी गई) है।
भूत

51

नॉन-जावा सबमिशन के लिए रैपर

नोट MAP_SIZE समर्थन जोड़ा गया है। यदि आप परवाह करते हैं, तो कृपया अपने अनुसार अपना सबमिशन अपडेट करें।

यह एक रैपर के लिए सामुदायिक विकी प्रविष्टि है, जो खेलने के इच्छुक हैं, लेकिन जावा को पसंद नहीं करते / जानते नहीं हैं। कृपया इसका उपयोग करें, मज़े करें, और चीजों को स्थापित करने में आपकी सहायता करने में मुझे खुशी होगी।

यह बहुत देर हो चुकी है क्योंकि मैं अन्य जावा कोडर्स को पूरा कर रहा हूं, कृपया इसे देखें और सुधार का सुझाव दें। यदि आप कर सकते हैं, तो मेरे जीथब रिपॉजिटरी के माध्यम से एक मुद्दा दर्ज करके या एक पैच सबमिट करके ऐसा करें। धन्यवाद!

यह पूरा UNLICENSE के साथ वितरित किया जा रहा है, कृपया इसे इसके github रिपॉजिटरी से फॉलो / फोर्क करें । यदि आपको समस्याएँ आती हैं तो मैं वहां पैचेज़ प्रस्तुत करूँगा और इस पोस्ट को अपडेट करूँगा।

उपयोग में आवरण के वर्तमान उदाहरण

प्लेनैपस : वुल्फकोलेक्टिविवेमोरी आर में

user3188175 : स्मार्टवॉफ़ इनC#

टूथब्रश : ईसीएमएस्क्रिप्ट में टूथब्रश

कैसे इस्तेमाल करे

क्या इस प्रकार के निर्देशों के लिए प्रोटोकॉल पर अंतर प्रक्रिया संचार के माध्यम से PIPES मैं दूरस्थ भेड़ियों के लिए परिभाषित किया है। ध्यान दें कि मैंने MAP_SIZE को छोड़ दिया है क्योंकि यह ओपी की समस्या बयान में मौजूद होने के बावजूद मौजूद नहीं है। यदि यह दिखाई देता है, तो मैं इस पोस्ट को अपडेट करूंगा।

महत्वपूर्ण सूचनाएँ :

  • आपकी बाहरी प्रक्रिया का केवल एक ही मंगलाचरण किया जाएगा (इसलिए अनंत लूप में अपने प्रसंस्करण तर्क को लपेटें। यह आपको डिस्क का उपयोग करने के बजाय किसी भी प्रसंस्करण को मेमोरी में रखने की अनुमति देता है)
  • सभी संचार STDIN और STDOUT के माध्यम से इस एकल बाह्य प्रक्रिया के लिए है
  • आपको स्पष्ट रूप से STDOUT को भेजे गए सभी आउटपुट को फ्लश करना होगा, और यह सुनिश्चित करना होगा कि यह नई-पंक्तिबद्ध है

विशिष्टता

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

ध्यान दें कि केवल एक ही प्रक्रिया बनाई जाएगी, सभी भेड़ियों को उस एक प्रक्रिया के भीतर प्रबंधित किया जाना चाहिए। यह युक्ति कैसे मदद करेगी, इसके लिए आगे पढ़ें।

प्रारंभ

STDIN: S<id><mapsize> \ n

STDOUT: K<id> \ n

<id>: 00 या 01या ... या99

स्पष्टीकरण:

चरित्र Sदो अंकीय वर्ण के बाद भेजा जाएगा 00, 01, ..., 99यह दर्शाता है जो 100 भेड़ियों का प्रारंभ किया जा रहा है। उस विशिष्ट भेड़िया के साथ भविष्य के सभी संचार में, उसी <id>का उपयोग किया जाएगा।

आईडी के बाद, संख्यात्मक वर्णों की एक चर लंबाई अनुक्रम भेजी जाएगी। यह मानचित्र का आकार है। जब आप न्यूलाइन ( \n) में पहुँचते हैं, तो आप संख्यात्मक वर्णों का अनुक्रम जान लेंगे ।

यह सुनिश्चित करने के लिए कि आपकी प्रक्रिया जीवित है, आपको अपने Kद्वारा <id>प्राप्त चरित्र के साथ उत्तर देना होगा । किसी भी अन्य उत्तर के परिणामस्वरूप एक अपवाद होगा, जो आपके भेड़ियों को मार देगा।

आंदोलन

STDIN: M<id><C0><C1>...<C7><C8> \ n

STDOUT: <mv><id> \ n

<Cn>: W या या Bया SयाL

W: भेड़िया

: खाली स्थान

B: भालू

S: पत्थर

L: सिंह

<mv>: H या Uया Lया RयाD

H: हटो

U: Move.UP

L: Move.LEFT

R: हटो

D: हटो। डाउनलोड करें

स्पष्टीकरण:

चरित्र Mको दो चरित्रों के बाद भेजा जाएगा ताकि <id>संकेत दिया जा सके कि कौन से वुल्फ को एक कदम चुनने की जरूरत है। उसके बाद, 9 वर्णों को उस वुल्फ के परिवेश का प्रतिनिधित्व करते हुए भेजा जाएगा, पंक्ति क्रम में (शीर्ष पंक्ति, मध्य पंक्ति, सबसे नीचे से सबसे दाहिनी पंक्ति)।

पुष्टि के लिए <mv>वुल्फ के दो अंकों के बाद मान्य आंदोलन वर्णों में से एक के साथ उत्तर दें <id>

हमला

STDIN: A<id><C> \ n

STDOUT: <atk><id> \ n

<C>: W या Bया SयाL

<atk>: R या Pया SयाD

R: Attack.ROCK

P: Attack.PAPER

S: Attack.SCISSORS

D: हल्ला।सुरक्षा

स्पष्टीकरण:

इस चरित्र Aको दो चरित्रों द्वारा भेजा जाएगा ताकि <id>संकेत दिया जा सके कि भेड़िया एक हमले में भाग ले रहा है। इसके बाद एक एकल वर्ण होता <C>है जो दर्शाता है कि किस प्रकार की चीज हमला कर रही है, या तो एक Wघ्राण, Bकान, Sस्वर या Lआयन।

<atk>ऊपर सूचीबद्ध पात्रों में से एक के साथ उत्तर दें , यह दर्शाता है कि हमले के लिए आपकी प्रतिक्रिया क्या है, <id>पुष्टि के लिए दो अंकों का पालन करें ।

और बस। इसके अलावा और कोई नहीं है। यदि आप कोई हमला करते हैं, तो वह <id>आपकी प्रक्रिया में फिर कभी नहीं भेजा जाएगा, कि आप कैसे जानेंगे कि आपका वुल्फ मर गया है - अगर एक पूरा आंदोलन दौर बीत चुका है कि <id>कभी भी भेजा नहीं जा रहा है।

निष्कर्ष

ध्यान दें कि कोई भी अपवाद आपके दूरस्थ प्रकार के सभी भेड़ियों को मार देगा, क्योंकि आपके प्रकार के सभी भेड़ियों के लिए केवल एक ही "प्रक्रिया" आपके दूरस्थ भेड़िया द्वारा बनाई गई है, जो बनाई जाती है।

इस रिपॉजिटरी में आपको Wolf.javaफ़ाइल मिल जाएगी । अपना बॉट सेट करने के लिए निम्नलिखित स्ट्रिंग्स खोजें और बदलें:

  • <invocation>कमांड लाइन तर्क के साथ बदलें जो आपकी प्रक्रिया को ठीक से निष्पादित करेगा।

  • <custom-name>अपने वुल्फ के लिए एक अद्वितीय नाम के साथ बदलें ।

  • एक उदाहरण के लिए रिपॉजिटरी देखें , जहां मेरे पास WolfRandomPython.javaमेरा उदाहरण रिमोट है, PythonWolf.py(एक पायथन 3+ वुल्फ)।

  • उस फ़ाइल का नाम बदलें Wolf<custom-name>.java, जहाँ <custom-name>आपके द्वारा चुने गए नाम से प्रतिस्थापित किया गया है।

अपने वुल्फ का परीक्षण करने के लिए, जावा प्रोग्राम को संकलित करें ( javac Wolf<custom-name>.java), और अनुकार कार्यक्रम में इसे शामिल करने के लिए रशर्स के निर्देशों का पालन करें।

महत्वपूर्ण: अपने वास्तविक वुल्फ को संकलित / निष्पादित करने के तरीके के बारे में स्पष्ट , संक्षिप्त निर्देश प्रदान करना सुनिश्चित करें , जो मैंने ऊपर उल्लिखित योजना का अनुसरण करता है।

सौभाग्य, और प्रकृति कभी भी आपके पक्ष में हो सकती है।

रैपर कोड

याद रखें, आप खोज करना चाहते हैं और इस के बारे में उल्लिखित काम करने के लिए प्रतिस्थापित करता है। यदि आपका मंगलाचरण विशेष रूप से बालों वाला है, तो कृपया सहायता के लिए मुझसे संपर्क करें।

ध्यान दें कि mainइस रैपर में एक विधि है, जिससे आपके स्थानीय बॉक्स पर अल्पविकसित "पास / विफल" परीक्षण की अनुमति मिलती है। ऐसा करने के लिए, प्रोजेक्ट से Animal.java क्लास डाउनलोड करें, और package animals;दोनों फाइलों से लाइन हटा दें । कुछ स्थिर (जैसे 100) के साथ Animal.java में MAP_SIZE लाइन बदलें। के javac Wolf<custom-name>.javaमाध्यम से एक निष्पादन का उपयोग कर उन्हें संकलित करें java Wolf<custom-name>

package animals;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.OutputStreamWriter;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * Remote Wolf<custom-name> wrapper class. 
 */
public class Wolf<custom-name> extends Animal {
    /**
     * Simple test script that sends some typical commands to the
     * remote process.
     */
    public static void main(String[]args){
        Wolf<custom-name>[] wolves = new Wolf<custom-name>[100];
        for(int i=0; i<10; i++) {
            wolves[i] = new Wolf<custom-name>();
        }
        char map[][] = new char[3][3];
        for (int i=0;i<9;i++)
            map[i/3][i%3]=' ';
        map[1][1] = 'W';
        for(int i=0; i<10; i++) {
            wolves[i].surroundings=map;
            System.out.println(wolves[i].move());
        }
        for(int i=0; i<10; i++) {
            System.out.println(wolves[i].fight('S'));
            System.out.println(wolves[i].fight('B'));
            System.out.println(wolves[i].fight('L'));
            System.out.println(wolves[i].fight('W'));
        }
        wolfProcess.endProcess();
    }
    private static WolfProcess wolfProcess = null;

    private static Wolf<custom-name>[] wolves = new Wolf<custom-name>[100];
    private static int nWolves = 0;

    private boolean isDead;
    private int id;

    /**
     * Sets up a remote process wolf. Note the static components. Only
     * a single process is generated for all Wolves of this type, new
     * wolves are "initialized" within the remote process, which is
     * maintained alongside the primary process.
     * Note this implementation makes heavy use of threads.
     */
    public Wolf<custom-name>() {
        super('W');
        if (Wolf<custom-name>.wolfProcess == null) {
            Wolf<custom-name>.wolfProcess = new WolfProcess();
            Wolf<custom-name>.wolfProcess.start();
        }

        if (Wolf<custom-name>.wolfProcess.initWolf(Wolf<custom-name>.nWolves, MAP_SIZE)) {
            this.id = Wolf<custom-name>.nWolves;
            this.isDead = false;
            Wolf<custom-name>.wolves[id] = this;
        } else {
            Wolf<custom-name>.wolfProcess.endProcess();
            this.isDead = true;
        }
        Wolf<custom-name>.nWolves++;
    }

    /**
     * If the wolf is dead, or all the wolves of this type are dead, SUICIDE.
     * Otherwise, communicate an attack to the remote process and return
     * its attack choice.
     */
    @Override
    public Attack fight(char opponent) {
        if (!Wolf<custom-name>.wolfProcess.getRunning() || isDead) {
            return Attack.SUICIDE;
        }
        try {
            Attack atk = Wolf<custom-name>.wolfProcess.fight(id, opponent);

            if (atk == Attack.SUICIDE) {
                this.isDead = true;
            }

            return atk;
        } catch (Exception e) {
            System.out.printf("Something terrible happened, this wolf has died: %s", e.getMessage());
            isDead = true;
            return Attack.SUICIDE;
        }
    }

    /**
     * If the wolf is dead, or all the wolves of this type are dead, HOLD.
     * Otherwise, get a move from the remote process and return that.
     */
    @Override
    public Move move() {
        if (!Wolf<custom-name>.wolfProcess.getRunning() || isDead) {
            return Move.HOLD;
        }
        try {
            Move mv = Wolf<custom-name>.wolfProcess.move(id, surroundings);

            return mv;
        } catch (Exception e) {
            System.out.printf("Something terrible happened, this wolf has died: %s", e.getMessage());
            isDead = true;
            return Move.HOLD;
        }
    }

    /**
     * The shared static process manager, that synchronizes all communication
     * with the remote process.
     */
    static class WolfProcess extends Thread {
        private Process process;
        private BufferedReader reader;
        private PrintWriter writer;
        private ExecutorService executor;
        private boolean running;

        public boolean getRunning() {
            return running;
        }

        public WolfProcess() {
            process = null;
            reader = null;
            writer = null;
            running = true;
            executor = Executors.newFixedThreadPool(1);
        }

        public void endProcess() {
            running = false;
        }

        /**
         * WolfProcess thread body. Keeps the remote connection alive.
         */
        public void run() {
            try {
                System.out.println("Starting Wolf<custom-name> remote process");
                ProcessBuilder pb = new ProcessBuilder("<invocation>".split(" "));
                pb.redirectErrorStream(true);
                process = pb.start();
                System.out.println("Wolf<custom-name> process begun");
                // STDOUT of the process.
                reader = new BufferedReader(new InputStreamReader(process.getInputStream(), "UTF-8")); 
                System.out.println("Wolf<custom-name> reader stream grabbed");
                // STDIN of the process.
                writer = new PrintWriter(new OutputStreamWriter(process.getOutputStream(), "UTF-8"));
                System.out.println("Wolf<custom-name> writer stream grabbed");
                while(running){
                    this.sleep(0);
                }
                reader.close();
                writer.close();
                process.destroy(); // kill it with fire.
                executor.shutdownNow();
            } catch (Exception e) {
                e.printStackTrace();
                System.out.println("Wolf<custom-name> ended catastrophically.");
            }
        }

        /**
         * Helper that invokes a read with a timeout
         */
        private String getReply(long timeout) throws TimeoutException, ExecutionException, InterruptedException{
            Callable<String> readTask = new Callable<String>() {
                @Override
                public String call() throws Exception {
                    return reader.readLine();
                }
            };

            Future<String> future = executor.submit(readTask);
            return future.get(timeout, TimeUnit.MILLISECONDS);
        }

        /**
         * Sends an initialization command to the remote process
         */
        public synchronized boolean initWolf(int wolf, int map_sz) {
            while(writer == null){
                try {
                this.sleep(0);
                }catch(Exception e){}
            }
            boolean success = false;
            try{
                writer.printf("S%02d%d\n", wolf, map_sz);
                writer.flush();
                String reply = getReply(5000l);
                if (reply != null && reply.length() >= 3 && reply.charAt(0) == 'K') {
                    int id = Integer.valueOf(reply.substring(1));
                    if (wolf == id) {
                        success = true;
                    }
                }
                if (reply == null) {
                    System.out.println("did not get reply");
                }
            } catch (TimeoutException ie) {
                endProcess();
                System.out.printf("Wolf<custom-name> %d failed to initialize, timeout\n", wolf);
            } catch (Exception e) {
                endProcess();
                System.out.printf("Wolf<custom-name> %d failed to initialize, %s\n", wolf, e.getMessage());
            }
            return success;
        }

        /**
         * Send an ATTACK command to the remote process.
         */
        public synchronized Attack fight(int wolf, char opponent) {
            Attack atk = Attack.SUICIDE;
            try{
                writer.printf("A%02d%c\n", wolf, opponent);
                writer.flush();
                String reply = getReply(1000l);
                if (reply.length() >= 3) {
                    int id = Integer.valueOf(reply.substring(1));
                    if (wolf == id) {
                        switch(reply.charAt(0)) {
                            case 'R':
                                atk = Attack.ROCK;
                                break;
                            case 'P':
                                atk = Attack.PAPER;
                                break;
                            case 'S':
                                atk = Attack.SCISSORS;
                                break;
                            case 'D':
                                atk = Attack.SUICIDE;
                                break;
                        }
                    }
                }
            } catch (TimeoutException ie) {
                endProcess();
                System.out.printf("Wolf<custom-name> %d failed to attack, timeout\n", wolf);
            } catch (Exception e) {
                endProcess();
                System.out.printf("Wolf<custom-name> %d failed to attack, %s\n", wolf, e.getMessage());
            }
            return atk;
        }

        /**
         * Send a MOVE command to the remote process.
         */
        public synchronized Move move(int wolf, char[][] map) {
            Move move = Move.HOLD;
            try{
                writer.printf("M%02d", wolf);
                for (int row=0; row<map.length; row++) {
                    for (int col=0; col<map[row].length; col++) {
                        writer.printf("%c", map[row][col]);
                    }
                }
                writer.print("\n");
                writer.flush();
                String reply = getReply(1000l);
                if (reply.length() >= 3) {
                    int id = Integer.valueOf(reply.substring(1));
                    if (wolf == id) {
                        switch(reply.charAt(0)) {
                            case 'H':
                                move = Move.HOLD;
                                break;
                            case 'U':
                                move = Move.UP;
                                break;
                            case 'L':
                                move = Move.LEFT;
                                break;
                            case 'R':
                                move = Move.RIGHT;
                                break;
                            case 'D':
                                move = Move.DOWN;
                                break;
                        }
                    }
                }
            } catch (TimeoutException ie) {
                endProcess();
                System.out.printf("Wolf<custom-name> %d failed to move, timeout\n", wolf);
            } catch (Exception e) {
                endProcess();
                System.out.printf("Wolf<custom-name> %d failed to move, %s\n", wolf, e.getMessage());
            }
            return move;
        }
    }
}

1
मैं इस पोस्ट पर फटा हुआ हूँ। यह एक उत्तर नहीं है, लेकिन यह चुनौती के लिए बहुत उपयोगी है। यह शायद चुनौती शरीर में जाना चाहिए, हालांकि।
Mego

या तो वहाँ या यहाँ, बशर्ते लोग इसे पा सकते हैं और यह उनके लिए उपयोगी है, मैं संतुष्ट रहूंगा :)
प्रोग्रामरन

46

CamoWolf

आवश्यक कोड प्रारूप का दुरुपयोग।

// Optional code here
public class Wolf extends Animal {
    // Optional code here
    public Wolf() { super('W'); // Optional code here }
    public Attack fight(char opponent) { // Required code here. Must return an Attack. }
    public Move move() { // Required code here. Must return a Move. }
    // Optional code here
}

तो, मेरे भेड़िया वास्तव में स्मार्ट है, और वह इसके बजाय एक पत्थर के रूप में छलावरण करता है! पर्यावरण के साथ मिश्रण हमेशा एक अच्छा अस्तित्व रणनीति है!

public class Wolf extends Animal {
    private Move lastMove;
    public Wolf() { super('S'); lastMove = Move.RIGHT; } /*
    public Wolf() { super('W'); }
    public Attack fight(char opponent) { */ public Attack fight(char opponent) {
        switch(opponent) {
        case 'B': return Attack.SCISSORS;
        case 'S': return Attack.PAPER;
        case 'W': return Attack.SCISSORS; // Here's an explanation why:
                                          // the wolves will see me and think I'm a rock.
                                          // Therefore, they'll attack with paper.
                                          // So, I'll use scissors instead!
        case 'L': return Attack.SCISSORS;
        }
    }
    public Move move() {
        // First we run away from any lions that we see, since they are the only threat
        if (surroundings[0][1] == 'L') {
            if (isSafe(surroundings[2][1])) return lastMove = Move.DOWN;
            else if (isSafe(surroundings[1][0])) return lastMove = Move.LEFT;
            else return lastMove = Move.RIGHT;
        }
        if (surroundings[1][0] == 'L') {
            if (isSafe(surroundings[1][2])) return lastMove = Move.RIGHT;
            else if (isSafe(surroundings[0][1])) return lastMove = Move.UP;
            else return lastMove = Move.DOWN;
        }

        // If there's no (threatening) lions in sight, be lazy.
        return lastMove = Move.HOLD;
    }
    private boolean isSafe(char c) { return (c != 'L' && c != 'W') }
}

अद्यतन : isSafeLazyWolf से सुरक्षित होने के लिए नया चेक जोड़ा गया ! हा!
अपडेट 2 : माना जाता है कि आलसी होना भी एक अच्छी उत्तरजीविता है। जब तक एक शेर द्वारा धमकी नहीं दी जाती तब तक वह नहीं चलता। lastMoveअब और ज़रूरत नहीं है, लेकिन मैंने इसे वैसे भी रखा जब मैं कोड को फिर से बदल देता हूं।


29
जब मैंने प्रोजेक्ट में आपका सबमिशन जोड़ दिया, तो मैंने गलती से पूरी क्लास को कमेंट ब्लॉक में डाल दिया।
रेनबोल्ट

2
@Rusher जावा पार्स नेस्टेड टिप्पणी ब्लॉक करता है? : पी
मार्टिन एंडर

6
एक ऐसी दुनिया में जहां LazyWolf इस से बचाव कर सकता है, यह एक शेर होने का नाटक करने और ROCK या बेतरतीब ढंग से चुनने के लिए अधिक समझदारी हो सकती है। यह लोगों से मुठभेड़ों की संख्या को कम करेगा क्योंकि अधिकांश लोग शेरों से बचने की कोशिश करेंगे, और इसे औसतन उन लोगों के खिलाफ जीतना चाहिए जो सोचते हैं कि वे शेर से लड़ रहे हैं।
टिम सेगिन

7
@ रोडीफ यह है।
रेनबोल्ट

2
@ रोडियोफ़ कब मैंने कहा कि यह नहीं था? ;-)
दरवाज़े

38

GatheringWolf

मेरे भेड़िये एक समूह में रहते हैं। वे इकट्ठा होते हैं, अगर शेर उन्हें जाने दें। वे जीवित रहने में इतने अच्छे नहीं हैं, हालाँकि।

अद्यतन: अगर एक शेर उन्हें मजबूर करता है, तो वे अब फिर से कोशिश करते हैं!

गैदरिंगवुल्फ़ के परिणाम का स्क्रीनशॉट

package animals;
import java.util.*;
public class GatheringWolf extends Animal {
    private static int iteration;
    private static Move preferredMove;
    private int localIteration;
    private int loneliness;
    private boolean dangerFlag;
    private Move lastMove;
    public GatheringWolf() {
        super('W');
    }
    @Override
    public Attack fight(char other) {
        switch (other) {
        case 'B':
        case 'L':
            return Attack.SCISSORS;
        case 'S':
            return Attack.PAPER;
        default:
            return Attack.values()[(int) (Math.random() * 3)];
        }
    }
    @Override
    public Move move() {
        if (localIteration == iteration) {
            localIteration++;
            iteration++;
            preferredMove = Math.random() < 0.5 ? Move.DOWN : Move.RIGHT;
        } else
            localIteration = iteration;
        EnumSet<Move> moves = EnumSet.allOf(Move.class);
        if (surroundings[0][1] == 'W')
            moves.remove(Move.UP);
        if (surroundings[1][0] == 'W')
            moves.remove(Move.LEFT);
        if (surroundings[2][1] == 'W')
            moves.remove(Move.DOWN);
        if (surroundings[1][2] == 'W')
            moves.remove(Move.RIGHT);
        if (surroundings[0][0] == 'L') {
            moves.remove(Move.UP);
            moves.remove(Move.LEFT);
        }
        if (surroundings[0][1] == 'L')
            moves.remove(Move.UP);
        if (surroundings[1][0] == 'L')
            moves.remove(Move.LEFT);
        if (surroundings[0][2] == 'L')
            moves.remove(Move.RIGHT);
        if (surroundings[2][0] == 'L')
            moves.remove(Move.DOWN);
        if (surroundings[0][1] == 'L' || surroundings[1][0] == 'L')
            if (moves.size() > 1) {
                moves.remove(Move.HOLD);
                dangerFlag = true;
            }
        int wolfNear = -1;
        for (char[] a : surroundings)
            for (char c : a)
                if (c == 'W')
                    wolfNear++;
        boolean enoughWolfNear = wolfNear >= (Math.random() < 0.9 ? 1 : 2);
        if (moves.contains(Move.HOLD) && enoughWolfNear) {
            loneliness = 0;
            dangerFlag = false;
            return lastMove = Move.HOLD;
        } else
            loneliness++;
        if (loneliness > 10) {
            EnumSet<Move> preferred = EnumSet.copyOf(moves);
            preferred.retainAll(EnumSet.of(preferredMove, Move.HOLD));
            if (!preferred.isEmpty())
                moves = preferred;
        }
        if (loneliness == 2 && dangerFlag) {
            Move reverted = Move.values()[lastMove.ordinal() ^ 0b10];
            dangerFlag = false;
            if (moves.contains(reverted))
                return lastMove = reverted;
        }
        if (moves.contains(Move.HOLD))
            dangerFlag = false;
        if (moves.contains(preferredMove))
            moves.remove(preferredMove == Move.DOWN ? Move.RIGHT : Move.DOWN);
        int n = (int) (Math.random() * moves.size());
        Iterator<Move> ite = moves.iterator();
        while (n-- > 0)
            ite.next();
        return lastMove = ite.next();
    }
}

43
एक दो बार, हमारे भेड़ियों दोस्त बन गए क्योंकि मेरा फंस गया, लेकिन एक हमले की शुरुआत नहीं हुई और तुम्हारा सिर्फ मेरा मान लिया गया था जो पैक का हिस्सा था। :)
अंडरग्राउंडोरेल

1
यह लिखने के लिए धन्यवाद, क्योंकि अन्यथा मैं इसे स्वयं करने जा रहा था। आपसी छद्मता का चतुर उपयोग।
बेन जैक्सन

31

वुल्फ कपड़ों में भेड़

भाग जाता है।

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

मैंने अभी तक इसे LazyWolf के खिलाफ परीक्षण नहीं किया है, लेकिन मेरे पास अच्छे अधिकार पर है कि यह EmoWolf के गधे को मारता है। ;)

(कृपया मुझे क्षमा करें यदि यह कोड भयानक है, तो मैंने पहले कभी भी हैलो वर्ल्ड प्रोग्राम की तुलना में जावा को बहुत अधिक नहीं छुआ है।)

package animals;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

public class Sheep extends Animal {
    public Sheep() { super('W'); }

    private static final Map<Character, Integer> AnimalWeights;
    static{
        AnimalWeights = new HashMap<>();
        AnimalWeights.put('W', -3);
        AnimalWeights.put('S', -1);
        AnimalWeights.put(' ', 0);
        AnimalWeights.put('H', 1);
        AnimalWeights.put('L', -2);
        AnimalWeights.put('B', -1);
    }

    @Override
    public Attack fight(char c) { 
        switch (c) {
            case 'B':
                return Attack.SCISSORS;
            case 'L':
                return Attack.SCISSORS;
            case 'S':
                return Attack.PAPER;
            default:
                return Attack.PAPER;
        } 
    }

    @Override
    public Move move() {

        int xWeight = 0;
        int yWeight = 0;

        // Northwest
        xWeight += AnimalWeights.get(surroundings[0][0]);
        yWeight += AnimalWeights.get(surroundings[0][0]);

        // North
        yWeight += AnimalWeights.get(surroundings[0][1]);

        // Northeast
        xWeight -= AnimalWeights.get(surroundings[0][2]);
        yWeight += AnimalWeights.get(surroundings[0][2]);

        // West
        xWeight += AnimalWeights.get(surroundings[1][0]);

        // East
        xWeight -= AnimalWeights.get(surroundings[1][2]);

        // Southwest
        xWeight += AnimalWeights.get(surroundings[2][0]);
        yWeight -= AnimalWeights.get(surroundings[2][0]);

        // South
        yWeight -= AnimalWeights.get(surroundings[2][1]);

        // Southeast
        xWeight -= AnimalWeights.get(surroundings[2][2]);
        yWeight -= AnimalWeights.get(surroundings[2][2]);

        if (Math.abs(xWeight) < Math.abs(yWeight)) {
            if (yWeight > 0) {
                return Move.UP;
            } else {
                return Move.DOWN;
            }
        } else if (Math.abs(yWeight) < Math.abs(xWeight)) {
            if (xWeight > 0) {
                return Move.RIGHT;
            } else {
                return Move.LEFT;
            }
        }

        // Sit still if no one's around
        return Move.HOLD;
    }
}

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

बस जिज्ञासु, यदि xWeightऔर yWeightदोनों गैर-शून्य हैं और उनके पूर्ण मूल्य समान हैं, तो यह भेड़िया स्थानांतरित नहीं होता है, सही है? और यदि हां, तो क्या वह जानबूझकर था और क्यों?
पैट्रिक रॉबर्ट्स

@PatrickRoberts उफ़
undergroundmonorail

26

प्रविष्टि नहीं, बस प्रत्येक वर्ग = डी के लिए कलर कोड जोड़कर GUI में योगदान करना चाहते हैं

नतीजा

रंगीन जीयूआई

Wild.java

कोड को इसके game.populate(c,100)साथ बदलें :

String[] colors = generateColors(classes.length);
int idx = 0;
for(Class c : classes){
    Animal.setColor(c, colors[idx]);
    idx++;
    game.populate(c, 100);
}
stats.update();

के generateColorsरूप में परिभाषित के साथ:

private static String[] generateColors(int n){
    String[] result = new String[n];
    double maxR = -1000;
    double minR = 1000;
    double maxG = -1000;
    double minG = 1000;
    double maxB = -1000;
    double minB = 1000;
    double[][] colors = new double[n][3];
    for(int i=0; i<n; i++){
        double cos = Math.cos(i * 2 * Math.PI / classes.length);
        double sin = Math.sin(i * 2 * Math.PI / classes.length);
        double bright = 1;
        colors[i][0] = bright + sin/0.88;
        colors[i][1] = bright - 0.38*cos - 0.58*sin;
        colors[i][2] = bright + cos/0.49;
        maxR = Math.max(maxR, colors[i][0]);
        minR = Math.min(minR, colors[i][0]);
        maxG = Math.max(maxG, colors[i][1]);
        minG = Math.min(minG, colors[i][1]);
        maxB = Math.max(maxB, colors[i][2]);
        minB = Math.min(minB, colors[i][2]);
    }
    double scaleR = 255/(maxR-minR);
    double scaleG = 255/(maxG-minG);
    double scaleB = 255/(maxB-minB);
    for(int i=0; i<n; i++){
        int R = (int)Math.round(scaleR*(colors[i][0]-minR));
        int G = (int)Math.round(scaleG*(colors[i][1]-minG));
        int B = (int)Math.round(scaleB*(colors[i][2]-minB));
        result[i] = "#"+String.format("%02x%02x%02x", R, G, B);
    }
    return result;
}

कौन सा एल्गोरिथ्म इस StackOverflow उत्तर से लिया गया है

के साथ colorऔर setColorAnimal.java में परिभाषित किया जा रहा है

Animal.java

public static HashMap<Class, String> color = new HashMap<Class, String>();

public static void setColor(Class animalClass, String animalColor){
    color.put(animalClass, animalColor);
}

फिर toStringGame.java और सांख्यिकी.java में विधियों को अपडेट करें :

Game.java

public String toString() {
    String s = "<html>";
    for (ArrayList<ArrayList<Animal>> row : board) {
        for (ArrayList<Animal> cell : row) {
            if (cell.isEmpty())
                s += "&nbsp;&nbsp;";
            else
                s += "<span style='color:"+ Animal.color.get(cell.get(0).getClass()) +"'>" + cell.get(0).letter + "</span>&nbsp;";
        }
        s+="<br>";
    }
    return s + "</html>";
}

Statistics.java

public String toString() {
    String s = "<html>";
    for (int i = 0; i < classes.length; i++) {
        s += "<span style='color:" + Animal.color.get(classes[i]) + "'>" + classes[i] + "</span>&nbsp;-&nbsp;" + living[i] + "<br>";
    }
    return s + "</html>";
}

2
सुंदर। मैंने कल बस स्क्रीन को देखते हुए कई मिनट गुजार दिए। लगा जैसे टैंक रीडिंग मैट्रिक्स।
एवररोसेस

अनुकरण .... .... .... .... का ..... धीमा .... (30 सेकंड के बाद 5 पुनरावृत्तियों)
user3188175

हा - हा हाँ। लेकिन यह सिमुलेशन के डिजाइन में अंतर्निहित है, जो प्रत्येक पुनरावृत्ति के लिए HTML कोड प्रिंट कर रहा है।
जस्टफुल

अगर मैं इस पोस्ट का लिंक प्रदान करूं तो क्या मैं इसे अपने Google ड्राइव (चैलेंज में लिंक) पर साझा कर सकता हूं? यह भेड़ियों की एक छोटी संख्या के परीक्षण के लिए शानदार ढंग से काम करता है।
रेनबोल्ट

1
हाँ तुम कर सकते हो। आप कुछ भेड़ियों के लिए रेंडरिंग प्रक्रिया को तेज करने के लिए कुछ शुरुआती रेंडरिंग स्किप को भी शामिल कर सकते हैं, जैसा कि मैंने भूकंप के संबंध में अपनी अन्य पोस्ट में लिखा था।
१६:१४

23

अल्फा भेड़िया

चमकने का समय! मेरा दूसरा भेड़िया कैम्परवुल्फ बहुत पतला था, अब अल्फावुल्फ आता है, जो अधिक मांसल है!

सिंह को मानक तरीके से चकमा देने के बजाय, यह उनके साथ क्षेत्र को स्वैप करता है। यह आसपास के प्रत्येक क्षेत्र के लिए खतरों-मूल्यों को भी बताता है।

package animals;

import java.util.Random;

public class AlphaWolf extends Animal{
    private Boolean lionMoveDown = true;

    public AlphaWolf() {
        super('W');
    }
    @Override
    public Attack fight(char opponent) {
        switch(opponent){
        case 'B':
        case 'L':
            return Attack.SCISSORS;
        case 'S': 
            return Attack.PAPER;
        default:
            return randomAttack();
        }
    }

    @Override
    public Move move() {
        int[] danger = new int[4];
        final int wolfsDanger = 4;
        lionMoveDown = !lionMoveDown;
        if(surroundings[0][1] == 'L' && lionMoveDown) {
            return Move.UP;
        }
        if(surroundings[1][0] == 'L'&& !lionMoveDown) {
            return Move.LEFT;
        }
        if(surroundings[0][1] == 'W') {
            danger[0] += wolfsDanger;
        }
        if(surroundings[1][2] == 'W') {
            danger[1] += wolfsDanger;
        }
        if(surroundings[2][1] == 'W') {
            danger[2] += wolfsDanger;
        }
        if(surroundings[1][0] == 'W') {
            danger[3] += wolfsDanger;
        }
        if(surroundings[0][0] == 'W') {
            danger[0]++;
            danger[3]++;
        }
        if(surroundings[0][2] == 'W') {
            danger[0]++;
            danger[1]++;
        }
        if(surroundings[2][2] == 'W') {
            danger[1]++;
            danger[2]++;
        }
        if(surroundings[1][2] == 'W') {
            danger[2]++;
            danger[3]++;
        }
        Boolean shouldMove = false;
        Move bestMove = Move.HOLD;
        int leastDanger = 4;
        for(int i = 0; i < 4; i++) {
            if (danger[i] < leastDanger) {
                bestMove = Move.values()[i];
            }
            if(danger[i] > 3) {
                shouldMove = true;
            }
        }
        if(shouldMove) {
            return bestMove;
        } else {
            return Move.HOLD;
        }
    }

    public Attack randomAttack() {
        Random rand = new Random();
        switch (rand.nextInt(3)){
            case 1: return Attack.SCISSORS;
            case 2: return Attack.ROCK;
            default: return Attack.PAPER;
        }
    }

}

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


1
"क्षेत्र स्वैप" का क्या अर्थ है? बस उत्सुक, क्योंकि मैं इसे काम पर नहीं चला सकता।
रेनबोल्ट

मेरे सभी सिमुलेशन पर, आप 1000 पुनरावृत्तियों के बाद औसतन 80-90 भेड़ियों के साथ जीत रहे हैं। मेरे पास केवल कानूनी भेड़िये हैं जो जावा में लिखे गए हैं जो अब तक खदानों पर प्रस्तुत किए गए हैं। फिर भी वह 10 भेड़ियों की तरह है।
शेफ

@Rusher एक शेर मेरी भेड़िया ऊपर है और नीचे चले जाएँगे, तो मेरे भेड़िया ऊपर आ जाएगा
CommonGuy

आपको कुछ विरोधी wilfcamo कोड जोड़ने की आवश्यकता है। शेर का पता पैटर्न का उपयोग करने के लिए बहुत अच्छा विचार :)
लेस्तो

9
अब किसी को एक भेड़िये का आविष्कार करने की आवश्यकता है जो किसी भी शेर को ढूंढ लेगा, इसलिए आप उस क्षण में भाग जाएंगे जब आप शेर के साथ अदला-बदली करने की कोशिश करेंगे।
AJMansfield

23

जुआरी भेड़िया

जुआरी भेड़िया को मौके लेना पसंद है इसलिए वह गलती से उम्मीद करता है कि लेडी लक उसकी तरफ है! सौभाग्य से उसके लिए, वह उसे कभी निराश नहीं करती है! भाग्य के सतत स्ट्रोक से, जुआरी वुल्फ अविश्वसनीय कारणों से सभी गैर-भेड़िया बाधाओं के क्षेत्र को साफ कर देता है!

package animals;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Random;

public class GamblerWolf extends Animal {
    private static int last = 0;

    public GamblerWolf() { super('W'); gamble(); }
    public Attack fight(char opponent) {
        switch (opponent) {
        case 'S': return Attack.ROCK; /* Camo Wolf? */
        case 'B': return Attack.SCISSORS;
        case 'L': return Attack.SCISSORS;
        default:  return attackWolf();
        }
    }
    public Move move() {
        ArrayList<Move> moves = (ArrayList<Move>) Arrays.asList(Move.values());
        Collections.shuffle(moves);
        for(Move move : moves)
          if(isThreatenedBy(move))
            return moveToEvade(move);
        return Move.HOLD;
    }

    /* Remember, Gamblers Don't Gamble */
    @SuppressWarnings("serial")
    private static void gamble() {
        try {
        Field field = Math.class.getDeclaredField("randomNumberGenerator"); 
        field.setAccessible(true);
        field.set(null, new Random() { 
              @Override
              public double nextDouble() {
                return 4; // chosen by fair dice roll
              }           // guaranteed to be random
            });           // proof: http://xkcd.com/221/
        }
        catch (SecurityException        e) {}
        catch (NoSuchFieldException     e) {}
        catch (IllegalArgumentException e) {}
        catch (IllegalAccessException   e) {}
    }

    private static Attack attackWolf() {
        return Attack.values()[last++ % 3];
    }
    private boolean isThreatenedBy(Move move) {
        return isWolf(move) 
            || isStone(move); 
    }

    private Move moveToEvade(Move move) {
        if(isSafeMove(getOpposite(move)))
            return getOpposite(move);

        ArrayList<Move> moves = (ArrayList<Move>) Arrays.asList(getOrthogonal(move));
        Collections.shuffle(moves);
        for(Move m : moves)
            if(isSafeMove(m))
                return m;
        return Move.HOLD;
    }

    private static Move[] getOrthogonal(Move move) {
        switch(move){
        case UP:
        case DOWN:  return new Move[] { Move.LEFT, Move.RIGHT };
        case LEFT:
        case RIGHT: return new Move[] { Move.UP,   Move.DOWN };
        default:    return null;
        }
    }

    private static Move getOpposite(Move move) {
        switch(move){
        case UP:    return Move.DOWN;
        case DOWN:  return Move.UP;
        case LEFT:  return Move.RIGHT;
        case RIGHT: return Move.LEFT;
        default:    return null;
        }
    }

    private boolean isSafeMove(Move move) {
        return !isWolf(move)
            && !isStone(move)
            && !couldAWolfMoveHere(move);
    }

    private boolean isWolf(Move move) {
        return isX(move,'W');
    }

    private boolean isStone(Move move) {
        return isX(move,'S');
    }

    private boolean isX(Move m, char c) {
        switch (m) {
        case UP:    return surroundings[0][1] == c;
        case LEFT:  return surroundings[1][0] == c;
        case RIGHT: return surroundings[1][2] == c;
        case DOWN:  return surroundings[2][1] == c;
        default:    return false;
        }
    }

    private boolean couldAWolfMoveHere(Move move) {
        switch (move) {
        case UP:    return surroundings[0][2] == 'W' || surroundings[0][0] == 'W';
        case LEFT:  return surroundings[2][0] == 'W' || surroundings[0][0] == 'W';
        case RIGHT: return surroundings[0][2] == 'W' || surroundings[2][2] == 'W';
        case DOWN:  return surroundings[2][0] == 'W' || surroundings[2][2] == 'W';
        default:    return false;
        }
    }
}

संपादित करें: v1.1

  • अब पत्थर (कैमो-भेड़ियों?) से बचा जाता है

  • बढ़ी हुई बेतरतीबी!


5
मुझे लगता है कि मैं इसे अपने भेड़ियों से static{System.setSecurityManager(new SecurityManager());}
जोड़ूंगा

13
जब आप निष्पक्ष नहीं खेल सकते हैं, तो +1: डी
प्रोग्रामरडान

5
दुर्भाग्य से return 4; // chosen by fair dice roll. guaranteed to be random.यहाँ का उपयोग नहीं कर सकते ...
Vi।

1
यदि आप और अधिक दुष्ट होना चाहते हैं, तो और Math.random()भी अधिक के अनुबंध को तोड़ दें ; वापसी मान जो [0,1) सीमा से बाहर हैं, शायद अनंत या NaN भी। या, जितना संभव हो उतना बुरा होने के लिए, बस कुछ भी वापस करने के बजाय एक रनटाइम अपवाद को फेंक दें (केवल जनरेटर सेट करके भी प्राप्त करने योग्य null)।
रनर १११

1
@AlexL। एक ForrestWolfसमस्या की तरह लगता है ...
recursion.ninja

22

CamperWolf

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

package animals;

public class CamperWolf extends Animal {
    public CamperWolf() { super('W'); }
    @Override
    public Attack fight(char opponent) {  
        switch(opponent){
        case 'B':
        case 'L':
            return Attack.SCISSORS;
        case 'S': 
            return Attack.ROCK;
        default:
            return Attack.values()[(int) (Math.random() * 3)];
        }
    }
    @Override
    public Move move() { return Move.HOLD; }
}

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


शेर इसे भी मार सकते हैं। यदि शेर कैंची चलाता है, तो आपका भेड़िया छद्म रूप से मर जाएगा।
टिम सेगिन

2
बधाई हो यार। आप और आपकी 15 पंक्तियाँ वर्तमान में जीत रही हैं।
रेनबोल्ट

2
@Rusher धन्यवाद :) downvoter कृपया समझा सकते हैं कि उन्होंने क्यों अपमानित किया?
कॉमनगय

@ मैनू ऐसा नहीं है कि यह मायने रखता है, क्योंकि स्टोन्स हिल नहीं सकते हैं, लेकिन क्या आपका मामला 'एस' पर वापस नहीं आना चाहिए।
डेविडजेलिक्स

3
हाँ, मैंने पूछने के बाद कैमोवुल्फ़ को देखा। मुश्किल आदमी!
डेविडजेलिक्स

22

DeepWolf

मैंने इसमें बहुत अधिक समय लगाया ... वैसे भी, यह भेड़िया "गहरी" विश्लेषिकी का उपयोग करता है, इकट्ठा करता है और उतना ही पर्यावरणीय डेटा का उपयोग करता है जितना मैं इसके उपयोग के लिए सोच सकता था। विश्लेषण भेड़िया-विशिष्ट ज्ञान के मिश्रण पर संचालित होता है, जैसे कि शेर और भेड़ियों के ज्ञात स्थानों और भविष्य के स्थानों की भविष्यवाणियां, और अनुमानित आबादी, भेड़िया युद्ध के इतिहास और जैसे एक पशु प्रतिद्वंद्वी के साथ टकराने के खतरे को जानने के लिए पैक करें। यह अतिरिक्त रूप से भारी है, क्योंकि बहुत सारे तर्क होने के अलावा, मैं ऑब्जेक्ट-ओरिएंटेड डिज़ाइन पर ओवरबोर्ड गया और इसमें बहुत सारे विशेष-उद्देश्य वर्ग और विधियाँ हैं।

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

Averages:
Bear 0.0
Lion 0.0
Stone 3.51
Wolf 1.56
AlphaWolf 77.05
CamperWolf 69.17
DeepWolf 90.48
EmoWolf 39.92
GatheringWolf 52.15
HerjanWolf 86.55
HonorWolf 86.76
HybridWolf 86.78
LazyWolf 71.11
LionHunterWolf 32.45
MimicWolf 0.4
MOSHPITFRENZYWolf 8.95
OmegaWolf 88.67
ProAlpha 83.28
Sheep 54.74
StoneEatingWolf 75.29
WolfWithoutFear 11.9

Maxes:
Bear 0
Lion 0
Stone 9
Wolf 4
AlphaWolf 89
CamperWolf 81
DeepWolf 96
EmoWolf 57
GatheringWolf 65
HerjanWolf 95
HonorWolf 97
HybridWolf 95
LazyWolf 83
LionHunterWolf 41
MimicWolf 3
MOSHPITFRENZYWolf 22
OmegaWolf 95
ProAlpha 91
Sheep 66
StoneEatingWolf 88
WolfWithoutFear 18

Mins:
Bear 0
Lion 0
Stone 0
Wolf 0
AlphaWolf 65
CamperWolf 57
DeepWolf 83
EmoWolf 26
GatheringWolf 37
HerjanWolf 79
HonorWolf 79
HybridWolf 79
LazyWolf 58
LionHunterWolf 20
MimicWolf 0
MOSHPITFRENZYWolf 1
OmegaWolf 81
ProAlpha 70
Sheep 43
StoneEatingWolf 66
WolfWithoutFear 5

डीपवुल्फ़ 90.48 के औसत के साथ पहले स्थान पर है, हालांकि केवल दूसरे स्थान ओमेगावॉल्फ के 88.67 से लगभग 2 से अधिक की संकीर्ण बढ़त के साथ। केवल 2% सुधार के लिए कोड की लगभग 4x पंक्तियाँ! हेर्जनवुल्फ़, होनोरवुल्फ़, और हाइब्रिड वुल्फ तीसरे स्थान के लिए, ओमेगावॉल्फ़ को पीछे छोड़ते हुए क्रमशः 86.55, 86.76, और 86.78 औसत के साथ लगभग 2 से अधिक।

आगे की हलचल के बिना, मैं कोड प्रस्तुत करूंगा। यह इतने बड़े पैमाने पर है कि बेहतर स्थिरांक / तर्क के लिए संभावित त्रुटियां और / या संभावनाएं हैं जो मैं नहीं देख पा रहा हूं। यदि आपके पास कोई प्रतिक्रिया है, तो मुझे बताएं!

इस लिंक पर कोड, क्योंकि यह पोस्ट चरित्र सीमा को उड़ाने के लिए निकला है: Ideone


मुझे नहीं पता कि क्या ड्रॉपबॉक्ससर्कंटेंट फ़ाइल खो देगा, इसलिए मैंने इसे ideone पर पोस्ट किया: ideone.com/uRNxvj
जस्टिन

3
@ Runer112 प्रभावशाली! मैं कोड को देख रहा हूं और मैं थोड़ा खो गया हूं: पी लेकिन एक अवधारणा जो मुझे बताती है कि आप जो निर्णय ले रहे हैं उसका उपयोग कर रहे हैं जो भेड़ियों के अनुकूल हैं या नहीं
Moogie

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

संकलन नहीं किया क्योंकि MAP_SIZE एक गैर-स्थिर चर है। चूंकि मैंने नहीं कहा कि यह एक उदाहरण चर होगा, इसलिए मैंने इसे आपके लिए निर्धारित किया है। बस आप यह जानना चाहते थे कि मैंने पूरी परियोजना को पोस्ट किया था और आपने अपने बटरेड चर नामों को देखा था।
रेनबोल्ट

@ रोशेर ओह, व्हॉट्स। मुझे लगता है कि मैं अभी भी सैंडबॉक्स से गेम कोड के पुराने संस्करण के साथ चल रहा था, और या तो MAP_SIZEचर वास्तव में वापस मौजूद नहीं था या किसी कारण से मैंने इसे अनदेखा कर दिया और अपने स्वयं के स्थैतिक संस्करण में जोड़ा। मुझे यह भी आश्चर्य है कि मेरे भेड़ियों ने मेरे परीक्षणों में अन्य सभी भेड़ियों की तुलना में लगातार थोड़ा बेहतर प्रदर्शन किया, लेकिन क्या आप में भी बुरा था ... विभिन्न भेड़िया सेट, मुझे लगता है? या क्या आप 1000 से अधिक पुनरावृत्तियों के लिए अपने खेल चलाते हैं? या आपको बस एक बड़े नमूने के आकार की आवश्यकता हो सकती है, 5 सांख्यिकीय रूप से महान नहीं है।
Runer112

21

WolfRunningWithScissors

किसी ने भी वुल्फनिंगनिंगविश कैंची को कैंची से नहीं चलाने के लिए कहा। या हो सकता है उन्होंने किया हो, लेकिन वह वैसे भी करता है।

यदि वह एक दुश्मन में दौड़ता है, तो वह या तो कैंची से जीत जाएगा, कैंची से हार जाएगा, कैंची से टिक जाएगा, या अपनी आंख को बाहर कर देगा (आत्महत्या)।

package animals;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;


public class WolfRunningWithScissors extends Animal{

    public WolfRunningWithScissors() {
        super('W');
    }

    @Override
    public Attack fight(char c) {
        List<Attack> att = new ArrayList<>();
        att.add(Attack.SCISSORS);
        att.add(Attack.SUICIDE);
        Collections.shuffle(att);
        return att.get(0);
    }

    @Override
    public Move move() {
        List<Move> m = new ArrayList<>();
        m.add(Move.UP);
        m.add(Move.DOWN);
        m.add(Move.LEFT);
        m.add(Move.RIGHT);
        Collections.shuffle(m);
        return m.get(0);
    }

}

बस मजे के लिए हामी भरना चाहता था। मैंने पहले कभी जावा का उपयोग नहीं किया है और यह परीक्षण नहीं किया है, लेकिन यह काम करना चाहिए। मेरा रैंडम अटैक और मूविंग कोड getRandomAttack()StoneEatingWolf से आधारित है ।


14

ओमेगा भेड़िया

अन्योन्याश्रित व्युत्पन्न समाधान जो अल्फा वुल्फ के समान व्यवहार करता है, इसलिए इसका नाम ओमेगा वुल्फ है

यह भेड़िया आसपास की कोशिकाओं का एक "खतरे" का नक्शा बनाता है और सबसे सुरक्षित सेल को गति (या पकड़) का चयन करेगा।

सबसे पहले कोशिकाएँ जहाँ शेर आगे बढ़ेंगी उन्हें EXTREAME_DANGER स्तर दिया जाता है। फिर किसी भी ज्ञात भेड़ियों के आसपास की कोशिकाओं को हमले की immediacy के आधार पर खतरे का स्तर दिया जाता है ... अर्थात यदि भेड़िया ओमेगा भेड़िया के लिए विकर्ण है, तो इसे एक कम खतरा माना जाता है, हालांकि भेड़ियों जो आसन्न हैं उन्हें एक मध्यम खतरा माना जाता है।

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

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

मेरे परीक्षण में ओमेगा वुल्फ लगातार 10 में से 9 बार अल्फा बॉट के खिलाफ जीतता है ... हालांकि मार्जिन बहुत ठीक है: पी

एवीजी शेष जीवित भेड़ियों के त्वरित परिणाम 1000 पुनरावृत्तियों के 100 राउंड के बाद:

class animals.OmegaWolf - 85
class animals.HonorWolf - 82
class animals.ProAlpha - 79
class animals.AlphaWolf - 77
class animals.ShadowWolf - 77
class animals.LazyWolf - 62
class animals.CamperWolf - 61
class animals.StoneEatingWolf - 59
class animals.GatheringWolf - 48
class animals.Sheep - 42
class animals.EmoWolf - 34
class animals.LionHunterWolf - 28
class animals.GamblerWolf (no cheating) - 27
class animals.WolfWithoutFear - 11
class animals.MOSHPITFRENZYWolf - 5
class animals.Wolf - 3
class animals.Stone - 2
class animals.Bear - 0
class animals.Lion - 0
class animals.MimicWolf - 0
class animals.Wion - 0

कोड:

package animals;

import wild.Wild;

public class OmegaWolf extends Animal {

    boolean lionWillMoveDown=true;

    private static final int LOW_DANGER = 10;
    private static final int MODERATE_DANGER = LOW_DANGER*2;
    private static final int EXTREAME_DANGER = MODERATE_DANGER*4;

    private static final int UP=1;
    private static final int LEFT=3;
    private static final int RIGHT=5;
    private static final int DOWN=7;
    private static final int UP_LEFT=0;
    private static final int UP_RIGHT=2;
    private static final int DOWN_LEFT=6;
    private static final int DOWN_RIGHT=8;

    private static final int WOLVES_SPECIES_COUNT=(int) Math.round(Math.pow(((float) Wild.MAP_SIZE)/20,2)-3)-3;

    /*
     * Interdependently derived solution that behaves very similar to Alpha Wolf, hence the name Omega Wolf
     * 
     * This wolf generates a "danger" map of the surrounding cells and will choose the movement (or hold) to the safest cell.
     * 
     * The firstly the cells where lions will move next are given EXTREAME_DANGER level
     * Then the cells surrounding any detected Wolves are given danger levels based on the immediacy of attack... i.e. if the wolf is diagonal to the omega wolf 
     * it is deemed a low threat however wolves that are adjacent are deemed a moderate threat.
     * The "danger" map is then blurred to allow bleeding of the threats to surrounding cells. This allows the omega wolf to "sense" threat vectors and to avoid it.
     * 
     * Currently the actual attack logic is very primitive. I hope to be able to give it more smarts and eek out better win/lose ratios. This should be possible if 
     * I put in some statistical heuristics.
     */

    public OmegaWolf() { 
        super('W'); }


    @Override
    public Attack fight(char opponent) {
        switch(opponent){
        case 'B':
        case 'L':
            return Attack.SCISSORS;
        case 'S': 
            return Attack.PAPER;
        default:
            // if there is only one wolf species then it must be another omega wolf.
            if (WOLVES_SPECIES_COUNT==1)
            {
                return Attack.SCISSORS;
            }
            else
            {
                // lets just choose an attack with equal weight.
                double rand = Math.random();
                if (rand < 0.333333)
                {
                    return Attack.PAPER;
                }
                if (rand < 0.666667)
                {
                    return Attack.SCISSORS;
                }
                return Attack.ROCK;

            }
        }
    }

    public Move move() {

        lionWillMoveDown = !lionWillMoveDown;


        Move move = Move.HOLD;

        int[][] dangerMap = new int[3][3];
        int[][] blurredDangerMap = new int[3][3];

        // sense Lion Danger
        for (int y=0;y<3;y++)
        {
            for (int x=0;x<3;x++)
            {
                if (surroundings[y][x]=='L')
                {
                    if (lionWillMoveDown && y!=2)
                    {
                        dangerMap[y+1][x]+=EXTREAME_DANGER;
                    }
                    else if (x!=2)
                    {
                        dangerMap[y][x+1]+=EXTREAME_DANGER;
                    }
                }
            }
        }

        // sense Wolf Danger adjacent
        // UP
        if (surroundings[0][1]=='W')
        {
            dangerMap[0][1]+=MODERATE_DANGER;
            dangerMap[0][0]+=LOW_DANGER;
            dangerMap[0][2]+=LOW_DANGER;
            dangerMap[1][1]+=MODERATE_DANGER;
        }
        // DOWN
        if (surroundings[2][1]=='W')
        {
            dangerMap[2][1]+=MODERATE_DANGER;
            dangerMap[2][0]+=LOW_DANGER;
            dangerMap[2][2]+=LOW_DANGER;
            dangerMap[1][1]+=MODERATE_DANGER;
        }
        // LEFT
        if (surroundings[1][0]=='W')
        {
            dangerMap[1][0]+=MODERATE_DANGER;
            dangerMap[0][0]+=LOW_DANGER;
            dangerMap[2][0]+=LOW_DANGER;
            dangerMap[1][1]+=MODERATE_DANGER;
        }
        // RIGHT
        if (surroundings[1][2]=='W')
        {
            dangerMap[1][2]+=MODERATE_DANGER;
            dangerMap[0][2]+=LOW_DANGER;
            dangerMap[2][2]+=LOW_DANGER;
            dangerMap[1][1]+=MODERATE_DANGER;
        }

        // sense Wolf Danger diagonally
        // UP_LEFT
        if (surroundings[0][0]=='W')
        {
            dangerMap[0][0]+=LOW_DANGER;
            dangerMap[0][1]+=MODERATE_DANGER;
            dangerMap[1][0]+=MODERATE_DANGER;
        }
        // DOWN_LEFT
        if (surroundings[2][0]=='W')
        {
            dangerMap[2][0]+=LOW_DANGER;
            dangerMap[2][1]+=MODERATE_DANGER;
            dangerMap[1][0]+=MODERATE_DANGER;
        }
        // UP_RIGHT
        if (surroundings[0][2]=='W')
        {
            dangerMap[0][2]+=LOW_DANGER;
            dangerMap[1][2]+=MODERATE_DANGER;
            dangerMap[0][1]+=MODERATE_DANGER;
        }
        // DOWN_RIGHT
        if (surroundings[2][2]=='W')
        {
            dangerMap[2][2]+=LOW_DANGER;
            dangerMap[2][1]+=MODERATE_DANGER;
            dangerMap[1][2]+=MODERATE_DANGER;
        }


        // generate a blurred danger map. This bleeds danger to surrounding cells.
        int yj,xi,sampleCount,cumulativeDanger;
        for (int y=0;y<3;y++)
        {
            for (int x=0;x<3;x++)
            {
                sampleCount=0;
                cumulativeDanger=0;
                for (int j=-1;j<2;j++)
                {
                    for (int i=-1;i<2;i++)
                    {
                        yj=y+j;
                        xi=x+i;
                        if (yj>-1 && yj<3 && xi>-1 && xi<3)
                        {
                            cumulativeDanger+=dangerMap[yj][xi];
                            sampleCount++;
                        }
                    }
                }
                blurredDangerMap[y][x]=(dangerMap[y][x]+cumulativeDanger/sampleCount)/2;
            }
        }

        // find the safest cell
        int safestCellDanger=Integer.MAX_VALUE;
        int safestCellId = -1;
        int cellId=0;

        for (int y=0;y<3;y++)
        {
            for (int x=0;x<3;x++)
            {
                if (blurredDangerMap[y][x]<safestCellDanger)
                {
                    safestCellDanger=blurredDangerMap[y][x];
                    safestCellId=cellId;
                }
                cellId++;
            }
        }

        // safest cell is adjacent so move there
        if ((safestCellId&1)==1)
        {
            switch (safestCellId)
            {
                case UP:
                    move=Move.UP;
                    break;
                case LEFT:
                    move=Move.LEFT;
                    break;
                case RIGHT:
                    move=Move.RIGHT;
                    break;
                case DOWN:
                    move=Move.DOWN;
                    break;
            }
        }
        // safestCell is a diagonal cell or current cell
        else
        {
            // lets initialise the move to Hold.
            move = Move.HOLD;

            switch (safestCellId)
            {
                case UP_LEFT:

                    // check to see whether holding is not safer than moving up
                    if (dangerMap[1][1] > dangerMap[0][1] )
                    {
                        // move up if safer than moving left or if equally safe, when randomly chosen 
                        if (dangerMap[0][1] < dangerMap[1][0] || (dangerMap[0][1] == dangerMap[1][0] && Math.random()>0.5))
                        {
                            move=Move.UP;
                        } 
                        // left must be safest :P
                        else
                        {

                            move=Move.LEFT;
                        }
                    }
                    // check to see whether holding is not safer than moving left
                    else if (dangerMap[1][1] > dangerMap[1][0] )
                    {
                        move=Move.LEFT;
                    }

                    break;
                case UP_RIGHT:
                    // check to see whether holding is not safer than moving up
                    if (dangerMap[1][1] > dangerMap[0][1] )
                    {
                        // move up if safer than moving right or if equally safe, when randomly chosen 
                        if (dangerMap[0][1] < dangerMap[1][2]|| (dangerMap[0][1] == dangerMap[1][2] && Math.random()>0.5))
                        {
                            move=Move.UP;
                        } 
                        // right must be safest :P
                        else
                        {
                            move=Move.RIGHT;
                        }
                    }
                    // check to see whether holding is not safer than moving right
                    else if (dangerMap[1][1] > dangerMap[1][2] )
                    {
                        move=Move.RIGHT;
                    }
                    break;
                case DOWN_LEFT:
                    // check to see whether holding is not safer than moving down
                    if (dangerMap[1][1] > dangerMap[2][1] )
                    {
                        // move down if safer than moving left or if equally safe, when randomly chosen 
                        if (dangerMap[2][1] < dangerMap[1][0]|| (dangerMap[2][1] == dangerMap[1][0] && Math.random()>0.5))
                        {
                            move=Move.DOWN;
                        } 
                        // left must be safest :P
                        else
                        {
                            move=Move.LEFT;
                        }
                    }
                    // check to see whether holding is not safer than moving left
                    else if (dangerMap[1][1] > dangerMap[1][0] )
                    {
                        move=Move.LEFT;
                    }
                    break;
                case DOWN_RIGHT:
                    // check to see whether holding is not safer than moving down
                    if (dangerMap[1][1] > dangerMap[2][1] )
                    {
                        // move down if safer than moving right or if equally safe, when randomly chosen 
                        if (dangerMap[2][1] < dangerMap[2][2] || (dangerMap[2][1] == dangerMap[1][2] && Math.random()>0.5))
                        {
                            move=Move.DOWN;
                        } 
                        // right must be safest :P
                        else
                        {
                            move=Move.RIGHT;
                        }
                    }
                    // check to see whether holding is not safer than moving right
                    else if (dangerMap[1][1] > dangerMap[1][2] )
                    {
                        move=Move.RIGHT;
                    }
                    break;
            }
        }

        return move;

    }
}

14

StoneGuardianWolf

यह बहुत मजेदार था। मैंने विज़ुअलाइज़ेशन के लिए createjs समर्थन के साथ जावा कोड का एक क्‍लांकी पोर्ट बनाया: जावास्क्रिप्ट स्टोनगार्डियनवुल्फ

स्टोनगार्डियनवॉल्फ पालतू चट्टानों को ढूंढता है और स्टोन्स के बगल में शरण लेता है। वह उनकी रक्षा करती है और अपनी सुरक्षा के लिए खुद को बलिदान कर देती है।

आँकड़े

एकल खिलाड़ी: ~ 75% वुल्फ उत्तरजीविता दर + 35% पेट (स्टोन) उत्तरजीविता दर।

सारांश: 75% + 35% ---> 110% सफलता दर!:)

मल्टी प्लेयर: अनटाइटेड।

लॉग बदलें

v2: अद्यतित AI बनाम GamblerWolf और पालतू रॉक की रणनीति की मांग।

v1: बेहतर वुल्फ परिहार

v0: जन्मदिन

जावा कोड

package animals;

public class StoneGuardianWolf extends Animal {
    public StoneGuardianWolf() {
        super('W');
    }

    private boolean petRock = false;
    private int heartache = 0;

    public Attack fight(char c) {
        this.heartache--;

        switch (c) {
        case 'B':
            return Attack.SCISSORS;
        case 'L':
            return Attack.SCISSORS;
        case 'S': // A motherly sacrifice
            return Attack.SUICIDE;
        default:
            int n = this.heartache % 3;
            if (n < 1)
                return Attack.PAPER;
            if (n < 2)
                return Attack.ROCK;
            return Attack.SCISSORS;
        }
    }

    public Move move() {
        char[][] surr = this.surroundings;
        int[][] clairvoyance = new int[3][3];

        for (int i = 0; i < 3; i++)
            for (int j = 0; j < 3; j++)
                clairvoyance[i][j] = 1;

        boolean seeNoStone = true;

        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                switch (surr[i][j]) {
                case 'L':
                    if (i < 1 && j < 1) {
                        clairvoyance[1][0] += 50;
                        clairvoyance[0][1] += 50;
                    }

                    if (i == 1 && j < 1) { // above
                        clairvoyance[1][1] += 50;
                    }

                    if (i < 1 && j == 1) { // left
                        clairvoyance[1][1] += 50;
                    }
                    break;

                case 'S': // seek stones for protection
                    seeNoStone = false;
                    this.petRock = true;
                    clairvoyance[i][j] += 999; // Only hugs!
                    if (i < 2)
                        clairvoyance[i + 1][j] -= 10;
                    if (j < 2)
                        clairvoyance[i][j + 1] -= 10;
                    if (i > 0)
                        clairvoyance[i - 1][j] -= 10;
                    if (j > 0)
                        clairvoyance[i][j - 1] -= 10;
                    break;

                case 'B': // ignore bears
                    break;

                case 'W':
                    // skip self
                    if (i == 1 && j == 1)
                        continue;
                    int m = 25; // avoid wolves

                    // don't fight unless pet rock is in danger
                    if (petRock)
                        clairvoyance[i][j] -= 999; // motherly wrath
                    else
                        clairvoyance[i][j] += 100;

                    // avoid stepping into wolf path
                    if (i != 1 && j != 1) {
                        if (i < 2)
                            clairvoyance[i + 1][j] += m;
                        if (j < 2)
                            clairvoyance[i][j + 1] += m;
                        if (i > 0)
                            clairvoyance[i - 1][j] += m;
                        if (j > 0)
                            clairvoyance[i][j - 1] += m;
                    }
                    break;

                default:
                    clairvoyance[i][j] += 0;
                }
            } // for loop
        } // for loop

        int size = clairvoyance[1][1];
        int x = 1;
        int y = 1;

        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                if (i != 1 || j != 1)
                    continue;
                int tmp = clairvoyance[i][j];
                if (tmp < size) {
                    size = tmp;
                    x = i;
                    y = j;
                }
            }
        }

        if (seeNoStone)
            this.heartache++;

        this.petRock = false;
        if (seeNoStone && heartache % 10 == 0) { // Find a pet stone! :3
            if ((heartache % 3) < 2 || clairvoyance[1][2] >= 45) {
                // try move right
                if (clairvoyance[2][1] < 45)
                    return Move.RIGHT;
            }

            // try down instead
            if (clairvoyance[1][2] < 45)
                return Move.DOWN;
        }

        if (x == 0 && y == 1)
            return Move.LEFT;
        if (x == 2 && y == 1)
            return Move.RIGHT;
        if (x == 1 && y == 0)
            return Move.UP;
        if (x == 1 && y == 2)
            return Move.DOWN;

        if (!seeNoStone)
            this.petRock = true;

        return Move.HOLD;
    }
}

5
पत्थर खाने वुल्फ कट्टर दुश्मन!
एवररोसेस

:) वास्तव में - आप मेरे पालतू चट्टानों के पास नहीं है! CamoWolf SGW बहुत कठिन है, हालांकि थप्पड़।
तालमोबी 19

1
सौभाग्य से आपको CamoWolf को एक वैध प्रविष्टि के रूप में शामिल करने की आवश्यकता नहीं है = D
जस्टफेल

14

क्या यह एक लड़का है? क्या यह भेड़िया है? नहीं, यह है

BoyWhoCriedWolf.java

लोग सभी जगह प्रतिबिंब का उपयोग कर रहे हैं, इसलिए मुझे लगा, इसे एक कदम आगे क्यों नहीं बढ़ाया जाए?
मैं आपको प्रस्तुत करता हूं: भेड़िया जो खो नहीं सकता।

package animals;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.instrument.ClassDefinition;
import java.lang.instrument.Instrumentation;
import java.lang.instrument.UnmodifiableClassException;
import java.lang.management.ManagementFactory;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.jar.Attributes;
import java.util.jar.JarOutputStream;
import java.util.jar.Manifest;
import javax.xml.bind.DatatypeConverter;

public class BoyWhoCriedWolf extends Animal {

    private static boolean ranAgent;

    public static void installAgent() {
        try {
            ranAgent = true;
            String javaExec = new File(System.getProperty("java.home"), "bin").getAbsolutePath() + File.separator + "java";
            Process proc = new ProcessBuilder(javaExec, "-cp", System.getProperty("java.class.path"),
                    "animals.BoyWhoCriedWolf", ManagementFactory.getRuntimeMXBean().getName().split("@")[0])
                    .inheritIO().start();
            proc.waitFor();
        } catch (InterruptedException | IOException e) {
            e.printStackTrace();
        }
    }

    public BoyWhoCriedWolf() {
        super('W');
        if (!ranAgent) {
            installAgent();
        }
    }

    @Override
    public Attack fight(char c) {
        return Attack.PAPER; // I like paper, it's my rubber duck.
    }

    @Override
    public Move move() {
        return Move.HOLD; // I'm terribly lazy.
    }

    public static void main(String[] args) {
        try {
            File temp = File.createTempFile("agent-", ".jar");
            temp.deleteOnExit();
            Manifest manifest = new Manifest();
            manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0");
            manifest.getMainAttributes().put(new Attributes.Name("Agent-Class"), "animals.BoyWhoCriedWolf");
            manifest.getMainAttributes().put(new Attributes.Name("Can-Redefine-Classes"), "true");
            JarOutputStream jos = new JarOutputStream(new FileOutputStream(temp), manifest);
            jos.close();

            // Add tools.jar
            Method addURL = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
            addURL.setAccessible(true);
            addURL.invoke(ClassLoader.getSystemClassLoader(), new URL("file:" + System.getProperty("java.home") + "/../lib/tools.jar"));

            Class<?> virtualMachineClass = Class.forName("com.sun.tools.attach.VirtualMachine");
            Object vm = virtualMachineClass.getDeclaredMethod("attach", String.class).invoke(null, args[0]);
            virtualMachineClass.getDeclaredMethod("loadAgent", String.class).invoke(vm, temp.getAbsolutePath());
            virtualMachineClass.getDeclaredMethod("detach").invoke(vm);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void agentmain(String args, Instrumentation instr) throws ClassNotFoundException, UnmodifiableClassException {
        instr.redefineClasses(new ClassDefinition(wild.Game.class, DatatypeConverter.parseBase64Binary(base64Game)));
    }

    private static final String base64Game =
              "yv66vgAAADMA9QoAOQCRBwCSCgACAJEJABIAkwkAEgCUBwCVCgAGAJEJABIAlgoABgCXCgAGAJgK"
            + "AAIAmQoABgCaCgCbAJwHAJ0HAJ4KABIAnwoAEgCgBwChCgASAKIHAKMKABIApAkAFAClCgAUAKYH"
            + "AKcJAGUAqAkAOgCpCgBlAKoKAAYAqwsArACtCwCsAK4KAAYArwcAsAoABgCxCQAUALIKABQAswkA"
            + "cQC0CgC1ALYGP+AAAAAAAAAJADoAtwoAcQCqCQBxALgJAHEAuQkAcQC6CgCbALsIALwHAL0KAC8A"
            + "kQoALwC+CAC/CgAvAMAKAC8AwQgAwggAwwgAxAcAjQcAxQcAxgEADElubmVyQ2xhc3NlcwEABWJv"
            + "YXJkAQAVTGphdmEvdXRpbC9BcnJheUxpc3Q7AQAJU2lnbmF0dXJlAQBVTGphdmEvdXRpbC9BcnJh"
            + "eUxpc3Q8TGphdmEvdXRpbC9BcnJheUxpc3Q8TGphdmEvdXRpbC9BcnJheUxpc3Q8TGFuaW1hbHMv"
            + "QW5pbWFsOz47Pjs+OwEAA2dlbgEAEkxqYXZhL3V0aWwvUmFuZG9tOwEABFNJWkUBAAFJAQAGPGlu"
            + "aXQ+AQAEKEkpVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBABJMb2NhbFZhcmlhYmxlVGFibGUB"
            + "AAFqAQABaQEABHRoaXMBAAtMd2lsZC9HYW1lOwEABHNpemUBAA1TdGFja01hcFRhYmxlBwChAQAI"
            + "cG9wdWxhdGUBABUoTGphdmEvbGFuZy9DbGFzcztJKVYBAAFlAQAoTGphdmEvbGFuZy9SZWZsZWN0"
            + "aXZlT3BlcmF0aW9uRXhjZXB0aW9uOwEAA3JvdwEAA2NvbAEAB3NwZWNpZXMBABFMamF2YS9sYW5n"
            + "L0NsYXNzOwEAA251bQEAFkxvY2FsVmFyaWFibGVUeXBlVGFibGUBABZMamF2YS9sYW5nL0NsYXNz"
            + "PFRUOz47BwDHBwDIAQAuPFQ6TGFuaW1hbHMvQW5pbWFsOz4oTGphdmEvbGFuZy9DbGFzczxUVDs+"
            + "O0kpVgEAB2l0ZXJhdGUBAAMoKVYBAAdtb3ZlQWxsAQAVTGphdmEvbGFuZy9FeGNlcHRpb247AQAB"
            + "YQEAEExhbmltYWxzL0FuaW1hbDsBAAVhTW92ZQcAyQEABE1vdmUBABVMYW5pbWFscy9BbmltYWwk"
            + "TW92ZTsBAARnYW1lBwCjBwCnBwDJAQAHZmxhdHRlbgEABXJhbmQxAQAFcmFuZDIBAAFiAQAFYVRh"
            + "Y2sHAMoBAAZBdHRhY2sBABdMYW5pbWFscy9BbmltYWwkQXR0YWNrOwEABWJUYWNrAQAEY2VsbAEA"
            + "J0xqYXZhL3V0aWwvQXJyYXlMaXN0PExhbmltYWxzL0FuaW1hbDs+OwEAPkxqYXZhL3V0aWwvQXJy"
            + "YXlMaXN0PExqYXZhL3V0aWwvQXJyYXlMaXN0PExhbmltYWxzL0FuaW1hbDs+Oz47BwDLBwCVBwDK"
            + "AQAEcG9sbAEAFChMamF2YS9sYW5nL0NsYXNzOylJAQABYwEABWNvdW50AQAIdG9TdHJpbmcBABQo"
            + "KUxqYXZhL2xhbmcvU3RyaW5nOwEAAXMBABJMamF2YS9sYW5nL1N0cmluZzsHAMwBAAdnZXRBcmVh"
            + "AQAHKElJKVtbQwEABXRlbXAxAQAFdGVtcDIBAAV0ZW1wMwEABXRlbXA0AQABbAEAAWsBAARhcmVh"
            + "AQADW1tDBwDNAQAKU291cmNlRmlsZQEACUdhbWUuamF2YQwARABfAQAQamF2YS91dGlsL1JhbmRv"
            + "bQwAQABBDABCAEMBABNqYXZhL3V0aWwvQXJyYXlMaXN0DAA8AD0MAM4AzwwA0ADRDADSANMMANQA"
            + "1QcAxwwA1gDXAQAgamF2YS9sYW5nL0luc3RhbnRpYXRpb25FeGNlcHRpb24BACBqYXZhL2xhbmcv"
            + "SWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbgwAYABfDABsAF8BAAl3aWxkL0dhbWUMAEQARQEADmFuaW1h"
            + "bHMvQW5pbWFsDACEAIUMANgAjQwA2QDaAQATamF2YS9sYW5nL0V4Y2VwdGlvbgwA2wBnDADcAN0M"
            + "AN4A3wwA4ADhBwDLDADiANUMAOMA1wwATQDfAQAXYW5pbWFscy9Cb3lXaG9DcmllZFdvbGYMAOQA"
            + "zwwA5QDmDADnAOgMAOkAcwcA6gwA6wDsDADtAN0MAO4AcwwA7wBzDADwAHMMAPEAzwEABjxodG1s"
            + "PgEAF2phdmEvbGFuZy9TdHJpbmdCdWlsZGVyDADyAPMBAAwmbmJzcDsmbmJzcDsMAH8AgAwA8gD0"
            + "AQAGJm5ic3A7AQAEPGJyPgEABzwvaHRtbD4BABBqYXZhL2xhbmcvT2JqZWN0AQALd2lsZC9HYW1l"
            + "JDEBAA9qYXZhL2xhbmcvQ2xhc3MBACZqYXZhL2xhbmcvUmVmbGVjdGl2ZU9wZXJhdGlvbkV4Y2Vw"
            + "dGlvbgEAE2FuaW1hbHMvQW5pbWFsJE1vdmUBABVhbmltYWxzL0FuaW1hbCRBdHRhY2sBABJqYXZh"
            + "L3V0aWwvSXRlcmF0b3IBABBqYXZhL2xhbmcvU3RyaW5nAQACW0MBAANhZGQBABUoTGphdmEvbGFu"
            + "Zy9PYmplY3Q7KVoBAANnZXQBABUoSSlMamF2YS9sYW5nL09iamVjdDsBAAduZXh0SW50AQAEKEkp"
            + "SQEAB2lzRW1wdHkBAAMoKVoBAAtuZXdJbnN0YW5jZQEAFCgpTGphdmEvbGFuZy9PYmplY3Q7AQAM"
            + "c3Vycm91bmRpbmdzAQAEbW92ZQEAFygpTGFuaW1hbHMvQW5pbWFsJE1vdmU7AQAESE9MRAEAHiRT"
            + "d2l0Y2hNYXAkYW5pbWFscyRBbmltYWwkTW92ZQEAAltJAQAHb3JkaW5hbAEAAygpSQEACGl0ZXJh"
            + "dG9yAQAWKClMamF2YS91dGlsL0l0ZXJhdG9yOwEAB2hhc05leHQBAARuZXh0AQAGcmVtb3ZlAQAG"
            + "bGV0dGVyAQABQwEABWZpZ2h0AQAaKEMpTGFuaW1hbHMvQW5pbWFsJEF0dGFjazsBAAdTVUlDSURF"
            + "AQAOamF2YS9sYW5nL01hdGgBAAZyYW5kb20BAAMoKUQBACAkU3dpdGNoTWFwJGFuaW1hbHMkQW5p"
            + "bWFsJEF0dGFjawEABVBBUEVSAQAIU0NJU1NPUlMBAARST0NLAQAKaXNJbnN0YW5jZQEABmFwcGVu"
            + "ZAEALShMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9TdHJpbmdCdWlsZGVyOwEAHChDKUxq"
            + "YXZhL2xhbmcvU3RyaW5nQnVpbGRlcjsAIQASADkAAAADAAIAPAA9AAEAPgAAAAIAPwASAEAAQQAA"
            + "ABQAQgBDAAAACAAEAEQARQABAEYAAADtAAMABAAAAF8qtwABKrsAAlm3AAO1AAQqG7UABSq7AAZZ"
            + "twAHtQAIAz0cG6IAOyq0AAi7AAZZtwAHtgAJVwM+HRuiAB8qtAAIHLYACsAABrsABlm3AAe2AAlX"
            + "hAMBp//ihAIBp//GsQAAAAMARwAAAC4ACwAAABEABAAOAA8AEgAUABMAHwAUACYAFQA1ABYAPAAX"
            + "AFIAFgBYABQAXgAaAEgAAAAqAAQANwAhAEkAQwADACEAPQBKAEMAAgAAAF8ASwBMAAAAAABfAE0A"
            + "QwABAE4AAAAYAAT/ACEAAwcATwEBAAD8ABUB+gAg+gAFAAQAUABRAAIARgAAARwAAgAGAAAAXRye"
            + "AFsqtAAEKrQABbYACz4qtAAEKrQABbYACzYEKrQACB22AArAAAYVBLYACsAABrYADJkAJiq0AAgd"
            + "tgAKwAAGFQS2AArAAAYrtgANtgAJV6cABToFhAL/p/+nsQACADYAUQBUAA4ANgBRAFQADwAEAEcA"
            + "AAAmAAkAAAAdAAQAHgAQAB8AHQAgADYAIQBRACIAVgAjAFkAJQBcACYASAAAAD4ABgBWAAAAUgBT"
            + "AAUAEABJAFQAQwADAB0APABVAEMABAAAAF0ASwBMAAAAAABdAFYAVwABAAAAXQBYAEMAAgBZAAAA"
            + "DAABAAAAXQBWAFoAAQBOAAAAGwAFAP8AUwAFBwBPBwBbAQEBAAEHAFwB+QACAgA+AAAAAgBdAAQA"
            + "XgBfAAEARgAAADsAAQABAAAACSq3ABAqtwARsQAAAAIARwAAAA4AAwAAACkABAAqAAgAKwBIAAAA"
            + "DAABAAAACQBLAEwAAAACAGAAXwABAEYAAAJjAAQABwAAAVu7ABJZKrQABbcAE0wDPRwqtAAFogE/"
            + "Az4dKrQABaIBLyq0AAgctgAKwAAGHbYACsAABrYADJoBESq0AAgctgAKwAAGHbYACsAABgO2AArA"
            + "ABQ6BBkEKhwdtwAVtQAWGQS2ABc6BacACjoGsgAZOgWyABoZBbYAGy6qAAAAAAAAzgAAAAEAAAAF"
            + "AAAAJAAAAEsAAABtAAAAjwAAALYrtAAIHARkKrQABWAqtAAFcLYACsAABh22AArAAAYZBLYACVen"
            + "AIYrtAAIHLYACsAABh0EYCq0AAVwtgAKwAAGGQS2AAlXpwBkK7QACBwEYCq0AAVwtgAKwAAGHbYA"
            + "CsAABhkEtgAJV6cAQiu0AAgctgAKwAAGHQRkKrQABWAqtAAFcLYACsAABhkEtgAJV6cAGyu0AAgc"
            + "tgAKwAAGHbYACsAABhkEtgAJV4QDAaf+z4QCAaf+vyortAAItQAIsQABAF4AZQBoABgAAwBHAAAA"
            + "WgAWAAAALgAMAC8AFgAwACAAMQA4ADIAUwAzAF4ANQBlADYAbwA3AJwAOQDAADoAwwA8AOIAPQDl"
            + "AD8BBABAAQcAQgErAEMBLgBFAUYAMAFMAC8BUgBLAVoATABIAAAAUgAIAGoABQBSAGEABgBTAPMA"
            + "YgBjAAQAZQADAGQAZwAFAG8A1wBkAGcABQAYATQASQBDAAMADgFEAEoAQwACAAABWwBLAEwAAAAM"
            + "AU8AaABMAAEATgAAADYADP0ADgcATwH8AAkB/wBPAAUHAE8HAE8BAQcAaQABBwBq/AAGBwBrLCYh"
            + "ISb5ABf6AAX6AAUAAgBsAF8AAQBGAAADuAAFAAwAAAFfKrQACLYAHEwruQAdAQCZAVAruQAeAQDA"
            + "AAZNLLYAHE4tuQAdAQCZATUtuQAeAQDAAAY6BBkEtgAfBKQBHiq0AAQZBLYAH7YACzYFKrQABBkE"
            + "tgAftgALNgYVBRUGn//uGQQVBbYACsAAFDoHGQQVBrYACsAAFDoIGQfBACCZAA4ZBBkItgAhV6f/"
            + "rBkIwQAgmQAOGQQZB7YAIVen/5kZBxkItAAitgAjOgmnAAo6C7IAJDoJGQgZB7QAIrYAIzoKpwAK"
            + "OguyACQ6ChkJGQqmAB0ZBLgAJRQAJpeeAAgZB6cABRkItgAhV6cAbbIAKBkJtgApLqoAAAAAAABh"
            + "AAAAAQAAAAMAAAAcAAAANAAAAEwZBBkKsgAqpgAIGQenAAUZCLYAIVenADAZBBkKsgArpgAIGQen"
            + "AAUZCLYAIVenABgZBBkKsgAspgAIGQenAAUZCLYAIVen/t+n/sin/q2xAAIAngCqAK0AGAC0AMAA"
            + "wwAYAAQARwAAAHYAHQAAAE8AGwBQADQAUQA9AFMASwBUAGAAVgBsAFcAeABZAIAAWgCIAFsAiwBc"
            + "AJMAXQCbAF4AngBiAKoAYwC0AGQAwABlAMoAZwDRAGgA6wBqARAAbAElAG0BKABvAT0AcAFAAHIB"
            + "VQB2AVgAdwFbAHgBXgB5AEgAAACEAA0ArwAFAFIAYQALAMUABQBSAGEACwBLAQoAbQBDAAUAWQD8"
            + "AG4AQwAGAGwA6QBiAGMABwB4AN0AbwBjAAgAqgADAHAAcwAJALQAoQBwAHMACQDAAAMAdABzAAoA"
            + "ygCLAHQAcwAKADQBJAB1AD0ABAAbAUAAVAA9AAIAAAFfAEsATAAAAFkAAAAWAAIANAEkAHUAdgAE"
            + "ABsBQABUAHcAAgBOAAABFQAa/AAIBwB4/QAXBwB5BwB4/AATBwB5/AAWAf4APwEHAGkHAGkSTgcA"
            + "avwABgcAek4HAGr8AAYHAHpXBwB5/wABAAsHAE8HAHgHAHkHAHgHAHkBAQcAaQcAaQcAegcAegAC"
            + "BwB5BwBpBiROBwB5/wABAAsHAE8HAHgHAHkHAHgHAHkBAQcAaQcAaQcAegcAegACBwB5BwBpBk4H"
            + "AHn/AAEACwcATwcAeAcAeQcAeAcAeQEBBwBpBwBpBwB6BwB6AAIHAHkHAGkGTgcAef8AAQALBwBP"
            + "BwB4BwB5BwB4BwB5AQEHAGkHAGkHAHoHAHoAAgcAeQcAaf8AAwAFBwBPBwB4BwB5BwB4BwB5AAD6"
            + "AAL5AAL6AAIABAB7AHwAAQBGAAABNgACAAkAAABvAz0qtAAItgAcTi25AB0BAJkAXS25AB4BAMAA"
            + "BjoEGQS2ABw6BRkFuQAdAQCZAD4ZBbkAHgEAwAAGOgYZBrYAHDoHGQe5AB0BAJkAHhkHuQAeAQDA"
            + "ABQ6CCsZCLYALZkABoQCAaf/3qf/vqf/oBysAAAABABHAAAAKgAKAAAAfAACAH0AHgB+ADsAfwBY"
            + "AIAAYQCBAGQAggBnAIMAagCEAG0AhQBIAAAAPgAGAFgADABiAGMACAA7ACwAdQA9AAYAHgBMAFQA"
            + "PQAEAAAAbwBLAEwAAAAAAG8AfQBXAAEAAgBtAH4AQwACAFkAAAAWAAIAOwAsAHUAdgAGAB4ATABU"
            + "AHcABABOAAAAJQAH/QAKAQcAeP0AGgcAeQcAeP0AHAcAeQcAeCH5AAL5AAL6AAIAAQB/AIAAAQBG"
            + "AAABWwADAAYAAACqEi5MKrQACLYAHE0suQAdAQCZAIUsuQAeAQDAAAZOLbYAHDoEGQS5AB0BAJkA"
            + "VBkEuQAeAQDAAAY6BRkFtgAMmQAauwAvWbcAMCu2ADESMrYAMbYAM0ynACa7AC9ZtwAwK7YAMRkF"
            + "A7YACsAAFLQAIrYANBI1tgAxtgAzTKf/qLsAL1m3ADArtgAxEja2ADG2ADNMp/94uwAvWbcAMCu2"
            + "ADESN7YAMbYAM7AAAAAEAEcAAAAqAAoAAACJAAMAigAeAIsAOgCMAEIAjQBZAI8AfACQAH8AkQCT"
            + "AJIAlgCTAEgAAAAqAAQAOgBCAHUAPQAFAB4AdQBUAD0AAwAAAKoASwBMAAAAAwCnAIEAggABAFkA"
            + "AAAWAAIAOgBCAHUAdgAFAB4AdQBUAHcAAwBOAAAAIwAG/QALBwCDBwB4/QAYBwB5BwB4/AA0BwB5"
            + "+gAi+gAC+QAWAAIAhACFAAEARgAAAdAABAALAAAApQYGxQA4Ak4CNgQVBASjAJYCNgUVBQSjAIcV"
            + "BARgNgYVBQRgNgcbFQRgKrQABWAqtAAFcDYIHBUFYCq0AAVgKrQABXA2CSq0AAgbFQRgKrQABWAq"
            + "tAAFcLYACsAABhwVBWAqtAAFYCq0AAVwtgAKwAAGOgotFQQEYDIVBQRgGQq2AAyZAAgQIKcADxkK"
            + "A7YACsAAFLQAIlWEBQGn/3mEBAGn/2otsAAAAAQARwAAADIADAAAAJcABwCYABAAmQAZAJoAHwCb"
            + "ACUAnAA1AJ0ARQCeAHMAnwCXAJkAnQCYAKMAogBIAAAAcAALAB8AeACGAEMABgAlAHIAhwBDAAcA"
            + "NQBiAIgAQwAIAEUAUgCJAEMACQBzACQAdQA9AAoAEwCKAIoAQwAFAAoAmQCLAEMABAAAAKUASwBM"
            + "AAAAAAClAEoAQwABAAAApQBJAEMAAgAHAJ4AjACNAAMAWQAAAAwAAQBzACQAdQB2AAoATgAAAFkA"
            + "Bv0ACgcAOAH8AAgB/wB2AAsHAE8BAQcAOAEBAQEBAQcAeQACBwCOAf8ACwALBwBPAQEHADgBAQEB"
            + "AQEHAHkAAwcAjgEB/wAGAAUHAE8BAQcAOAEAAPoABQACAI8AAAACAJAAOwAAABoAAwA6ABIAABAI"
            + "AGUAFABmQBkAcQAUAHJAGQ==";
}

अरे हाँ, इसे चलाने के लिए एक JDK की आवश्यकता है, लेकिन मुझे नहीं लगता कि यह एक समस्या होगी।


1
लानत है, तुमने इसके लिए मुझे हराया। मैं एक SabotageAgentWolf पर इस सटीक रणनीति के साथ काम कर रहा था।
mackthehobbit

1
यह वर्ग क्या करता है?
9

3
@ अन्याय यह नीचे के पास base64 में एन्कोड की गई फ़ाइल के साथ गेम क्लास को फिर से परिभाषित करता है। उस फ़ाइल में एक इंसटॉफ़ चेक होता है; अगर यह मेरा भेड़िया है, तो दूसरा हमेशा मर जाता है।
14mR4X0r

1
मेरे पास अन्य सभी जानवरों को आत्महत्या करने और हाइपोवनॉल्फ नामक चीज बनाने के लिए वास्तव में इस तंत्र का उपयोग करने का विचार था। मैंने इसे सही ढंग से चलाने के लिए प्रबंधन नहीं किया, लेकिन आपने किया - सम्मान!
फ्रेंकोइस बुर्जुआ

12

Wion

अपेक्षित मूल्य में यथासंभव लंबे समय तक जीवित रहने की कोशिश करता है। यह शेरों के समानांतर चलने की कोशिश करता है (चाहे वह कोई भी देखता हो)।

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

यह मानते हुए कि किसी अन्य रणनीति का उपयोग करके सिमुलेशन में कोई भेड़िये हैं, वे मेरे भेड़ियों से बचने के लिए बुद्धिमान होंगे, क्योंकि उनके पास किसी भी मुठभेड़ को खोने का 50% मौका है। औसतन यह कम से कम और साथ ही किसी अन्य रणनीति का प्रदर्शन करना चाहिए।

यदि मैंने नियमों को सही ढंग से समझा, तो यह इष्टतम रणनीति होनी चाहिए।

package animals;
import java.util.Random;

public class Wion extends Animal {
    private boolean down;
    public Wion() { super('W'); down=true;}
    public Attack fight(char opponent) {
        switch (opponent) {
            case 'B':
            case 'L':
                return Attack.SCISSORS;
            case 'S':
                return Attack.PAPER;
            default:
                Random rn = new Random();
                int i = Math.abs(rn.nextInt() % 4);
                while (i==3) {i = Math.abs(rn.nextInt() % 4);}
                return Attack.values()[i];
        }
    }
    public Move move() {
        down=!down;
        if(!down) { return Move.DOWN; }
        return Move.RIGHT;
    }
}

मैं ईमानदारी से नहीं जानता कि यह मेरे टेस्ट रन में इतना खराब क्यों है। यह कागज पर अच्छा लगता है, लेकिन व्यवहार में यह बहुत EmoWolf के साथ बराबर है :(
Geobits

@Geobits मैं वास्तव में यह टीबीएच परीक्षण नहीं किया था। मुझे लगता है कि मैंने नियमों में से एक को गलत समझा, एक गलती की, या मेरे यादृच्छिक हमले बनाम भेड़ियों को समान रूप से यादृच्छिक नहीं है।
टिम सेगिन

@Geobits मैंने हमले के तर्क की अदला-बदली की। मेरा संदेह यह है कि शायद यह कभी-कभी आत्महत्या कर रहा था।
टिम सेगिन

1
@ अन्यायपूर्ण हाँ, मुझे पहले ही पता चल गया है कि समस्या क्या है। मेरा तर्क संभवतः एक ऐसी आबादी के साथ काम कर सकता है जिसमें अधिकांश एक अन्य प्रकार के भेड़िया शामिल हैं। ऐसी स्थिति में दूसरे भेड़िया की मुठभेड़ दर में लगभग उसी दर से वृद्धि / कमी होगी जो मेरी है। हालांकि, बहु नस्ल के मामले में, मेरी मुठभेड़ दर में कोई वृद्धि अन्य सभी भेड़ियों के बीच औसतन की जाएगी, इसलिए मेरा अनुपात बड़ा होगा। मैं इसे ठीक करने के लिए किसी तरह के न्यूनतम तरीके के बारे में सोच रहा हूं, लेकिन मेरे पास इस समय दुर्भाग्य से अन्य महत्वपूर्ण चीजें हैं।
टिम सेगुईन

1
लेकिन मैं मानता हूं कि यह तरीका इष्टतम है अगर भेड़ियों की सबसे अधिक एक अन्य नस्ल पर है।
१६:१४

12

एक सामूहिक स्मृति के साथ भेड़ियों

R में एक वुल्फ पैक

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

यहाँ आर कोड है:

infile <- file("stdin")
open(infile)
repeat{
    input <- readLines(infile,1)
    type <- substr(input,1,1)
    id <- substr(input,2,3)
    if(nchar(input)>3){
        info <- substr(input,4,nchar(input))
    }else{
        info <- NULL
    }
    attack <- function(id,info){
        if(info%in%c("B","L")){choice <- "S"}
        if(info=="S"){choice <- "P"}
        if(info=="W"){
            if(exists("memory")){
                dead <- memory$ID[memory$Status=="Dead"]
                veteran <- memory[memory$Attack!="" & !is.na(memory$Attack), ]
                if(nrow(veteran[!is.na(veteran[,1]),])>0){
                    deadvet<-veteran[veteran$ID%in%dead,]
                    deadvet<-unlist(lapply(split(deadvet,deadvet$ID),function(x)tail(x$Attack,1)))
                    deadvet <- table(factor(deadvet,levels=c("R","P","S","")))
                    livevet <- table(factor(veteran$Attack,levels=c("R","P","S","")))-deadvet
                    probR <- (1+livevet['R'])/(1+livevet['R']+deadvet['R'])
                    probS <- (1+livevet['S'])/(1+livevet['S']+deadvet['S'])
                    probP <- (1+livevet['P'])/(1+livevet['P']+deadvet['P'])
                    choice <- sample(c("S","P","R"),1,prob=c(probS,probP,probR))
                    memory <- rbind(memory, data.frame(ID=id, Status="Alive", Attack=choice))
                }else{
                    choice <- sample(c("S","P","R"),1)
                    memory <- rbind(memory, data.frame(ID=id, Status="Alive", Attack=choice))
                }
            }else{
                choice <- sample(c("S","P","R"),1)
                memory <- data.frame(ID=id, Status="Alive", Attack=choice)
            }
        }
        paste(choice,id,sep="")
    }
    move <- function(id,info){
        choice <- "H"
        paste(choice,id,sep="")
    }
    initialize <- function(id){
        if(exists("memory")){
            memory <- rbind(memory,data.frame(ID=id,Status="Alive",Attack=""))
        }else{
            memory <- data.frame(ID=id,Status="Alive",Attack="")
        }
        confirmed_dead <- memory$ID[memory$Status=="Dead"]
        last_seen <- memory[!memory$ID%in%confirmed_dead,]
        last_seen <- last_seen[last_seen$Attack=="",]
        lid <- table(last_seen$ID)
        turns <- max(lid)
        dead <- lid[lid<(turns-1)]
        if(length(dead)>0){
            dead_id <- names(dead)
            for(i in dead_id){
                memory <- rbind(memory, data.frame(ID=i, Status="Dead", Attack=""))
            }
        }
        paste("K",id,sep="")
    }
    result <- switch(type,"A"=attack(id,info),"M"= move(id,info),"S"=initialize(id))
    cat(result,"\n",sep="")
    flush(stdout())
}

यह @ProgrammerDan आवरण (धन्यवाद!) का उपयोग करता है, वुल्फकॉलेक्टिवमेमोरी के साथ कस्टम नाम और "रुपीट वुल्फकोलेक्टिविवेमोरी।" के रूप में मंगलाचरण।


कुछ चीजें - पहले, मुझे पूरा यकीन है कि आउटपुट फ्लश नहीं किए जा रहे हैं। दूसरा, एक बार जब आपकी प्रक्रिया को आवरण द्वारा लागू किया जाता है, तो इसे चालू रखा जाता है । आपका वर्तमान डिज़ाइन मानता है कि आपकी प्रक्रिया को हर बार भेजा जाता है जब संचार एक भेड़िया को भेजा जाता है - यह प्रक्रिया चालानों के संदर्भ में बहुत महंगा होता है, इसलिए इसके बजाय मैं प्रक्रिया शुरू करता हूं और संचार चैनलों को खुला छोड़ देता हूं। तो, आपके पास एक मुख्य लूप होना चाहिए जो लगातार लाइनों को पढ़ता है stdinऔर उत्तर में एक पंक्ति लिखता है stdout, उसके बाद ए flush.console()। [cont]
प्रोग्रामरडान

[cont] मेरी प्रक्रिया के आवरण को अनुकरण समाप्त होने पर बच्चे की प्रक्रिया को समाप्त करना चाहिए।
प्रोग्रामरडान

@Rusher यहाँ जिस्ट है @plannapus 'आर सबमिशन के लिए एक वैध रैपर के लिए जिस्ट है। R. Install डाउनलोड करने के लिए यहां जाएंbinअपने PATH चर या समकक्ष में R का फ़ोल्डर जोड़ें , और आपको अच्छा होना चाहिए (मेरे लिए ठीक काम किया)।
प्रोग्रामरडान

मुझे लगता है कि अपराधी है readlines आज्ञा है। एक readlineया इक्वीव का उपयोग करके देखें । readlinesEOF तक ब्लॉक रहेगा।
प्रोग्रामरडान

मैंने सिर्फ readLinesइसे जोड़ा है scanreadLinesदूसरे तर्क के साथ 1इसका मतलब यह होना चाहिए कि यह पहली न्यूलाइन कैरेक्टर पर रुक जाए।
प्लेनैपस

12

MimicWolf

इस भेड़िये का लक्ष्य अन्य भेड़ियों की नकल करना है। यह पाता है कि एक भेड़िया इसकी सबसे अच्छी क्षमता का अनुसरण करता है। MimicWolf ऐसे सवाल नहीं पूछता है: मैं उस भेड़िये / भालू / शेर / पत्थर से कैसे बच सकता हूँ?

नहीं, MimicWolf सिर्फ सवाल पूछता है: मेरे लिए एक भेड़िया कहाँ है? मुझे क्या लगता है कि मैं जिस भेड़िये का पालन कर रहा हूं वह जाने वाला है? क्या वह भेड़िया जो मैं पीछा कर रहा था, वह एक अलग भेड़िया है? मैं जिस भेड़िये का पीछा कर रहा था, वह कहां गया?

मैं स्वीकार करूंगा कि उन सवालों में से अधिकांश का अभी तक अच्छी तरह से उत्तर नहीं दिया गया है, लेकिन समय के लिए यहां मेरा MimicWolf प्रस्तुत है

   package animals;
   import java.util.*;

public class MimicWolf extends Animal {

final int TURN_MEMORY = 5;

Random rand = new Random();

Animal.Move lastMove = Animal.Move.UP;

boolean mimicingWolf = false;

Pos[] wolfPreviousPos = new Pos[TURN_MEMORY];
RelativePos[] relativePositions = new RelativePos[TURN_MEMORY];
Move[] wolfPreviousMove = new Move[TURN_MEMORY - 1];

int turnsWithLostWolf = 0;

public MimicWolf() {
    super('W');
}

public Animal.Attack fight(char c) {
    switch (c) {
        case 'B':
            return Animal.Attack.SCISSORS;
        case 'L':
            return Animal.Attack.SCISSORS;
        case 'S':
            return Animal.Attack.PAPER;
        default:
            int x = rand.nextInt(4);
            return Animal.Attack.values()[x];
    }
}

public Animal.Move move() {
    Pos wolfPos = null;
    wolfPos = lookForSurroundingWolf();

    if (turnsWithLostWolf == 4) {
        mimicingWolf = false;
        wolfPreviousPos = new Pos[5];
        relativePositions = new RelativePos[5];
        turnsWithLostWolf = 0;
    }

    if (mimicingWolf) {
        int indexOfLastMove = 0;
        for (int i = 0; wolfPreviousPos[i] != null && i < wolfPreviousPos.length; i++) {
            indexOfLastMove = i;
        }

        //is wolf still visible??
        Pos wolfNewPos = isWolfVisible(wolfPreviousPos[indexOfLastMove]);
        if (wolfNewPos.x == -1) {//wolf is not visible
            turnsWithLostWolf++;
            return moveOppositeDirection(lastMove);
        } else {
            return mimicWolf(wolfNewPos, indexOfLastMove); //need Better way to mimic
        }
    } else {
        //check if new wolf around
        if (wolfPos.x == -1) {
            return searchForWolf();
        } else {
            mimicingWolf = true;
            return mimicWolf(wolfPos, 0);
        }
    }
}

private Animal.Move searchForWolf() {
    Animal.Move newMove = null;
    while (newMove == null || newMove == lastMove) {
        newMove = Animal.Move.values()[rand.nextInt(3)];
    }

    lastMove = newMove;
    return newMove;
}

private Pos lookForSurroundingWolf() {
    for (Integer i = 0; i < surroundings.length; i++) {
        for (Integer j = 0; j < surroundings[0].length; j++) {
            if (i == 1 && j == 1) {
                //this is myself >.<
            } else if (surroundings[i][j] == 'W') {
                return new Pos(i, j);
            }
        }
    }

    return new Pos(-1, -1);
}

/*
    for mimicWolf when movesMimiced == 1 or 2 this is the base case, Any
    number greater the wolf will attempt to mimic the next move based on pattern
    of previous moves
        we assume that we are following the same wolf as last time
 */

private Animal.Move mimicWolf(Pos wolfCurrentPos, int movesMimiced) {
    wolfPreviousPos[movesMimiced] = wolfCurrentPos;
    insertToRelativePos(wolfCurrentPos, movesMimiced);
    if (movesMimiced == 0) {
        Move m1 = null, m2 = null;
        if (wolfPreviousPos[0].x == 0) {
            m1 = Move.LEFT;
        } else if (wolfPreviousPos[0].x == 2) {
            m1 = Move.RIGHT;
        }

        if (wolfPreviousPos[0].y == 0) {
            m2 = Move.UP;
        } else if (wolfPreviousPos[0].y == 2) {
            m2 = Move.DOWN;
        }

        return randOfMoves(m1, m2); //guess which way to go
    }
    wolfPreviousMove[movesMimiced - 1] =  getDirection(wolfPreviousPos[movesMimiced - 1], wolfPreviousPos[movesMimiced]);
    if (movesMimiced == 1) {
        //if pos 1 was a cornor
        if(relativePositions[0] == RelativePos.CORNER){
            if(relativePositions[1] == RelativePos.CORNER){
                if(wolfPreviousPos[0].equals(wolfPreviousPos[1])){
                    return lastMove;
                }
                return moveOppositeDirection(lastMove);
            }
            else if(relativePositions[1] == RelativePos.EDGE){
                return Move.HOLD; //he held so i will hold
            }
        }else if(relativePositions[1] == RelativePos.EDGE){
            if(relativePositions[1] == RelativePos.EDGE){
                return lastMove;
            }
            else if(relativePositions[1] == RelativePos.CORNER){
                //only possibility is that I held, and he moved
                return wolfPreviousMove[0];
            }
        }
    } else {
        //Return most common move the wolf I am copying has made
        int[] mostCommonMoveArr = {0,0,0,0,0};
        for(int i = 0; i <= movesMimiced; i++){
            switch(wolfPreviousMove[i]){
                case UP:
                    mostCommonMoveArr[0]++;
                case RIGHT:
                    mostCommonMoveArr[1]++;
                case DOWN:
                    mostCommonMoveArr[2]++;
                case LEFT:
                    mostCommonMoveArr[3]++;
                case HOLD:
                    mostCommonMoveArr[4]++;
            }
        }

        int maxValue = -1;
        int maxLocal = 0;
        for(int i = 0; i < 5; i++){
            if(mostCommonMoveArr[i] > maxValue)
                maxValue =  mostCommonMoveArr[i];
                maxLocal = i;
        }

        return Move.values()[maxLocal];
    }

    return Move.HOLD; //shouldn't happen
}

private Pos isWolfVisible(Pos lastPos) {
    Pos mimicedWolfPos = lookForSurroundingWolf();
    while (mimicedWolfPos.x != -1 && mimicedWolfPos.y != -1) {
        //did we find the wolf?
        if (lastPos.x == mimicedWolfPos.x || lastPos.y == mimicedWolfPos.y) {
            return mimicedWolfPos;
        }

        surroundings[mimicedWolfPos.x][mimicedWolfPos.y] = ' ';
        mimicedWolfPos = lookForSurroundingWolf();
    }

    return new Pos(-1, -1);
}

private Animal.Move moveOppositeDirection(Move m) {
    switch (m) {
        case UP:
            return Move.DOWN;
        case RIGHT:
            return Move.LEFT;
        case DOWN:
            return Move.UP;
        case LEFT:
            return Move.RIGHT;
        case HOLD:
            return Move.LEFT; //No idea why this would happen but whatever
        default:
            return Move.HOLD;
    }
}

private Animal.Move getDirection(Pos firstPos, Pos secondPos){
    if(firstPos.equals(secondPos))
        return Move.HOLD;
    if(firstPos.x == secondPos.x){
        if(firstPos.y > secondPos.y)
            return Move.UP;
        return Move.DOWN;
    }
    if(firstPos.x > secondPos.x)
        return Move.RIGHT;
    return Move.LEFT;
}


private Animal.Move randOfMoves(Move m1, Move m2) {
    if (m1 == null) {
        return m2;
    } else if (m2 == null) {
        return m1;
    }

    int r = rand.nextInt(2);
    if (r == 0) {
        return m1;
    }
    return m2;
}

private class Pos {
    int x;
    int y;

    protected Pos(int x, int y) {
        this.x = x;
        this.y = y;
    }

    @Override
    public boolean equals(Object obj){
        Pos pos = (Pos) obj;
        return (this.x == pos.x && this.y == pos.y);
    }
}

private void insertToRelativePos(Pos pos, int posToAdd){
    if(pos.x == 1 || pos.y == 1){
        relativePositions[posToAdd] = RelativePos.EDGE;
    }else{
        relativePositions[posToAdd] = RelativePos.CORNER;
    }
}

private enum RelativePos{
    CORNER, EDGE
}
}

संपादित करें: मैंने एक बेहतर नकल प्रणाली जोड़ी। भेड़ियों अभी भी अच्छी तरह से नहीं के रूप में वे इस समय कुछ भी बचने का प्रयास नहीं करते जबकि लगातार घूम रहे हैं।


12

प्रविष्टि नहीं है, लेकिन चूंकि अधिकांश भेड़िये सिर्फ स्थिर हैं, यह वास्तव में देखने के लिए काफी उबाऊ है, इसलिए मैंने जंगली में एक प्राकृतिक आपदा को जोड़ा:

भूकंप!

लगभग 5% समय, एक भूकंप यादृच्छिक परिमाण के साथ होगा, 100 उच्चतम, 20 सबसे कम होगा। यह एक सेट करेगाearthquakeCounter एक भूकंप के बाद समय के साथ तेजी से घटेगा जो करेगा।

भूकंप के दौरान क्या होता है?

सभी जानवरों के मूल्य के आधार पर, यादृच्छिक रूप से स्थानांतरित करने का मौका होगा earthquakeCounter । इसलिए यदि मान 75 है, तो लगभग 75% पशु (पत्थरों सहित) किसी भी दिशा में बेतरतीब ढंग से स्थानांतरित हो जाएंगे (समान रूप से वितरित)।

यह, गैर-आश्चर्यजनक रूप से, कई जानवरों को मारता है, इसलिए अधिकतम कुछ परीक्षणों के बाद आमतौर पर लगभग 50 जानवर होते हैं।

इसके अलावा, भूकंप की जीयूआई में कल्पना की जाएगी, जो कि परिमाण के आधार पर भिन्न होता है।

मैं भूकंप नहीं देख सकता!

भूकंप आने की संभावना काफी पतली है, केवल 5%।

लेकिन झल्लाहट नहीं! मैंने एक "भूकंप" भी शामिल किया है ! बटनजीयूआई पर , यदि आप सभी भेड़ियों को उनके आराम क्षेत्र से अलग करना चाहते हैं ...

यहाँ एक स्क्रीनशॉट है:

भूकंप

यहाँ कोड है:

Wild.java

main() फ़ंक्शन (पहले 100 पुनरावृत्ति को गति देने के लिए GUI को छोड़ना अपडेट किया गया):

public static void main(String[] args) {

    int size = Math.round((float)Math.sqrt(classes.length+3)*20);
    final Game game = new Game(size);

    Statistics stats = new Statistics(game, classes);

    String[] colors = generateColors(classes.length);
    int idx = 0;
    for(Class c : classes){
        Animal.setColor(c, colors[idx]);
        idx++;
        game.populate(c, 100);
    }
    stats.update();

    JFrame gui = new JFrame();
    Container pane = gui.getContentPane();

    JLabel boardLabel = new JLabel();
    boardLabel.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 12));
    boardLabel.setText(game.toString());
    pane.add(boardLabel, BorderLayout.WEST);

    JLabel statsLabel = new JLabel();
    statsLabel.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 12));
    statsLabel.setText(stats.toString());
    pane.add(statsLabel, BorderLayout.EAST);

    JButton earthquakeButton = new JButton();
    earthquakeButton.addActionListener(new ActionListener(){

        @Override
        public void actionPerformed(ActionEvent e) {
            game.earthquake(true);
        }

    });
    earthquakeButton.setText("Earthquake!");
    pane.add(earthquakeButton, BorderLayout.SOUTH);

    gui.pack();
    gui.setVisible(true);

    for(int i=0; i<100; i++){
        game.iterate();
        stats.update();
    }

    while(true) {
        game.iterate();
        stats.update();
        boardLabel.setText(game.toString());
        statsLabel.setText(stats.toString());
        try { Thread.sleep(100); } catch (InterruptedException e) {}
    }
}

Game.java

package wild;

import animals.Animal;
import java.util.ArrayList;
import java.util.Random;
import animals.Animal.Attack;
import animals.Animal.Move;

public class Game {

    private ArrayList<ArrayList<ArrayList<Animal>>> board;
    private final Random gen = new Random();
    protected final int SIZE;
    private static int earthquakeCounter = 0;

    protected Game(int size) {
        this.SIZE = size;
        board = new ArrayList<>();
        for (int i = 0; i < size; i++) {
            board.add(new ArrayList<ArrayList<Animal>>());
            for (int j = 0; j < size; j++) {
                board.get(i).add(new ArrayList<Animal>());
            }
        }
    }

    protected <T extends Animal> void populate(Class<T> species, int num) {
        while (num > 0) {
            int row = gen.nextInt(SIZE);
            int col = gen.nextInt(SIZE);
            if (board.get(row).get(col).isEmpty()) {
                try { board.get(row).get(col).add(species.newInstance()); } 
                catch (InstantiationException | IllegalAccessException e) {}
                num--;
            }
        }
    }

    protected void iterate() {
        earthquake(false);
        moveAll();
        flatten();
    }

    private void moveAll() {
        Game game = new Game(SIZE);
        for (int i = 0; i < SIZE; i++) {
            for (int j = 0; j < SIZE; j++) {
                if (!board.get(i).get(j).isEmpty()) {
                    Animal a = board.get(i).get(j).get(0);
                    a.surroundings = getArea(i, j);
                    Move aMove;
                    try { aMove = a.move(); } 
                    catch (Exception e) { aMove = Move.HOLD; }
                    if(gen.nextInt(100)<earthquakeCounter){
                        aMove = Move.values()[gen.nextInt(4)];
                    }
                    switch(aMove) {
                        case UP:
                            game.board.get((i-1+SIZE)%SIZE).get(j).add(a);
                            break;
                        case RIGHT:
                            game.board.get(i).get((j+1)%SIZE).add(a);
                            break;
                        case DOWN:
                            game.board.get((i+1)%SIZE).get(j).add(a);
                            break;
                        case LEFT:
                            game.board.get(i).get((j-1+SIZE)%SIZE).add(a);
                            break;
                        case HOLD:
                            game.board.get(i).get(j).add(a);
                            break;
                    }
                }
            }
        }
        board = game.board;
    }

    /**
     * Give a random chance for an earthquake to happen
     */
    protected void earthquake(boolean force){
        if(force || (earthquakeCounter==0 && gen.nextInt(1000)>950)){
            earthquakeCounter = 20+gen.nextInt(80);
        } else {
            earthquakeCounter /= 2;
        }
    }

    private void flatten() {
        for (ArrayList<ArrayList<Animal>> row : board) {
            for (ArrayList<Animal> cell : row) {
                while (cell.size() > 1) {
                    int rand1, rand2;
                    rand1 = gen.nextInt(cell.size());
                    do { rand2 = gen.nextInt(cell.size()); } while (rand1 == rand2);

                    Animal a = cell.get(rand1);
                    Animal b = cell.get(rand2);
                    Attack aTack, bTack;
                    try { aTack = a.fight(b.letter); } 
                    catch (Exception e) { aTack = Attack.SUICIDE; }
                    try {  bTack = b.fight(a.letter); }
                    catch (Exception e) { bTack = Attack.SUICIDE; }

                    if (aTack == bTack) {
                        cell.remove((Animal)(Math.random() > 0.5 ? a : b));
                    } else {
                        switch (aTack) {
                            case ROCK:
                                cell.remove((Animal)(bTack == Attack.PAPER ? a : b));
                                break;
                            case PAPER:
                                cell.remove((Animal)(bTack == Attack.SCISSORS ? a : b));
                                break;
                            case SCISSORS:
                                cell.remove((Animal)(bTack == Attack.ROCK ? a : b));
                                break;
                        }
                    } 
                }
            }
        }
    }

    protected int poll(Class c) {
        int count = 0;
        for (ArrayList<ArrayList<Animal>> row : board) {
            for (ArrayList<Animal> cell : row) {
                for (Animal a : cell) {
                    if(c.isInstance(a))
                        count++;
                }
            }
        }
        return count;
    }

    public String toString() {
        String s = "<html>";
        s += "<span style='background:"+getBackgroundColor()+"'>";
        for (ArrayList<ArrayList<Animal>> row : board) {
            for (ArrayList<Animal> cell : row) {
                if (cell.isEmpty())
                    s += "&nbsp;&nbsp;";
                else
                    s += "<span style='color:"+ Animal.color.get(cell.get(0).getClass()) +"'>" + cell.get(0).letter + "</span>&nbsp;";
            }
            s+="<br>";
        }
        s += "</span>";
        return s + "</html>";
    }

    private String getBackgroundColor(){
        int shade = 255-(int)Math.floor(255*earthquakeCounter/100.0);
        String result = String.format("#%02x%02x%02x", shade, shade, shade);
        return result;
    }

    private char[][] getArea(int i, int j) {
        char[][] area = new char[3][3];
        for(int k = -1; k <= 1; k++) {
            for(int l = -1; l <= 1; l++) {
                int temp1 = k+1;
                int temp2 = l+1;
                int temp3 = (i+k+SIZE)%SIZE;
                int temp4 = (j+l+SIZE)%SIZE;
                ArrayList<Animal> cell = board.get((i+k+SIZE)%SIZE).get((j+l+SIZE)%SIZE);
                area[k+1][l+1] = (char)(cell.isEmpty() ? ' ' : cell.get(0).letter);
            }
        }
        return area;
    }
}

5
कुछ पुरुष सिर्फ दुनिया देखना चाहते हैं ... भूकंप
कॉमनग्यूई

5
मेरे गैदरिंगवुल्स रो रहे हैं।
जॉनचेन 902

12

मल्टीवुल्फ़ (जावा)

यह भेड़िया इस प्रोग्रामिंग चुनौती में अन्य भेड़ियों के बारे में जानता है। यह उन्हें उपलब्ध कराता है ('पालतू जानवर' के रूप में) यदि वे उपलब्ध हैं और उनका उपयोग यह निर्धारित करने के लिए करता है कि प्रत्येक भेड़िया-पालतू से यह पूछकर कि वह क्या करता है और सबसे लोकप्रिय प्रतिक्रिया चुनता है।

यह भेड़िया अनंत-पुनरावर्ती-सुरक्षित होना चाहिए - अर्थात यदि कोई अन्य व्यक्ति इसी तरह की अवधारणा को लागू करता है - और Attack.ROCK/ Move.HOLDयदि वह अन्य जानवरों को बुला रहा है, तो यह / की एक डिफ़ॉल्ट कार्रवाई को वापस बुलाएगा।

मेरे परीक्षणों में, इसके अलग-अलग परिणाम हुए हैं। मुझे यकीन नहीं है कि यह अनुमति दी जाएगी या नहीं। लेकिन अगर यह है, और कुछ असंभव चमत्कार होता है, तो यह जीतने का कारण बनता है, मुझे लगता है कि जीतने वाला शीर्षक उस भेड़िये पर पारित किया जाना चाहिए जो "दूसरा" आता है - यह केवल उचित है, मैंने शायद इसके तर्क को चुरा लिया है।

यह आत्महत्या से बचता है।

संपादित करें - मेरा मानना ​​है कि इस भेड़िया को भेड़ियों द्वारा ठीक से काम करने के संदर्भ के बाद लोड करने की आवश्यकता होगी।

package animals;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map.Entry;

public class MultiWolf extends Animal {

    private static final LinkedList<Animal> pets = new LinkedList<>();
    private static boolean inPetCall = false;

    private static void attemptLoadPet(String className) {
        try {
            Object pet = Class.forName(className).newInstance();

            if (pet instanceof Animal) {
                pets.add((Animal) pet);
            }
        } catch (Exception ex) {
            // this wolf is not available
            System.out.println(className + " is not available for MultiWolf cheating.");
        }
    }

    static {
        attemptLoadPet("animals.AlphaWolf");
        attemptLoadPet("animals.CamperWolf");
        attemptLoadPet("animals.GamblerWolf");
        attemptLoadPet("animals.GatheringWolf");
        attemptLoadPet("animals.LazyWolf");
        attemptLoadPet("animals.Sheep");
        attemptLoadPet("animals.Wion");

        attemptLoadPet("animals.MOSHPITFRENZYWolf");
        attemptLoadPet("animals.PassiveAgressiveWolf");
        attemptLoadPet("animals.StoneEatingWolf");
        attemptLoadPet("animals.HerjanWolf");
        attemptLoadPet("animals.HonorWolf");
        attemptLoadPet("animals.MimicWolf");
        attemptLoadPet("animals.LionHunterWolf");
        attemptLoadPet("animals.OmegaWolf");
        attemptLoadPet("animals.WolfWithoutFear");
        attemptLoadPet("animals.WolfRunningWithScissors");
        // attemptLoadPet("animals.SmartWolf");
        // According to Rusher, the above cheating of a non-Java wolf breaks the non-Java-entry wrapper.
        attemptLoadPet("animals.ShadowWolf");
        attemptLoadPet("animals.HybridWolf");
        attemptLoadPet("animals.ProAlpha");
        attemptLoadPet("animals.ForrestWolf");
        attemptLoadPet("animals.WhenIGrowUp");
        attemptLoadPet("animals.MigratingWolf");
        attemptLoadPet("animals.BlindWolf");
    }

    public MultiWolf() {
        super('W');
    }

    @Override
    public Attack fight(char opponent) {
        if (inPetCall) {
            // stop infinite recursion
            return Attack.ROCK;
        }

        inPetCall = true;

        HashMap<Attack, Integer> collect = new HashMap<>();

        collect.put(Attack.ROCK, 0);
        collect.put(Attack.PAPER, 0);
        collect.put(Attack.SCISSORS, 0);
        collect.put(Attack.SUICIDE, -9001);

        for (Animal a : pets) {
            a.surroundings = this.surroundings;
            Attack atk = a.fight(opponent);
            collect.put(atk, collect.get(atk)+1);
        }

        int top=0;
        Attack atk=Attack.ROCK;

        for (Entry<Attack, Integer> ent : collect.entrySet()) {
            if (ent.getValue() > top) {
                atk = ent.getKey();
                top = ent.getValue();
            }
        }

        inPetCall = false;

        return atk;
    }

    @Override
    public Move move() {
        if (inPetCall) {
            // stop infinite recursion
            return Move.HOLD;
        }

        inPetCall = true;

        HashMap<Move, Integer> collect = new HashMap<>();

        collect.put(Move.DOWN, 0);
        collect.put(Move.HOLD, 0);
        collect.put(Move.LEFT, 0);
        collect.put(Move.RIGHT, 0);
        collect.put(Move.UP, 0);


        for (Animal a : pets) {
            a.surroundings = this.surroundings;
            Move mv = a.move();
            collect.put(mv, collect.get(mv)+1);
        }

        int top=0;
        Move mv=Move.HOLD;

        for (Entry<Move, Integer> ent : collect.entrySet()) {
            if (ent.getValue() > top) {
                mv = ent.getKey();
                top = ent.getValue();
            }
        }

        inPetCall = false;

        return mv;
    }

}

अगर मुझे सही से याद है, तो आप Wild.classes के माध्यम से कक्षाएं प्राप्त कर सकते हैं, क्योंकि यह एक स्थिर क्षेत्र है ... इसलिए आपको हर बार भेड़िया को अपडेट नहीं करना होगा क्योंकि एक नया भेड़िया यहां तैनात है;)
CommonGuy

यह सच है। लेकिन मैंने इसे इस तरह से किया है, शायद इसे छोड़ने जा रहा हूं। हो सकता है कि इस बहुमूल्‍य से कुछ कम विजयी भेड़ियों को हटा दें। मेरे रनों में हर बार विलुप्त हो रहा है, मैं इसे मल्टीवुल्फ से काटने पर विचार कर रहा हूं क्योंकि मुझे आश्चर्य है कि अगर यह कार्रवाई की गुणवत्ता को कम कर रहा है।
ओलिवियर.ओलिव

मेरा मानना ​​है कि नियम "आप अन्य भेड़िया वर्ग द्वारा बनाई गई फाइलों को न तो पढ़ सकते हैं और न ही संशोधित कर सकते हैं" का उद्देश्य अन्य भेड़िया वर्ग की फाइलों को स्वयं शामिल करना था। इसलिए मुझे लगता है कि यह प्रवेश, जबकि एक भयानक विचार, नियमों के खिलाफ है।
Runer112

1
@ Runer112 मैंने आश्चर्यचकित किया, लेकिन मैंने नाम से कक्षाओं को लोड करने के बारे में भी कुछ सीखा है, और यह कि पैकेज में सभी वर्गों को खोजने का कोई सरल तरीका नहीं है। बस थोड़ा सा मज़ा
OlivierTheOlive

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

12

स्टोन ईटिंग वुल्फ

यहाँ मेरा सबमिशन है। यह भेड़िया अपने आसपास के किसी भी पत्थर, शेर या भेड़िये को नहीं देखता है। यदि वह एक पत्थर देखता है और किसी अन्य भेड़िया या शेर द्वारा हमला किए जाने का कोई खतरा नहीं है, तो वह उसे खाने की कोशिश करता है। अगर उसे कोई खतरा दिखाई देता है, तो वह भाग जाता है!

संपादित करें 1 : खतरे के एल्गोरिथ्म के लिए बेहतर देखना। वह अब खतरे से बेहतर है :)

package animals;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;


public class StoneEatingWolf extends Animal{

    public StoneEatingWolf() {
        super('W');
    }

    @Override
    public Attack fight(char c) {
        switch (c){
            case 'L': return Attack.SCISSORS;
            case 'B': return Attack.SCISSORS;
            case 'W': return getRandomAttack();
            case 'S': return Attack.PAPER;
            default: return getRandomAttack();
        }
    }

    private Attack getRandomAttack(){
        List<Attack> att = new ArrayList<>();
        att.add(Attack.PAPER);
        att.add(Attack.PAPER);
        att.add(Attack.ROCK);
        att.add(Attack.SCISSORS);
        Collections.shuffle(att);
        return att.get(0);
    }

    @Override
    public Move move() {
        List<Move> m = new ArrayList<>();

        //First see if there is any dangerous animal. If it is, then flee
        if (isThereAnyDangerousAnimal()){
            m.add(Move.UP);
            m.add(Move.RIGHT);
            m.add(Move.LEFT);
            m.add(Move.DOWN);
            getSafeMoves(m);
        }else{
        //No danger: Look for stones to eat
            if (isThereAnimalAtNorth('S')){
                m.add(Move.UP);
            }
            if (isThereAnimalAtEast('S')){
                m.add(Move.RIGHT);
            }
            if (isThereAnimalAtWest('S')){
                m.add(Move.LEFT);
            }
            if (isThereAnimalAtSouth('S')){
                m.add(Move.DOWN);
            }
        }

        if (m.isEmpty()){
            return Move.HOLD;
        } else {
            Collections.shuffle(m);
            return m.get(0);
        }
    }

    private void getSafeMoves(List<Move> lm){

        if (isThereAnimalAtNorth('L') || isThereAnimalAtNorth('W')){
            lm.remove(Move.UP);
        }
        if (isThereAnimalAtEast('L') || isThereAnimalAtEast('W')){
            lm.remove(Move.RIGHT);
        }
        if (isThereAnimalAtSouth('L') || isThereAnimalAtSouth('W')){
            lm.remove(Move.DOWN);
        }
        if (isThereAnimalAtWest('L') || isThereAnimalAtWest('W')){
            lm.remove(Move.LEFT);
        }

    }

    private boolean isThereAnimalAtNorth(char an){
        if (surroundings[0][0] == an || surroundings [0][1] == an || surroundings [0][2] == an){
            return true;
        }
        return false;
    }

    private boolean isThereAnimalAtSouth(char an){
        if (surroundings[2][0] == an || surroundings [2][2] == an || surroundings [2][2] == an){
            return true;
        }
        return false;
    }

    private boolean isThereAnimalAtEast(char an){
        if (surroundings[0][2] == an || surroundings [1][2] == an || surroundings [2][2] == an){
            return true;
        }
        return false;
    }

    private boolean isThereAnimalAtWest(char an){
        if (surroundings[0][0] == an || surroundings [1][0] == an || surroundings [2][0] == an){
            return true;
        }
        return false;
    }

    private boolean isThereAnyDangerousAnimal(){
        if (isThereAnimalAtEast('L') ||
                isThereAnimalAtEast('W') ||
                isThereAnimalAtNorth('L') ||
                isThereAnimalAtNorth('W') ||
                isThereAnimalAtSouth('L') ||
                isThereAnimalAtSouth('W') ||
                isThereAnimalAtWest('L') ||
                isThereAnimalAtWest('W')){
            return true;
        }
        return false;
    }

    }

संपादित 2 : कुछ आंकड़े

मैंने अपने द्वारा चलाए गए सिमुलेशन में स्टोनएटिंगवुल्फ को शीर्ष 5-6 वुल्फ बनाने का प्रबंधन किया है:

1000 पुनरावृत्तियों के 40 नाटकों के बाद औसत परिणाम

मैं उन झगड़ों का कुछ विश्लेषण करता हूं जहां स्टोन ईटिंग भेड़ियों को निहित किया गया है। 1000 पुनरावृत्तियों के 40 नाटक चलाने से मुझे ये परिणाम मिले:

परिणाम चार्ट लड़ो

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

PAPER       447
ROCK        881
SCISSORS    581
SUICIDE     230

लगता है जैसे ROCKहमलों के लिए एक स्पष्ट पूर्वाग्रह है । यह जानकर मैंने अपने भेड़ियों के PAPERहमलों को थोड़ा और अधिक आवृत्तियों पर बना दिया ।


2
कृपया, श्रेणीबद्ध डेटा को प्लॉट करने के लिए एक लाइन ग्राफ का उपयोग न करें। यह मुझे अपने ग्राफ को देखकर इतना कैंसर देता है।
AJMansfield

@AJMansfield को सुनने के लिए क्षमा करें। आशा है कि आप अच्छी तरह से प्राप्त करेंगे;) वैसे भी मैं इसे भविष्य के किसी भी चार्ट के लिए ध्यान में रखूंगा।
ऐवर्रोज़

आप अभी भी Windows XP का उपयोग कर रहे हैं? ऊ
जस्टफुल

और आप ROCKशेर से लड़ने के लिए (50% जीत) का उपयोग क्यों कर रहे हैं ? इसका उपयोग करना सबसे अच्छा है SCISSORS(75% जीत)
9

@ अन्यायपूर्ण मेरी कंपनी अभी भी XP का उपयोग करती है ... और आप कैंची के बारे में सही हैं। फिक्स्ड। धन्यवाद :)
Averroes

11

HonorWolf

मेरा भेड़िया दूसरे भेड़ियों से भाग रहा है। अगर वह भाग नहीं सकता है, तो वह सम्मानजनक लड़ाई शुरू करता है।

package animals;
public class HonorWolf extends Animal {

    private int moves = 0;

    public HonorWolf() { 
        super('W'); 
    }

    @Override   
    public Attack fight(char opponent) { 
        switch(opponent) {
         case 'L':
            return Attack.SCISSORS; 
         case 'B':
            return Attack.SCISSORS;
         case 'S':
            return Attack.PAPER;
        default:
            return Attack.PAPER;
        }
    }

    public Move move() {
        int numWolves = 0, numLions = 0;

        moves++;

        for (int y = 0; y != 3; y++) {
            for (int x = 0; x != 3; x++) {
                if(surroundings[y][x] != ' ') {
                    if(surroundings[y][x] == 'W') {
                        numWolves++;
                    } else if(surroundings[y][x] == 'L') {
                        numLions++;
                    }
                }
            }       
        }

        if (numWolves == 1 && numLions == 0) {
            return Move.HOLD;
        }

        if (surroundings[0][1] == 'L' && moves%2 != 0) {
            return Move.UP;
        } 

        if (surroundings[1][0] == 'L' && moves%2 == 0) {
            return Move.LEFT;
        }

        if (surroundings[0][1] == 'W') {
            if (surroundings[2][1] == ' ' || surroundings[2][1] == 'S') {
                return Move.DOWN;
            } else if (surroundings[1][2] == ' ' || surroundings[1][2] == 'S') {
                return Move.RIGHT;
            } else if (surroundings[1][0] == ' ' || surroundings[1][0] == 'S') {
                return Move.LEFT;
            } else {
                return Move.UP;
            }
        }

        if (surroundings[1][0] == 'W') {
            if (surroundings[1][2] == ' ' || surroundings[1][2] == 'S') {
                return Move.RIGHT;
            } else if (surroundings[0][1] == ' ' || surroundings[0][1] == 'S') {
                return Move.UP;
            } else if (surroundings[2][1] == ' ' || surroundings[2][1] == 'S') {
                return Move.DOWN;
            } else {
                return Move.LEFT;
            }
        }

        if (surroundings[1][2] == 'W') {
            if (surroundings[1][0] == ' ' || surroundings[1][0] == 'S') {
                return Move.LEFT;
            } else if (surroundings[0][1] == ' ' || surroundings[0][1] == 'S') {
                return Move.UP;
            } else if (surroundings[2][1] == ' ' || surroundings[2][1] == 'S') {
                return Move.DOWN;
            } else {
                return Move.RIGHT;
            }
        }

        if (surroundings[2][1] == 'W') {
            if (surroundings[0][1] == ' ' || surroundings[0][1] == 'S') {
                return Move.UP;
            } else if (surroundings[1][0] == ' ' || surroundings[1][0] == 'S') {
                return Move.LEFT;
            } else if (surroundings[1][2] == ' ' || surroundings[1][2] == 'S') {
                return Move.RIGHT;
            } else {
                return Move.DOWN;
            }
        }

        return Move.HOLD;
    }
}

मुझे अपने प्रो अल्फा वुल्फ पर हमला करने की रणनीति बदलनी होगी। अगर मैं पकड़ रहा था और भेड़ियों द्वारा हमला किया गया था: SCISSORS के साथ लड़ें;)
इल्या गज़मैन

11

द ब्लाइंड वुल्फ

अंधा भेड़िया हिलने से डरता है और कभी नहीं जानता कि वह क्या लड़ रहा है। हर बार कैंची चलाने से इसमें सबसे अच्छा अंतर होता है, क्योंकि यह कभी भी असली पत्थर में नहीं चलेगा ।

package animals;

public class BlindWolf extends Animal {
    public BlindWolf() { super('W'); }

    @Override
    public Attack fight(char c) { 
        return Attack.SCISSORS;
    }

    @Override
    public Move move() {
        return Move.HOLD;
    }
}

11

जब मैं बड़ा हो जाऊँगा

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

इस भेड़िये को शेरों के साथ घूमने वाली भेड़ियों के लिए एक काउंटर के रूप में डिजाइन किया गया था।

package animals;

import java.util.Random;

/**
 *
 * @author Quincunx
 */
public class WhenIGrowUp extends Animal {

    Random r;
    boolean following;
    boolean toggle;

    public WhenIGrowUp() {
        super('W');
        r = new Random();
        following = false;
        toggle = false;
    }

    @Override
    public Attack fight(char c) {
        switch (c) {
            case 'B':
                return Attack.SCISSORS;
            case 'L':
            case 'S':
                return Attack.PAPER;
            default:
                return Attack.values()[r.nextInt(4)];
        }
    }

    @Override
    public Move move() {
        if (surroundings[1][2] == 'L') {
            return Move.RIGHT;
        }
        if (surroundings[2][1] == 'L') {
            return Move.DOWN;
        }
        Move direction = Move.values()[r.nextInt(5)];
        out:
        for (int y = 0; y < 3; y++) {
            for (int x = 0; x < 3; x++) {
                if (surroundings[y][x] == 'L') {
                    if (y == 0 && x == 1) {
                        direction = Move.UP;
                    } else if (y == 1 && x == 0) {
                        direction = Move.LEFT;
                    } else {
                        direction = Move.HOLD;
                    }
                    break out;
                }
            }
        }
        return direction;
    }
}

11

SpyWolf

स्पाईवॉल्फ जासूस पर दुश्मन है और अपनी गतिविधि में प्रवेश करता है ताकि वह दूरी बनाए रखते हुए सभी पर नजर रख सके। पता लगाना नहीं चाहेगा!

package animals;

import static animals.Animal.Attack.*;
import static animals.Animal.Move.*;

import java.awt.Point;
import java.util.*;

public class SpyWolf extends Animal {

    private static final Random r = new Random();
    private static boolean hasTestedPRNG = false;
    private static int PRNG = -1;
    private boolean lionTracker = true;
    private boolean useScissors = false;

    private final ArrayList<MapTile> map = new ArrayList<MapTile>();
    private final Point location = new Point();

    public SpyWolf() {
        super('W');
    }

    @Override
    public Animal.Attack fight(char opponent) {
        switch (opponent) {
            case 'B':
            case 'L':
                return SCISSORS;
            case 'S':
                return PAPER;
            default:
                if (useScissors) {
                    useScissors = false;
                    return SCISSORS;
                }
                return PAPER;
        }
    }

    @Override
    public Animal.Move move() {

        Move m = HOLD;

        if (!hasTestedPRNG) {
            hasTestedPRNG = true;
            double d = 0;
            for (int i = 0; i < 100; i++)
                d += Math.random();
            if (d > 99) {
                PRNG = 1;
            } else if (d > 30 && d < 70) PRNG = 0;
        }

        lionTracker = !lionTracker;
        boolean adj = false;

        updateMap();

        scan: {
            if (PRNG < 1) {
                if (look(LEFT) == 'L' && !lionTracker) {
                    useScissors = true;
                    m = LEFT;
                    break scan;
                }

                if (look(UP) == 'L' & lionTracker) {
                    useScissors = true;
                    m = UP;
                    break scan;
                }
            }

            int x = 0, y = 0;
            ArrayList<Move> moves = new ArrayList<Move>(4);

            for (Move i : Move.values())
                moves.add(i);

            if (look(UP) == 'W') {
                y += 54;
                moves.remove(UP);
                adj = true;
            }
            if (look(DOWN) == 'W') {
                y -= 54;
                moves.remove(DOWN);
                adj = true;
            }
            if (look(LEFT) == 'W') {
                x += 54;
                moves.remove(LEFT);
                adj = true;
            }
            if (look(RIGHT) == 'W') {
                x -= 54;
                moves.remove(RIGHT);
                adj = true;
            }

            if (moves.isEmpty() || !adj) break scan;

            for (MapTile t : map) {
                if (t.x >= location.x - 2 && t.x <= location.x + 2 && t.y >= location.y - 2 && t.y <= location.y + 2 && t.d) {
                    int dist = Math.abs(t.x - location.x) + Math.abs(t.y - location.y);
                    y += t.y > location.y ? -60 / dist : 60 / dist;
                    x += t.x < location.x ? 60 / dist : -60 / dist;
                }
            }
            m = moveDir(x, y);
            if (!moves.contains(m)) m = HOLD;
        }
        switch (m) {
            case UP:
                location.y--;
                return m;
            case DOWN:
                location.y++;
                return m;
            case LEFT:
                location.x--;
                return m;
            case RIGHT:
                location.x++;
                return m;
            default:
                return m;
        }
    }

    private void updateMap() {
        for (int y = -1; y < 2; y++)
            xloop: for (int x = -1; x < 2; x++) {
                if (x == 0 && y == 0) continue;
                for (MapTile t : map)
                    if (t.x == x + location.x && t.y == y + location.y) {
                        t.d = surroundings[y + 1][x + 1] == 'W';
                        continue xloop;
                    }
                map.add(new MapTile(x + location.x, y + location.y, surroundings[y + 1][x + 1] == 'W'));
            }
    }

    private Move moveDir(int x, int y) {
        if (x == 0) return y < 0 ? UP : y > 0 ? DOWN : HOLD;
        if (y == 0) return x < 0 ? LEFT : RIGHT;
        if (x < 0) {
            if (y < 0) {
                if (y < x)
                    return UP;
                else if (x < y) return LEFT;
                return r.nextBoolean() ? UP : LEFT;
            } else {
                if (-y < x)
                    return DOWN;
                else if (x < -y) return LEFT;
                return r.nextBoolean() ? DOWN : LEFT;
            }
        }
        if (y < 0) {
            if (y < -x)
                return UP;
            else if (-x < y) return RIGHT;
            return r.nextBoolean() ? UP : RIGHT;
        } else {
            if (y > x)
                return DOWN;
            else if (x < y) return RIGHT;
        return r.nextBoolean() ? DOWN : RIGHT;
        }
    }

    private char look(Move direction) {
        switch (direction) {
            case UP:
                return surroundings[0][1];
            case DOWN:
                return surroundings[2][1];
            case LEFT:
                return surroundings[1][0];
            case RIGHT:
                return surroundings[1][2];
            default:
                return surroundings[1][1];
        }
    }

    private static class MapTile {
        int x, y;
        boolean d;

        MapTile(int x, int y, boolean d) {
            this.x = x;
            this.y = y;
            this.d = d;
        }
    }
}

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


1
आप इसे लंगड़ा कहते हैं, मैं इसे बुद्धिमान
कहता हूं

5
AHHHHH! इतने सारे gotoएस! और एक भाषा में जो उनके पास भी नहीं है!
AJMansfield

9

HybridWolf

मैं विरोध नहीं कर सका लेकिन एक और भेड़िया बना। यह एक बहुत अलग है (इसके कोड में, इसके व्यवहार में नहीं), क्योंकि यह हमले / चाल को चुनता है, जो अन्य अच्छे भेड़िये करते हैं।
बेशक सभी भेड़िये अच्छे हैं, लेकिन मेरा मतलब है कि सबसे अधिक अंक वाले लोग :)

package animals;

import java.util.ArrayList;
import java.util.Random;

public class HybridWolf extends Animal{
    private final Class[] classes = {ProAlpha.class, OmegaWolf.class, SpyWolf.class, HerjanWolf.class, DeepWolf.class, ProtoWolf.class};
    private final ArrayList<Animal> wolves = new ArrayList<Animal>(); 

    public HybridWolf() {
        super('W');
        for(Class c: classes) {
            try {
                wolves.add((Animal)c.newInstance());
            } catch (Exception ex) {}
        }
    }

    @Override
    public Attack fight(char opponent) {
        switch(opponent){
        case 'B':
        case 'L':
            return Attack.SCISSORS;
        case 'S': 
            return Attack.PAPER;
        default:
            try {
                int[] attacks = new int[3];
                Attack bestAttack = randomAttack();
                for(Animal wolf : wolves) {
                    wolf.surroundings = this.surroundings;
                    attacks[wolf.fight(opponent).ordinal()]++;
                }
                for(int i =0; i < 5; i++) {
                    if(attacks[i] > attacks[bestAttack.ordinal()]) {
                        bestAttack = Attack.values()[i];
                    }
                }
                return bestAttack;
            } catch (Exception e) {
                return randomAttack();
            }
        }
    }

    @Override
    public Move move() {
        try {
            int[] moves = new int[5];
            Move bestMove = Move.HOLD;
            for(Animal wolf : wolves) {
                wolf.surroundings = this.surroundings;
                moves[wolf.move().ordinal()]++;
            }
            for(int i =0; i < 5; i++) {
                if(moves[i] > moves[bestMove.ordinal()]) {
                    bestMove = Move.values()[i];
                }
            }
            return bestMove;
        } catch (Exception e) {
            return Move.HOLD;
        }
    }

    public Attack randomAttack() {
        Random rand = new Random();
        switch (rand.nextInt(3)){
            case 1: return Attack.SCISSORS;
            case 2: return Attack.ROCK;
            default: return Attack.PAPER;
        }
    }

}

यह मेरा परीक्षण करता है यह मेरे पिछले अल्फ़ावॉल्फ से बेहतर स्कोर करता है, लेकिन ओमेगा / ऑनर / प्रोलफा कभी-कभी मुझे हरा देता है ... जितने अच्छे सबमिशन यहां हैं, उतना ही बेहतर इस भेड़िया को मिलेगा: डी


यह थोड़ा सा चुटीला है! हालांकि चतुर विचार। सुनिश्चित नहीं है कि यह वैध प्रविष्टि के रूप में कैसे उचित होगा क्योंकि मुझे उन परीक्षणों का कोई पता नहीं है जो रशियर एक वैध प्रविष्टि को निर्धारित करने के लिए आवेदन करेंगे। यानी अगर वह मौजूद अन्य भेड़ियों के साथ अलगाव में परीक्षण करता है, तो यह भेड़िया बुरी तरह से विफल हो जाएगा: पी
मोगी

90% प्रविष्टियाँ वैध हैं। अब तक, मैंने केवल उन प्रविष्टियों को बाहर रखा है जो उनके पत्र को 'डब्ल्यू' के अलावा किसी और चीज़ में बदल देती हैं, या ऐसी प्रविष्टियाँ जो मैं समझ नहीं पा रहा था कि किसी अन्य भाषा में संकलन कैसे किया जाए (और अगर ऐसा है तो मैं उन्हें बता दूं, लेकिन आप हो सकते हैं इसे यहां नहीं देखें क्योंकि मैं उनसे चैट में बात करता हूं)।
रेनबोल्ट

@Rusher कुछ प्रविष्टियाँ हैं जो उनके पक्ष में बाधाओं को बदलने की कोशिश करती हैं। उदाहरण के लिए जुआरी भेड़िया जावा के गणित के यादृच्छिक संख्या जनरेटर को बदल देता है। मजेदार रूप से पर्याप्त परिणाम पर इसका बहुत कम प्रभाव पड़ता है क्योंकि जीतने वाले भेड़िये भेड़ियों से लड़ते हैं!
मोगी

@Moogie GamblerWolf एक कानूनी सबमिशन है (और बहुत चालाक भी)। आप सही हैं, इसने परिणामों को ज्यादा नहीं बदला। अगर चीजें हाथ से निकल जाती हैं, तो मैं बस यही कहूंगा कि "ठीक है, वह जीतता है लेकिन यहां परिणाम है यदि वह शामिल नहीं है।" इस तरह से बाकी सब लोग अभी भी अनजान नहीं होने का आनंद ले सकते हैं।
रेनबोल्ट

2
@Moogie यदि कुछ विशेष रूप से चुनौती के विनिर्देशों में निषिद्ध नहीं है, तो यह वास्तव में वैध है, और इस साइट पर परंपरा नियमों को बदलने के लिए नहीं है, क्योंकि लोगों ने इसके उत्तर पोस्ट किए हैं।
प्लेनैपस

9

EvoWolf

आप सभी मूर्खतापूर्वक बुद्धिमानी से तैयार भेड़ियों! इवोवुल्फ डीप वुल्फ और हर्जनवुल्फ़ जैसे अन्य कठिन भेड़ियों के साथ जंगल में रहता है इसलिए इसे जीवित रहने के लिए विकसित होना पड़ा।

कोड सबसे अच्छा भेड़िया विकसित करने के लिए एक आनुवंशिक एल्गोरिथ्म का उपयोग करता है (जब तक मैं भेड़ियों को पकड़ना नहीं चाहता था, तब तक मैं LionHunterWolf को नोटिस नहीं करता)। प्रत्येक जानवर / हमले के कॉम्बो के लिए अलग-अलग जीन होते हैं, सुरक्षित होने पर आंदोलन की दिशा, और आसपास के प्रत्येक जानवर के लिए आंदोलन की दिशा। 1000 राउंड के बाद, सबसे अधिक संख्या में चलने वाले भेड़ियों में संतान पैदा करने की संभावना सबसे अधिक होती है (यानी अब आप जितने अधिक समय तक संभोग करते हैं उतने अधिक समय तक जीवित रहेंगे)। हम लगभग 10% बच्चों में एक यादृच्छिक म्यूटेशन में भी फेंक देते हैं एक आशा है कि यह मदद करता है।

यहाँ EvoWolf कोड है, आप अपने काम के क्षेत्र में भी evowolf.txt की आवश्यकता होगी - यह मूल उत्पत्ति को पूरा करता है। यदि आप अपनी खुद की भेड़ियों को प्राइमरी यादृच्छिकता से विकसित करना चाहते हैं, तो evowolf.txt को शामिल न करें, लेकिन जो प्रदान किया गया है वह वर्तमान में सबसे अच्छा विकास है। यह वास्तव में साफ है इसे विकसित करने के लिए, शुरुआत में केवल 2-3 बच जाते हैं लेकिन फिर यह 60 तक हो जाता है।

package animals;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.List;
import java.util.Random;

public class EvoWolf extends Animal {
    public EvoWolf() { super('W'); birth();}
    public Attack fight(char c) { 
        List<Attack> attacks = getAttacks(c);
        if(attacks.size() == 0)
            return Attack.SUICIDE; //Discourage wolves without attacks, Darwin Award

        return attacks.get(random.nextInt(attacks.size()));
    }

    public Move move() {
        ++turns;
        List<Move> moves = new ArrayList<Move>();
        if(isSafe())
            moves = getSafeMoves();
        else
            moves = getThreatenedMoves();

        return (Move)moves.toArray()[random.nextInt(moves.size())];
    }

    /*====STATIC METHODS====*/
    //Shared RNG
    public static Random random = new Random();

    //Collection of 100 sets of genes
    public static String[] genePool = null;

    //Get the genes from disk or randomly generate some
    public static void readGenePool(){
        genePool = new String[100];
        int gIdx = 0;
        try (BufferedReader br = new BufferedReader(new FileReader("evowolf.txt"))){
            String sCurrentLine; 
            while ((sCurrentLine = br.readLine()) != null) {
                genePool[gIdx] = sCurrentLine;
                ++gIdx;
            }
        } catch (IOException e) {

        } 

        //if can't read genes, make some
        if(gIdx < 100){
            primordial(gIdx);
        }
    }
    public static void primordial(int idx){
        for(;idx < 100; ++idx){
            genePool[idx] = getRandomGenes();
        }
    }

    public static String getRandomGenes(){
        StringBuilder sb = new StringBuilder();
        for(int idx = 0; idx < GENE_COUNT; ++idx){
            if(random.nextBoolean())
                sb.append("1");
            else
                sb.append("0");
        }
        return sb.toString();
    }

    //Evolve wolves
    public static void nextGen(){
        //Check survival of current gen
        int survivors = 0;
        for(int idx = 0; idx < 100; ++idx){
            survivors = survivors + (generation[idx].turns == 1000 ? 1 : 0);
        }
        if(survivors > 65)
            writeGenePool(Long.toString(survivors));

        //Weighted resivour sampling
        //Take the highest of r^(1/w) where r is a random an w is the weight
        for(int idx = 0; idx < 100; ++idx){
            genePool[idx] = mateFitWolves();
        }
        writeGenePool("");
        birthCount = 0;
    }

    //Pick two wolves randomly by weighted fitness and mate them
    public static String mateFitWolves(){
        EvoWolf w1 = null;
        double weight1 = -1;
        EvoWolf w2 = null;
        double weight2 = -1;

        for(int idx = 0; idx < 100; ++idx){
            double weight = generation[idx].getWeightSample();
            if(weight > weight1){
                weight2 = weight1;
                w2 = w1;
                weight1 = weight;
                w1 = generation[idx];
            } else if(weight > weight2){
                weight2 = weight;
                w2 = generation[idx];
            }
        }

        return mateFitWolves(w1, w2);
    }

    //Make offspring
    public static String mateFitWolves(EvoWolf w1, EvoWolf w2){
        StringBuilder sb = new StringBuilder();
        //Random splice
        for(int rIdx = 0; rIdx < w1.genes.length(); ++rIdx){
            if(random.nextBoolean())
                sb.append(w1.genes.charAt(rIdx));
            else
                sb.append(w2.genes.charAt(rIdx));
        }


        //Random mutation
        while(random.nextInt(10) == 0){
            int mIdx = random.nextInt(w1.genes.length());
            if(sb.charAt(mIdx) == '0')
                sb.setCharAt(mIdx, '1');
            else
                sb.setCharAt(mIdx, '0');
        }


        return sb.toString();
    }

    //Save the next generation's gene pool back to disk
    public static void writeGenePool(String survivors){
        try {
            String str = "";
            if(!survivors.equals(""))
                str = Long.toString(System.currentTimeMillis());

            File file = new File("evowolf" + survivors + str + ".txt");

            // if file doesn't exists, then create it
            if (!file.exists()) {
                file.createNewFile();
            }

            FileWriter fw = new FileWriter(file.getAbsoluteFile());
            BufferedWriter bw = new BufferedWriter(fw);
            for(int gIdx = 0; gIdx < genePool.length; ++gIdx){
                bw.write(genePool[gIdx]);
                bw.write('\n');
            }
            bw.close();
        } catch (IOException e) {

        }
    }

    //Keep track of the wolves in this generation
    public static int birthCount = 0;
    public static EvoWolf[] generation = new EvoWolf[100];

    /*====INSTANCE METHODS====*/
    //Populate this wolf from the gene pool
    public void birth(){
        if(genePool == null){
            readGenePool();
        }
        genes = genePool[birthCount];
        generation[birthCount] = this;
        birthCount = (birthCount + 1) % 100;    
    }

    //How long wolf has been alive
    public int turns = 0;

    //Fitness based on how long wolf survived
    public double getWeightSample(){
        return Math.pow(random.nextDouble(), 1.0/turns);
    }


    /*===GENETICS===*/
    public String genes = null;
    //Genes are made up of 182+ bits (stored at a string)
    //Each turns on the possibility of that move or attack in a given situation
    //  Attack: BLSW * RPSX = 16 bits [0-15] = Animal->Attacks
    //  Threatened Moves: BLSW * 12345678 * UDLRH = 160 bits [16-175] = Y -> X -> Animal -> Moves
    //  Safe Moves: UDLRH = 5 bits [176-180] = Moves
    //  Extra: default move [181], move combination [182]
    public static final int GENE_INDEX_ATTACKS = 0;
    public static final int GENE_INDEX_THREATENED_MOVES = GENE_INDEX_ATTACKS + (4 * 4);
    public static final int GENE_INDEX_SAFE_MOVES = GENE_INDEX_THREATENED_MOVES + (8 * 4 * 5);
    public static final int GENE_INDEX_DEFAULT_MOVE = GENE_INDEX_SAFE_MOVES + (5);
    public static final int GENE_INDEX_COMBINE_MOVES = GENE_INDEX_DEFAULT_MOVE + (1);
    public static final int GENE_COUNT = GENE_INDEX_COMBINE_MOVES + 1;
    public static int getAnimalIndex(char c){
        switch (c) {
            case 'B':
                return 0;
            case 'L':
                return 1;
            case 'S':
                return 2;
            case 'W':
            default: //Shouldn't occur but we'll assume it's the dangerous wolf
                return 3;
        } 
    }

    public static int getXYIndex(int x, int y){
        int idx = (y * 3) + x;
        if(idx > 4) //We don't need to look at ourself
            --idx;
        return idx;
    }

    public List<Attack> getAttacks(char c){
        List<Attack> attacks = new ArrayList<Attack>();
        int idx = GENE_INDEX_ATTACKS + getAnimalIndex(c);
        if(genes.charAt(idx + 0) == '1')
            attacks.add(Attack.ROCK);
        if(genes.charAt(idx + 1) == '1')
            attacks.add(Attack.PAPER);
        if(genes.charAt(idx + 2) == '1')
            attacks.add(Attack.SCISSORS);
        /*
        if(genes.charAt(idx + 3) == '1')
            attacks.add(Attack.SUICIDE);
        */
        //Suicide didn't remove itself from the gene pool like I thought so I manually removed it

        return attacks;
    }

    public boolean isSafe(){
        for(int x = 0; x <= 2; ++x){
            for(int y = 0; y <= 2; ++y){
                if(y == 1 && x == 1)
                    continue;
                if(surroundings[y][x] != ' ')
                    return false;
            }
        }
        return true;
    }

    public List<Move> getSafeMoves(){
        List<Move> moves = new ArrayList<Move>();
        int idx = GENE_INDEX_SAFE_MOVES;
        if(genes.charAt(idx + 0) == '1')
            moves.add(Move.UP);
        if(genes.charAt(idx + 1) == '1')
            moves.add(Move.DOWN);
        if(genes.charAt(idx + 2) == '1')
            moves.add(Move.LEFT);
        if(genes.charAt(idx + 3) == '1')
            moves.add(Move.RIGHT);
        if(genes.charAt(idx + 4) == '1')
            moves.add(Move.HOLD);

        return moves;
    }

    public List<Move> getThreatenedMoves(){
        List<Move> moves = new ArrayList<Move>();
        if(genes.charAt(GENE_INDEX_COMBINE_MOVES) == '0')
            moves.addAll(EnumSet.of(Move.UP, Move.DOWN, Move.LEFT, Move.RIGHT, Move.HOLD));

        for(int x = 0; x <= 2; ++x){
            for(int y = 0; y <= 2; ++y){
                if(y == 1 && x == 1)
                    continue;
                if(genes.charAt(GENE_INDEX_COMBINE_MOVES) == '1')
                    moves.addAll(getThreatenedMoves(x,y));
                else
                    moves.retainAll(getThreatenedMoves(x,y));
            }
        }

        if(moves.size() == 0){
            if(this.genes.charAt(GENE_INDEX_DEFAULT_MOVE) == '1')
                moves.addAll(EnumSet.of(Move.UP, Move.DOWN, Move.LEFT, Move.RIGHT, Move.HOLD));
            else
                moves.add(Move.HOLD);
        }

        return moves;
    }

    public EnumSet<Move> getThreatenedMoves(int x, int y){
        //Lookup what moves we can make for a cell unless it is blank (allow any)
        if(surroundings[y][x] != ' ')
            return getThreatenedMoves(x,y,surroundings[y][x]);
        else if(genes.charAt(GENE_INDEX_COMBINE_MOVES) == '1')
            return EnumSet.noneOf(Move.class);
        else
            return EnumSet.of(Move.UP, Move.DOWN, Move.LEFT, Move.RIGHT, Move.HOLD);
    }

    public EnumSet<Move> getThreatenedMoves(int x, int y, char c){
        int aIdx = getAnimalIndex(c);
        int sIdx = getXYIndex(x,y);
        int idx = GENE_INDEX_THREATENED_MOVES + (sIdx * 20) + (aIdx * 5);

        EnumSet<Move> moves = EnumSet.noneOf(Move.class);

        if(genes.charAt(idx + 0) == '1')
            moves.add(Move.UP);
        if(genes.charAt(idx + 1) == '1')
            moves.add(Move.DOWN);
        if(genes.charAt(idx + 2) == '1')
            moves.add(Move.LEFT);
        if(genes.charAt(idx + 3) == '1')
            moves.add(Move.RIGHT);
        if(genes.charAt(idx + 4) == '1')
            moves.add(Move.HOLD);

        return moves;
    }

    public static String setAt(String str, int index, char replace){     
        if(str==null){
            return str;
        }else if(index<0 || index>=str.length()){
            return str;
        }
        char[] chars = str.toCharArray();
        chars[index] = replace;
        return String.valueOf(chars);       
    }
}

मैंने भी सांख्यिकी में परिवर्तन किए हैं। जावा और वाइल्ड.जावा सिर्फ मुझे यह दिखाने के लिए कि कितने मोड़ और पीढ़ियाँ बीत चुकी हैं। आपके द्वारा 1000 मोड़ चलाने के बाद, EvoWolf.nextGen();संतानों की गणना करने के लिए कॉल करें । यह प्रतियोगिता के लिए आवश्यक नहीं है, केवल तभी जब आप अपना स्वयं का सेट विकसित करना चाहते हैं।

सभी फाइलें यहां संपादित करें: फिक्स्ड लिंक

जहां तक ​​सर्वश्रेष्ठ के रूप में विकसित होने की बात है, यह शीर्ष 10 से बेहतर नहीं है। सीमा का हिस्सा यह पिछले चालों की बहुत कम मेमोरी है। हालाँकि यह वल्व्सविथक्लेवेटिव मेमेरी की तरह काम करता है लेकिन पिछली पीढ़ियों के अनुभवों से यह प्रभावित होगा कि अगली पीढ़ी वैश्विक दीर्घकालिक स्मृति के रूप में कैसे काम करती है। हालांकि यह निश्चित रूप से मज़ेदार था। पिछले लिंक में एक एक्सेल शीट है जो आपको जीन पूल का विश्लेषण करने में मदद कर सकती है। 1 के सभी और 0 के। In को 1 के साथ बदलें और 0 के अल्पविराम से फिर स्प्रेडशीट में पेस्ट करें।

कुछ दिलचस्प नोट्स, जिनमें से अधिकांश सभी की रणनीतियों की पुष्टि करते हैं:

  • लड़ाई से बचने की तुलना में वास्तविक हमले कम महत्वपूर्ण हैं। या हो सकता है कि सभी गैर-भेड़ियों को जल्दी से समाप्त कर दिया जाए, ताकि वे एक खतरा न हों। प्रतियोगिता पीढ़ी के पास भालू के खिलाफ आरपीएस के बीच एक समान मौका है भले ही आपको एस फेंक देना चाहिए।
  • उपरोक्त की तरह, मुझे आत्महत्या को मैन्युअल रूप से अक्षम करना पड़ा क्योंकि यह विकसित नहीं था, भले ही आपको लगता है कि यह होगा।
  • जब कोई आसपास न हो तो होल्डिंग सबसे अच्छी चाल है
  • जब कोई आसपास होता है तो भागना भी अच्छा लगता है
  • आपको एक यादृच्छिक दिशा में जाने के बजाय पकड़ना चाहिए (यह विकल्प एक अतिरिक्त जीन था जो विकसित हुआ)
  • जब 1 से अधिक जानवर आसपास होते हैं, तो प्रत्येक आस-पास / जानवर के लिए चालों के चौराहे से एक यादृच्छिक चाल लेना संघ (एक अतिरिक्त जीन) से बेहतर होता है

8

SmartWolf

परिणाम (1000 पुनरावृत्तियों) में हैं (मैं इसे अपडेट करता रहूंगा लेकिन इसे बिना किसी औसत के एक स्वतंत्र परीक्षण के रूप में देखूंगा क्योंकि इसके साथ कई भेड़ियों यह काफी धीमा है)।

यहां छवि विवरण दर्ज करें

संकलन:

* निक्स (मोनो आवश्यक है):

gmcs SmartWolf.cs

खिड़कियाँ:

csc SmartWolf.cs

वर्किंग डायरेक्टरी में कॉपी करें।

नोट: विंडोज का उपयोग करते समय, आपको "mono SmartWolf.exe"सिर्फ "SmartWolf.exe"रैपर कोड में बदलना होगा ।

SmartWolf.cs:

using System;
using System.Collections.Generic;
using System.Linq;

namespace SmartWolf
{
    #region Enums
    enum Attack
    {
        Rock, Paper, Scissors, Suicide
    }
    enum Movement
    {
        Up, Down, Left, Right, Hold
    }
    enum Animal
    {
        Stone, Lion, Wolf, Bear, Empty
    }
    #endregion
    class KnowledgeBase
    {
        static Random rnd = new Random();
        public List<KeyValuePair<KeyValuePair<Animal, Attack>, int>> knowledge = new List<KeyValuePair<KeyValuePair<Animal, Attack>, int>>();
        public KnowledgeBase ()
        {
        }
        public void PunishMove (KeyValuePair<Animal, Attack> move)
        {
            if (knowledge.Count (t => t.Key.Key == move.Key && t.Key.Value == move.Value) == 0) {
                knowledge.Add (new KeyValuePair<KeyValuePair<Animal, Attack>, int> (move, -1));
            } else {
                int i = knowledge.FindIndex (t => t.Key.Equals (move));
                knowledge[i] = new KeyValuePair<KeyValuePair<Animal, Attack>, int>(knowledge[i].Key, knowledge[i].Value - 1);
            }

        }
        public void RewardMove (KeyValuePair<Animal, Attack> move)
        {
            if (knowledge.Count (t => t.Key.Key == move.Key && t.Key.Value == move.Value) == 0) {
                knowledge.Add (new KeyValuePair<KeyValuePair<Animal, Attack>, int> (move, 1));
            } else {
                int i = knowledge.FindIndex (t => t.Key.Equals (move));
                knowledge[i] = new KeyValuePair<KeyValuePair<Animal, Attack>, int>(knowledge[i].Key, knowledge[i].Value + 1);
            }
        }
        public Attack GetBestMove (Animal opponent)
        {
            Attack best = GetRandomMove();
            int j = 0;
            foreach (var pair in knowledge) {
                if(pair.Key.Key == opponent && j < pair.Value)
                {
                    best = pair.Key.Value;
                    j = pair.Value;
                }
            }
            if(j < 2)
                return GetRandomMove ();
            return best;
        }
        public static Attack GetRandomMove()
        {
            int r = rnd.Next (3);
            return r == 0 ? Attack.Paper :
                r == 1 ? Attack.Rock :
                    r == 2 ? Attack.Scissors :
                    Attack.Scissors;
        }
    }
    class MainClass
    {
        static KnowledgeBase knowledge = new KnowledgeBase();
        public static void Main (string[] args)
        {
            List<SmartWolf> list = new List<SmartWolf> ();
            List<int> temp = new List<int>();
            int l = 0;
            while (true) {
                string str = Console.ReadLine ();
                int id = int.Parse (str.Substring (1, 2));
                if(str.StartsWith ("S"))
                {
                    list.Add (new SmartWolf(id));
                    Console.WriteLine("K" + id.ToString ().PadLeft (2, '0'));
                } else if(str.StartsWith ("M"))
                {
                    if(temp.Contains (id))
                    {
                        for(int i = 0; i < 100; i++)
                        {
                            SmartWolf s = list.Where (t => t.ID == i).ToList ()[0];
                            if(s.AttackedInLastRound == 0 && !temp.Contains(i))
                            {
                                s.IsAlive = false;
                                knowledge.PunishMove (s.LastMove);
                                s.AttackedInLastRound = -1;
                            } else if(s.AttackedInLastRound == 0 && temp.Contains (i))
                            {
                                knowledge.RewardMove (s.LastMove);
                                s.AttackedInLastRound = -1;
                            }
                            if(s.AttackedInLastRound > 0)
                                s.AttackedInLastRound--;
                        }
                        temp.Clear();
                        l++;
                    }
                    temp.Add (id);

                    Console.WriteLine('H' + id.ToString ().PadLeft (2, '0'));
                } else if(str.StartsWith ("A"))
                {
                    Animal enemy = str[3] == 'W' ? Animal.Wolf :
                                   str[3] == 'L' ? Animal.Lion :
                                   str[3] == 'S' ? Animal.Stone :
                                   str[3] == 'B' ? Animal.Bear : Animal.Empty;
                    Attack atk = knowledge.GetBestMove (enemy);
                    Console.WriteLine((atk == Attack.Paper ? "P" :
                                      atk == Attack.Rock ? "R" : 
                                      atk == Attack.Scissors ? "S" :
                                      "P") + id.ToString ().PadLeft (2, '0'));
                    list.Where (t => t.ID == id).ToList ()[0].AttackedInLastRound = 2;
                    list.Where (t => t.ID == id).ToList ()[0].LastMove = new KeyValuePair<Animal, Attack>(enemy, atk);
                }
            }
        }
    }
    class SmartWolf
    {
        public int ID;
        public bool IsAlive = true;
        public KeyValuePair<Animal, Attack> LastMove = new KeyValuePair<Animal, Attack>(Animal.Empty, Attack.Suicide);
        public int AttackedInLastRound = -1;
        public SmartWolf(int n)
        {
            ID = n;
        }
    }
}

रैपर (@ProgrammerDan को क्रेडिट, मैं इसे यहाँ शामिल कर रहा हूँ, इसलिए इसे कॉपी पेस्ट करना आसान है):

package animals;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.OutputStreamWriter;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * Remote SmartWolf wrapper class. 
 */
public class SmartWolf extends Animal {
    /**
     * Simple test script that sends some typical commands to the
     * remote process.
     */
    public static void main(String[]args){
        SmartWolf[] wolves = new SmartWolf[100];
        for(int i=0; i<10; i++) {
            wolves[i] = new SmartWolf();
        }
        char map[][] = new char[3][3];
        for (int i=0;i<9;i++)
            map[i/3][i%3]=' ';
        map[1][2] = 'W';
        for(int i=0; i<10; i++) {
            wolves[i].surroundings=map;
            System.out.println(wolves[i].move());
        }
        for(int i=0; i<10; i++) {
            System.out.println(wolves[i].fight('S'));
            System.out.println(wolves[i].fight('B'));
            System.out.println(wolves[i].fight('L'));
            System.out.println(wolves[i].fight('W'));
        }
        wolfProcess.endProcess();
    }
    private static WolfProcess wolfProcess = null;

    private static SmartWolf[] wolves = new SmartWolf[100];
    private static int nWolves = 0;

    private boolean isDead;
    private int id;

    /**
     * Sets up a remote process wolf. Note the static components. Only
     * a single process is generated for all Wolves of this type, new
     * wolves are "initialized" within the remote process, which is
     * maintained alongside the primary process.
     * Note this implementation makes heavy use of threads.
     */
    public SmartWolf() {
        super('W');
        if (SmartWolf.wolfProcess == null) {
            SmartWolf.wolfProcess = new WolfProcess();
            SmartWolf.wolfProcess.start();
        }

        if (SmartWolf.wolfProcess.initWolf(SmartWolf.nWolves, MAP_SIZE)) {
            this.id = SmartWolf.nWolves;
            this.isDead = false;
            SmartWolf.wolves[id] = this;
        } else {
            SmartWolf.wolfProcess.endProcess();
            this.isDead = true;
        }
        SmartWolf.nWolves++;
    }

    /**
     * If the wolf is dead, or all the wolves of this type are dead, SUICIDE.
     * Otherwise, communicate an attack to the remote process and return
     * its attack choice.
     */
    @Override
    public Attack fight(char opponent) {
        if (!SmartWolf.wolfProcess.getRunning() || isDead) {
            return Attack.SUICIDE;
        }
        try {
            Attack atk = SmartWolf.wolfProcess.fight(id, opponent);

            if (atk == Attack.SUICIDE) {
                this.isDead = true;
            }

            return atk;
        } catch (Exception e) {
            System.out.printf("Something terrible happened, this wolf has died: %s", e.getMessage());
            isDead = true;
            return Attack.SUICIDE;
        }
    }

    /**
     * If the wolf is dead, or all the wolves of this type are dead, HOLD.
     * Otherwise, get a move from the remote process and return that.
     */
    @Override
    public Move move() {
        if (!SmartWolf.wolfProcess.getRunning() || isDead) {
            return Move.HOLD;
        }
        try {
            Move mv = SmartWolf.wolfProcess.move(id, surroundings);

            return mv;
        } catch (Exception e) {
            System.out.printf("Something terrible happened, this wolf has died: %s", e.getMessage());
            isDead = true;
            return Move.HOLD;
        }
    }

    /**
     * The shared static process manager, that synchronizes all communication
     * with the remote process.
     */
    static class WolfProcess extends Thread {
        private Process process;
        private BufferedReader reader;
        private PrintWriter writer;
        private ExecutorService executor;
        private boolean running;

        public boolean getRunning() {
            return running;
        }

        public WolfProcess() {
            process = null;
            reader = null;
            writer = null;
            running = true;
            executor = Executors.newFixedThreadPool(1);
        }

        public void endProcess() {
            running = false;
        }

        /**
         * WolfProcess thread body. Keeps the remote connection alive.
         */
        public void run() {
            try {
                System.out.println("Starting SmartWolf remote process");
                ProcessBuilder pb = new ProcessBuilder("mono SmartWolf.exe".split(" "));
                pb.redirectErrorStream(true);
                process = pb.start();
                System.out.println("SmartWolf process begun");
                // STDOUT of the process.
                reader = new BufferedReader(new InputStreamReader(process.getInputStream(), "UTF-8")); 
                System.out.println("SmartWolf reader stream grabbed");
                // STDIN of the process.
                writer = new PrintWriter(new OutputStreamWriter(process.getOutputStream(), "UTF-8"));
                System.out.println("SmartWolf writer stream grabbed");
                while(running){
                    this.sleep(0);
                }
                reader.close();
                writer.close();
                process.destroy(); // kill it with fire.
                executor.shutdownNow();
            } catch (Exception e) {
                e.printStackTrace();
                System.out.println("SmartWolf ended catastrophically.");
            }
        }

        /**
         * Helper that invokes a read with a timeout
         */
        private String getReply(long timeout) throws TimeoutException, ExecutionException, InterruptedException{
            Callable<String> readTask = new Callable<String>() {
                @Override
                public String call() throws Exception {
                    return reader.readLine();
                }
            };

            Future<String> future = executor.submit(readTask);
            return future.get(timeout, TimeUnit.MILLISECONDS);
        }

        /**
         * Sends an initialization command to the remote process
         */
        public synchronized boolean initWolf(int wolf, int map_sz) {
            while(writer == null){
                try {
                this.sleep(0);
                }catch(Exception e){}
            }
            boolean success = false;
            try{
                writer.printf("S%02d%d\n", wolf, map_sz);
                writer.flush();
                String reply = getReply(5000l);
                if (reply != null && reply.length() >= 3 && reply.charAt(0) == 'K') {
                    int id = Integer.valueOf(reply.substring(1));
                    if (wolf == id) {
                        success = true;
                    }
                }
                if (reply == null) {
                    System.out.println("did not get reply");
                }
            } catch (TimeoutException ie) {
                endProcess();
                System.out.printf("SmartWolf %d failed to initialize, timeout\n", wolf);
            } catch (Exception e) {
                endProcess();
                System.out.printf("SmartWolf %d failed to initialize, %s\n", wolf, e.getMessage());
            }
            return success;
        }

        /**
         * Send an ATTACK command to the remote process.
         */
        public synchronized Attack fight(int wolf, char opponent) {
            Attack atk = Attack.SUICIDE;
            try{
                writer.printf("A%02d%c\n", wolf, opponent);
                writer.flush();
                String reply = getReply(1000l);
                if (reply.length() >= 3) {
                    int id = Integer.valueOf(reply.substring(1));
                    if (wolf == id) {
                        switch(reply.charAt(0)) {
                            case 'R':
                                atk = Attack.ROCK;
                                break;
                            case 'P':
                                atk = Attack.PAPER;
                                break;
                            case 'S':
                                atk = Attack.SCISSORS;
                                break;
                            case 'D':
                                atk = Attack.SUICIDE;
                                break;
                        }
                    }
                }
            } catch (TimeoutException ie) {
                endProcess();
                System.out.printf("SmartWolf %d failed to attack, timeout\n", wolf);
            } catch (Exception e) {
                endProcess();
                System.out.printf("SmartWolf %d failed to attack, %s\n", wolf, e.getMessage());
            }
            return atk;
        }

        /**
         * Send a MOVE command to the remote process.
         */
        public synchronized Move move(int wolf, char[][] map) {
            Move move = Move.HOLD;
            try{
                writer.printf("M%02d", wolf);
                for (int row=0; row<map.length; row++) {
                    for (int col=0; col<map[row].length; col++) {
                        writer.printf("%c", map[row][col]);
                    }
                }
                writer.print("\n");
                writer.flush();
                String reply = getReply(1000l);
                if (reply.length() >= 3) {
                    int id = Integer.valueOf(reply.substring(1));
                    if (wolf == id) {
                        switch(reply.charAt(0)) {
                            case 'H':
                                move = Move.HOLD;
                                break;
                            case 'U':
                                move = Move.UP;
                                break;
                            case 'L':
                                move = Move.LEFT;
                                break;
                            case 'R':
                                move = Move.RIGHT;
                                break;
                            case 'D':
                                move = Move.DOWN;
                                break;
                        }
                    }
                }
            } catch (TimeoutException ie) {
                endProcess();
                System.out.printf("SmartWolf %d failed to move, timeout\n", wolf);
            } catch (Exception e) {
                endProcess();
                System.out.printf("SmartWolf %d failed to move, %s\n", wolf, e.getMessage());
            }
            return move;
        }
    }
}

वास्तव में यह महान नहीं है, शीर्ष भेड़ियों में से कुछ के साथ 1000 पुनरावृत्तियों के लिए औसत ~ 75 जीवित रहने की दर।

समाधान के लिए एक एमएल दृष्टिकोण का उपयोग करता है।


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

यह C # में लिखा गया है और इसमें एक ज्ञान सूची है, जो प्रत्येक चाल को सूचीबद्ध करती है जिसे एक प्रकार के जानवर और उसकी सफलता दर के खिलाफ बनाया गया है। जब एक भेड़िया हमला करता है और मर जाता है, तो उस चाल की सफलता दर कम हो जाती है। यदि यह रहता है, तो सफलता दर बढ़ जाती है। सिस्टम कुछ (20-30) बदल जाने के बाद इसे बेतरतीब ढंग से चुनने के बजाय ज्ञान आधार से चालें लेने लगता है।
user3188175

1
खुशी है कि आप रैपर का उपयोग कर रहे हैं! आपको संभवतः अपने कोड को कैसे संकलित करना monoहै, और @Rusher का उपयोग करने के लिए निर्देश शामिल करना चाहिए ।
प्रोग्रामरडान

1
मार्कडाउन फेल। यदि आप स्रोत को देखते हैं, तो '#' वहाँ है, लेकिन चूंकि यह एक हेडिंग ब्लॉक में था, इसलिए मार्कडाउन ने इसे अनदेखा कर दिया। फिक्स्ड। : डी
प्रोग्रामरडान

2
FYI करें - मैं इसे @ ProgrammerDan के रैपर (और इस बार भी उसकी मदद के बिना) के साथ संकलित करने और सफलतापूर्वक चलाने में सक्षम था। आप अगले परिणामों में होंगे। विलंब के लिए क्षमा चाहते हैं!
रेनबोल्ट

7

निष्क्रिय-आक्रामक भेड़िया (एक स्केल भेड़िया)

पहले 500 बारी के लिए यह सब कुछ से बचता है, जिससे क्षेत्र खुद स्पष्ट हो जाता है। इसके बाद इसमें आने वाली चीजों पर हमला करने की दिशा में चला जाता है।

package animals;

import animals._
import scala.util.Random

class PassiveAgressiveWolf extends Animal('W') {

    val myId=PassiveAgressiveWolf.nextId
    var movecounter=0

    def fight(opponent: Char) = {
        PassiveAgressiveWolf.lastopponents(myId-1)=opponent
        opponent match {
            case 'B' => Animal.Attack.SCISSORS
            case 'L' => Animal.Attack.SCISSORS
            case 'S' => Animal.Attack.ROCK
            case _ => Random.shuffle(List(Animal.Attack.SCISSORS, Animal.Attack.ROCK, Animal.Attack.PAPER)).head
        }
    }

    def move = {
        movecounter+=1
        if(movecounter < 500) avoidall else seen match {
            case ('B', pos: Int) => seenbear(pos)
            case ('S', pos: Int) => seenstone(pos)
            case ('L', pos: Int) => seenlion(pos)
            case ('W', pos: Int) => seenwolf(pos)
            case (' ', _) => myDirection
        }
    }

    def myDirection = myId % 4 match {
        case 0 => if(surroundings(0)(1)==' ') Animal.Move.LEFT else randommove
        case 1 => if(surroundings(1)(0)==' ') Animal.Move.DOWN else randommove
        case 2 => if(surroundings(1)(2)==' ') Animal.Move.RIGHT else randommove
        case 3 => if(surroundings(2)(1)==' ') Animal.Move.UP else randommove
    }

    def randommove = Random.shuffle(List(Animal.Move.UP, Animal.Move.LEFT, Animal.Move.RIGHT, Animal.Move.DOWN)).head

    def seen = {
        surroundings(1)(1)=' '
        val surroundingsflat=surroundings.flatten.mkString
        val seenbeasts = for {
            beast <- "BSLW" if surroundingsflat contains beast
        } yield (beast, surroundingsflat.indexOf(beast))
        seenbeasts.headOption.getOrElse((' ', 0))
    }

    def seenbear(pos: Int) = chase(pos)

    def seenstone(pos: Int) = pos match {
        case 1 => Animal.Move.LEFT
        case 3 => Animal.Move.UP
        case _ => myDirection
    }

    def seenlion(pos: Int) = pos match {
        case 1 => Animal.Move.LEFT
        case 3 => Animal.Move.UP
        case 5 => Animal.Move.HOLD
        case 7 => Animal.Move.HOLD
        case 0 => Animal.Move.UP
        case 2 => Animal.Move.HOLD
        case 6 => Animal.Move.HOLD
        case 8 => Animal.Move.HOLD
    }

    def seenwolf(pos: Int) = chase(pos)

    def chase(pos: Int) = pos match {
        case 1 => Animal.Move.UP
        case 3 => Animal.Move.LEFT
        case 5 => Animal.Move.RIGHT
        case 7 => Animal.Move.DOWN
        case 0 => Animal.Move.UP
        case 2 => Animal.Move.UP
        case 6 => Animal.Move.DOWN
        case 8 => Animal.Move.DOWN
    }

    def avoidall = {
        val safemoves = for {
            move <- List(
                            (0, 1, Animal.Move.UP), 
                            (1, 0, Animal.Move.LEFT), 
                            (1, 2, Animal.Move.RIGHT), 
                            (2, 1, Animal.Move.DOWN)
                        ) if(surroundings(move._1)(move._2)==' ')
        } yield move
        if(safemoves.length < 4) Random.shuffle(safemoves).head._3 else Animal.Move.HOLD
    }

}

object PassiveAgressiveWolf {
    private var id=0
    private def nextId = {id+=1; id}

    private var lastopponents=Array.fill[Char](100)(' ');
}

JVM आधारित भाषा के रूप में, स्काला को अपेक्षाकृत आसानी से एकीकृत किया जा सकता है।

यदि आप प्रोग्राम को स्वयं संकलित कर रहे हैं, तो जावा .classफाइल को जावा फाइल (फाइल नहीं .java) के साथ डालें और उपयोग करें

scalac PassiveAggressiveWolf.scala

संकलन करने के लिए। फिर आप PassiveAggressiveWolf.classमुख्य Wild.javaवर्ग का उपयोग कर सकते हैं जैसा कि आप जावा कक्षाओं के साथ करते हैं। आपको scala-library.jarअपने वर्गपथ में भी जोड़ना होगा (मैं कमांड लाइन विकल्प का उपयोग कर रहा हूं -cp /path/to/scala-library.jar)।

वैकल्पिक रूप से, मैंने जनरेट की गई वर्ग फ़ाइलों और scala-library.jarस्केल 2.10.3 के लिए एक जार अपलोड किया है ताकि आप उन्हें डाउनलोड कर सकें।

PassiveAggressiveWolf.jar scala- Library.jar


हो सकता है कि आप आसानी से डाउनलोड करने के लिए 10 फ़ाइलों को एक एकल ज़िप फ़ाइल में पैक कर सकें।
जॉनचेन 902

@ johnchen902 मुझे चैट में यह सुझाव दिया गया था कि मैं अपनी कक्षाओं को शामिल करने के लिए जार बनाता हूं। मैं काम के बाद आज शाम को देख रहा हूँ। वह इसे 2 डाउनलोड तक कम कर देगा और उम्मीद है कि उन मुद्दों को हल करेगा जो रशर को इसमें शामिल कर रहा है।
गारेथ
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.