Calabozo de botdom

8

- de crisis y martirio

(ese es el subtítulo porque los subtítulos son geniales)

En este desafío del en (sí; no tienes que ir más lejos para saber que no puedes presentarte en Java), debes crear un bot que juegue un juego muy similar al de bienvenida a la mazmorra

Reglas del juego

(ten en cuenta que este no es el juego original)

Hay un mazo, un conjunto de objetos y algunas cartas de recompensa y cartas de muerte. Base HP es 3. El mazo consiste en 13 cartas de monstruos numeradas 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 9para denotar sus fortalezas.

Lista de articulos

  1. Pacto demoníaco: Derrota al demonio (monstruo de fuerza 7) y al monstruo debajo de él en la pila de mazmorras. - (solo derrota al demonio si el demonio fue el último en la mazmorra)

  2. Poción de vida: cuando caes a 0 HP, derrota al monstruo y regresa a 3 HP.

  3. Santo Grial: derrota a los monstruos de fuerza par (en el juego, estos son muertos vivientes). Si se produce un monstruo par después de que se haya utilizado el pacto demoníaco, eso actúa primero, y no obtendrás una muerte extra por pacto después de este monstruo.

  4. Daga Vorpal: elige un monstruo antes de entrar en la mazmorra; Este tipo de monstruo es derrotado. Si el monstruo objetivo ocurre después de que se haya usado el pacto demoníaco, eso actúa primero, y no obtendrás una muerte extra por pacto después de este monstruo.

  5. Escudo: Agregue 3 al total de HP antes de espeleología. Esto no afecta el uso de la poción de salud, que siempre devolverá la salud a 3.

  6. Armadura: Agregue 5 al total de HP antes de espeleología. Esto no afecta el uso de la poción de salud, que siempre devolverá la salud a 3.

Las tarjetas de recompensa se utilizan para realizar un seguimiento de quién ha tenido éxito en la mazmorra. Las cartas de muerte rastrean quién ha fallado en el calabozo.

Fase de dibujo

Antes de que comience la fase de extracción, todas las cartas de monstruos se devuelven al mazo, ambos jugadores se restauran a 3 HP, y todos los elementos descartados se restauran de modo que haya uno de cada uno.

El primer jugador decide si roba una carta del mazo, ocultándola del otro jugador. Si es así, deben elegir colocarlo encima de la pila de mazmorras o descartarlo junto con un elemento de su elección. Los artículos y cartas descartados no estarán disponibles para ninguno de los jugadores hasta la próxima ronda.

Después de que el jugador uno toma su turno, el jugador dos hace lo mismo. Los jugadores deciden alternativamente si roban y qué hacer con la carta robada, hasta que alguien decida no robar o un jugador tome la última carta del mazo. Si un jugador decide no robar, o roba la última carta, la fase de robo termina y el otro jugador ahora tiene que ingresar a la mazmorra y comenzar a hacer espeleología.

Fase de espeleología

Si la daga Vorpal no se ha descartado, el jugador de espeleología ahora debe decidir a qué carta aplicarla. No hay que tomar decisiones activas para el resto de esta fase.

El primer jugador toma la carta superior; es decir, la última carta colocada en la mazmorra, y ver su número de fuerza. Si el pacto demoníaco está activo desde el turno anterior, la carta robada se descarta. De lo contrario, los artículos del jugador serán verificados en el orden 'pacto demoníaco', 'santo grial', 'Daga Vorpal'. El primer elemento no descartado capaz de derrotar la carta robada se usará y la carta se descartará. Si se usa el pacto demoníaco, ahora estará activo para la próxima carta. El artículo usado no se descarta.

Si no hay ningún elemento aplicable disponible, la fuerza de la carta se resta de la salud del jugador. Si su salud ya no es positiva, serán restaurados a 3 HP y la poción se descartará si está disponible, de lo contrario, el rastreo de mazmorra termina y toman una carta de muerte.

Si bien el jugador no es derrotado y quedan cartas en la mazmorra, este proceso de robar la carta superior se repite. Al derrotar con éxito todas las cartas en el calabozo, el rastreo del calabozo termina y el jugador de espeleología recoge una carta de recompensa.

Descripción completa del juego

