Dolarlık banknot müzayede


33

Bu oyun teorisindeki dolarlık açık artırma oyunu için KOTH mücadelesi . İçinde en yüksek teklifi verene bir dolar satılmaktadır. Teklifler 5 ¢ artışlarla artar ve kaybeden de teklifini öder. Buradaki fikir, her iki oyuncunun da kayıplarını azaltmak için ihale savaşını bir doların değerinin çok ötesine yükseltmesi.

Umarım botların bundan daha akıllıdır.

net.ramenchef.dollarauction.DollarBidderSınıfı genişleterek bu oyunu oynamak için bir bot oluşturacaksınız . nextBidDiğer botun önceki teklifine göre botunuzun bir sonraki teklifini döndüren yöntemi uygulamalısınız . Gerekirse, newAuctionrakibin botunun sınıfı ile her açık artırma için sıfırlama yöntemini de kullanabilirsiniz .

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);
}

Teklif verme, aşağıdakilerden biri gerçekleşinceye kadar devam eder:

  • nextBidbir istisna atar. Bu durumda, istisnayı atan bot önceki teklifini öder ve diğer bot bedavaya dolar kazanır.
  • Her iki bot da bir önceki teklife yetecek kadar ödeme yapmıyor. Bu olursa, iki bot da tekliflerini verir (kaybeden önceki teklifini öder) ve kazanan bir dolar alır.
  • Her iki bot da 100 $ 'ın üzerinde teklif veriyor. Bu olursa, her iki bot da 100 dolar ödüyor ve hiçbir bot da dolar kazanmıyor.

Her bot kombinasyonu için 2 açık artırma düzenlenmiştir. Botlar, bu açık artırmalardan elde ettikleri toplam kar ile puanlanır. En yüksek puan kazanır.

Örnekler

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

Bunu analitik fikirli botlar için şablon olarak kullanmayın; kullanmak ImprovedAnalystBotyerine.

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;
    }
}

Ek Kurallar

  • Standart boşluklar yasaktır.
  • Diğer botların sabote edilmesine izin verilir, ancak alan / yöntem görünürlüğünü değiştirmeye çalışmak gizemli sonuçlara neden olur SecurityException. Bir istisna, başka bir botun 500ms sınırını aşmasına neden oluyor.
  • Botlar, DollarBiddersınıfı genişletmek dışında koşucu paketine erişemez .
  • Tüm yöntemler 500 ms veya daha kısa sürede geri dönmelidir.
  • Botların deterministik olmaları gerekmez.
  • Teklifiniz yok değil ¢ 5 katı olması gerekir.
  • $ 1 = 100 ¢
  • Sonuçlar 24 Nisan 2018’de yayınlanacaktır.

GitHub'da Runner

Sonuçlar

Bireysel turları burada görüntüleyin.

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

MTargetedBot14.30 dolar karla tebrik ederiz !


11
Bu zorluk temel olarak One-Upping'e karşı savunmasızdır. Rakibimin sınıfını bildiğim için, ona karşı en iyi stratejiyi seçmek kolaydır. (Sonra birisi ortaya çıkınca, ve can tek yukarı benim bot vs.)
Nathan Merrill

2
" Teklifler 5 inc artışlarla artıyor ". Gerçi .. bu doğrulamak için kodunuzda şey yok LuckyDiceBotartışlarla örnek teklifler için 2-12rastgele ..
Kevin Cruijssen

4
Ayrıca: botum diğer botların 500ms sınırlamasını aşmasına neden olursa ?
Nathan Merrill

4
@RamenChef Burada kötü amaçlı koddan bahsediyoruz. Başka bir botun beni aradığını tespit edip Thread.sleep (1000) 'i arayabilirsem ne olur?
Nathan Merrill

3
Ben VTC'yim, çünkü hangi sabotaja izin verilip verilmediği belli değil. OP, "koşucuya saldıran" (belirsiz) olan gönderilere izin vermedi ve izin verilen kötü amaçlı kod ile izinsiz kötü amaçlı kod arasında net bir satır yok (Hangi botun çok uzun sürmesine neden olduğunu nasıl belirlersiniz?) ?)
Nathan Merrill,

