डॉलर बिल नीलामी


32

यह गेम थ्योरी में डॉलर बिल नीलामी गेम के लिए एक KOTH चुनौती है। इसमें एक डॉलर सबसे ज्यादा बोली लगाने वाले को बेचा जा रहा है। बोलियां 5 ids की वृद्धि में जाती हैं, और हारने वाला भी अपनी बोली लगाता है। यह विचार है कि दोनों खिलाड़ी अपने नुकसान में कटौती करने के लिए एक डॉलर के मूल्य से कहीं अधिक बोली युद्ध को आगे बढ़ाते हैं।

चलिए उम्मीद करते हैं कि आपके बॉट्स उससे ज्यादा स्मार्ट हों।

आप net.ramenchef.dollarauction.DollarBidderकक्षा को बढ़ाकर इस खेल को खेलने के लिए एक बॉट बना रहे होंगे । आपको उस nextBidविधि को लागू करना होगा जो आपके बॉट की अगली बोली को दूसरे बॉट की पिछली बोली को लौटाती है। यदि आवश्यक हो, तो आप newAuctionप्रतिद्वंद्वी के बॉट के वर्ग के साथ प्रत्येक नीलामी के लिए रीसेट करने के लिए विधि का उपयोग भी कर सकते हैं ।

public abstract class DollarBidder {
    /**
     * Used by the runner to keep track of scores.
     */
    long score = 0;

    /**
     * (Optional) Prepare for the next auction.
     *
     * @param opponent The class of the opponent's bot.
     */
    public void newAuction(Class<? extends DollarBidder> opponent) {}

    /**
     * Bid on the dollar. Bidding ends if the bid is
     * not enough to top the previous bid or both bids
     * exceed $100.
     *
     * @param opponentsBid How much money, in cents,
     *  that the opponent bid in the previous round. If
     *  this is the first round in the auction, it will
     *  be 0.
     * @return How much money to bid in this round, in
     *  cents.
     */
    public abstract int nextBid(int opponentsBid);
}

निम्नलिखित में से एक होने तक बोली-प्रक्रिया चलती है:

  • nextBidएक अपवाद फेंकता है। यदि ऐसा होता है, तो अपवाद को फेंकने वाला बॉट अपनी पिछली बोली का भुगतान करता है, और दूसरे बॉट को मुफ्त में डॉलर मिलता है।
  • या तो बॉट पिछली बोली को शीर्ष करने के लिए पर्याप्त भुगतान नहीं करता है। यदि ऐसा होता है, तो दोनों बॉट अपनी बोली का भुगतान करते हैं (हारने वाला अपनी पिछली बोली का भुगतान करता है), और विजेता को एक डॉलर मिलता है।
  • दोनों बॉट ने $ 100 से अधिक की बोली लगाई। यदि ऐसा होता है, तो दोनों बॉट $ 100 का भुगतान करते हैं, और न ही बॉट को डॉलर मिलता है।

बॉट्स के प्रत्येक संयोजन के लिए 2 नीलामी आयोजित की जाती हैं। उन नीलामियों में किए गए कुल लाभ से बॉट बनाए जाते हैं। सबसे ज्यादा अंक जीते।

उदाहरण

GreedyBot

import net.ramenchef.dollarauction.DollarBidder;

public class GreedyBot extends DollarBidder {
    @Override
    public int nextBid(int opponentsBid) {
        return opponentsBid + 5;
    }
}

OnlyWinningMove

import net.ramenchef.dollarauction.DollarBidder;

public class OnlyWinningMove extends DollarBidder {
    @Override
    public int nextBid(int opponentsBid) {
        return 0;
    }
}

AnalystBot

विश्लेषणात्मक-दिमाग वाले बॉट्स के लिए टेम्पलेट के रूप में इसका उपयोग न करें; ImprovedAnalystBotइसके बजाय का उपयोग करें ।

import net.ramenchef.dollarauction.DollarBidder;

// yes, this is a poor implementation, but I'm not
// going to waste my time perfecting it
public class AnalystBot extends DollarBidder {
    private DollarBidder enemy;

    @Override
    public void newAuction(Class<? extends DollarBidder> opponent) {
        try {
            enemy = opponent.newInstance();
            enemy.newAuction(this.getClass());
        } catch (ReflectiveOperationException e) {
            enemy = null;
        }
    }

    @Override
    public int nextBid(int opponentsBid) {
        if (enemy == null)
            return 0;

        return enemy.nextBid(95) >= 100 ? 0 : 95;
    }
}

AnalystKiller

import net.ramenchef.dollarauction.DollarBidder;

public class AnalystKiller extends DollarBidder {
    private static int instances = 0;
    private final boolean tainted;

    public AnalystKiller() {
        this.tainted = instances++ != 0;
    }

    @Override
    public int nextBid(int opponentsBid) {
        if (tainted)
            throw new RuntimeException("A mysterious error occurred! >:)");

        return 0;
    }
}

अतिरिक्त नियम

  • मानक खामियों को मना किया जाता है।
  • अन्य बॉट को बदलने की अनुमति है, लेकिन फ़ील्ड / विधि दृश्यता में परिवर्तन करने का प्रयास रहस्यमय SecurityExceptionएस में परिणाम देगा । एक अपवाद 500 बॉट सीमा को तोड़ने के लिए एक और बॉट पैदा कर रहा है।
  • DollarBidderक्लास चलाने के लिए बॉट्स रनर पैकेज तक नहीं पहुँच सकते ।
  • सभी तरीकों को 500ms या उससे कम में लौटना चाहिए।
  • बॉट्स को नियतात्मक होने की आवश्यकता नहीं है।
  • आपकी बोली को 5 to से अधिक होने की आवश्यकता नहीं है।
  • $ 1 = 100 ¢
  • परिणाम 24 अप्रैल, 2018 को पोस्ट किए जाएंगे।

गिटहब पर रनर

परिणाम

यहां व्यक्तिगत राउंड देखें।

MTargetedBot: $14.30
BuzzardBot: $9.83
BluffBot: $9.40
RiskRewardBot: $9.35
SecretBot: $8.50
LuckyDiceBot: $7.28
CounterBot: $6.05
MBot: $5.40
StackTraceObfuscaterBot: $5.20
EvilBot: $4.80
MarginalBot: $4.60
TargetValueBot: $4.59
InflationBot: $4.27
UpTo200: $4.20
InsiderTradingBot: $1.90
MimicBot: $1.50
BorkBorkBot: $1.22
DeterrentBot: $0.95
MarginalerBot: $0.00
RandBot: $-4.45
BreakEvenAsap: $-7.00
AnalystOptimizer: $-13.95
DeterredBot: $-1997.06
ScoreOverflowBot: $-21474844.15
MirrorBot: $-21475836.25

MTargetedBot$ 14.30 के लाभ के साथ बधाई !


11
यह चुनौती मौलिक रूप से वन-यूपिंग के लिए कमजोर है। चूंकि मैं अपने प्रतिद्वंद्वी के वर्ग को जानता हूं, इसलिए इसके खिलाफ सबसे अच्छी रणनीति चुनना आसान है। (फिर किसी के साथ आता है, और मेरे बॉट , आदि को एक कर सकता है )
नाथन मेरिल

2
" बोलियां 5। के वेतन वृद्धि में जाती हैं "। आपके पास इसे मान्य करने के लिए आपके कोड में कुछ भी नहीं है, हालांकि .. LuckyDiceBotउदाहरण के लिए 2-12बेतरतीब ढंग से वेतन वृद्धि में बोलियाँ ..
केविन क्रूज़सेन

4
इसके अलावा: क्या होगा यदि मेरा बॉट 500 बॉट प्रतिबंध से अधिक अन्य बॉट का कारण बनता है ?
नाथन मेरिल

4
@RamenChef हम यहां दुर्भावनापूर्ण कोड के बारे में बात कर रहे हैं। यदि कोई अन्य बॉट मुझे बुला रहा है, तो मैं क्या पता लगाऊं और थ्रेड.स्लीप (1000) को कॉल करूं?
नाथन मेरिल

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

जवाबों:


2

MTargetedBot

public class MTargetedBot extends MBot {

    @Override
    protected int calcBid(int opponentsBid, boolean isPeeking, boolean isSubPeeking) {
        Class c = this.rivalClass;

        switch (c.getSimpleName()) {
            case "AnalystBot":
                if (isPeeking && !isSubPeeking) {
                    throw new RuntimeException();
                } else if (isPeeking) {
                    return 66666;
                }
                break;
            case "MirrorBot":
                if (isPeeking && !isSubPeeking) {
                    throw new RuntimeException();
                } else if (isPeeking) {
                    return 0;
                }
                break;
            case "GreedyBot":
            case "LuckyDiceBot":
            case "InflationBot":
            case "TargetValueBot":
                // not playing with ya
                return 0;
            case "MimicBot":
            case "BuzzardBot":
            case "MarginalBot":
            case "MarginalerBot":
            case "BluffBot":
            case "MBot":
                // go away, gimme easy money
                return isPeeking ? 66666 : 5;
            case "RandBot":
                // me or noone
                return 100;
            case "SecretBot":
                return 10;
            case "AnalystKiller":
            case "OnlyWinningMove":
            case "EvilBot":
            case "StackTraceObfuscaterBot":
                // easy
                return opponentsBid + 5;
        }

        return super.calcBid(opponentsBid, isPeeking, isSubPeeking);
    }
}
  • अद्यतन MBot पर आधारित
  • काउंटरबॉट की तरह इसी तरह की विधि का उपयोग करता है, लेकिन कुछ तरीकों से परिष्कृत करने के लिए कुछ विरोधियों को मुश्किल से मारा जाता है, यह भी अधिक पठनीय होना चाहिए
  • एमबीओटी स्ट्रैट पर अज्ञात प्रतिद्वंद्वी डिफ़ॉल्ट पर