Un juego consiste en una serie de rondas, cada una con una fase de dibujo y luego una fase de espeleología. Al final de cada ronda, un jugador habrá recogido una carta de muerte o una carta de recompensa; Una vez que un jugador acumula 5 de cualquier tipo, el juego termina. Si tienen 5 cartas de muerte, pierden el juego. Si tienen 5 cartas de recompensa, ganan. De cualquier manera, el otro jugador recibe el resultado opuesto. Si ninguno de los jugadores tiene 5 cartas de un tipo, el juego avanza a la siguiente ronda y el jugador que quedó segundo en la ronda anterior ahora va primero y viceversa.

KOTH detalles

Cada bot jugará 400 juegos contra cualquier otro bot de acuerdo con las reglas descritas anteriormente. ¿Qué bot es el jugador uno?

Aquí están los artículos nuevamente:

  1. Pacto demoníaco: Derrota al demonio (monstruo de fuerza 7) y al monstruo debajo de él en la pila de mazmorras. - (solo derrota al demonio si el demonio fue el último en la mazmorra)

  2. Poción de vida: cuando caes a 0 HP, derrota al monstruo y regresa a 3 HP.

  3. Santo Grial: derrota a los monstruos de fuerza par (en el juego, estos son muertos vivientes). Si se produce un monstruo par después de que se haya utilizado el pacto demoníaco, eso actúa primero, y no obtendrás una muerte extra por pacto después de este monstruo.

  4. Daga Vorpal: elige un monstruo antes de entrar en la mazmorra; Este tipo de monstruo es derrotado. Si el monstruo objetivo ocurre después de que se haya usado el pacto demoníaco, eso actúa primero, y no obtendrás una muerte extra por pacto después de este monstruo.

  5. Escudo: Agregue 3 al total de HP antes de espeleología. Esto no afecta el uso de la poción de salud, que siempre devolverá la salud a 3.

  6. Armadura: Agregue 5 al total de HP antes de espeleología. Esto no afecta el uso de la poción de salud, que siempre devolverá la salud a 3.

y la cubierta: 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 9.

Debe implementar una clase de bot que no utilice variables de clase, derivadas de la siguiente clase base:

class BasePlayer:
    def start_turn(self, last_turn):
        raise NotImplementedError

    def play(self, card):
        raise NotImplementedError

    def vorpal_choice(self, last_turn):
        raise NotImplementedError

    def result(self, bot, result, dungeon, vorped):
        raise NotImplementedError

Esta clase base muestra los métodos que su clase necesita implementar, y la cantidad de argumentos tomados por cada uno.

Método Argumento Descripciones

  • last_turnin vorpal_choicey start_turnes un entero o un valor None. Un valor de 0 a 5 indica que el enemigo descartó la carta robada junto con el ítem indicado por ese valor (ver la lista de ítems más arriba). Un valor de 6 indica que el enemigo colocó la carta en la mazmorra. Un valor None indica que el bot está jugando primero en esta ronda (no es posible vorpal_choice). En vorpal_choicelast_turn es probable que sea 7, lo que indica que pasaron ese turno. La única circunstancia en la que no es 7 es cuando el enemigo roba la última carta.

  • card es un número que representa la fuerza de una de las cartas del mazo como se enumeró anteriormente.

Ahora, los argumentos para resultson un poco más complejos:

  • botindica el bot que entró en la mazmorra. 0 indica que ingresó a la mazmorra y 1 indica que el enemigo ingresó a la mazmorra.

  • resultIndica el éxito del viaje. False indica que el bot de espeleología tuvo éxito, mientras que True indica que fallaron.

  • dungeones una lista de cartas / entradas que representan las cartas que estaban en la mazmorra. La mazmorra se ordena por orden; la primera carta colocada en el calabozo es la primera en la lista, y la última carta colocada está al final. No recibirá ninguna información sobre tarjetas descartadas; son secretos del otro bot.

  • vorpedes un número entero que representa el vorpal_choicehecho por el robot espeleólogo. Si bot==0, ya lo sabes, pero si bot==1, puede ser información útil.

Seré honesto, no recuerdo completamente por qué hice que el resultado ganador sea Falso, pero creo que fue una buena idea en ese momento.