Yanıtlar:


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);
    }
}
  • Güncellenmiş MBot'a göre
  • CounterBot gibi benzer bir yöntem kullanır, ancak bazı yöntemlerde rakiplerine daha sert vurmak için rafine edilmiş yöntemlerle daha okunaklı olması gerekir
  • MBot strat için bilinmeyen rakip varsayılan olarak

1
Bu adil değil.
Joshua

@Joshua Sizce bu çözüm hakkında özellikle adil olmayan ne var?
mleko

Rakiplerinin isimlerini bilmek.
Joshua

@Joshua çözümlerin yarısı bu bilgiyi kullanır. İşte öyle - Biz bile bu değiştirilmelidir veya yükselten bir pozisyona oluşacağını yazara yazdığı o meydan değiştirmek reddetti
mleko

1
Zaten yaptım ....
Joshua

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;
        }
    }
}

Kutsal inek. Bunun yazması basit olmasını beklerdim, daha sonra üzerine 3 saat geçirdim.

Özünde, MimicBotmevcut botların bir koşu listesini tutar. Yeni bir müzayedeye gittiğinde, mevcut rakibe karşı en etkili olanı bulmak için listede ilerler. Daha sonra bu bot açık artırmada bir "referans" olarak kullanır.

Test amacıyla, gönderilerin randomize bir alt kümesini veya tam setini kullanmak en iyisi olacaktır. O ile başlar GreedyBot, MimicBotsadece ¢ 5 teklifleri olduğunu ve bir daha bot.


11

InsiderTradingBot

@ StephenLeppik'in cevabına göre InsiderTradingBot tüm rakiplerini tanıyor ve stratejilerini anlıyor. Senin sıran, Stephen.

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
Hayır, içeriden öğrenenlerin ticareti, botunuz RichJerkiçin belirli bir istisna yaptıysa ve bunun için 0 dolar verdiyse olur.
Nissa

Diğer cevaplara göre optimizasyon yapmak için çok erken Ayrıca, AnalystBotdeğil Analyst.
RamenChef

8
Muhtemelen bir kural olması gerekir "sınıf adları rastgele olacak".
user202729

1
@ user202729 "Sınıflara doğrudan referans yok" nasıl?
RamenChef

1
Bunu MimicBot’un idaresinde görmek isterim.
Nissa

8

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;
    }
}

Çok basit, bir rakibin minimum bir teklife itiraz edip etmeyeceğini belirlemeye çalışır ve olmasa da yerleştirir.

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;
    }
}

En az kazanmayı ummak yerine, para kazanmak için herhangi bir para kazanıp kazanamayacağını kontrol eden yeni ve daha akıllı bir MarginalBot sürümü.

Önceki botumla aynı ailede olduğundan, ancak onu yenmeye çalışan stratejilerden uzak durduğum için, aynı paylaşımda yeni bir girişin onu sunmanın en makul yolu olduğunu düşündüm.

Düzenleme 1: Diğer analizör tipi botlara karşı optimize etmek için newAuction yönteminde küçük bir değişiklik yapıldı.

Düzenleme 2: Sinsi veya deterministik olmayan stratejilere karşı kayıpları en aza indirmek için MarginalerBot’ta bir değişiklik yapıldı.


PPCG'ye Hoşgeldiniz!
Martin Ender

1
Çok basit, ama diğer tüm botları oldukça büyük bir farkla atıyor!
RamenChef

8

MirrorBot

Düşmanın kendine karşı oynamasını sağlar.

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
AnalystMuhteşem bir şekilde vurdun .
Silvio Mayolo

@ SilvioMayolo Nasıl?
dkudriavtsev

Ayna, Analyst'in kendisine karşı oynadığı ve yığın taşmasıyla sonuçlandığı taklit etmeye çalışır.
Silvio Mayolo

8