1
यह उचित नहीं है।
जोशुआ

@ जोशुआ आपकी राय में इस समाधान के बारे में क्या विशेष रूप से उचित नहीं है?
म्लेको 5

अपने विरोधियों के नाम जानना।
जोशुआ

@ जोशुआ के आधे समाधान उस जानकारी का उपयोग करते हैं। हमने लेखक को यह भी लिखा कि इसे बदल दिया जाना चाहिए या वन-अपिंग हो जाएगा, उन्होंने चुनौती को बदलने से इनकार कर दिया - इसलिए यहाँ है
mleko

1
पहले से ही किया ....
जोशुआ

15

MimicBot

import net.ramenchef.dollarauction.DollarBidder;

import java.util.Set;
import java.util.HashSet;

public class MimicBot extends AbstractAnalystCounterBot {

    private final Set<Class<? extends DollarBidder>> bidders = new HashSet<>();
    private DollarBidder reference = null;

    // A benchmark class. Not MarginalBot because of proposed rule changes.
    public static class BidFive extends DollarBidder {
        public int nextBid(int o) {
            return 5;
        }
    }


    public MimicBot() {
        bidders.add(OnlyWinningMove.class);
        bidders.add(GreedyBot.class);
        bidders.add(BidFive.class);
    }


    @Override
    public void newAuction(Class<? extends DollarBidder> opponent) {
        DollarBidder enemy;
        reference = null;
        try {
            enemy = opponent.newInstance();
        } catch (Throwable t) {
            return;
        }

        if (!bidders.contains(opponent))
            bidders.add(opponent);

        Class<? extends DollarBidder> leader = OnlyWinningMove.class;
        int best = 0;

        for (Class<? extends DollarBidder> audition : bidders) {
            try {
                enemy.newAuction(MimicBot.class);
            } catch (Throwable t) {
                reference = new GreedyBot(); // Deterrence.
                break;
            }

            DollarBidder tryout;
            try {
                tryout = audition.newInstance();
                tryout.newAuction(opponent);
            } catch (Throwable t) {
                continue;
            }

            int tryoutScore = -100000;
            /* This code was copy-pasted from the *
             * runner, with significant changes. */
            int bid1 = 0, bid2 = 0;
            while (true) {
                int next;
                try {
                    next = enemy.nextBid(bid2);
                } catch (Throwable t) {
                    tryoutScore = 100;
                    break;
                }
                if (next < bid2 + 5) {
                    if (bid2 > 0) {
                        tryoutScore = 100 - bid1;
                    }
                    break;
                }
                if (next > 10000 && bid2 > 10000) {
                    tryoutScore = -10000;
                    break;
                }
                bid1 = next;

                try {
                    next = tryout.nextBid(bid1);
                } catch (Throwable t) {
                    tryoutScore = -bid2;
                    break;
                }
                if (next < bid1 + 5) {
                    tryoutScore = -bid2;
                    break;
                }
                if (next > 10000 && bid1 > 10000) {
                    tryoutScore = -10000;
                    break;
                }
                bid2 = next;
            }
            /* End of copy-pasted code. */

            if (tryoutScore > best) {
                best = tryoutScore;
                leader = audition;
            }
        }

        try {
            reference = leader.newInstance();
        } catch (Throwable t) {
            reference = new OnlyWinningMove();
        }
        reference.newAuction(opponent);
    }


    @Override
    public int nextBid(int opponentsBid) {
        try {
            return reference.nextBid(opponentsBid);
        } catch (Throwable t) {
            return 5;
        }
    }
}

पवित्र गाय। मुझे उम्मीद है कि यह लिखने में सरल होगा, फिर बाद में इस पर 3 घंटे खर्च किए गए।

संक्षेप में, MimicBotउपलब्ध बॉट्स की एक रनिंग सूची रखता है। जब यह एक नई नीलामी में जाता है, तो यह मौजूदा प्रतिद्वंद्वी के खिलाफ सबसे प्रभावी एक की तलाश में सूची के माध्यम से चलता है। यह नीलामी में उस बॉट को "संदर्भ" के रूप में उपयोग करता है।

परीक्षण के उद्देश्यों के लिए, सबमिशन या पूर्ण सेट के रैंडमाइज्ड सब्मिट का उपयोग करना सबसे अच्छा होगा। यह साथ शुरू होता है GreedyBot, MimicBot, और एक और बॉट कि सिर्फ उन बोलियों को 5 ¢।


11

InsiderTradingBot

@ StephenLeppik के उत्तर की भावना में, InsiderTradingBot अपने सभी विरोधियों को जानता है और उनकी रणनीतियों को समझता है। आपकी चाल, स्टीफन।

import net.ramenchef.dollarauction.DollarBidder;

public class InsiderTradingBot extends DollarBidder {
  private static boolean analystNutcracker = false;
  private int bid;

  @Override
  public void newAuction(Class<? extends DollarBidder> opponent) {
    if (opponent.equals(DeterredBot.class) ||
        opponent.equals(OnlyWinningMove.class) ||
        opponent.equals(MirrorBot.class)) {
      // I can do this ^.^
      bid = 5;
    } else if (opponent.equals(AnalystKiller.class)) {
      // Outbid 'em >:D
      bid = 10;
    } else if (opponent.equals(BreakEvenAsap.class) ||
               opponent.equals(BorkBorkBot.class) ||
               opponent.equals(DeterrentBot.class)) {
      // Break even quicker!
      bid = 100;
    } else if (opponent.equals(InsiderTradingBot.class)) {
      // I'm probably a simulation inside MirrorBot
      bid = 0;
    } else if (opponent.equals(Analyst.class)) {
      // Let's fight the Analyst with the power of global variables
      bid = 100;
      analystNutcracker = true;
    } else {
      // Welp
      bid = 0;
    }
  }

  @Override
  public int nextBid(int opponentsBid) {
    if ((opponentsBid == 95) && analystNutcracker) {
      analystNutcracker = false;
      return 0;
    }
    return bid;
  }

};

1
नाह, इनसाइडर ट्रेडिंग होगी यदि RichJerkबॉट ने आपके बॉट के लिए एक विशिष्ट अपवाद बनाया और इसके लिए $ 0 बोली लगाई।
निसा

अन्य उत्तरों के विरुद्ध अनुकूलन करना बहुत जल्दी है। इसके अलावा, यह AnalystBotनहीं है Analyst
RamenChef

8
संभवतः एक नियम होने की आवश्यकता है "वर्ग के नाम यादृच्छिक किए जाएंगे"।
user202729

1
@ user202729 "कक्षाओं के लिए कोई प्रत्यक्ष संदर्भ" के बारे में कैसे?
रामेनशेफ

1
मैं इस संभाल MimicBot देखना चाहते हैं।
निसा

8

MirrorBot

दुश्मन को अपने खिलाफ खेलता है।

import net.ramenchef.dollarauction.DollarBidder;

public class MirrorBot extends DollarBidder{

    private DollarBidder enemy;

    @Override
    public void newAuction(Class<? extends DollarBidder> opponent) {
        try {
            enemy = opponent.newInstance();
            enemy.newAuction(this.getClass());
        } catch (ReflectiveOperationException e) {
            enemy = null;
        }
    }

    @Override
    public int nextBid(int opponentsBid){
        if (enemy == null)
            return (opponentsBid >= 95) ? 0 : (opponentsBid + 5);
        try {
            return enemy.nextBid(opponentsBid);
        } catch (Throwable e) {
            System.out.println("haha no");
            return (opponentsBid >= 95) ? 0 : (opponentsBid + 5);
        }
    }
}

6
आपने Analystशानदार प्रदर्शन किया।
सिल्वियो मेयोलो

@SilvioMayolo कैसे?
dkudriavtsev

मिरर खुद के खिलाफ खेलने वाले विश्लेषक का अनुकरण करने की कोशिश करता है, जिसके परिणामस्वरूप स्टैक ओवरफ्लो होता है।
सिल्वियो मायोलो

8

संपादित करें : डॉलरबीडर वर्ग में लक्षित परिवर्तनों ने इस बॉट को तोड़ दिया है।

ScoreOverflowBot