Valores de retorno

  • start_turn: Devuelve 1 para robar una carta o 0 para pasar.

  • play: Regrese 0 a 5 para descartar el elemento correspondiente y la carta robada, o 6 para colocar la carta en la mazmorra (consistente con la entrada last_turn, excepto para pasar, que se realiza durante start_turn).

  • vorpal_choice: Devuelve el número de la carta que deseas eliminar con la daga Vorpal (1 para eliminar 1s, 5 para eliminar 5s). Elegir una carta inexistente te mata (8 es ilegal, 10 es ilegal, 0 es ilegal).

  • result: Puede devolver cualquier cosa, porque esta es una función informativa para actualizar los datos del bot.

Puedes ver el controlador aquí

Aclaraciones adicionales, o simplemente repitiendo algunos pequeños detalles que quizás haya omitido y que desee saber rápidamente:

Los bots juegan 400 juegos entre ellos bot.

No hay variables de clase.

No apuntar a otros bots específicos

No apuntalar otros bots

Sin reflexiones, como modificar el módulo aleatorio u otros bots.

6 bots máximo (por persona), a menos que sea obvio que todos los bots valen la pena incluirlos en el KOTH (pero probablemente aún no hagas un montón de bots, por favor)


No hay una hora de finalización específica para este KOTH, excepto el final de la recompensa por lo que vale. Solo trata de ganar en cada momento.

Resultados hasta ahora (perdón por ser bastante flojo con estos tipos: P)

1 GrailThief 2732 0.98
2 Steve 2399 0.86
3 DevilWorshipper 1854 0.66
4 RunAway 1336 0.48
5 BoringPlayer 1190 0.42
6 SlapAndFlap 783 0.28
7 DareDevilDumDum 750 0.27
8 RandomMandom 156 0.06

Grailthief "roba" la recompensa. en realidad no, porque se lo ganó. Buen trabajo, Sleafar!

Limón Destructible
fuente
2
De hecho, he jugado este juego una o dos veces. Bastante desafiante a veces.
Draco18s ya no confía en SE
1
ehhh, tbh dudo que sea tan popular: P
Destructible Lemon
2
2. place the item in the dungeon. The item goes in the dungeon (duh)parece ser un error tipográfico; no hay ningún elemento mencionado en ese punto (acabas de robar una carta del mazo de monstruos). Las reglas probablemente deberían aclararse un poco.
1
@ ais523 ¿no or any information known only to one player.estoy claro otra vez? la mazmorra solo se revela al final, por lo que las cartas robadas por un bot solo son conocidas por un bot. Como bonificación, las cartas descartadas nunca se revelan. si piensas "oh bueno, entonces hay una mejor estrategia probabilística", la predicción del oponente sigue siendo muy importante, por lo que esto también es inválido
Destructible Lemon
1
Ah, actualmente no está claro a partir de las reglas que no conozcas el contenido actual de la mazmorra (solo la influencia que has tenido personalmente en ella). Es casi seguro que debería aclararse.

Respuestas:

3

GrialThief

Un viejo y experimentado rastreador de mazmorras. Él sabe que la mayoría de los demás esperan, que el santo grial los salva, por lo tanto, se asegura de que desaparezca.

from base import BasePlayer
import copy