Düzenleme : DollarBidder sınıfındaki hedeflenen değişiklikler bu botu kırdı.

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 açık artırmadan sonra, puanı -2147483645 olacak, ancak bir dahaki sefere puanları olumlu ve çok büyük hale getirerek 5 veya 105 puan kaybedecek. Diğer tüm kayıplar daha sonra ihmal edilebilir düzeyde olacaktır.

İlk açık artırmada GreedyBot'un 5 ile bölünemeyen -2147483646'ya bahis yapması da mümkün oldu.


scorepaket korumalıdır. Botların erişemiyor.
RamenChef

@RamenChef Oops, CheatingBot
Winter

“Koşuya saldırmak” a karşı hiçbir kural yoktur, sadece bu işe yaramazsa “erişir”. Sorunu çözen hatayı gidermeyi öneririm :)
Nathan Merrill

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;
        }
    }
}

Bunu şu anda test edemiyorum, bu yüzden lütfen kırılırsa bana bildirin.

Temel olarak, dolar için bir değer seçin ve bu değeri aşana kadar rakibi atarız.


6

BorkBorkBot

import net.ramenchef.dollarauction.DollarBidder;

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

Hatta kırılmazsa pes eder.


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;
    }
}

Yapılması gerekiyordu.


" Teklifler 5 inc artışlarla artıyor ". Botunuz şu anda bunu yapmıyor.
Kevin Cruijssen

1
@KevinCruijssen Adil yeterli. Ayrıca üst limiti de değiştirdim, böylece 1 $ 'a tam teklif verebilirdi,
Neil

6

DeterrentBot

import net.ramenchef.dollarauction.DollarBidder;

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

Analitik düşünceye sahip herhangi bir botu tek kazanan hamlenin oynamak değil olduğuna ikna etmeye çalışır.


1
Biraz şifreli yorumumun "Joshua? Sen misin?" Olduğunu fark ettim. silindi. Bu yüzden sadece açıklamak gerekirse, WarGames filminden ünlü bir alıntıya atıfta bulundu: "tek kazanan hamle oynamak değil" . (Joshua, WOPR'ın takma adıdır .)
Arnauld,

5

LuckyDiceBot

LuckyDiceBot sadece zarlarına güveniyor. İki zar attı, mevcut teklif sahibinin değerine toplamı ekledi ve o kadar teklif etti. Rakibin teklifinin üstesinden gelmek yeterli değilse, kaybını azaltır ve yoluna devam eder.

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
Bu, kayıplarını nasıl azaltır veya kayıpları nasıl durdurur? Her zaman zar atışını rakiplerin teklifine eklerse, o zaman her zaman daha fazlasını teklif edersin. Rasgelelik yeterince analitik bir botun kafasını karıştırabilir, ben konsepti seviyorum.
Freiheit

Eğer atış 4 veya daha az ise (istatistiksel olarak olası değildir, ancak sonuçta ortaya çıkar), o zaman teklif rakibi yenmek için yeterli değildir ve açık artırma sona erer.
Silvio Mayolo

İki şey: 1. @Freiheit haklıdır ve bu bot ne kadar yüksek olursa olsun kazanana kadar teklif vermeye devam edecektir. opponentsBidiçinde nextBid(int opponentsBid)tutan toplam rakibiniz, bugüne kadar değil, sonraki teklifi teklif verdi teklif verdi. Bu yöntem için daha iyi bir terim raise(Poker terim gibi) imho olabilir. 2. Botunuz 5'lik artışlarla bitmiyor, bu nedenle kurallardan birini doğrulıyor. Bu sorunlar çözülürse yine de konsepti beğenirim çünkü analitik botlar karşı koyamayacak ve bu yüzden büyük olasılıkla oldukça sık kazanacaksınız.
Kevin Cruijssen

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 ile yaptığı yasadışı kumardan bir servet kazandı. Elbette, polis (DeterrentBot) geldiğinde, bir sonraki açık artırmada teklif vermek gibi kazançlarını hızla bir şekilde elden çıkarması gerekiyor.


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;
        }
    }
}

Bunu şu anda test edemiyorum, bu yüzden lütfen kırılırsa bana bildirin.

Her turda doların değeri artar.