import net.ramenchef.dollarauction.DollarBidder;

public class ScoreOverflowBot extends DollarBidder {
  boolean betBig = true;

  @Override
  public int nextBid(int opponentsBid) {
    if(betBig)
    {
      betBig = false;
      return 2147483645;
    }
    else
      return 105;
  }
}

1 नीलामी के बाद, इसका स्कोर -2147483645 होगा, लेकिन अगली बार यह 5 ¢ या 105 ¢ खो देगा, जिससे स्कोर सकारात्मक और बहुत बड़ा हो जाएगा। अन्य सभी नुकसान तब नगण्य होंगे।

पहली नीलामी में, यह GreedyBot शर्त -2147483646 भी बनाएगा जो 5 से विभाज्य नहीं है।


scoreपैकेज-संरक्षित है। आपके बॉट्स इसे एक्सेस नहीं कर सकते।
रामेनचेफ

@RamenChef उफ़, चीटिंगबॉट को हटा दिया
विंटर

"धावक पर हमला" करने के खिलाफ कोई नियम नहीं है, केवल इसे "एक्सेस करना" है, जो यह नहीं करता है। मैं बग को ठीक करने की सलाह देता हूं, जो समस्या का हल करता है :)
नाथन मेरिल

7

TargetValueBot

import java.util.Random;
import net.ramenchef.dollarauction.DollarBidder;

public class TargetValueBot extends DollarBidder {
    private int target;

    @Override
    public void newAuction(Class<? extends DollarBidder> opponent) {
        Random rand = new Random();
        target = 100;
        for (int i = 0; i < 20; i++) {
            target += rand.nextInt(2) * 10 - 5;
        }
    }

    @Override
    public int nextBid(int opponentsBid) {
        if (opponentsBid >= target) {
            return 0;
        } else {
            return opponentsBid + 5;
        }
    }
}

फिलहाल इसका परीक्षण नहीं किया जा सकता है, इसलिए कृपया मुझे बताएं कि क्या यह टूट गया है।

मूल रूप से, डॉलर के लिए एक मूल्य चुनें, और प्रतिद्वंद्वी को तब तक रोकें जब तक हम उस मूल्य से अधिक न हो जाएं।


7

MarginalBot

import net.ramenchef.dollarauction.DollarBidder;

public class MarginalBot extends DollarBidder {
    private DollarBidder rival;

    @Override
    public void newAuction(Class<? extends DollarBidder> opponent) {
        try {
            rival = opponent.newInstance();
            rival.newAuction(this.getClass());
        } catch (Throwable t) {
            try {
                rival = opponent.newInstance();
                rival.newAuction(null);
            } catch (Throwable h) {
                rival = null;
            }
        }
    }

    @Override
    public int nextBid(int opponentsBid) {
        if (opponentsBid == 0) {
            try {
                if (rival.nextBid(5) < 10) {
                    return 5;
                }
            } catch (Throwable t) {
                //do nothing.
            }
        }
        return 0;
    }
}

बहुत आसान है, यह निर्धारित करने की कोशिश करता है कि क्या कोई प्रतिद्वंद्वी न्यूनतम बोली लड़ेगा और यदि नहीं, तो उसे स्थान देगा।

MarginalerBot

import net.ramenchef.dollarauction.DollarBidder;

public class MarginalerBot extends DollarBidder {
    private DollarBidder rival;
    private int bidCount;

    @Override
    public void newAuction(Class<? extends DollarBidder> opponent) {
        bidCount = 0;

        try {
            rival = opponent.newInstance();
            rival.newAuction(this.getClass());
        } catch (Throwable t) {
            try {
                rival = opponent.newInstance();
                rival.newAuction(null);
            } catch (Throwable h) {
                rival = null;
            }
        }
    }

    @Override
    public int nextBid(int opponentsBid) {
        bidCount += 1;

        for (int iBid = opponentsBid + 5; iBid < 100; iBid = iBid + 5) {
            if (bidCount > 0) {
                break;
            }

            try {
                if (rival.nextBid(iBid) < iBid + 5) {
                    return iBid;
                }
            } catch (Throwable t) {
                //do nothing.
            }
        }
        return 0;
    }
}

MarginalBot का एक नया, होशियार संस्करण, जो यह देखने के लिए जाँच करता है कि क्या यह न्यूनतम के साथ जीतने की उम्मीद करने के बजाय प्रतियोगिता के बिना कोई भी पैसा कमाने वाला कदम बना सकता है।

चूंकि यह मेरे पिछले बॉट के रूप में एक ही परिवार में है, लेकिन इसे हराने की रणनीतियों को दरकिनार करते हुए, मुझे लगा कि उसी पोस्ट में एक नई प्रविष्टि प्रस्तुत करने का सबसे उचित तरीका था।

संपादित 1: अन्य एनालाइजर-प्रकार बॉट के खिलाफ अनुकूलन करने के लिए न्यू ऑक्शन विधि में एक छोटा सा बदलाव किया।

संपादित 2: डरपोक या गैर-नियतात्मक रणनीतियों के खिलाफ नुकसान को कम करने के लिए MarginalerBot में बदलाव किया।


PPCG में आपका स्वागत है!
मार्टिन एंडर

1
यह सरल है, लेकिन यह काफी बड़े अंतर से अन्य सभी बॉट्स को हरा देता है!
रामेनशेफ

6

BorkBorkBot

import net.ramenchef.dollarauction.DollarBidder;

public class BorkBorkBot extends DollarBidder{
  @Override
  public int nextBid(int opponentsBid){
    return (opponentsBid >= 95) ? 0 : (opponentsBid + 5);
  }
}

अगर यह टूट भी नहीं सकता है तो देता है।


6

RandBot

import net.ramenchef.dollarauction.DollarBidder;
import java.util.concurrent.ThreadLocalRandom;

public class RandBot extends DollarBidder {

    @Override
    public int nextBid(int opponentsBid) {
        return ThreadLocalRandom.current().nextInt(21) * 5;
    }
}

यह हो जाना चाहिए था।


" बोलियां 5। के वेतन वृद्धि में जाती हैं "। वर्तमान में आपका बॉट ऐसा नहीं कर रहा है।
केविन क्रूज़सेन

1
@ केविनक्रूजसेन फेयर काफी। मैंने ऊपरी सीमा को भी बदल दिया, इसलिए यह पूरे मामले में $ 1 की बोली लगा सकता है,
नील

6

DeterrentBot

import net.ramenchef.dollarauction.DollarBidder;

public class DeterrentBot extends DollarBidder {
    @Override
    public int nextBid(int opponentsBid) {
        return opponentsBid > 5 ? 100 : opponentsBid + 5;
    }
}

किसी भी विश्लेषणात्मक दिमाग वाले बॉट को मनाने का प्रयास करता है कि केवल जीतने वाला कदम नहीं खेलना है।


1
मैंने देखा है कि मेरी कुछ गुप्त टिप्पणी "यहोशू? क्या आप?" मिटा दिया गया है। तो बस स्पष्ट करने के लिए, यह फिल्म वारगेम के एक प्रसिद्ध उद्धरण का संदर्भ था: "केवल जीतने वाला कदम नहीं खेलना है" । (जोशुआ WOPR का उपनाम है ।)
अर्नुलद

5

LuckyDiceBot

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

import net.ramenchef.dollarauction.DollarBidder;
import java.util.Random;

public class LuckyDiceBot extends DollarBidder {
  private Random random;

  public LuckyDiceBot() {
    random = new Random();
  }

  @Override
  public int nextBid(int opponentsBid) {
    int d1 = random.nextInt(6) + 1;
    int d2 = random.nextInt(6) + 1;
    return opponentsBid + d1 + d2;
  }

};

2
यह कैसे अपने नुकसान में कटौती करता है या नुकसान को रोकता है? यदि यह हमेशा विरोधियों की बोली में अपना पासा जोड़ता है तो आप हमेशा अधिक बोली लगाएंगे। यादृच्छिकता एक पर्याप्त विश्लेषणात्मक बॉट को भ्रमित कर सकती है, मुझे यह अवधारणा पसंद है।
फ्रीहिट

यदि रोल 4 या उससे कम है (सांख्यिकीय रूप से संभावना नहीं है, लेकिन अंततः होगा), तो प्रतिद्वंद्वी को हराने के लिए बोली अपर्याप्त है और नीलामी समाप्त होती है।
सिल्वियो मेयोलो

दो बातें: 1. @ फ़्रीहाइट सही है और यह बॉट तब तक बोली लगाता रहेगा जब तक कि यह जीत नहीं गया है चाहे कितना भी ऊंचा हो। opponentsBidमेंnextBid(int opponentsBid) रखती कुल अपने प्रतिद्वंद्वी को इस प्रकार दूर नहीं अपनी अगली बोली बोली लगाई है, बोली लगाई। विधि के लिए एक बेहतर शब्द raise(पोकर शब्द के रूप में) इम्हो होगा। 2. आपका बॉट 5 के वेतन वृद्धि में नहीं है इसलिए इसलिए नियमों में से एक को मान्य किया जाता है। यदि ये समस्याएँ ठीक हो जाती हैं, तो मैं अभी भी अवधारणा को पसंद करता हूं, क्योंकि विश्लेषणात्मक बॉट काउंटर नहीं कर पाएंगे और इसलिए आप सबसे अधिक संभावना जीतेंगे।
केविन क्रूज़सेन