class GrailThief(BasePlayer):
    class Stats:
        def __init__(self):
            self.deck = [1, 2, 3, 4, 5] * 2 + [6, 7, 9]
            self.items = {0, 1, 2, 3, 4, 5}
            self.dungeon_known = []
            self.dungeon_unknown = 0
            self.monsters_safe = {2, 4, 6, 7}
            self.update()

        def update(self):
            self.dungeon_total = len(self.dungeon_known) + self.dungeon_unknown
            deck_factor = float(self.dungeon_unknown) / len(self.deck) if len(self.deck) > 0 else 1.0
            self.dungeon_weighted = [(i, 0.0 if i in self.monsters_safe else 1.0) for i in self.dungeon_known] + [(i, 0.0 if i in self.monsters_safe else deck_factor) for i in self.deck]
            dungeon_weighted_sums = dict.fromkeys(self.dungeon_known + self.deck, 0.0)
            for i in self.dungeon_weighted:
                dungeon_weighted_sums[i[0]] += i[0] * i[1]
            self.vorpal = max(dungeon_weighted_sums, key = dungeon_weighted_sums.get)
            if 3 in self.items:
                self.dungeon_weighted = [(i[0], 0.0 if i[0] == self.vorpal else i[1]) for i in self.dungeon_weighted]

        def discard_item(self, item, card):
            new = copy.copy(self)
            new.items = {i for i in new.items if i != item}
            if item == 0:
                new.monsters_safe = {i for i in new.monsters_safe if i != 7}
            elif item == 2:
                new.monsters_safe = {i for i in new.monsters_safe if i not in {2, 4, 6}}
            if card is not None:
                new.deck = list(new.deck)
                new.deck.remove(card)
            new.update()
            return new

        def to_dungeon(self, card):
            new = copy.copy(self)
            if card is None:
                new.dungeon_unknown += 1
            else:
                new.deck = list(new.deck)
                new.deck.remove(card)
                new.dungeon_known = list(new.dungeon_known)
                new.dungeon_known.append(card)
            new.update()
            return new

        def effective_hp(self):
            hp = 3.0
            if 1 in self.items:
                hp += 3.0
                if self.dungeon_total > 0:
                    hp += sum([(i[0] - 1) * i[1] for i in self.dungeon_weighted]) / self.dungeon_total
            if 4 in self.items:
                hp += 3.0
            if 5 in self.items:
                hp += 5.0
            return hp

        def effective_damage(self):
            damage = sum([i[0] * i[1] for i in self.dungeon_weighted])
            if 0 in self.items:
                if self.dungeon_total > 1:
                    damage -= damage / (self.dungeon_total - 1)
            return damage

    def __init__(self):
        self.stats = self.Stats()

    def process_last_turn(self, last_turn):
        if last_turn in [0, 1, 2, 3, 4, 5]:
            self.stats = self.stats.discard_item(last_turn, None)
        elif last_turn == 6:
            self.stats = self.stats.to_dungeon(None)

    def start_turn(self, last_turn):
        self.process_last_turn(last_turn)
        if self.stats.effective_hp() > self.stats.effective_damage() + 1.5:
            return 1
        else:
            return 0

    def play(self, card):
        if 2 in self.stats.items:
            self.stats = self.stats.discard_item(2, card)
            return 2
        else:
            self.stats = self.stats.to_dungeon(card)
            return 6

    def vorpal_choice(self, last_turn):
        self.process_last_turn(last_turn)
        return self.stats.vorpal

    def result(self, bot, result, dungeon, vorped):
        self.stats = self.Stats()
Sleafar
fuente
Debo decir, buen trabajo! gracias por unirse a este koth
Destructible Lemon
3

DevilWorshipper

Mi primer intento en un desafío KOTH:

from base import BasePlayer
#from random import randint

class DevilWorshipper(BasePlayer):
    def reset(self):
        self.items = [0, 1, 2, 3, 4, 5]
        self.turns = 0
        self.demon = False
        self.dragon = False

    def __init__(self):
        self.reset()

    def start_turn(self, last_turn):
        if last_turn in self.items:
            self.items.remove(last_turn)

        if last_turn is not None:
            #self.demon = True if randint(1, 13 - self.turns) <= 2 else False
            self.turns += 1

        if (((self.demon == True and not (0 in self.items)) or (self.dragon == True)) and not (3 in self.items)):
            return 0
        if (len(self.items) <= 1):
            return 0
        return 1

    def play(self, card):
        self.turns += 1

        if (card == 9):
            self.dragon = True
            return 6

        if (card == 7):
            self.demon = True
            return 6

        for i in [3, 0, 2, 1, 5, 4]:
            if (i in self.items):
                self.items.remove(i)
                return i

        return 6

    def vorpal_choice(self, last_turn):
        return 5 #If it works for others maybe it will work for us

    def result(self, bot, result, dungeon, vorped):
        self.reset()

Esencialmente, nos deshacemos del pacto y la daga vorpal, esperamos a que el demonio entre en la cubierta y pasa. Cada ronda que el oponente haya robado al demonio, tiene el% de posibilidades de que la última carta que el oponente haya robado sea un demonio para asumir que ya jugaron al demonio.

Avísame si hay algo que hice mal; No me he metido con Python en mucho tiempo, este es mi primer KOTH, y son las 2 am, así que seguramente habrá algo.