Bu MirrorBot, MarginalerBot ve muhtemelen MimicBot'a karşı mükemmel olurdu.
Nissa

@StephenLeppik Yaparken bunu düşünüyordum. Yine de, çok fazla zayıflık var.
Anma

+1, fikri sevdim. Hmm, botunuzun 0 teklif vermesi ve bir raund başlatsa bile kırılması mı amaçlanıyor ( opponentsBidhala 0 olduğunda )?
Kevin Cruijssen

@KevinCruijssen Evet. Bu sadece ilk rakibe karşı olabilir. Onu kopyalayan botlardan herhangi biri 0'da başlayacak, bu yüzden bunlar üzerinde 5 c'den fazla boşa harcamayacak.
Anma

4

Rekabet etmeyen: 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;
        }
    }
}

Bu, gerçek bir sunum olarak değil, başkalarının evcil hayvan bulundurma botlarını caydırmak için kullanması için bazı kazan plakaları olarak tasarlanmamıştır. MirrorBot ve MimicBot.

Varsayılan yapıcı olduğundan, alt sınıfınızda arama yapmanız gerekmez. isPeekingBaşka bir botun merak edip etmediğini belirlemek için bir yöntem uygular .


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;
  }
}

Senaryolar

  • Eğer rakip başlayabilir ve teklif verebilirse <= 0 kaybeder.
  • Eğer rakip başlayabilir ve teklif verebilirse [5,95] : 100 teklif ver. Ya rakibiniz şimdi durur ya da toplamda 100'ün üzerinde teklif verir, bu durumda kazanmalarını sağlamak ve kendinizi bile kırmak için teklif vermeyi bırakırsınız.
  • Eğer rakip başlayabilir ve teklif verebilirse >= 100 : kaybetmek, hatta kırmak için kendiniz 0 verin.
  • Başlayabilirseniz: hemen 100 teklif verin. Ya rakibiniz şimdi durur ya da 100'ün üzerinde teklif verir, bu durumda kazanmalarını sağlamak ve kendinizi bile kırmak için teklif vermeyi bırakırsınız.

Vay bu bir hatadır. Soruyla ilgili yorum yaptığımı söyledi, ancak burada sona erdi. Onu yeniden üretmenin bir yolunu bulmalıyım
Stan Strum

@RamenChef Typo .. Ama bütün botu değiştirdim. Yine de bazı hatalar vardı ..
Kevin Cruijssen

4
Bu kesinlikle para kaybedebilir. Eğer 100 teklif, o zaman rakibiniz 105 teklifleri, sadece kaybetmek 5. 100 kaybetme sonunda ve onlar
anımsatıcı

Elbette @ Anımsatıcı Ah .. Bu kısmı hakkında düşünmemiştim .. Hmm .. Bu işler daha ilginç ama aynı zamanda zorlaştırır. Şimdilik açıklamayı düzenleyeceğim, ancak botu olduğu gibi bırakın.
Kevin Cruijssen

1
Bence "kaybetmek değil" kaybetmek "demek istiyorsun. Lose kazanmanın tam tersi. Gevşek, sıkı olanın zıttıdır.
Kat

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;
    }

}

Karışık analistlere bir İstisna yerine bir Hata fırlatır.


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;
    }
}

Karşılaştığı rakibi değerlendirmeye çalışır ve çiğneyebileceğinden fazla ısırmamaya dikkat edin.


1
PPCG'ye Hoşgeldiniz!
Alion

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;
        }
    }
}

diğer botların parçalarından bir araya toplanmış. bu oyun AnalystBot olmaya çalışarak oynuyor ve başarısız olursa BorkBorkBot oluyor.

Bunun bunu iyi yapacağını sanmıyorum.


Dikkat et AnalystKiller.
RamenChef

@RamenChef AFAIK, analist katili, kendisini analiz edildiğini görürse, bir istisna atar. Bunu yakalayabilirim
dkudriavtsev 17:18

1
Muhtemelen yakalamalısın.
RamenChef