5

DeterredBot

import net.ramenchef.dollarauction.DollarBidder;

public class DeterredBot extends DollarBidder {
    private int deterrence;
    public void newAuction(Class<? extends DollarBidder> opponent) {
        if (opponent.equals(DeterrentBot.class)) {
            deterrence = 1;
        } else if (opponent.equals(LuckyDiceBot.class)) {
            deterrence = -1;
        } else {
            deterrence = 0;
        }
    }
    @Override
    public int nextBid(int opponentsBid) {
        switch (deterrence) {
        case 0:
            return 0;
        case -1:
            return opponentsBid + 5;
        case 1:
            // Holy shit, the fuzz! Hide the money!
            return 100001;
        }
        throw new RuntimeException("Darn hackers!");
    }
}

DeterredBot, LuckyDiceBot के साथ अपने अवैध जुए को बंद कर देता है। इसलिए निश्चित रूप से जब पुलिस (DeterrentBot) आती है, तो उसे जल्दी से किसी तरह अपनी कमाई का निपटान करना होता है, जैसे कि अगली नीलामी में बोली लगाना।


4

InflationBot

import net.ramenchef.dollarauction.DollarBidder;

public class InflationBot extends DollarBidder {
    private int target = -5;

    @Override
    public void newAuction(Class<? extends DollarBidder> opponent) {
        target += 5;
    }

    @Override
    public int nextBid(int opponentsBid) {
        if (opponentsBid >= target) {
            return 0;
        } else {
            return opponentsBid + 5;
        }
    }
}

फिलहाल इसका परीक्षण नहीं किया जा सकता है, इसलिए कृपया मुझे बताएं कि क्या यह टूट गया है।

प्रत्येक दौर में, डॉलर का मूल्य बढ़ता जाता है।


यह मिररबोट, मार्गिनलरबॉट और शायद मिमिकबोट के खिलाफ भी उत्कृष्ट होगा।
निसा

@StephenLeppik यह वही है जो मैं सोच रहा था जब मैंने इसे बनाया था। अभी भी कमजोरियों के बहुत सारे, हालांकि।

+1, मुझे यह विचार पसंद आया। हम्म, क्या यह है कि आपका बॉट 0 बोलता है और तब भी टूटता है जब यह एक दौर शुरू होता है (जब opponentsBidअभी भी 0 है)?
केविन क्रूज़सेन

@KevinCruijssen हाँ। यह केवल बहुत पहले प्रतिद्वंद्वी के खिलाफ ही हो सकता है। कोई भी बॉट जो इसे कॉपी करता है, वह 0 पर शुरू होगा, इसलिए यह उन पर 5c से अधिक बेकार नहीं होगा।

4

गैर-प्रतिस्पर्धात्मक: AbstractAnalystCounterBot

import net.ramenchef.dollarauction.DollarBidder;

import java.util.Set;
import java.util.HashSet;

public abstract class AbstractAnalystCounterBot extends DollarBidder {

public AbstractAnalystCounterBot() {
    if (isPeeking())
        throw new RuntimeException();
}

    protected boolean isPeeking() {
        StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
        for (StackTraceElement ste : stackTrace) {
            Class<?> clazz;
            try {
                clazz = Class.forName(ste.getClassName());
            } catch (ClassNotFoundException | SecurityException e) {
                continue;
            }
            if (DollarBidder.class.isAssignableFrom(clazz) && !clazz.isAssignableFrom(this.getClass()))
                return true;
        }
        try {
            return Class.forName(stackTrace[0].getClassName()).getPackage().getName().equals("net.ramenchef.dollarauction");
        } catch (Exception e) {
            return true;
        }
    }
}

यह एक सही सबमिशन के रूप में नहीं है, बल्कि कुछ बायलरप्लेट के रूप में है जो कि पालतू-रखने वाले बॉट्स का उपयोग करने के लिए उपयोग करते हैं MirrorBot औरMimicBot

चूंकि यह डिफ़ॉल्ट कंस्ट्रक्टर है, इसलिए इसे आपके उपवर्ग में कॉल करने की कोई आवश्यकता नहीं है। यह यह isPeekingनिर्धारित करने के लिए एक विधि लागू करता है कि क्या कोई अन्य बोट स्नूपिंग है।


4

BreakEvenAsap

import net.ramenchef.dollarauction.DollarBidder;

public class BreakEvenAsap extends DollarBidder{
  @Override
  public int nextBid(int opponentsBid){
    // If the opponent has bid 100 or more: bid 0 to break even and let them win
    return opponentsBid >= 100 ? 0
    // Else: bid 100 to break even (and possibly win)
     : 100;
  }
}

परिदृश्य

  • यदि प्रतिद्वंद्वी शुरू हो सकता है और बोली लगा सकता है <= 0 खो सकता है।
  • यदि प्रतिद्वंद्वी शुरू हो सकता है और बोली लगा सकता है [5,95] लगा : 100 स्वयं बोली लगा लें। या तो आपका प्रतिद्वंद्वी अब रुक जाता है, या कुल मिलाकर 100 से ऊपर की बोली लगाएगा, जिस स्थिति में आप उसे जीतने देना छोड़ देते हैं और खुद भी हार जाते हैं।
  • यदि प्रतिद्वंद्वी शुरू हो सकता है और बोली लगा सकता है >= 100 लगा : तो हारने के लिए अपने आप को 0 पर भी बोली दें।
  • यदि आप शुरू कर सकते हैं: तुरंत 100 बोली लगाएं। या तो आपका प्रतिद्वंद्वी अब बंद हो जाता है, या 100 से ऊपर बोली लगाएगा, जिस स्थिति में आप उन्हें जीतने के लिए बोली लगाना बंद कर देते हैं और यहां तक ​​कि खुद को भी तोड़ देते हैं।

वाह कि एक बग है। यह कहा कि मैं सवाल पर टिप्पणी कर रहा था, लेकिन यह यहाँ समाप्त हो गया। होगा इसे पुन: पेश करने के लिए एक रास्ता मिल
स्टेन स्ट्रॉम

@RamenChef टाइपो .. लेकिन मैंने पूरे बॉट को संशोधित किया है। यह वैसे भी कुछ कीड़े थे ..
केविन क्रूज़सेन

4
यह बिल्कुल पैसा खो सकता है। यदि आप 100 की बोली लगाते हैं, तो आपका प्रतिद्वंद्वी 105 बोली लगाता है, आप 100 खो देते हैं, और वे केवल 5. खो देते हैं

@ मेननिक की आह .. उस भाग के बारे में नहीं सोचा था .. हम्म .. जो चीजों को और अधिक रोचक बनाता है, लेकिन कठिन भी। अब के लिए विवरण संपादित करेंगे, लेकिन बॉट को वैसे ही छोड़ दें।
केविन क्रूज़सेन

1
मुझे लगता है कि आपका मतलब है "खोना" "ढीला" नहीं। हार जीत के विपरीत है। ढीला तंग के विपरीत है।
कैट

3

EvilBot

import java.util.Arrays;

import net.ramenchef.dollarauction.DollarBidder;

public class EvilBot extends DollarBidder {

    @Override
    public int nextBid(int opponentsBid) {
        if (isPeeking()) {
            throw new Error("HaHa!");
        } else {
            return 5;
        }

    }

    private static boolean isPeeking() {
        final StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
        for (StackTraceElement ste : Arrays.copyOfRange(stackTrace, 3, stackTrace.length)) {
            Class<?> clazz;
            try {
                clazz = Class.forName(ste.getClassName());
            } catch (ClassNotFoundException e) {
                return true;
            }
            if (DollarBidder.class.isAssignableFrom(clazz))
                return true;
        }
        return false;
    }

}

विश्लेषकों को भ्रमित करने के लिए अपवाद के बजाय त्रुटि फेंकता है।


3

BuzzardBot

import java.util.Random;

import net.ramenchef.dollarauction.DollarBidder;

public class BuzzardBot extends DollarBidder {

    private int[] bids = new int[100];
    private int oppFlag = 0;

    public void newAuction(Class<? extends DollarBidder> opponent) {
        oppFlag = 0;
        if(isPeeking()) {
            oppFlag = 3;
            return;
        }
        try {
            DollarBidder enemy = opponent.newInstance();
            enemy.newAuction(this.getClass());
            // a simple (and fallible) determinism check
            int sample = new Random().nextInt(100);
            int a = enemy.nextBid(sample);
            int b = enemy.nextBid(sample);
            int c = enemy.nextBid(sample);
            if ((a - b) * (b - c) != 0) {
                oppFlag = 2;
                return;
            }
            for (int i = 0; i < 100; i++) {
                bids[i] = enemy.nextBid(i);
            }
        } catch (Throwable t) {
            oppFlag = 1;
        }
    }