EDICIONES:

Sacar la aleatoriedad resulta ser de gran ayuda. Con la aleatoriedad es muy tonto. Además, como se dice en los comentarios a continuación, trata de convocar al demonio o al dragón.

Steve

from base import BasePlayer
from random import choice

class Steve(BasePlayer):

    def reset(self):
        self.items = [0, 1, 2, 3, 4, 5]
        self.turns = 0
        self.dungeon = []
        self.possibledungeon = [1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 9]
        self.lastDied = 0

    def __init__(self):
        self.TRIALS = 10 #How many dungeon runs to do each turn
        self.PASS = 8    #How many dungeon runs have to have died to pass
        self.SMASHITEMS = 4 #If less dungeon runs died, smash items.
        self.reset()


    def start_turn(self, last_turn):
        if (last_turn is not None):
            self.turns += 1

            if (last_turn in self.items):
                self.items.remove(last_turn)
            else:
                self.dungeon.append(-1)


        #Check if the dungeon is lethal
        died = 0
        total_hp = 3
        if (5 in self.items):
            total_hp += 5
        if (3 in self.items):
            total_hp += 3
        vorpal = self.vorpal_choice(None)
        for i in range(self.TRIALS):
            hp = total_hp
            temppossible = self.possibledungeon.copy()
            usedpotion = False
            killedDemon = False
            #Going for a crawl
            for j in self.dungeon[::-1]:
                if (killedDemon == True): #If last round we killed the Demon
                    killedDemon = False
                    j = 0
                if (j == -1): #If we don't know what this card is
                    j = choice(temppossible)
                    temppossible.remove(j)
                if (j == 7 and 0 in self.items): #If we kill demon with the pact
                    j = 0
                    killedDemon = True
                if (j % 2 == 0 and 2 in self.items) or (j == vorpal): #If we vorpal or grail
                    j = 0

                hp -= j

                if (hp <= 0):
                    if (not usedpotion and 1 in self.items):
                        hp = 3
                        usedpotion = True
                    else:
                        died += 1
                        break

        if (died >= self.PASS):
            return 0

        died = self.lastDied
        return 1


    def play(self, card):
        self.possibledungeon.remove(card)

        if (self.lastDied < self.SMASHITEMS):
            if (7 in self.dungeon) and (0 in self.items):
                self.items.remove(0)
                return 0
            if ( (9 in self.dungeon) or (5 in self.dungeon) ) and (3 in self.items):
                self.items.remove(3)
                return 3
            for i in [2, 1, 5, 4, 3, 0]:
                if (i in self.items):
                    self.items.remove(i)
                    return i

        self.dungeon.append(card)
        return 6

    def vorpal_choice(self, last_turn):
        if (last_turn is not None):
            self.turns += 1

            if (last_turn in self.items):
                self.items.remove(last_turn)
            else:
                self.dungeon.append(-1)

        if (self.dungeon.count(5) == 2):
            return 5
        if (9 in self.dungeon):
            return 9
        if (self.dungeon.count(4) == 2 and not 2 in self.items):
            return 4
        if (7 in self.dungeon and not 0 in self.items):
            return 7
        for i in range(6)[::-1]:
            if (i+1 in self.dungeon):
                return i+1
        return 5

    def result(self, bot, result, dungeon, vorped):
        self.reset()

Steve intenta adivinar si la mazmorra es letal o no. Si él piensa que es, pasa. Aparte de eso, traté de hacer que se deshaga de los elementos de forma inteligente. Solía ​​ajustar su umbral de PASS dependiendo de si murió en el calabozo o si el oponente vivía, pero terminó haciéndolo mucho más tonto, así que me deshice de él.

Todavía no vence a GrailThief en mi máquina, pero al menos se acerca.

J. Dingo
fuente
¿Sabes que 9 es el dragón, no el demonio?
Destructible Lemon
...Oh. No me había dado cuenta de eso. Bueno, este código parece estar funcionando bien, al menos
J. Dingo
He cambiado el código para intentar convocar al demonio o al dragón.
J. Dingo
Me gustaría decir: buen trabajo y también gracias por unirse al koth
Destructible Lemon
Intentaré ejecutar esto en algún momento en el futuro, pero actualmente no tengo mi computadora preferida, así que puede ser difícil ... ¿tal vez le pediré a alguien más que lo ejecute por mí?
Destructible Lemon
2

