Este es un KOTH desafío para el juego de subasta de billetes de un dólar en teoría de juegos. En él, se vende un dólar al mejor postor. Las ofertas aumentan en incrementos de 5 ¢, y el perdedor también paga su oferta. La idea es que ambos jugadores intensifiquen la guerra de ofertas mucho más allá del valor de un dólar para reducir sus pérdidas.
Esperemos que tus bots sean más inteligentes que eso.
Creará un bot para jugar este juego ampliando la net.ramenchef.dollarauction.DollarBidder
clase. Debe implementar el nextBid
método que devuelve la próxima oferta de su bot dada la oferta anterior del otro bot. Si es necesario, también puede usar el newAuction
método para reiniciar para cada subasta con la clase del bot del oponente.
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);
}
La licitación continúa hasta que ocurre uno de los siguientes:
nextBid
lanza una excepción. Si esto sucede, el bot que lanzó la excepción paga su oferta anterior, y el otro bot obtiene el dólar gratis.- Cualquiera de los bot no paga lo suficiente para superar la oferta anterior. Si esto sucede, ambos robots pagan sus ofertas (el perdedor paga su oferta anterior) y el ganador recibe un dólar.
- Ambos bots ofertaron más de $ 100. Si esto sucede, ambos bots pagan $ 100 y ninguno de ellos recibe el dólar.
Se realizan 2 subastas por cada combinación de bots. Los bots se puntúan según el beneficio total que obtuvieron en esas subastas. El puntaje más alto gana.
Ejemplos
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
No use esto como plantilla para bots con mentalidad analítica; utilizar ImprovedAnalystBot
en su lugar.
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;
}
}
Reglas Adicionales
- Las lagunas estándar están prohibidas.
- Se permite sabotear otros bots, pero intentar alterar la visibilidad del campo / método dará como resultado misteriosos
SecurityException
s. Una excepción está causando que otro bot rompa el límite de 500 ms. - Los bots no pueden acceder al paquete del corredor excepto para extender la
DollarBidder
clase. - Todos los métodos deben regresar en 500 ms o menos.
- Los bots no necesitan ser deterministas.
- Su oferta no necesita ser un múltiplo de 5 ¢.
- $ 1 = 100 ¢
- Los resultados se publicarán el 24 de abril de 2018.
Resultados
Ver las rondas individuales aquí.
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
¡Felicitaciones a MTargetedBot
con una ganancia de $ 14.30!
fuente
LuckyDiceBot
por ejemplo, ofertas en incrementos2-12
aleatorios ...Respuestas:
MTargetedBot
fuente
MimicBot
Santa vaca Esperaba que esto fuera simple de escribir, luego pasé 3 horas en ello.
En esencia,
MimicBot
mantiene una lista actualizada de los bots disponibles. Cuando va a una nueva subasta, recorre la lista en busca de la más efectiva contra el oponente actual. Luego usa ese bot como "referencia" en la subasta.Para fines de prueba, sería mejor usar un subconjunto aleatorio de los envíos o el conjunto completo. Comienza con
GreedyBot
,MimicBot
y un bot más que solo ofrece 5 ¢.fuente
InsiderTradingBot
En el espíritu de la respuesta de @ StephenLeppik, InsiderTradingBot conoce a todos sus oponentes y comprende sus estrategias. Tu movimiento, Stephen.
fuente
RichJerk
bot hiciera una excepción específica para su bot y oferte $ 0 por él.AnalystBot
, noAnalyst
.MirrorBot
Hace que el enemigo juegue contra sí mismo.
fuente
Analyst
espectacularmente.Editar : los cambios dirigidos en la clase DollarBidder han roto este bot.
ScoreOverflowBot
Después de 1 subasta, su puntaje será -2147483645, pero la próxima vez perderá 5 ¢ o 105 ¢, lo que hará que el puntaje sea positivo y muy grande. Todas las demás pérdidas serían entonces insignificantes.
En la primera subasta, también haría que GreedyBot apueste -2147483646, que no es divisible por 5.
fuente
score
está protegido por paquete. Tus bots no pueden acceder a él.TargetValueBot
No puedo probar esto en este momento, así que avíseme si está roto.
Básicamente, elige un valor para el dólar y supera al oponente hasta que superemos ese valor.
fuente
MarginalBot
Muy simple, trata de determinar si un oponente disputaría una oferta mínima y, si no, la coloca.
MarginalerBot
Una nueva versión más inteligente de MarginalBot que comprueba si puede hacer algún movimiento para ganar dinero sin competencia, en lugar de solo esperar ganar con el mínimo.
Como está en la misma familia que mi bot anterior, pero esquiva las estrategias que intentan superarlo, pensé que una nueva entrada en la misma publicación era la forma más razonable de presentarlo.
Edición 1: Se realizó un pequeño cambio en el nuevo método de Subasta para optimizar contra otros bots de tipo analizador.
Edición 2: realizó un cambio en MarginalerBot para minimizar las pérdidas contra estrategias furtivas o no deterministas.
fuente
BorkBorkBot
Se rinde si no puede alcanzar el equilibrio.
fuente
RandBot
Que se tenía que hacer.
fuente
DeterrentBot
Intenta persuadir a los bots de mentalidad analítica de que el único movimiento ganador es no jugar.
fuente
LuckyDiceBot
LuckyDiceBot solo confía en sus dados. Lanza dos dados, agrega la suma al valor del postor actual y ofrece esa cantidad. Si no es suficiente para superar la oferta del oponente, corta sus pérdidas y sigue su camino.
fuente
opponentsBid
innextBid(int opponentsBid)
contiene la oferta total que su oponente ha ofertado hasta ahora, no su próxima oferta. Un mejor término para el método seríaraise
(como el término de Poker) en mi humilde opinión. 2. Su bot no muerde en incrementos de 5, por lo que está validando una de las reglas. Si se solucionan estos problemas, todavía me gusta el concepto, porque los bots analíticos no podrán contrarrestar y, por lo tanto, lo más probable es que ganes con bastante frecuencia.DeterredBot
DeterredBot hace una fortuna con su juego ilegal con LuckyDiceBot. Entonces, por supuesto, cuando llega la policía (DeterrentBot), tiene que deshacerse rápidamente de sus ganancias de alguna manera, como ofertar en la próxima subasta.
fuente
InflaciónBot
No puedo probar esto en este momento, así que avíseme si está roto.
Cada ronda, el valor del dólar sube.
fuente
opponentsBid
todavía es 0)?No competidor: AbstractAnalystCounterBot
Esto no pretende ser una presentación verdadera, sino más bien como una placa repetitiva para que otros la utilicen para disuadir a los robots de mascotas como
MirrorBot
yMimicBot
.Como es el constructor predeterminado, no hay necesidad de llamarlo en su subclase. Implementa un
isPeeking
método para determinar si otro bot está husmeando.fuente
BreakEvenAsap
Escenarios
<= 0
, pierde.[5,95]
pujar: oferte 100 usted mismo. O bien tu oponente se detiene ahora, o pujará por encima de 100 en total, en cuyo caso dejas de pujar para dejar que ganen y te saldes bien.>= 100
puja: apuesta 0 a ti mismo para perder pero llega a un punto de equilibrio.fuente
EvilBot
Lanza un error en lugar de una excepción para confundir a los analistas.
fuente
BuzzardBot
Intenta evaluar al oponente con el que se enfrenta y asegúrate de no morder más de lo que puede masticar.
fuente
Analista Optimizador
empedrado de partes de otros bots. este se juega tratando de ser AnalystBot, y si no tiene éxito, se convierte en BorkBorkBot.
No creo que este lo haga bien.
fuente
AnalystKiller
.CounterBot
Contadores:
DarthVader
se contrarresta causando unSecurityException
antes de que comience la licitación, pero ofertaré 5 por si acaso.AnalystBot
yAnalystOptimizer
ambos verán mi respuesta cuando oferte 95, en cuyo caso mostraré que oferto 100 para que oferte 95. Sin embargo, ofertaré 5 si empiezo (o 100 si han comenzado), por lo que pierden 95 centavos y gano el billete de 1 USD al ofertar solo 5 centavos o al llegar al punto de equilibrio.MirrorBot
ofertaré lo que yo ofertaría contra él. Entonces apostaré 5, y quien comience gana 95 centavos, y el otro pierde 5 centavos.MarginalBot
ofertaré 5 si oferte menos de 10 (o lo que comienza), de lo contrario, ofertará 0. Entonces, si solo oferto 5 cuando comienzo, o 10 cuando comienza, gano 95 o 90 centavos, y pierden 5 centavosGreedyBot
siempre ofrece 5 más que yo, así que solo apuesta 0 para alcanzar el punto de equilibrio y déjalos ganarOnlyWinningMove
yAnalystKiller
ambos siempre ofertan 0, así que solo apuesta 5 para ganarTargetValueBot
ofertará en el rango[100,200]
, así que oferte 5 más cada vez hasta que estén en 190, en cuyo caso aumentaremos a 200 para alcanzar el punto de equilibrio al ganar el dólar (y dejarlos perder 190 o 195 dependiendo de quién comenzó)BorkBorkBot
ofertará en el rango[5,95]
, así que oferte 5 más cada vez también. Tan pronto como oferten 85 o 90 (dependiendo de quién comenzó), oferte 95 usted mismo. Perderán 85 o 90 centavos, y usted gana la factura de 1 USD por una ganancia de 5 centavos.DeterrentBot
ofertará 5 si comienzan o 100 si comenzamos, así que solo oferte 105 para que contrarresten con 100, haciendo que pierdan 100 y que nosotros perdamos solo 5 centavos al ganar la factura de 1 USD.BreakEvenAsap
ofertará 100 de inmediato. Entonces, si comenzaron con su oferta de 100, contrarresten con 105 para ganar 95 centavos y dejen que pierdan 100. Si podemos comenzar, solo oferte 100 para que ambos lleguemos a un punto de equilibrio.RichJerk
ofertará 10,001 de inmediato, así que solo haga una oferta de 0 para alcanzar el punto de equilibrio y déjelos perder 9,901.DeterredBot
no me conoce y por lo tanto ofertará 0, así que solo apuesta 5 para ganar.LuckyDiceBot
sigue pujando hasta que gana. Entonces, si comenzamos, oferte 5 con la esperanza de que oferten lo más alto posible para ganar el dólar. Si han comenzado, solo haga una oferta de 0 para permitirles ganar y alcanzar el punto de equilibrio.RandBot
ofertará al azar en el rango[5,100]
, así que solo apuesta 5 más hasta que se detenga, en cuyo caso has ganado 95 centavos y han perdido0-100
.UpTo200
(como su nombre lo indica) ofertará hasta 200. Así que solo oferte 5 más hasta que se detengan. Ganaremos el billete de 1 USD y tomaremos una pérdida total de 105 centavos, sin embargo, pierden 200 centavos.InsiderTradingBot
no me conoce, así que solo apuesta 5 centavos para ganarMimicBot
Fue lo más difícil. Simplemente ofrezca 10 para comenzar o contrarrestar su primera oferta de 5. Si intentan acceder a mí, lanzaré una RuntimeException (que atraparán, en cuyo caso actuaría como si hubiera ofrecido 100 en su lugar, aunque romperá el bucle while interno). Según los enemigos que tiene en su HashSet, sucede algo diferente. Tendré que volver a visitar y mirar más de cerca para ver si hay un contador real.RiskRewardBot
no me conoce, así que solo pujaré 5, en cuyo caso apostaré 5 para ganar.MarginalerBot
mordirá hasta 100 dependiendo de lo que ofertaría. Si puedo comenzar, ofertaré 90, luego ofertaré 95, luego ofertaré 100 para que oferte 0 y pierda 95 centavos, mientras gano el billete de 1 USD y alcanzo el punto de equilibrio. Si puede comenzar en su lugar, ve que ofertaría 90 contra él, por lo que se oferta 90 por sí mismo, luego ofertaré 95 para que oferte 0 y pierda 90 centavos, mientras gano el billete de 1 USD con una ganancia de 5 centavos.BuzzardBot
analizará todos mis contadores en el rango[0,100)
. Si hago una oferta de100
inmediato, usaráoppFlag = 0
y la matriz completa de tamaño 100 contendrá 100 veces el valor 100. En el interruptorcase 0
, el bucle volverá a estar en el rango[0,100)
, y comoi + 5
máximo será 104, el ifbids[i] < i + 5
nunca será cierto , por lo que la puja que sigue siendo 0ImprovedAnalystBot
siempre lo tendráthis.enemy = null
porque su oponente esCounterBot
, no él mismo. Por lo tanto, siempre ofertará 0, que acabo de contrarrestar con una oferta de 5.InflationBot
ofertará 0 para alcanzar el punto de equilibrio cuando comience, de lo contrario seguirá haciendo una oferta 5. Así que solo hagamos una oferta 0 para alcanzar el punto de equilibrio de inmediato y dejar que ganen.ScoreOverflowBot
ofertarán cercaInteger.MAX_VALUE
si pueden comenzar, de lo contrario, ofertarán105
. Entonces, si han ofertado 105, solo oferte 110 nosotros mismos (perderán 105, nosotros perderemos 10), de lo contrario, solo haga una oferta 0 para que puedan ganar.MBot
es lo mismo queMarginalerBot
, pero con una protección adicional contra oponentes "asomados". Como no me asomo, es básicamente lo mismo queMarginalerBot
.SecretBot
tendrá suisPeeking()
método devuelto falso, por lo que si puede comenzar o si oferto 5, ofertará 5 o 10 respectivamente. De lo contrario, ofertará 0. Entonces, ya sea que empiece o no,opponentsBid + 5
me haría ganar de cualquier manera, ya sea con mi oferta de 10 centavos o 15 centavos, haciendo que pierdan 5 o 10 centavos.BluffBot
analizará lo que ofertaría cuando su oferta sea 95, y si es mayor o igual a 100, ofrecerá 0 para alcanzar el punto de equilibrio, de lo contrario, ofertaráopponentsBid + 5
. Así que solo pujaréopponentsBid + 5
. Se igualará independientemente de quién comience, y gano 100 o 95 centavos dependiendo de si he comenzado o no.StackTraceObfuscaterBot
actuará igual queMarginalerBot
.EvilBot
siempre ofertará 5, así que solo oferteopponentsBid + 5
. De cualquier manera, perderán esos 5 centavos, y ganaremos la oferta de 1 USD (ya sea con una oferta de 5 centavos si hemos comenzado, o una oferta de 10 centavos si han comenzado).MSlowBot
es lo mismoMBot
y por lo tanto tambiénMarginalerBot
.Avísame si ves algún error o error tipográfico en mis contadores.
fuente
MirrorBot
llama a newAuction con tu propia clase, así que eso es un problema. Además, me alegra saber que las 3 horas que pasé en MimicBot no fueron en vano.newAuction
porque fallaría la mayoría de las veces ... No puedo contrarrestarmeMirrorBot
ni puede contrarrestarme. Quien comience de los dos gana 95 centavos y el otro pierde 5 centavos.BorkBorkBot
, ¿no deberías subir a 95 cuando llegan a 85? De lo contrario, ambos están ofertando 95 si comienzan.RiskRewardBot
No puedo probar esto en este momento, así que avíseme si está roto.
El objetivo es obtener el puntaje total más alto, así que no te preocupes por vencer a nadie. Simplemente tome las victorias fáciles y no desperdicie dinero en posibles pérdidas.
fuente
BluffBot
Un espía que conoces es más valioso que ningún espía ...
Si alguien más intenta llamar al método getBid, BluffBot responde con $ 100 para engañarlos para que abandonen o apuesten realmente alto.
De lo contrario, vea si es posible ganar por menos de $ 1, y no haga una oferta si no es así.
fuente
Más de 200
fuente
SecretBot
Este bot hace intentos mínimos de ganar al hacer una oferta de 5 o 10. También comprueba el seguimiento de la pila para ver si otro Bot lo llamó y luego les miente sobre las ofertas que hará.
fuente
isPeeking
enAbstractAnalystCounterBot
?Un extra
Ofrece 6 más que la última oferta, solo porque puede.
fuente
StackTraceObfuscaterBot
Este bot se ríe de los intentos de detectar el reflejo a través del seguimiento de la pila. Lo más parecido que ven a una
DollarBidder
clase lambda que creó. Claramente, no otro robot tratando de reflejarlos. Poco saben que esa clase lambda en realidad está funcionando para aDollarBidder
. Más allá de eso, él actúa comoMarginalerBot
.fuente
Darth Vader
Este intenta forzar al bot del oponente a pagar de más al establecer la memoria caché entera al valor por encima del límite de $ 100.
fuente
return opponentsBid <= 195 ? opponentsBid + 5 : 0
y hacerloreturn opponentsBid <= 100001 ? opponentsBid + 100001 : 100001
.ImprovedAnalystBot
(no competidor)Muchas personas parecen estar usando el
AnalystBot
código como plantilla, a pesar de que es un código deliberadamente malo. Entonces estoy haciendo una mejor plantilla.fuente
AnalystBot
es un código deliberadamente malo para que pueda demostrar elAnalystKiller
sabotaje.MBot
MarginalerBot ligeramente refinado
fuente
nextBid
tirarClassCastException
.No competidor: MSlowBot
La misma lógica que MBot, solo usa el tiempo de espera en lugar de la excepción al luchar contra el enemigo. Hasta ahora nadie está defendiendo contra el tiempo de espera, por lo que debería ser efectivo
fuente