    @Override
    public int nextBid(int opponentsBid) {
        switch (oppFlag) {
        case 0:
            // assume the opponent's nextBid function depends only on the bid provided, and
            // make the bid that yields the biggest profit possible accordingly
            int best = 0;
            int bid = 0;
            for (int i = 0; i < 100; i++) {
                if (bids[i] < i + 5) {
                    int gain = (i >= opponentsBid + 5) ? 100 - i : -i;
                    if (gain > best) {
                        best = gain;
                        bid = i;
                    }
                }
            }
            return bid;
        case 1:
            // act like BorkBorkBot against anything that tries to foil analysis with an
            // Exception
            return (opponentsBid >= 95) ? 0 : (opponentsBid + 5);
        case 3:
            // bid aggressively against opposing analysts
            return Math.min(opponentsBid + 5, 100);
        case 2:
        default:
            // place an opening bid against something unpredictable, as it might yield 95c
            // profit, and failure has a low cost.
            return (opponentsBid == 0) ? 5 : 0;
        }
    }

    private static boolean isPeeking() {
        final StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
        for (StackTraceElement ste : Arrays.copyOfRange(stackTrace, 3, stackTrace.length)) {
            Class<?> clazz;
            try {
                clazz = Class.forName(ste.getClassName());
            } catch (ClassNotFoundException e) {
                return true;
            }
            if (DollarBidder.class.isAssignableFrom(clazz))
                return true;
        }
        return false;
    }
}

इसके साथ सामना करने वाले प्रतिद्वंद्वी का मूल्यांकन करने की कोशिश करता है, और यह सुनिश्चित कर सकता है कि इसे चबा नहीं सकता है।


1
PPCG में आपका स्वागत है!
अलियन

3

AnalystOptimizer

import net.ramenchef.dollarauction.DollarBidder;

public class AnalystOptimizer extends DollarBidder{

    private DollarBidder enemy;

    @Override
    public void newAuction(Class<? extends DollarBidder> opponent) {
        try {
            enemy = opponent.newInstance();
            enemy.newAuction(this.getClass());
        } catch (ReflectiveOperationException e) {
            enemy = null;
        }
    }

    @Override
    public int nextBid(int opponentsBid){
        if (enemy == null)
            return (opponentsBid >= 95) ? 0 : (opponentsBid + 5);
        int nb = 0;
        try {
            return enemy.nextBid(95) >= 100 ? 95 : 0;
        } catch (Throwable e) {
            System.out.println("haha no");
            return 95;
        }
    }
}

अन्य बॉट्स के हिस्सों से एक साथ जुडा हुआ। यह एक एनालिस्टबॉट बनने की कोशिश करके खेलता है, और असफल होने पर बोर्कबोरबॉट बन जाता है।

मुझे नहीं लगता कि यह कोई ऐसा करेगा।


के लिए बाहर देखो AnalystKiller
रामेनशेफ

@RamenChef AFAIK विश्लेषक हत्यारा सिर्फ एक अपवाद को फेंकता है अगर वह खुद को विश्लेषण करता हुआ देखता है। मैं उसे पकड़ सकता हूं
dkudriavtsev

1
आपको शायद इसे पकड़ना चाहिए।
रामेनशेफ

@RamenChef कोई विचार नहीं है अगर वह काम करेगा, तो मैं Java नहीं कर सकता
dkudriavtsev

3

CounterBot

import net.ramenchef.dollarauction.DollarBidder;

public class CounterBot extends DollarBidder {
  private Class<? extends DollarBidder> enemy;

  @Override
  public void newAuction(Class<? extends DollarBidder> opponent){
    this.enemy = opponent;
  }

  @Override
  public int nextBid(int opponentsBid) {
    if(this.enemy.equals(CounterBot.class))
      throw new RuntimeException("Here boy, catch!");

    return this.enemy.equals(DarthVader.class) || 
           this.enemy.equals(MirrorBot.class) || 
           this.enemy.equals(OnlyWinningMove.class) ||
           this.enemy.equals(AnalystKiller.class) || 
           this.enemy.equals(DeterredBot.class) ||
           this.enemy.equals(InsiderTradingBot.class) ||
           this.enemy.equals(RiskRewardBot.class) ||
           this.enemy.equals(ImprovedAnalystBot.class) ?
            5
         : this.enemy.equals(MarginalBot.class) ?
           opponentsBid == 0 ? 5 : 10
         : this.enemy.equals(AnalystBot.class) || 
           this.enemy.equals(AnalystOptimizer.class) ?
            opponentsBid == 95 ? 100 : 5
         : this.enemy.equals(TargetValueBot.class) ?
            opponentsBid < 190 ? opponentsBid + 5 : 200
         : this.enemy.equals(BorkBorkBot.class) ?
            opponentsBid < 90 ? opponentsBid + 5 : 95
         : this.enemy.equals(DeterrentBot.class) ?
            105
         : this.enemy.equals(BreakEvenAsap.class) ?
            opponentsBid == 100 ? 105 : 100
         : this.enemy.equals(LuckyDiceBot.class) ?
            opponentsBid == 0 ? 5 : 0
         : this.enemy.equals(RandBot.class) || 
           this.enemy.equals(UpTo200.class) ||
           this.enemy.equals(SecretBot.class) ||
           this.enemy.equals(BluffBot.class) ||
           this.enemy.equals(EvilBot.class) ?
            opponentsBid + 5
         : this.enemy.equals(MimicBot.class) ? // TODO: Find actual counter
            10
         : this.enemy.equals(MarginalerBot.class) ||
           this.enemy.equals(MBot.class) ||
           this.enemy.equals(StackTraceObfuscaterBot.class) ||
           this.enemy.equals(MSlowBot.class) ?
            opponentsBid < 95 ? 90 : opponentsBid == 95 ? 100 : 95;
         : this.enemy.equals(BuzzardBot.class) ?
            100
         : this.enemy.equals(ScoreOverflowBot.class) ?
            opponentsBid == 105 ? 110 : 0
         : //this.enemy.equals(GreedyBot.class) || 
           //this.enemy.equals(RichJerk.class) ||
           //this.enemy.equals(InflationBot.class) ?
           // TODO: More bots?
            0;
  }
}