SlapAndFlap

Primera vez en KOTH, así que bofetada fuerte por errores.

Este simplón siempre está tratando de eliminar todos los elementos buenos con monstruos de baja fuerza, mientras mantiene a los poderosos y luego solo obliga al oponente a jugar.
Es mejor que RunAway y DumDum al menos: D
Mi otro bot en respuesta eliminada por algún tiempo, necesito arreglarlo mañana

from base import BasePlayer

class SlapAndFlap(BasePlayer):

    def reset(self):
        # Monsters that you pushed in
        self.know_monster = list(self.deck)

        # Items still in game
        self.items_in_game = [True, True, True, True, True, True]

        # List of items, sorted by value
        self.valuables = [3,1,5,0,2,4]

        # Counter
        self.cards = 13

    def __init__(self):
        # Deck
        self.deck = (1,1,2,2,3,3,4,4,5,5,6,7,9)
        # Indexes of item cards
        self.items = (0, 1, 2, 3, 4, 5)

        self.reset()

    def start_turn(self, last_turn):
        if last_turn is not None:
            self.cards -= 1

        # Sneak peak at items removed by opponent
        if last_turn is not None and  last_turn < 6:
            self.items_in_game[last_turn] = False
            self.valuables.remove(last_turn)

        # Flap!
        if self.cards < 6:
            return 0
        return 1

    def play(self, card):
        if card < 6 and any(self.items_in_game):
            self.know_monster.remove(card)
            to_return = self.valuables[0]   # remove the best of the rest
            self.valuables = self.valuables[1:]
            self.items_in_game[to_return] = False
            return to_return
        else:
            return 6

    def vorpal_choice(self, last_turn):
        # We can just guess what monster will be there
        # But we know ones, we removed

        # If we have pact, no need to remove demon
        if self.items_in_game[0]:
            self.know_monster.remove(7)
        # If we have grail, no need to remove even monsters (kinda)
        if self.items_in_game[2]:
            self.know_monster = [i for i in self.know_monster if i%2]

        # Find what threatens us the most, counting its strength multiplied by number
        weight = [i * self.know_monster.count(i) for i in self.know_monster]
        return weight.index(max(weight)) + 1


    def result(self, bot, result, dungeon, vorped):
        self.reset()  # we live for the thrill, not the result!
Zarigüeya muerta
fuente
2
Bueno, lo primero por lo que te voy a abofetear es que es KOTH, no KOHL.
Gryphon
2
@Gryphon Eso duele :(
Dead Possum
2

RandomMandom

El bot aleatorio obligatorio. Apropiadamente, pierde mucho con los bots predeterminados, lo cual es bueno, porque significa que el juego tiene al menos alguna estrategia.

from base import BasePlayer
from random import randint
from random import choice
class RandomMandom(BasePlayer):
    def __init__(self):
        self.items = [0,1,2,3,4,5]

    def start_turn(self, last_turn):
        if last_turn in self.items:
            self.items.remove(last_turn)
        if len(self.items) > 0:
            return randint(0,1)
        return 1

    def play(self, card):            
        if len(self.items) > 0:
            if randint(0,1) == 1:
                selection = choice(self.items)
                self.items.remove(selection)
                return selection
        return 6

    def vorpal_choice(self, last_turn):
        return choice([1,2,3,4,5,6,7,9])

    def result(self, bot, result, dungeon, vorped):
        # Never learns
        pass
Andrew U Baker
fuente
1
Estoy confundido ... ¿por qué el bot siempre sigue dibujando cuando todos los elementos se han ido? también es posible que desee pesarlo, de lo contrario, tiene una probabilidad de 50/50 de no colocar nada en la mazmorra y luego se ve tonto. PS buen nombre de bot
Destructible Lemon
(cuando dije que no colocaba nada, no quería jugar ningún turno)
Destructible Lemon
No analicé el controlador muy de cerca, porque asumí que no me presentaría una opción si no existiera. Además, es un bot súper ingenuo, porque quería obtener al menos una entrada antes de mi entrada real . Usaré tus comentarios en el próximo bot.
Andrew U Baker,
Creo que confundiste la baraja con objetos. no puedes tener elementos, pero aún tienes un mazo y tienes otro turno. Es poco probable dado que los robots probablemente jugarán para no ser estúpidos.
Destructible Lemon
también tienes un 75% de posibilidades de ganar la recompensa en este punto si haces ese nuevo bot, por lo que probablemente será divertido para ti (principalmente debido a que la gente no responde)
Destructible Lemon
1

DareDevilDumDum

un poco claro nunca retrocede. la única forma en que puedes (consistentemente; RunAway pierde a veces, pero aún supera esto la mayor parte del tiempo) perder con este bot es si no eliminas ningún artículo o eres un supercobarde. Piense en este bot como un recordatorio para eliminar elementos, de lo contrario, incluso esto puede ganar.

from base import BasePlayer


class DareDevilDumDum(BasePlayer):
    def start_turn(self, last_turn):
        return 1  # damn squiggles. Draw a card

    def play(self, card):
        return 6+card*0  # put the card in the dungeon, and use card to avoid squiggles :P

    def vorpal_choice(self, last_turn):
        return 9+last_turn*0  # dragon

    def result(self, bot, result, dungeon, vorped):
        pass  # we live for the thrill, not the result!

Y

Huir

prácticamente quitan la armadura y luego se escapan un tiempo antes del final. como daredevildumdum, no recuerda nada, excepto la cantidad de cartas en el mazo (que tbh no se recordaría en el juego real (solo verificaría)) y si alguien quitó la armadura (en su mayoría igual que antes) )

