32
10
This is a KOTH challenge for the dollar bill auction game in game theory. In it, a dollar is being sold to the highest bidder. Bids go up in increments of 5¢, and the loser also pays their bid. The idea is that both players escalate the bidding war far beyond the value of a dollar in order to cut their losses.
Let's hope your bots are smarter than that.
You will be creating a bot to play this game by extending the net.ramenchef.dollarauction.DollarBidder
class. You must implement the nextBid
method that returns your bot's next bid given the other bot's previous bid. If necessary, you can also use the newAuction
method to reset for each auction with the class of the opponent's bot.
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);
}
Bidding goes until one of the following happens:
nextBid
throws an exception. If this happens, the bot that threw the exception pays their previous bid, and the other bot gets the dollar for free.- Either bot does not pay enough to top the previous bid. If this happens, both bots pay their bids (the loser pays their previous bid), and the winner gets a dollar.
- Both bots bid over $100. If this happens, both bots pay $100, and neither bot gets the dollar.
2 auctions are held for each combination of bots. Bots are scored by the total profit they made across those auctions. The highest score wins.
Examples
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
Don't use this as a template for analytically-minded bots; use ImprovedAnalystBot
instead.
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;
}
}
Additional Rules
- Standard loopholes are forbidden.
- Sabotaging other bots is allowed, but attempting to alter field/method visibility will result in mysterious
SecurityException
s. An exception is causing another bot to break the 500ms limit. - Bots cannot access the runner package except to extend the
DollarBidder
class. - All methods should return in 500ms or less.
- Bots do not need to be deterministic.
- Your bid does not need to be a multiple of 5¢.
- $1=100¢
- Results will be posted on April 24, 2018.
Results
View the individual rounds here.
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
Congratulations to MTargetedBot
with a profit of $14.30!
11This challenge is fundamentally vulnerable to One-Upping. Since I know the class of my opponent, it is easy to pick the best strategy against it. (Then somebody comes along, and can one-up my bot, etc) – Nathan Merrill – 2018-04-17T21:28:27.600
2"Bids go up in increments of 5¢". You don't have anything in your code to validate this, though..
LuckyDiceBot
for example bids in increments of2-12
randomly.. – Kevin Cruijssen – 2018-04-18T14:59:55.1831
Comments are not for extended discussion; this conversation has been moved to chat.
– James – 2018-04-18T15:49:12.677You really should specify that bots need to be in the default package. – Nathan Merrill – 2018-04-18T17:12:56.073
@NathanMerrill Put your bot in any package you like, but if you put it in the runner package, it's breaking rule 3. – RamenChef – 2018-04-18T17:15:19.627
@RamenChef no it's not. If I put it in the runner package, and only access the DollarBidder class, that's still valid behavior. – Nathan Merrill – 2018-04-18T17:24:32.750
1@histocrat "The loser pays their previous bid". Yes; the bot would pay its last legal bid. – RamenChef – 2018-04-18T19:16:43.763
What happens if a bot exceeds the 500ms restriction? Does it lose like it would if it threw an error? – None – 2018-04-18T20:18:38.743
4Also: what if my bot causes other bots to exceed the 500ms restriction? – Nathan Merrill – 2018-04-18T20:30:34.137
If your bot regularly goes beyond the 500ms restriction, it’s an invalid submission. That being said, I don’t actually expect anybody to come close to 500ms. – RamenChef – 2018-04-18T20:33:45.980
Preliminary results – RamenChef – 2018-04-18T22:02:36.013
4@RamenChef We're talking about malicious code here. What if I detect when another bot is calling me, and call Thread.sleep(1000)? – Nathan Merrill – 2018-04-19T14:04:35.153
Then the counter bot would be invalid. Also, there is a counter to that. – RamenChef – 2018-04-19T15:19:16.880
Sorry, who is the "counter bot"? The one sleeping? – Nathan Merrill – 2018-04-19T18:54:35.407
@NathanMerrill yes. – RamenChef – 2018-04-19T19:39:31.843
3I'm VTC this as it is unclear what sabotage is allowed and what is not. The OP has disallowed submissions that "attacking the runner" (which is vague), and there's no clear line between malicious code that is allowed, and malicious code that isn't (How do you determine which bot caused a bot to take too long?) – Nathan Merrill – 2018-04-19T20:04:08.690
"Attacking the runner" is vague, but it should be fairly obvious whether a bot is breaking it or not. As for the malicious code, it's no longer allowed as a form of sabotage. My defense of the question is this: are you really going to close the question over a nitpick? – RamenChef – 2018-04-19T21:24:25.307
2@RamenChef Yes, I do think it should be closed: These are solvable issues, but they aren't small; We need challenges to be objective on this site. Decisions about whether something is valid shouldn't just be whatever the OP decides, it needs to be objectively defined in the spec. – Nathan Merrill – 2018-04-20T01:42:09.793
@NathanMerrill I feel like the issues raised - although avoidable, important and abundant - don't invalidate the challenge in its entirety. People are having fun anyway, right? Heck, even Formic Functions, which won Best of PPCG 2017, relies on sportsmanlike behavior of participants to not devolve into everlasting edit wars.
– Alion – 2018-04-20T13:49:26.713Just to be clear, I would've probably voted to close it if I paid closer attention at the start, though. – Alion – 2018-04-20T13:54:40.423
1@Alion That edit war wasn't banned by the rules though. That was a "whoever edits last wins" (the one-up scenario). That challenge still had objective rules. – Nathan Merrill – 2018-04-20T14:27:18.207
1Could you have
DollarBidder
implementIntUnaryOperator
? – Nissa – 2018-04-23T19:20:29.873@StephenLeppik ...why? If you need to use the
nextBid
method as a callback, you can useDollarBidder::nextBid
. – RamenChef – 2018-04-23T19:32:00.120Correction: use
instance::nextBid
. – RamenChef – 2018-04-24T13:35:00.793... I'm still unclear as to where the 5¢ comes in to play... – Neil – 2018-04-25T08:04:07.743