@RamenChef Eğer işe yarayacaksa hiçbir fikrim yok, Java
kullanamıyorum

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;
  }
}

Sayaçlar:

  • DarthVaderSecurityExceptionihale başlamadan önce bir atama yaparak kendisini sayar, ancak tam olarak 5 teklif edeceğim.
  • AnalystBot ve AnalystOptimizer her ikisi de, 95 teklif verdiğimde cevabımı arayacak, bu durumda 100 teklif vereceğim, böylece 95 teklif verecek. Ancak, eğer başlarsam (veya başlamışlarsa 100) 5 teklif vereceğim, bu yüzden 95 sent kaybediyorlar ve ya 1 USD fatura vererek ya da sadece 5 kuruş vererek kazanıyorum.
  • MirrorBotkarşı teklif edeceğim şeyi teklif edeceğim. Bu yüzden sadece 5 teklif vereceğim, ve kim başlar 95 cent kazanırsa, diğeri 5 cent kaybeder.
  • MarginalBot 10'dan daha az teklif verirsem (ya da ne kadar başlarsa) teklif verirseniz 5, aksi takdirde 0 olacaktır. Yani eğer başladığımda 5, ya da başladığında 10 teklif edersem, 95 ya da 90 kuruş kazanırım 5 kuruş.
  • GreedyBot her zaman benden 5 daha fazla teklif verir, bu yüzden sadece kırmak için 0 teklif et ve kazanmalarını sağla
  • OnlyWinningMove ve AnalystKiller her ikisi de her zaman 0 teklif eder, bu yüzden sadece 5 kazanmak için teklif verin
  • TargetValueBotaralığa göre teklif verecek [100,200], bu yüzden 190'a kadar her defasında 5 kez daha teklif ver, bu durumda dolar kazanarak kırmak için 200'e yükseltiriz (ve kimin başladığına bağlı olarak 190 veya 195 kaybetmelerine izin veririz)
  • BorkBorkBotaralığında teklif verecek [5,95], bu yüzden her seferinde 5 teklif daha ver. 85 ya da 90 teklif verdikleri anda (kimin başladığına bağlı olarak), 95 kendin teklif et. 85 veya 90 kuruş kaybedecekler ve 5 kuruş kar için 1 USD fatura kazanacaksınız.
  • DeterrentBot başlarlarsa 5 veya başlarsak 100 dolar, bu yüzden sadece 105 dolar, 100 dolar ile karşı karşıya kalsın, 100 dolar kaybeder ve 1 USD faturayı kazanarak sadece 5 kuruş kaybederiz.
  • BreakEvenAsaphemen 100 teklif verecek. Bu yüzden, 100'lük teklifleriyle başlamışlarsa, 95 sent kazanmak için 105'e karşı koy ve 100'lerini kaybetmelerine izin ver.
  • RichJerk hemen 10.001 teklif edecek, bu yüzden sadece kırmak için 0 teklif et ve 9,901 kaybetmelerine izin ver.
  • DeterredBot beni tanımıyor ve bu yüzden 0 teklif verecek, bu yüzden sadece 5 kazanmak için teklif ver.
  • LuckyDiceBotkazanana kadar teklif vermeye devam ediyor. Yani başlarsak, 5 dolar kazanmak için mümkün olduğunca yüksek teklif umuyoruz. Eğer kazanmaya başlayacaklarsa 0 teklif vermişlerse ve kendilerini bile kırmaya başlamışlarsa.
  • RandBotaralıkta rastgele teklif verecek [5,100], bu yüzden durdurulana kadar 5 teklif ver, bu durumda 95 sent kazandınız ve kaybettiler 0-100.
  • UpTo200(adının belirtildiği gibi) 200’e kadar teklif verir. 1 USD'lik banknotu kazanacağız ve toplamda 105 cent zarar alacağız, ancak 200 cent kaybedecekler.
  • InsiderTradingBot beni tanımıyor, bu yüzden kazanmak için sadece 5 sent teklif
  • MimicBoten zordu. Sadece ilk teklifleri olan 5 ile başlamak ya da karşı çıkmak için 10 teklif verin. Bana erişmeye çalışırlarsa bir RuntimeException vereceğim (hangi durumda yakalayacaklarsa, bunun yerine 100 teklif vermişim gibi davranırlar - iç döngü sırasında). HashSet'teki düşmanlarına göre farklı bir şey olur. Gerçek bir sayaç olup olmadığını görmek için tekrar bakmak ve daha yakından bakmak zorunda kalacağım.
  • RiskRewardBot beni tanımıyor, bu yüzden sadece 5 teklif vereceğim, bu durumda 5 kazanmak için teklif vereceğim.
  • MarginalerBotne teklif edeceğim bağlı olarak 100 kadar bit. Başlayabilirsem, 90 teklif vereceğim, sonra 95 teklif vereceğim, sonra 100 teklif vereceğim, böylece 0 teklif edecek ve 95 sent kaybedecek, 1 USD faturayı kazanacağım ve hatta kıracağım. Bunun yerine başlayabilirse, kendisine karşı 90 teklif verebileceğimi görüyor, bu yüzden 90 teklif veriyor, o zaman 95 teklif vereceğim, böylece 0 teklif verecek ve 90 sent kaybedecek, 1 USD'lik banknotu ise yüzde 5 kar elde edeceğim.
  • BuzzardBotSerideki tüm sayaçlarımı analiz edeceğim [0,100). 100Hemen teklif edersem , kullanması oppFlag = 0ve 100 boyutlu dizinin tamamı 100x değerinin 100x'ini içermesidir. Anahtarda case 0, döngü [0,100)tekrar aralıkta i + 5olacak ve en fazla 104 bids[i] < i + 5olacak , bu nedenle teklif 0 olarak kalır.
  • ImprovedAnalystBother zaman sahip olacak this.enemy = nullçünkü rakibi CounterBotkendisi değil. Bu yüzden her zaman 0, sadece 5 olan bir teklifle karşı karşıya kalırım.
  • InflationBot başladığında bile kırmak için 0 teklif edecek, aksi takdirde teklif vermeye devam edecektir. Yani hemen kendimizi kırmak ve kazanmalarını sağlamak için kendimize 0 teklif vereceğiz.
  • ScoreOverflowBotInteger.MAX_VALUEeğer başlayabilirlerse ya yakında teklif verecekler, yoksa teklif edecekler 105. Yani, eğer 105 teklif ettilerse 110 teklif veriyorlar (105 kaybedecekler, 10 kaybedeceğiz), aksi takdirde kazanmaları için 0 verin.
  • MBotaynı MarginalerBot, ancak 'gözetleme' rakiplerine karşı ek koruma ile. Gözetlemediğim için, temelde aynı MarginalerBot.
  • SecretBotOnun olacak isPeeking()o başlayabilir ya da ben 5 teklif, eğer sırasıyla 5 veya 10 teklif vereceğini eğer öyleyse, yöntem dönüş false. Aksi halde 0 koyacaktır. Öyleyse başlasam da istemesem de opponentsBid + 5, her iki şekilde de kazanmamı ya 10 kuruş ya da 15 kuruş teklifiyle 5 ya da 10 kuruş kaybetmelerine neden olur.
  • BluffBotteklifi 95 olduğunda ne teklif edeceğime bakacak ve bu 100'e eşit veya daha büyükse, kırmak için bile 0 teklif edecek, aksi takdirde teklif verecek opponentsBid + 5. Bu yüzden sadece teklif vereceğim opponentsBid + 5. Kim başlarsa başlasa bile kırılır ve başlamasam da başlamamasına bağlı olarak 100 veya 95 sent kazanırım.
  • StackTraceObfuscaterBotgibi davranacak MarginalerBot.
  • EvilBother zaman 5 teklif verecek, bu yüzden sadece teklif vereceğim opponentsBid + 5. Her iki durumda da bu 5 senti kaybedecekler ve 1 USD'lik teklifi (biz başlarsak 5 sentlik bir teklifle veya başlamışlarsa 10 sentlik bir teklifle) kazanacağız.
  • MSlowBotaynı MBotve dolayısıyla aynı zamanda MarginalerBot.