from base import BasePlayer


class RunAway(BasePlayer):

    def __init__(self):
        self.cards = 13
        self.armoured = True

    def start_turn(self, last_turn):
        if last_turn is not None:
            self.cards -= 1  # opponents play
        if last_turn is 5:
            self.armoured = False

        if self.cards < 4:
            return 0 * last_turn  # avoid the ---noid--- squiggles
        else:
            return 1

    def play(self, card):
        if self.cards > 11 and self.armoured:  # if it is the first turn and armour has not been removed
            choice = 5  # remove armour
        else:
            choice = 6  # put the card in the dungeon
        self.cards -= 1  # this play
        return choice

    def vorpal_choice(self, last_turn):
        return 5  # without using more memory, this is the best choice statistically

    def result(self, bot, result, dungeon, vorped):
        self.cards = 13
        self.armoured = True

También porque soy un póster de desafío especial, estos bots no cuentan para mi cuenta de bot, porque son bots de ejemplo que son tontos

Limón Destructible
fuente
Se arregló el segundo fragmento de código (el comienzo)
Mr. Xcoder
1

AburridoJugador

Al contrario de RandomMandom, BoringPlayer siempre toma las mismas decisiones. El problema es que parece que es demasiado exitoso para un bot tan simple. Obtiene más de 3800 en mi prueba local.

from base import BasePlayer

class BoringPlayer(BasePlayer):
    def start_turn(self, last_turn):
        return 1

    def play(self, card):
        return 6

    def vorpal_choice(self, last_turn):
        return 5

    def result(self, bot, result, dungeon, vorped):
        # Never learns
        pass
Andrew U Baker
fuente
Esto es casi idéntico a Daredevil, excepto que elige el golem por su espada vorpal. raro que consigas 3800+. esto parece un error oscuro
Destructible Lemon
ok, parece que elegir 5 sobre nueve es realmente una gran ventaja ... O_o. Supongo que esto no es un error
Destructible Lemon
Creo que 5 sobre 9 es significativo contra fugitivo (porque de todos modos 9 era excesivo), y los otros bots necesitan un ajuste más fino con sus números de todos modos
Destructible Lemon
No tenía la intención de que estuviera tan cerca de DareDevil. En realidad, estaba trabajando en un robot más sofisticado que rastreaba las tarjetas más de cerca, y esto era solo los valores de código auxiliar. Sin embargo, dado que superó todo lo demás, decidí que debería enviarlo de todos modos. Intentaré hacer que mi bot más sofisticado funcione para ver si puedo encontrar un bot mejor.
Andrew U Baker
Nota para las personas que ven esto: este bot no significa que esta estrategia simplista dominará; los otros bots también son muy simples y es por eso que este bot gana
Destructible Lemon