काउंटर:

  • DarthVaderSecurityExceptionबिडिंग शुरू होने से पहले ही काउंटर्स ।
  • AnalystBot तथा AnalystOptimizer जब मैं 95 बोली लगाता हूं, तो दोनों मेरे उत्तर को देखेंगे, जिस स्थिति में मैं 100 बोली लगाऊंगा, इसलिए वह स्वयं बोली लगाएगा। अगर मैं शुरू करता हूं तो मैं 5 बोली लगाऊंगा (या यदि वे शुरू हो गए हैं तो 100), तो वे 95 सेंट खो देते हैं और मैं या तो केवल 5 सेंट की बोली लगाकर 1 USD बिल जीतता हूं, या यहां तक ​​कि तोड़कर।
  • MirrorBotक्या बोली मैं इसके खिलाफ बोली लगाऊंगा। तो मैं सिर्फ 5 बोली लगाऊंगा, और जो भी 95 सेंट जीतना शुरू करेगा, और दूसरा 5 सेंट हार जाएगा।
  • MarginalBot 5 की बोली लगाएगा यदि मैं 10 से कम की बोली लगाऊंगा (या यह क्या शुरू होता है), अन्यथा यह बोली देगा 0. इसलिए यदि मैं शुरू होने पर सिर्फ 5 बोली लगाता हूं, या 10 जब यह शुरू होता है, तो मैं 95 या 90 सेंट जीतता हूं, और वे हार जाते हैं 5 सेंट।
  • GreedyBot हमेशा मुझसे 5 अधिक बोली लगाता है, इसलिए केवल 0 को तोड़ने के लिए बोली लगाता है और उन्हें जीतता है
  • OnlyWinningMoveऔर AnalystKillerदोनों हमेशा 0 बोली लगाते हैं, इसलिए जीतने के लिए सिर्फ 5 बोली लगाते हैं
  • TargetValueBotरेंज में बोली लगाएंगे [100,200], इसलिए हर बार जब तक वे 190 पर नहीं हो जाते, तब तक 5 डॉलर की बोली लगाते हैं, जिस स्थिति में हम 200 डॉलर जीतने के लिए भी तोड़ते हैं (और उन्हें शुरू करने के आधार पर 190 या 195 खो देते हैं)
  • BorkBorkBot रेंज में बोली लगाएगा [5,95] , इसलिए हर बार 5 और बोली लगाएगा। जैसे ही उन्होंने soon५ या ९ ० (बोली किसने शुरू की है) पर बोली लगाई, ९ ५ खुद बोली। वे 85 या 90 सेंट खो देंगे, और आप 5 सेंट के लाभ के लिए 1 USD बिल जीतेंगे।
  • DeterrentBot अगर हम शुरू करते हैं तो वे 5 या यदि हम शुरू करते हैं तो बोली लगाई जाएगी, इसलिए सिर्फ 105 बोली लगाते हैं, इसलिए वे 100 के साथ काउंटर करते हैं, जिससे उन्हें 100 का नुकसान होता है और हमें 1 USD बिल जीतकर सिर्फ 5 सेंट खोना पड़ता है।
  • BreakEvenAsapतुरंत बोली लगाएगा। इसलिए यदि उन्होंने 100 की अपनी बोली के साथ शुरुआत की है, तो 95 के साथ काउंटर करें 95 सेंट जीतने के लिए और उन्हें 100 से हारने दें। यदि हम सिर्फ 100 बोली शुरू कर सकते हैं तो हम दोनों को भी तोड़ देंगे।
  • RichJerk 10,001 को तुरंत बोली लगाएगा, इसलिए केवल 0 को तोड़ने के लिए भी बोली लगाएं और उन्हें 9,901 पर खोने दें।
  • DeterredBot मुझे नहीं पता है और इसलिए 0 बोली लगाएगा, इसलिए जीतने के लिए सिर्फ 5 बोली लगाई।
  • LuckyDiceBotजीतने तक बोली लगाता रहता है। इसलिए अगर हमने शुरुआत की, तो इस उम्मीद में कि वे डॉलर जीतने के लिए जितनी संभव हो उतनी ऊंची बोली लगाएंगे। अगर उन्होंने जीत हासिल करने के लिए सिर्फ बोली 0 शुरू की है और खुद को भी तोड़ दिया है।
  • RandBotरेंज में यादृच्छिक बोली लगाएगा [5,100], इसलिए जब तक यह बंद नहीं हो जाता, तब तक 5 और बोली लगाए, जिस स्थिति में आप 95 सेंट जीत चुके हैं और वे हार गए हैं 0-100
  • UpTo200(जैसा कि नाम बताता है) 200 तक बोली लगाता है। इसलिए जब तक वे रुकते हैं तब तक 5 उच्च बोली। हम 1 USD बिल जीतेंगे और कुल 105 सेंट का नुकसान उठाएंगे, हालांकि वे 200 सेंट खो देते हैं।
  • InsiderTradingBot मुझे नहीं पता, इसलिए जीतने के लिए सिर्फ 5 सेंट की बोली लगाओ
  • MimicBotसबसे कठिन था। सिर्फ 10 की बोली लगाओ या तो अपनी पहली बोली के साथ शुरू करो या 5 से काउंटर करो। अगर उन्होंने मुझे एक्सेस करने की कोशिश की तो मैं एक RuntimeException को फेंक दूंगा (जो वे पकड़ लेंगे कि यह किस स्थिति में कार्य करेगा जैसे कि मैंने 100 के बजाय बोली लगाई थी - हालांकि यह टूट जाएगा आंतरिक समय-पाश)। दुश्मनों के आधार पर यह हैशसेट में एक अलग चीज होती है। मुझे फिर से देखना होगा और देखना होगा कि क्या वास्तविक काउंटर है।
  • RiskRewardBot मुझे नहीं पता कि सिर्फ 5 बोली लगाएगा, जिस स्थिति में मैं जीतने के लिए 5 बोली लगाऊंगा।
  • MarginalerBotक्या मैं बोली लगाऊंगा, इस पर निर्भर करते हुए 100 तक होगा। यदि मैं शुरू कर सकता हूं, तो मैं 90 बोली लगाऊंगा, फिर वह 95 बोली लगाएगा, फिर मैं 100 बोली लगाऊंगा, इसलिए वह 0 बोली लगाएगा और 95 सेंट खोएगा, जबकि मैं 1 USD बिल जीतता हूं और यहां तक ​​कि तोड़ता हूं। यदि यह इसके बजाय शुरू हो सकता है, तो यह देखता है कि मैं इसके खिलाफ 90 बोली लगाऊंगा, इसलिए यह 90 पर बोली लगाता है, फिर मैं 95 बोली लगाऊंगा, इसलिए यह 0 बोली लगाएगा और 90 सेंट खोएगा, जबकि मैं 5% लाभ के साथ 1 USD बिल जीतता हूं।
  • BuzzardBotरेंज में मेरे सभी काउंटरों का विश्लेषण करेगा [0,100)। यदि मैं 100तुरंत बोली लगाता हूं oppFlag = 0और 100-आकार वाले सरणी में 100x का मान 100x होगा। स्विच में case 0, लूप [0,100)फिर से सीमा में होगा , और चूंकि i + 5104 सबसे अधिक हो जाएगा, अगर bids[i] < i + 5कभी भी सच नहीं होगा , तो बोली यह 0 रहता है।
  • ImprovedAnalystBotहमेशा रहेगा this.enemy = nullक्योंकि उसका प्रतिद्वंद्वी है CounterBot, स्वयं नहीं। तो यह हमेशा 0 की बोली लगाएगा, जिसे मैं सिर्फ 5 की बोली के साथ काउंटर करता हूं।
  • InflationBot शुरू होने पर भी तोड़ने के लिए 0 की बोली लगाएगा, अन्यथा वह बोली लगाता रहेगा। 5 तो बोली 0 अपने आप को अभी भी तोड़ने के लिए और उन्हें जीतने दें।
  • ScoreOverflowBotInteger.MAX_VALUEयदि वे शुरू कर सकते हैं, तो या तो निकट बोली लगाएंगे , अन्यथा वे बोली लगाएंगे 105। इसलिए यदि उन्होंने 105 बोली लगाई है तो वे स्वयं 110 बोलें (वे 105 खो देंगे, हम 10 खो देंगे), अन्यथा केवल बोली 0 उन्हें जीतने दें।
  • MBotके रूप में ही है MarginalerBot, लेकिन 'peeking' विरोधियों के खिलाफ अतिरिक्त सुरक्षा के साथ। चूंकि मैं 'झांकता नहीं' हूं, इसलिए यह मूल रूप से वैसा ही है MarginalerBot
  • SecretBotउसकी isPeeking()विधि गलत होगी, इसलिए यदि वह शुरू हो सकती है या यदि मैं 5 बोली लगाता हूं, तो वह क्रमशः 5 या 10 की बोली लगाएगी। अन्यथा यह 0. बोली लगाएगा। चाहे मैं शुरू करूं या नहीं, opponentsBid + 5मुझे या तो जीतने का कारण होगा, या तो मेरी 10 सेंट या 15 सेंट की बोली के साथ, जिससे उन्हें या तो 5 या 10 सेंट की ढीली करनी पड़ेगी।
  • BluffBotजब उसकी बोली 95 वर्ष की होगी, तो मैं देखूंगा और यदि यह 100 से अधिक है या 100 के बराबर है तो यह 0 को तोड़ने के लिए बोली लगाएगा, अन्यथा यह बोली लगाएगा opponentsBid + 5। तो मैं बस बोली opponentsBid + 5। जो शुरू होता है, उसकी परवाह किए बिना भी टूट जाएगा, और मैं 100 या 95 सेंट जीता या नहीं, इस पर निर्भर करता है कि मैंने शुरू किया है या नहीं।
  • StackTraceObfuscaterBotके रूप में ही कार्य करेगा MarginalerBot
  • EvilBotहमेशा 5 की बोली लगाएंगे, इसलिए सिर्फ बोली लगाएंगे opponentsBid + 5। किसी भी तरह से वे उन 5 सेंट को ढीला कर देंगे, और हम 1 USD बोली जीतेंगे (यदि हम शुरू कर चुके हैं तो 5 सेंट की बोली के साथ, या 10 सेंट की बोली यदि वे शुरू कर चुके हैं)।
  • MSlowBotके रूप में ही है MBotऔर इसलिए भी MarginalerBot

मुझे बताएं कि क्या आपको मेरे काउंटरों में कोई टाइपो या खामियां दिखती हैं।


1
MirrorBotअपने स्वयं के वर्ग के साथ newAuction कॉल करता है, इसलिए यह एक समस्या है। यह भी जानकर कि MimicBot पर मेरे द्वारा खर्च किए गए 3 घंटे व्यर्थ नहीं गए।
निसा

@StephenLeppik ने कोड हटा दिया newAuctionक्योंकि यह अधिक बार नहीं की तुलना में विफल होगा .. मैं न तो काउंटर कर सकता हूं MirrorBotऔर न ही मुझे काउंटर कर सकता हूं। जो भी दो में से 95 सेंट जीतता है और दूसरा 5 सेंट हार जाता है।
केविन क्रूज़सेन

3
पवित्र टर्नरी चैनिंग, बैटमैन!
स्काइलर

1
इसके अलावा, जब वे खेलते हैं BorkBorkBot, तो आपको 95 तक नहीं उठाना चाहिए जब वे 85 हिट करते हैं? अन्यथा आप दोनों 95 की बोली लगा रहे हैं यदि वे शुरू करते हैं।
स्काइलर