Sayaçlarımda yazım hatası veya kusur görürseniz bana bildirin.


1
MirrorBotKendi sınıfınızla newAuction'ı çağırır, bu yüzden bu bir problemdir. Ayrıca MimicBot'ta geçirdiğim 3 saati boşuna bilmediğim için memnunum.
Nissa

@StephenLeppik Kod kaldırıldı newAuctionçünkü daha sık başarısız olacaktır MirrorBot. İkisinden başlarsa, 95 sent kazanır, diğeri ise 5 cent kaybeder.
Kevin Cruijssen

3
Kutsal üçlü zincirleme, Batman!
Skyler

1
Ayrıca, oynarken BorkBorkBot, 85'e çıktıklarında 95'e yükselmemelisin? Aksi takdirde, ikiniz de başlarlarsa 95 teklif veriyorsunuz.
Skyler

1
@Freiheit biliyorum. Herhangi bir nedenden dolayı varsayılanı değiştirmek istediğimde 0 döndürmek için ek bir durum kullandım. Ama şimdi onları varsayılanın altına koydum (yorum yaparak). Ve her şeyi bir miktar golf oynayabileceğimi biliyorum, ama bu en kısa kodu yapmakla ilgili değil. Sadece biraz daha kompakt hale getirmek için üçlü yaptım, ama bu konuda. Şimdilik böyle bırakacak.
Kevin Cruijssen

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;
        }
    }
}