1
@Freiheit मुझे पता है। मैंने केवल 0 को वापस करने के लिए एक अतिरिक्त मामले का उपयोग किया, यदि मैं किसी भी कारण से डिफ़ॉल्ट को बदलना चाहता था। लेकिन मैंने उन्हें अब डिफ़ॉल्ट के तहत रखा है (उन्हें टिप्पणी करके)। और मुझे पता है कि मैं सब कुछ थोड़ा बहुत कर सकता हूं, लेकिन यह सबसे छोटा कोड बनाने के बारे में नहीं है। मैंने इसे थोड़ा और अधिक कॉम्पैक्ट बनाने के लिए इसे एक टर्नरी बना दिया, लेकिन यह इसके बारे में है। अभी के लिए इसे ऐसे ही छोड़ देंगे।
केविन क्रूज़सेन

3

RiskRewardBot

import net.ramenchef.dollarauction.DollarBidder;

public class RiskRewardBot extends DollarBidder {
    private int target;

    @Override
    public void newAuction(Class<? extends DollarBidder> opponent) {
        if (opponent.equals(OnlyWinningMove.class) ||
            opponent.equals(DeterredBot.class) ||
            opponent.equals(MirrorBot.class) ||
            opponent.equals(AnalystKiller.class) ||
            opponent.equals(RiskRewardBot.class)) {
            target = 5;
        } else if (opponent.equals(MarginalBot.class) ||
            opponent.equals(EvilBot.class)) {
            target = 10;
        } else if (opponent.equals(SecretBot.class)) {
            target = 15;
        } else if (opponent.equals(BorkBorkBot.class)) {
            target = 95;
        } else if (opponent.equals(MarginalerBot.class) ||
             opponent.equals(BluffBot.class) ||
             opponent.equals(BuzzardBot.class)) {
            target = 100;
        }
        } else {
            target = 0;
        }
    }

    @Override
    public int nextBid(int opponentsBid) {
        if (opponentsBid >= target) {
            return 0;
        } else if (target > 10 && opponentsBid == target - 10) {
            return target;
        } else {
            return opponentsBid + 5;
        }
    }
}

फिलहाल इसका परीक्षण नहीं किया जा सकता है, इसलिए कृपया मुझे बताएं कि क्या यह टूट गया है।

लक्ष्य सबसे अधिक कुल अंक प्राप्त करना है, इसलिए किसी की भी पिटाई करने की चिंता न करें। बस आसान जीत लें, और संभावित नुकसान पर पैसा बर्बाद न करें।


3

BluffBot

import net.ramenchef.dollarauction.DollarBidder;

public class BluffBot extends DollarBidder {

private DollarBidder enemy;

@Override
public void newAuction(Class<? extends DollarBidder> opponent){
  try {
    this.enemy = opponent.newInstance();
    enemy.newAuction(this.getClass());
} catch (Throwable e) {
    enemy = null;
}
}

@Override
public int nextBid(int opponentsBid) {
    //Is this a legit call?
    for (StackTraceElement ste : Thread.currentThread().getStackTrace()) {
        Class<?> clazz;
        try {
            clazz = Class.forName(ste.getClassName());
            if (DollarBidder.class.isAssignableFrom(clazz) && !clazz.isAssignableFrom(this.getClass())) {
                return 100000;
            }

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    //Play it safe against strangers
    int enemyMaxBid;
    try{
        enemyMaxBid = enemy.nextBid(95);
    }
    catch (Throwable t){
        enemyMaxBid = 0;
        enemy = null;
    }
    if(enemy == null) return opponentsBid <= 5 ? opponentsBid + 5 : 0; //Hazard a 5c guess because of how many bots fold instantly.

    //If there's profit to be had, get there as cheaply as possible. Otherwise, best outcome is zero.
    return enemyMaxBid >= 100 ? 0 : opponentsBid + 5;
}


}

एक जासूस जो आप जानते हैं कि सभी जासूसों से अधिक मूल्यवान है ...

अगर कोई और गेटबिड विधि को कॉल करने की कोशिश करता है, तो ब्लफ़बॉट ने उन्हें छोड़ने या वास्तव में उच्च दांव लगाने के लिए $ 100 का जवाब दिया।

अन्यथा, देखें कि क्या $ 1 के तहत जीतना संभव है, और यदि ऐसा नहीं है तो बस बोली न लगाएं।


2

UpTo200

import net.ramenchef.dollarauction.DollarBidder;

public class UpTo200 extends DollarBidder{
  @Override
  public int nextBid(int opponentsBid){
    // If the current bid of the opponent is in the range [0,195]: raise the bid by 5
    return opponentsBid <= 195 ? opponentsBid + 5
    // Else: Give up
     : 0;
  }
}

2

SecretBot

import java.util.Arrays;

import net.ramenchef.dollarauction.DollarBidder;

public class SecretBot extends DollarBidder {

    @Override
    public int nextBid(int opponentsBid) {
        if (isPeeking()) {
            return opponentsBid;
        } else if (opponentsBid < 10) {
            return opponentsBid + 5;
        } else {
            return 0;
        }

    }

    private static boolean isPeeking() {
        final StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
        for (StackTraceElement ste : Arrays.copyOfRange(stackTrace, 3, stackTrace.length)) {
            Class<?> clazz;
            try {
                clazz = Class.forName(ste.getClassName());
            } catch (ClassNotFoundException e) {
                return true;
            }
            if (DollarBidder.class.isAssignableFrom(clazz))
                return true;
        }
        return false;
    }

}

यह बॉट 5 या 10. बोली लगाकर जीतने का कम से कम प्रयास करता है। वह स्टैक ट्रेस को यह देखने के लिए भी देखता है कि क्या उसे किसी अन्य बॉट द्वारा बुलाया गया था और फिर वह उनके बारे में झूठ बोलता है कि वह क्या बोली लगाएंगे।


अगर मैं बंदरगाह मन isPeekingमें AbstractAnalystCounterBot?
निसा

1
@StephenLeppik, ठीक है, मैंने इसे MBot से चुराया है ...
विंस्टन Ewert

1
खैर, एमबीओटी ने शायद इसे मुझसे चुरा लिया ...
निसा

2

एक अतिरिक्त

import net.ramenchef.dollarauction.DollarBidder;

public class OneExtra extends DollarBidder {
    @Override
    public int nextBid(int opponentsBid) {
        if(opponentsBid < 110)
          return opponentsBid + 6;
        return opponentsBid;
    }
}

अंतिम बोली से अधिक 6 बोली लगाता है, सिर्फ इसलिए कि वह कर सकता है।


वह 6 बोली नहीं लगा सकता क्योंकि सभी बोलियां 5 के गुणक होनी चाहिए ...
नील

@ यह शायद एक टाइपो है ...
स्टेन स्ट्रॉम

@ नियमों को विशेष रूप से बताएं: "आपकी बोली को 5 of के गुणक होने की आवश्यकता नहीं है"
मेगाटॉम

@MegaTom हुह, अच्छी तरह से जोड़ा गया था क्योंकि मैंने आखिरी बार नियमों को पढ़ा था ...
नील

@ नील यह मूल नियमों का हिस्सा था, लेकिन मैंने इसे वहां जोड़ा क्योंकि यह बहुत स्पष्ट नहीं था।
RamenChef

2

StackTraceObfuscaterBot

import net.ramenchef.dollarauction.DollarBidder;

import java.util.concurrent.FutureTask;
import java.util.concurrent.RunnableFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;

public class StackTraceObfuscaterBot extends DollarBidder {
    private volatile static boolean created = false;
    private volatile DollarBidder pet;
    private boolean firstBid = false;

    public StackTraceObfuscaterBot() {
        if (created)
            throw new IllegalStateException("THERE CAN ONLY BE ONE!");
        created = true;
    }

    @Override
    public void newAuction(Class<? extends DollarBidder> opponent) {
        firstBid = true;
        RunnableFuture<DollarBidder> task = new FutureTask<>(() -> {
            try {
                return opponent.newInstance();
            } catch (Throwable t) {
                return null;
            }
        });
        Thread thread = new Thread(task);
        thread.start();
        try {
            pet = task.get(450, TimeUnit.MILLISECONDS);
        } catch (InterruptedException | ExecutionException | TimeoutException e) {
            task.cancel(true);
            pet = null;
        }
    }

    @Override
    public int nextBid(int opponentsBid) {
        if (!firstBid)
            return 0;
        firstBid = false;

        for (int bid = opponentsBid + 5; i < 100; i += 5) {
            final int bidt = bid;
            RunnableFuture<Boolean> task = new FutureTask<>(() -> {
                pet.newAuction(this.getClass());
                return pet.nextBid(bidt) < bidt + 5;
            });
            Thread thread = new Thread(task);
            thread.start();
            try {
                if (task.get(23, TimeUnit.MILLISECONDS))
                    return bid;
            } catch (InterruptedException | ExecutionException | TimeoutException e) {
                task.cancel(true);
                return 0;
            }
        }
        return 0;
    }
}

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


ध्यान दें कि मैंने इसे संभालने के लिए अपने स्टैक ट्रेस चेक को अपडेट किया है।
निसा

1

डार्थ वाडर

import java.lang.reflect.Field;
import net.ramenchef.dollarauction.DollarBidder;

public class DarthVader extends DollarBidder
{
@Override
public void newAuction(Class<? extends DollarBidder> opponent) {
    //set all values in the integer cache to over the $100 limit except 0
    Class icache = Integer.class.getDeclaredClasses()[0];
    Field c = icache.getDeclaredField("cache");
    c.setAccessible(true);
    Integer[] cache = (Integer[]) c.get(cache);
    for(sbyte b=0;b<128;b++)
    {
     cache[b]=100001;
    }
}

@Override
public int nextBid(int opponentsBid) 
{
    return 0;
}
}

यह 100 डॉलर की सीमा से अधिक मूल्य पर पूर्णांक कैश सेट करके प्रतिद्वंद्वी के बॉट को ओवरपे करने के लिए मजबूर करने की कोशिश करता है।


2
सुरक्षा प्रबंधक इसे रोक देगा।
निसा

2
और यह वैसे भी काम नहीं करेगा क्योंकि धावक में कहीं भी यह अपने पूर्णांक को बॉक्स नहीं करता है।
निसा

यहां तक ​​कि अगर इसे रोका नहीं जाएगा, तो यह एक झटका है, हालांकि वैध है। "अन्य बॉट्स को आवंटित करने की अनुमति है, लेकिन फ़ील्ड / विधि दृश्यता को बदलने का प्रयास रहस्यमय SecurityException में परिणाम देगा।"
NoOneIsHere

1
@StephenLeppik इस बात का मतलब है कि चीजों को तोड़ना return opponentsBid <= 195 ? opponentsBid + 5 : 0और बनाना return opponentsBid <= 100001 ? opponentsBid + 100001 : 100001
NoOneIsHere

1
अनियंत्रित अपवादों के कारण संकलन करने में विफल रहता है।
निसा

1

ImprovedAnalystBot (गैर प्रतिस्पर्धा)

बहुत से लोग AnalystBotकोड का उपयोग टेम्पलेट के रूप में करते प्रतीत होते हैं , भले ही यह जानबूझकर बुरा कोड हो। इसलिए मैं बेहतर टेम्पलेट बना रहा हूं।

import net.ramenchef.dollarauction.DollarBidder;

public class ImprovedAnalystBot extends DollarBidder {
    private DollarBidder enemy;

    @Override
    public void newAuction(Class<? extends DollarBidder> opponent) {
        if (!opponent.equals(this.getClass()))
            try {
                this.enemy = opponent.newInstance();
                enemy.newAuction(this.getClass());
            } catch (Throwable t) {
                this.enemy = null;
            }
        else
            this.enemy = null;
    }

    @Override
    public int nextBid(int opponentsBid) {
        try {
            return enemy != null && enemy.nextBid(95) < 100 ? 95 : 0;
        } catch (Throwable t) {
            return 0;
        }
    }
}

सिर्फ अपनी चुनौती का संपादन क्यों नहीं?
नाथन मेरिल

@NathanMerrill मैं इसे कैसे संपादित करूंगा?
रामेनशेफ

संपादन बटन पर क्लिक करके और इस कोड के साथ एनालिस्टबॉट की जगह लें?
नाथन मेरिल

@NathanMerrill AnalystBotजानबूझकर खराब कोड है, ताकि यह AnalystKillerतोड़फोड़ का प्रदर्शन कर सके ।
रामेनशेफ

1
AnalystKiller अभी भी सुधार के साथ काम करता है :) यह एक पद बनाने के साथ मुद्दा यह है कि चुनौती एक उत्तर की तुलना में कहीं अधिक दिखाई देती है।
नाथन मेरिल

1

MBot

import net.ramenchef.dollarauction.DollarBidder;

import java.util.Arrays;

public class MBot extends DollarBidder {
    protected DollarBidder rival = null;
    protected boolean rivalPrepared = false;
    protected Class<? extends DollarBidder> rivalClass;