Bunu şu anda test edemiyorum, bu yüzden lütfen kırılırsa bana bildirin.

Amaç en yüksek toplam puanı almak, bu yüzden kimseyi dövmek için endişelenmeyin. Sadece basit kazançları alın ve olası kayıplar için para harcamayın.


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;
}


}

Tanıdığınız bir casus hiç bir casustan çok daha değerlidir ...

Bir başkası getBid yöntemini çağırmaya çalışırsa, BluffBot, istifa ya da çok yüksek bahisler yapmalarını sağlamak için 100 $ ile yanıt verir.

Aksi takdirde, 1 doların altında kazanmanın mümkün olup olmadığını görün ve kazanmıyorsanız teklif vermeyin.


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;
    }

}

Bu bot, 5 veya 10 teklif vererek kazanmak için minimum girişimde bulunur. Ayrıca, başka bir Bot tarafından aranıp aranmadığını görmek için istif izini kontrol eder ve ardından ne kadar teklif vereceği konusunda onlara yalan söyler.


Ben portuna bir sakıncası isPeekingiçine AbstractAnalystCounterBot?
Nissa

1
@StephenLeppik, peki, onu MBot'tan çaldım ...
Winston Ewert

1
Eh, MBot muhtemelen benden çaldı…
Nissa

2

Bir Ekstra

import net.ramenchef.dollarauction.DollarBidder;

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

Son teklifinden 6 daha fazla teklif verir, çünkü yapabilir.


Tüm tekliflerin 5 katı olması gerektiğinden 6 teklifi veremez ...
Neil

@Neil muhtemelen bir yazım hatası ...
Stan Strum

@ Kurallar özellikle şunu belirtin: "Teklifinizin 5 multiple katı olması gerekmez"
MegaTom

@MegaTom Huh, kuralları en son okuduğumdan beri eklendi ...
Neil

@Neil Özgün kuralların bir parçasıydı, ancak oraya ekledim çünkü çok açık değildi.
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;
    }
}

Bu bot yığın izlemesi ile yansıma tespit etme girişimlerinde gülüyor. Gördükleri en yakın şey DollarBidderyarattığı bazı lambda sınıfıdır. Açıkçası başka bir bot onları yansıtmaya çalışıyor. Lamda sınıfının aslında bir iş için çalıştığını bilmiyorlar DollarBidder. Bunun ötesinde, o gibi davranır MarginalerBot.


Bu işlemle başa çıkmak için yığın izleme kontrolümü güncellediğimi unutmayın.
Nissa

1

Darth Vader

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;
}
}

Bu, tamsayı önbelleğini 100 $ sınırının üzerindeki değere ayarlayarak rakibin botunu fazladan ödeme yapmaya zorlar.


2
Güvenlik yöneticisi bunu durduracaktı.
Nissa

2
Ve bu hiçbir şekilde işe yaramaz, çünkü koşucunun hiçbir yerinde tam sayılarını kutlayamaz.
Nissa

Bu durdurulmasa bile, geçerli olmasına rağmen bu bir sarsıntı hareketidir. "Diğer botların sabote edilmesine izin verilir, ancak alan / yöntem görünürlüğünü değiştirmeye çalışmak gizemli SecurityExceptions ile sonuçlanır."
NoOneIsHere

1
@StephenLeppik Bunun amacı, bir şeyleri kırmak return opponentsBid <= 195 ? opponentsBid + 5 : 0ve onu yapmaktır return opponentsBid <= 100001 ? opponentsBid + 100001 : 100001.
NoOneIsHere

1
Denetlenmeyen istisnalar nedeniyle derlenemedi.
Nissa

1

ImprovedAnalystBot (Rekabetsiz)

AnalystBotKasıtlı olarak kötü bir kod olsa bile, birçok kişi kodu şablon olarak kullanıyor gibi görünüyor . Bu yüzden daha iyi bir şablon yapıyorum.

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;
        }
    }
}

Neden sadece mücadeleni değiştirmiyorsun?
Nathan Merrill

@NathanMerrill Nasıl düzenlerim?
RamenChef

Düzenle düğmesine tıklayarak ve AnalystBot’u bu kodla değiştirmek mi istiyorsunuz?
Nathan Merrill

@NathanMerrill AnalystBotkasıtlı olarak kötü bir kod olduğundan AnalystKillersabote edildiğini gösterebiliyor .
RamenChef

1
AnalystKiller hala geliştirilmiş olanla çalışıyor :) Gönderiyi oluştururken sorun, mücadelenin bir cevaptan çok daha fazla görünür olması.
Nathan Merrill

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;
    }
}

Biraz rafine MarginalerBot

  • seni kontrol etmek istemeyenlere karşı nazik ol
  • 100'ü ödemesine izin vermek, 100'ü almak ve davayı bozmak, sadece başkalarının kolay parasını reddetmek

Sen beyan edemez nextBidatmak ClassCastException.
RamenChef

@RamenChef tamam, bildirimi gerektirmeyen RuntimeException'a geçti :)
mleko

Yığın izleme denetimi kodunuz, benimkine kuşkuyla benziyor.
Nissa,

@StephenLeppik muhtemelen onun kopyası
mleko

@mleko neden olsa? Kopyalandığı sınıf, kullanımı ücretsiz olan soyut bir üst sınıftır.
Nissa

1

Rekabet etmeyen: 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 ile aynı mantık, yalnızca düşmana karşı savaşırken İstisna yerine zaman aşımı kullanın. Şimdiye kadar kimse tekrar zaman aşımına uğramadı, bu yüzden etkili olmalı


Belirtilen kurallar kasıtlı olarak başka bir botun zaman aşımına uğramasına neden olmayı yasaklamaktadır.
Winston Ewert,

@ WinstonEwert alıntı yapabilir misiniz? Buna izin vermeme kuralı bulamıyorum
mleko

"Diğer botların sabote edilmesine izin verilir, ancak saha / yöntem görünürlüğünü değiştirmeye çalışmak gizemli SecurityExceptions ile sonuçlanır. Bir istisna, başka bir botun 500ms sınırını aşmasına neden oluyor." Ayrıca zaman aşımına karşı savunuyorum.
RamenChef

@RamenChef ancak bu diğer elemanların görünürlüğünü değiştirmez. Seni doğru anladığımdan emin değilim. Kışkırtma zaman aşımına izin verilir mi?
mleko

"Bir istisna, başka bir botun 500ms sınırını aşmasına neden oluyor." Spesifik olarak, bu sabotaj ile ilgili kuralın bir istisnasıdır.
RamenChef
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.