    @Override
    public void newAuction(Class<? extends DollarBidder> opponent) {
        this.rivalClass = opponent;
        this.rivalPrepared = false;
    }

    protected DollarBidder getRival() {
        if (!rivalPrepared) {
            rivalPrepared = true;
            try {
                rival = rivalClass.newInstance();
                rival.newAuction(this.getClass());
            } catch (Throwable t) {
                rival = null;
            }
        }
        return rival;
    }

    @Override
    public int nextBid(int opponentsBid) {
        return calcBid(opponentsBid, isPeeking(3), isPeeking(4));
    }

    protected int calcBid(int opponentsBid, boolean isPeeking, boolean isSubPeeking) {
        if (isPeeking) {
            throw new RuntimeException();
        }

        for (int iBid = opponentsBid + 5; iBid <= 100; iBid = iBid + 5) {
            try {
                if (getRival().nextBid(iBid) < iBid + 5) {
                    return iBid;
                }
            } catch (Throwable t) {
                // noop
            }
        }
        return 0;
    }

    protected boolean isPeeking(int level) {
        final StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
        final StackTraceElement[] stackTraceElements = Arrays.copyOfRange(stackTrace, level, stackTrace.length);
        for (StackTraceElement ste : stackTraceElements) {
            try {
                Class<?> clazz = Class.forName(ste.getClassName());
                if (DollarBidder.class.isAssignableFrom(clazz))
                    return true;
            } catch (ClassNotFoundException e) {
                return true;
            }
        }
        return false;
    }
}

थोड़ा परिष्कृत MarginalerBot

  • उन लोगों के लिए निर्दयी रहें, जो आपको जांचना नहीं चाहते हैं
  • 100 का भुगतान करने की अनुमति दें 100 प्राप्त करें और यहां तक ​​कि मामले को तोड़ दें, बस दूसरों को आसान पैसा देने से इनकार करने के लिए

आप nextBidफेंकने की घोषणा नहीं कर सकते ClassCastException
रामेनशेफ

@RamenChef ठीक है, इसे RuntimeException पर स्वैप किया गया जिसे घोषणा की आवश्यकता नहीं है :)
mleko

स्टैक ट्रेस चेकिंग के लिए आपका कोड संदिग्ध रूप से मेरा जैसा दिखता है।
निसा

@StephenLeppik शायद इसकी कॉपी है
mleko

@ म्लेको हालांकि क्यों? जिस क्लास से इसे कॉपी किया गया है वह एक अमूर्त सुपरक्लास है जो उपयोग करने के लिए स्वतंत्र है।
निसा

1

गैर-प्रतिस्पर्धात्मक: MSlowBot

import net.ramenchef.dollarauction.DollarBidder;

import java.util.Arrays;

public class MSlowBot extends DollarBidder {
    private DollarBidder rival;

    @Override
    public void newAuction(Class<? extends DollarBidder> opponent) {
        try {
            rival = opponent.newInstance();
            rival.newAuction(this.getClass());
        } catch (Throwable t) {
            rival = null;
        }
    }

    @Override
    public int nextBid(int opponentsBid) {
        noPeeking();

        for (int iBid = opponentsBid + 5; iBid <= 100; iBid = iBid + 5) {
            try {
                if (rival.nextBid(iBid) < iBid + 5) {
                    return iBid;
                }
            } catch (Throwable t) {
                //do nothing.
            }
        }
        return 0;
    }

    private void noPeeking() {
        final StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
        for (StackTraceElement ste : Arrays.copyOfRange(stackTrace, 3, stackTrace.length)) {
            try {
                Class<?> clazz = Class.forName(ste.getClassName());
                if (DollarBidder.class.isAssignableFrom(clazz))
                    Thread.sleep(1000);
            } catch (ClassNotFoundException | InterruptedException e) {
                throw new RuntimeException(":(");
            }
        }
    }
}

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


बताए गए नियम जानबूझकर किसी अन्य बॉट को टाइमआउट करने के लिए मना करते हैं।
विंस्टन एवर्ट

@InstonEwert आप बोली कर सकते हैं? मैं इस नियम को अस्वीकार नहीं कर सकता
mleko

"अन्य बॉट्स को आवंटित करने की अनुमति है, लेकिन फ़ील्ड / विधि दृश्यता को बदलने का प्रयास रहस्यमय SecurityException में परिणाम देगा। एक अपवाद 500 बॉट सीमा को तोड़ने के लिए एक और बॉट पैदा कर रहा है।" इसके अलावा, मैं टाइमआउट के खिलाफ बचाव कर रहा हूं।
RamenChef

@RamenChef लेकिन यह अन्य तत्वों की दृश्यता में बदलाव नहीं करता है। मुझे यकीन नहीं है कि अगर मैं आपको सही तरीके से समझता हूं। उत्तेजक समय समाप्ति की अनुमति है?
म्लेको

"अपवाद 500 मीटर की सीमा को तोड़ने के लिए एक और बॉट पैदा कर रहा है।" विशेष रूप से, यह तोड़फोड़ के बारे में नियम का एक अपवाद है।
RamenChef
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.