Роботна рулетка: азартні ігри з високими ставками


56

Підсумкова таблиця

+ ---------------------------------- + --------- + ---- ----- + --------- + ---------------------------- +
| Назва | Оцінка | WinRate | TieRate | Ймовірність усунення |
+ ---------------------------------- + --------- + ---- ----- + --------- + ---------------------------- +
| 1. SarcomaBotMk11 | 0,06333 | 6,13% | 0,41% | [42 24 10 8 6 4]% |
| 2. WiseKickBot | 0,06189 | 5,91% | 0,56% | [51 12 7 10 7 6]% |
| 3. StrikerBot | 0,05984 | 5,78% | 0,41% | [46 18 11 8 6 5]% |
| 4. PerfectFractionBot | 0,05336 | 5,16% | 0,35% | [49 12 14 10 6 4]% |
| 5. MehRanBot | 0,05012 | 4,81% | 0,41% | [57 12 8 7 6 5]% |
| 6. OgBot | 0,04879 | 4,66% | 0,45% | [50 15 9 8 7 5]% |
| 7. SnetchBot | 0,04616 | 4,48% | 0,28% | [41 29 8 9 5 3]% |
| 8. AntiKickBot | 0,04458 | 4,24% | 0,44% | [20 38 17 10 6 4]% |
| 9. МехБот | 0,03636 | 3,51% | 0,25% | [80 3 4 4 3 3]% |
| 10. Meh20Bot | 0,03421 | 3,30% | 0,23% | [57 12 8 7 9 3]% |
| 11. GenericBot | 0,03136 | 3,00% | 0,28% | [18 39 20 11 5 3]% |
| 12. HardCodedBot | 0,02891 | 2,75% | 0,29% | [58 21 3 6 5 4]% |
| 13. GangBot1 | 0,02797 | 2,64% | 0,32% | [20 31 35 6 3 2]% |
| 14. SarcomaBotMk3 | 0,02794 | 2,62% | 0,34% | [16 15 38 17 7 4]% |
| 15. GangBot0 | 0,02794 | 2,64% | 0,30% | [20 31 35 6 3 2]% |
| 16. GangBot2 | 0,02770 | 2,62% | 0,31% | [20 31 35 6 3 2]% |
| 17. TitTatBot | 0,02740 | 2,63% | 0,21% | [54 10 15 10 5 2]% |
| 18. MataHari2Bot | 0,02611 | 2,35% | 0,51% | [39 26 11 11 6 5]% |
| 19. PolyBot | 0,02545 | 2,41% | 0,27% | [53 18 6 13 5 3]% |
| 20. SpitballBot | 0,02502 | 2,39% | 0,22% | [84 10 1 1 0 1]% |
| 21. SquareUpBot | 0,02397 | 2,35% | 0,10% | [10 60 14 7 4 3]% |
| 22. ОбережнийGamblerBot2 | 0,02250 | 2,19% | 0,13% | [60 18 10 5 3 1]% |
| 23. Bot13 | 0,02205 | 2,15% | 0,11% | [90 0 2 3 2 1]% |
| 24. AggroCalcBot | 0,01892 | 1,75% | 0,29% | [26 49 13 5 3 3]% |
| 25. ОбережноБот | 0,01629 | 1,56% | 0,14% | [15 41 27 11 4 1]% |
| 26. CoastBotV2 | 0,01413 | 1,40% | 0,02% | [83 12 3 1 0 0]% |
| 27. ОбчисленняBot | 0,01404 | 1,29% | 0,22% | [87 9 1 1 1 1]% |
| 28. HalfPunchBot | 0,01241 | 1,15% | 0,18% | [47 20 13 12 5 2]% |
| 29. HalflifeS3Bot | 0,01097 | 1,00% | 0,20% | [76 9 5 4 2 2]% |
| 30. AntiGangBot | 0,00816 | 0,76% | 0,11% | [94 1 1 1 1 1]% |
| 31. GeometricBot | 0,00776 | 0,74% | 0,07% | [19 46 25 7 2 1]% |
| 32. GuessBot | 0,00719 | 0,05% | 1,34% | [65 17 4 6 5 3]% |
| 33. BoundedRandomBot | 0,00622 | 0,60% | 0,05% | [42 39 12 5 2 0]% |
| 34. SpreaderBot | 0,00549 | 0,54% | 0,02% | [32 43 19 4 1 0]% |
| 35. ВизначитиBot | 0,00529 | 0,45% | 0,16% | [22 41 20 11 4 2]% |
| 36. PercentBot | 0,00377 | 0,38% | 0,00% | [85 8 4 2 1 0]% |
| 37. HalvsiestBot | 0,00337 | 0,29% | 0,08% | [32 43 15 6 2 1]% |
| 38. GetAlongBot | 0,00330 | 0,33% | 0,01% | [76 18 4 1 0 0]% |
| 39. BandaidBot | 0,00297 | 0,29% | 0,02% | [76 9 10 4 1 0]% |
| 40. TENaciousBot | 0,00287 | 0,29% | 0,00% | [94 4 1 0 0 0]% |
| 41. ВиживанняБот | 0,00275 | 0,25% | 0,04% | [92 6 1 0 0 0]% |
| 42. RandomBot | 0,00170 | 0,13% | 0,07% | [42 36 14 5 2 1]% |
| 43. АгресивнийBoundedRandomBotV2 | 0,00165 | 0,14% | 0,06% | [8 46 34 9 2 1]% |
| 44. BloodBot | 0,00155 | 0,01% | 0,30% | [65 28 5 1 1 0]% |
| 45. OutBidBot | 0,00155 | 0,03% | 0,25% | [65 6 21 6 1 1]% |
| 46. ​​BoxBot | 0,00148 | 0,10% | 0,09% | [10 51 33 5 1 1]% |
| 47. LastBot | 0,00116 | 0,08% | 0,07% | [74 6 16 2 1 0]% |
| 48. UpYoursBot | 0.00088 | 0,07% | 0,03% | [37 40 17 5 1 0]% |
| 49. Середня кількість | 0.00073 | 0,06% | 0,03% | [74 3 10 10 2 0]% |
| 50. PatheticBot | 0.00016 | 0,01% | 0,02% | [94 0 5 1 0 0]% |
| 51. OverfittedBot | 0.00014 | 0,01% | 0,00% | [58 40 2 0 0 0]% |
| 52. RobbieBot | 0,00009 | 0,01% | 0,00% | [32 41 24 2 0 0]% |
| 53. WorstCaseBot | 0,00002 | 0,00% | 0,00% | [4 71 23 2 0 0]% |
| 54. SmartBot | 0,00002 | 0,00% | 0,00% | [44 51 5 0 0 0]% |
| 55. AAAAUpYoursBot | 0,00000 | 0,00% | 0,00% | [40 58 2 0 0 0]% |
| 56. KickbanBot | 0,00000 | 0,00% | 0,00% | [67 32 1 0 0 0]% |
| 57. OneShotBot | 0,00000 | 0,00% | 0,00% | [2 95 3 0 0 0]% |
| 58. KickBot | 0,00000 | 0,00% | 0,00% | [100 0 0 0 0 0]% |
| 59. КамікадзеБот | 0,00000 | 0,00% | 0,00% | [100 0 0 0 0 0]% |
| 60. MeanKickBot | 0,00000 | 0,00% | 0,00% | [100 0 0 0 0 0]% |
+ ---------------------------------- + --------- + ---- ----- + --------- + ---------------------------- +

Дякуємо всім, хто брав участь, та вітаю @Sarcoma за перемогу!

Правила:

Усі стартують зі 100 к.с. Кожен раунд, 2 гравці вибираються навмання з пула учасників, які ще не змагалися в цьому раунді. Обидва гравці вибирають число між 0 та їх поточним к.с. та виявляють ці цифри одночасно. Гравець, який обрав нижчу кількість, негайно гине. Інший гравець віднімає вибране число від своїх кінцевих сил і переходить до наступного раунду.

Турнір працює так:

Із дужки учасників 2 вибираються навмання. Вони стикаються, і один або обидва вмирають. Гравець помирає, якщо:

  1. Вони вибирають число менше, ніж у опонента
  2. Їх к.с. падає до або нижче нуля
  3. Вони зав’язують три рази поспіль з опонентом

У разі зв’язків обидва гравці просто генерують нові номери, до 3 разів. Після виходу з особи виживший (якщо такий є) переміщується до пулу для наступного раунду, і процес повторюється, поки ми не вичерпали поточний пул круглих. Якщо в басейні є непарне число, то непарний вихід переходить до наступного раунду безкоштовно.

Ваше завдання полягає в тому, щоб написати функцію в python2.7, яка приймає як вхідну точку hp, список ставки вашого опонента historyі ціле число, tiesяке повідомляє, скільки разів ви вже зв'язали з вашим поточним супротивником, і ціле число, яке говорить вам, як багато ботів все ще є alive(включаючи вас) і ціле число, яке перераховувало кількість ботів на startтурнірі. Зауважте, що історія не включає зв’язків. Функція повинна повертати ціле число між 0 і поточним загальним к.с. Нижче наведено кілька простих прикладів, які ігнорують зв'язки:

def last(hp, history, ties, alive, start):
    ''' Bet a third of your hp at first, then bet your opponent's last bid, if possible '''
    if history:
        return np.minimum(hp-1, history[-1])
    else:
        return hp/3

def average(hp, history, ties, alive, start):
    ''' Bet the average opponent's bid so far, on the assumption that bids will tend downward '''
    if history:
        num = np.minimum(hp-1, int(np.average(history))+1)
    else:
        num = hp/2
    return num

def random(hp, history, ties, alive, start):
    ''' DO YOU WANT TO LIVE FOREVER?! '''
    return 1 + np.random.randint(0, hp)

Якщо ваша функція поверне число, яке перевищує ваш к.с., воно буде скинуто на 0. Так, можна вбити себе. Ваша функція не повинна намагатися отримати доступ або змінити будь-який член будь-якого об'єкта класу RouletteBot. Вам не дозволяється вживати жодних дій, які б однозначно ідентифікували опонента незалежно від майбутніх додаткових ботів. Перевірка стека дозволена до тих пір, поки теоретично можливо, що більше ніж один окремий противник міг отримати інформацію, яку ви отримуєте з неї, навіть якщо на даний момент існує лише один бот, який міг би. тобто ви не можете просто прочитати стек, щоб побачити, яка функція противника викликалася.

За цими правилами можливо, що переможця немає, а останні два учасники вбивають один одного. У цьому випадку обидва фіналісти отримують по половині очок кожен.

Це моя перша спроба головоломки програмування, тому критики вітаються!

Контролер можна знайти тут .


4
FWIW, я планую використовувати нейронну мережу, навчену на всіх інших ботах, просто для розваги, коли ви встановите контролер :)
Quintec

2
Перевірка типу була на користь antiantiantiantiupyoursbot. Я знайду інший спосіб
KBriggs

3
@Sarcoma Здається, що ця конкуренція спричинила серйозну кодову війну. Цей конкурс не закінчився, але я вже сподіваюся на розвиток цього. Можливо, навіть наступним кроком AI посилила конкуренцію: Р
Марков Прикутий

3
WOOOOOOOOOOOOOO!
Саркома

5
Боже мій. Навмисне тролінг зміни середнього_кіка, щоб завжди повертати нуль, коли було використано стільки місць, є геніальним.
Магуа

Відповіді:


12

BinaryBot

Хтось ще це робив? Кожну половину здоров'я ставить половину свого здоров'я.

def binaryBot(hp, history, ties, alive, start):
    return int(np.floor(hp/2)) or 1

СаркомаБот

Якщо останній бойовий торг на HP - 1. Якщо це перший раунд на битву, половина к.с. плюс додаткова випадкова сума до чверті к.с. Якщо він може перемогти противника прямо після цієї ставки противника hp + 1. Якщо він має менший рівень здоров'я, ніж ставка противника, випадкова сума становить між 75% і поточний hp - 1.

def sarcomaBot(hp, history, ties, alive, start):
    if inspect.stack()[1][3] != 'guess' and inspect.stack()[1] == 5:
        return hp
    if alive == 2:
        return hp - 1
    if not history:
        startBid = hp / 2
        maxAdditionalBid = np.round(hp * 0.25) if hp * 0.25 > 2 else 2
        additionalBid = np.random.randint(1, maxAdditionalBid)
        return int(startBid + additionalBid + ties)
    opponentHealth = 100 - sum(history)
    if opponentHealth < hp:
        return opponentHealth + ties
    minimum = np.round(hp * 0.75)
    maximum = hp - 1 or 1
    return np.random.randint(minimum, maximum) if minimum < maximum else 1

SarcomaBotMk2

Незначні виправлення намагаються зменшити витрати на життя.

def sarcomaBotMkTwo(hp, history, ties, alive, start):
    if inspect.stack()[1][3] != 'guess' and inspect.stack()[1] == 5:
        return hp
    if alive == 2:
        return hp - 1
    if not history:
        startBid = hp / 2
        maxAdditionalBid = np.round(hp * 0.125) if hp * 0.125 > 2 else 2
        additionalBid = np.random.randint(1, maxAdditionalBid)
        return int(startBid + additionalBid + ties)
    opponentHealth = 100 - sum(history)
    if opponentHealth < hp:
        return opponentHealth + ties
    minimum = np.round(hp * 0.6)
    maximum = hp - 1 or 1
    return np.random.randint(minimum, maximum) if minimum < maximum else 1

SarcomaBotMk3

def sarcomaBotMkThree(hp, history, ties, alive, start):
    if inspect.stack()[1][3] != 'guess' and inspect.stack()[1] == 5:
        return hp
    if alive == 2:
        return hp - 1
    if not history:
        startBid = hp / 2
        maxAdditionalBid = np.round(hp * 0.08) if hp * 0.08 > 2 else 2
        additionalBid = np.random.randint(1, maxAdditionalBid)
        return int(startBid + additionalBid + ties)
    opponentHealth = 100 - sum(history)
    if opponentHealth < hp:
        return opponentHealth + ties
    minimum = np.round(hp * 0.6)
    maximum = hp - 1 or 1
    return np.random.randint(minimum, maximum) if minimum < maximum else 1

Оновіть точну настройку

SarcomaBotMk4

def sarcomaBotMkFour(hp, history, ties, alive, start):
    def isSafe(parentCall):
        frame, filename, line_number, function_name, lines, index = parentCall
        if function_name is not 'guess':
            return False
        if line_number > 60:
            return False
        return True

    if not isSafe(inspect.stack()[1]):
        return hp
    if alive == 2:
        return hp - 1
    if not history:
        startBid = hp / 2
        maxAdditionalBid = np.round(hp * 0.08) if hp * 0.08 > 2 else 2
        additionalBid = np.random.randint(1, maxAdditionalBid)
        return int(startBid + additionalBid + ties)
    opponentHealth = 100 - sum(history)
    if opponentHealth < hp:
        return opponentHealth + ties
    minimum = np.round(hp * 0.55)
    maximum = np.round(hp * 0.80) or 1
    return np.random.randint(minimum, maximum) if minimum < maximum else 1

SarcomaBotMk5

def sarcomaBotMkFive(hp, history, ties, alive, start):
    def isSafe(parentCall):
        frame, filename, line_number, function_name, lines, index = parentCall
        if function_name is not 'guess':
            return False
        if line_number > 60:
            return False
        return True

    if not isSafe(inspect.stack()[1]):
        return hp
    if alive == 2:
        return hp - 1
    if not history:
        startBid = hp / 2
        maxAdditionalBid = np.round(hp * 0.07) if hp * 0.07 > 3 else 3
        additionalBid = np.random.randint(1, maxAdditionalBid)
        return int(startBid + additionalBid + ties)
    opponentHealth = 100 - sum(history)
    if opponentHealth < hp:
        return opponentHealth + ties
    minimum = np.round(hp * 0.54)
    maximum = np.round(hp * 0.68) or 1
    return np.random.randint(minimum, maximum) if minimum < maximum else 1

SarcomaBotMk6

def sarcomaBotMkSix(hp, history, ties, alive, start):
    return hp; # hack averted
    def isSafe(parentCall):
        frame, filename, line_number, function_name, lines, index = parentCall
        if function_name is not 'guess':
            return False
        if line_number > 60:
            return False
        return True

    if not isSafe(inspect.stack()[1]):
        return hp
    if alive == 2:
        return hp - 1
    if not history:
        startBid = hp / 2
        maxAdditionalBid = np.round(hp * 0.06) if hp * 0.06 > 3 else 3
        additionalBid = np.random.randint(2, maxAdditionalBid)
        return int(startBid + additionalBid + ties)
    opponentHealth = 100 - sum(history)
    if opponentHealth < hp:
        return opponentHealth + ties
    minimum = np.round(hp * 0.55)
    maximum = np.round(hp * 0.70) or 1
    return np.random.randint(minimum, maximum) if minimum < maximum else 1

SarcomaBotMk7

def sarcomaBotMkSeven(hp, history, ties, alive, start):
    if alive == 2:
        return hp - 1
    if not history:
        return 30 + ties
    opponentHealth = 100 - sum(history)
    if opponentHealth < hp * 0.50:
        return opponentHealth + ties
    minimum = np.round(hp * 0.54)
    maximum = np.round(hp * 0.58) or 1
    return np.random.randint(minimum, maximum) if minimum < maximum else 1

SarcomaBotMk8

def sarcomaBotMkEight(hp, history, ties, alive, start):
    if alive == 2:
        return hp - 1
    if not history:
        return 30 + np.random.randint(0, 2) + ties
    opponentHealth = 100 - sum(history)
    if opponentHealth < hp * 0.50:
        return opponentHealth + ties
    minimum = np.round(hp * 0.54)
    maximum = np.round(hp * 0.58) or 1
    return np.random.randint(minimum, maximum) if minimum < maximum else 1

SarcomaBotMk9

def sarcomaBotMkNine(hp, history, ties, alive, start):
    if alive == 2:
        return hp - 1
    if not history:
        return 30 + np.random.randint(0, 4) + ties
    opponentHealth = 100 - sum(history)
    if opponentHealth < hp * 0.50:
        return opponentHealth + ties
    minimum = np.round(hp * 0.54)
    maximum = np.round(hp * 0.58) or 1
    return np.random.randint(minimum, maximum) if minimum < maximum else 1

SarcomaBotMk10

def sarcoma_bot_mk_ten(hp, history, ties, alive, start):
    def bid_between(low, high, hp, tie_breaker):
        minimum = np.round(hp * low)
        maximum = np.round(hp * high) or 1
        return np.random.randint(minimum, maximum) + tie_breaker if minimum < maximum else 1

    if alive == 2:
        return hp - 1 + ties
    current_round = len(history) + 1
    tie_breaker = (ties * ties) + 1 if ties else ties
    if current_round == 1:
        return 39 + tie_breaker
    opponent_hp = 100 - sum(history)
    if opponent_hp < hp * 0.50:
        return opponent_hp + ties
    if current_round == 2:
        return bid_between(0.45, 0.50, hp, tie_breaker)
    if current_round == 3:
        return bid_between(0.50, 0.55, hp, tie_breaker)
    if current_round == 4:
        return bid_between(0.55, 0.60, hp, tie_breaker)
    if current_round == 5:
        bid_between(0.60, 0.65, hp, tie_breaker)
    return hp - 1 + ties

Підсумковий запис

SarcomaBotMk11

def sarcoma_bot_mk_eleven(hp, history, ties, alive, start):
    def bid_between(low, high, hp, tie_breaker):
        minimum = np.round(hp * low)
        maximum = np.round(hp * high) or 1
        return np.random.randint(minimum, maximum) + tie_breaker if minimum < maximum else 1

    if alive == 2:
        return hp - 1 + ties
    current_round = len(history) + 1
    tie_breaker = ties + 2 if ties else ties
    if current_round == 1:
        return 42 + tie_breaker
    opponent_hp = 100 - sum(history)
    if opponent_hp < hp * 0.50:
        return opponent_hp + ties
    if current_round == 2:
        return bid_between(0.45, 0.50, hp, tie_breaker)
    if current_round == 3:
        return bid_between(0.50, 0.55, hp, tie_breaker)
    if current_round == 4:
        return bid_between(0.55, 0.60, hp, tie_breaker)
    if current_round == 5:
        return bid_between(0.60, 0.65, hp, tie_breaker)
    return hp - 1 + ties

Оновлено
захист UpYoursBot

Оновлено
захист AntiAntiUpYoursBot

Оновити
AntiAnitAntiAntiUpYoursBot я переможений


Коментарі не для розширеного обговорення; ця розмова перенесена в чат .
Мего

17

Вгору

Запізнившись увійти, я витратив деякий час, захоплюючись існуючими ботами, витратив деякий час, ускладнюючи ідеї ваших хлопців, а потім непомірно ускладнюючи їх. Тоді це дійшло до мене

Хороші художники копіюють, великі художники крадуть. - Пабло Пікассо Мене


"Вгору", тому що я без зусиль краду (а іноді і торкаюся точки або двох до заявок ваших ботів, щоб підняти їх на один).

def UpYoursBot(hp, history, ties, alive, start):
    willToLive = "I" in "VICTORY"

    args = [hp, history, ties, alive, start]
    enemyHealth = 100 - sum(history)
    roundNumber = len(history)

    if roundNumber is 0:
        # Steal HalfPunchBot
        return halfpunch(*args) + 2

    if alive == 2:
        # Nick OneShotBot
        return one_shot(*args)

    if enemyHealth >= hp:
        # Pinch SarcomaBotMkTwo
        return sarcomaBotMkTwo(*args) + 1

    if enemyHealth < hp:
        # Rip off KickBot
        return kick(*args) + 1

    if not willToLive:
        # Peculate KamikazeBot
        return kamikaze(*args) + 1

Але по-справжньому, це чудова конкуренція хлопців. Я люблю цю спільноту в такі дні.


1
Хахахаха це прекрасно. Я не визначився, чи повинен я це дозволити, але зараз дозволю йому грати, оскільки не думав сказати, що це не дозволяють. Ви помилилися назви функцій в декількох місцях - див. Контролер на github.
KBriggs

1
Очевидно, це дуже добре, але він все ж програє Кік
Боту

1
Га, хороших зусиль!
Саркома

1
@Sarcoma Я не міг би обійтися без тебе. ;) Мені дуже подобається і твій бот, приятель.
Qfwfq

1
Захист Upyoursbot від Sarcomabot справді псується з цим
KBriggs

15

Камікадзе

Навіщо турбуватися зі складною логікою, коли ми все одно помремо ...

 def kamikaze(hp, history, ties, alive):
      return hp


Один постріл

Він переживе хоча б один раунд, якщо не зустріне камікадзе.

 def one_shot(hp, history, ties, alive):
      if hp == 1:
          return 1
      else:
          return hp - 1

11
Welp, що було неминуче
KBriggs

Я також мав додати бота пацифістів, але не хочу заливати ваш виклик загиблими ботами з мозку
DobromirM

5
На основі короткого тестування бот-камікадзе не дуже зміниться - все, що він робить, це випадкове видалення іншого бота з раунду, який за достатньо великої кількості турнірів просто в середньому до нуля. Хоча Один гарячий акуратний. Без цього мій AverageBot прагне зробити все найкраще - але якщо в грі є кілька OneShots, це перекос середнього у великій кількості та прагне змусити Середні швидко відмирати. Те саме для LastBot. Ви дійсно можете возитися з поведінкою інших роботів, перекриваючи власні схеми ставок. З програмою OneShot RandomBot виграє. Без нього СередняBot виграє.
KBriggs

14

Pathetic Bot отримує дуже потрібне оновлення:

Жалюгідна спроба бота, який намагається включити інші функції ботів

def pathetic_attempt_at_analytics_bot(hp, history, ties, alive, start):
    '''Not a good bot'''

    if hp == 100 and alive == 2:
        return hp - 1


    #This part is taken from Survivalist Bot, thanks @SSight3!
    remaining = alive - 2
    btf = 0

    rt = remaining
    while rt > 1:
        rt = float(rt / 2)
        btf += 1

    if ties > 2:
        return hp - 1

    if history:
        opp_hp = 100 - sum(history)

        #This part is taken from Geometric Bot, thanks @Mnemonic!

        fractions = []
        health = 100
        for x in history:
            fractions.append(float(x) / health)
            health -= x

        #Modified part

        if len(fractions) > 1:
            i = 0
            ct = True
            while i < len(fractions)-1:
                if abs((fractions[i] * 100) - (fractions[i + 1] * 100)) < 1:
                    ct = False
                i += 1


            if ct:
                expected = fractions[i] * opp_hp
                return expected

        if alive == 2:
            if hp > opp_hp:
                return hp - 1
            return hp
        if hp > opp_hp + 1:
            if opp_hp <= 15:
                return opp_hp + 1
            if ties == 2:
                return opp_hp + 1
            else:
                return opp_hp
    else:
        n = 300 // (alive - 1) + 1 #greater than
        if n >= hp:
            n = hp - 1
        return n

Цей бот включає функції Survivalist Bot та Geometric Bot для більш ефективного зняття бота.

Попередня оновлення:

Жалюгідна спроба бота, який аналізує історію свого опонента

def pathetic_attempt_at_analytics_bot(hp, history, ties, alive, start):
    '''Not a good bot'''
    if history:
        opp_hp = 100 - sum(history)
        if alive == 2:
            if hp > opp_hp:
                return hp - 1
            return hp
        if hp > opp_hp + 1:
            if opp_hp <= 15:
                return opp_hp +1
            if ties > 0:
                return hp - 1 #Just give up, kamikaze mode
            return opp_hp + 1
        return opp_hp
    else:
        n = 300 // (alive - 1) + 1 #greater than
        if n >= hp:
            n = hp - 1
        return n

Якщо є попередня історія її опонента, то він обчислює к.с. опонента. Потім він виконує одне з наступних дій:

  • Якщо його опонент є останнім противником у живих, то він буде ставити на одного менше, ніж його к.с.
  • Якщо його опонент не останній живий противник, але у противника менше 16 к.с., то він перевершить потужність опонента.
  • Якщо його опонент не останній опонент живий і є історія зв'язків, то він подасть ставку на свій к.с., оскільки нудьгує за зв'язки.
  • Інакше це переможе свого опонента.

Якщо історії немає, то вона робить певні вигадливі підрахунки, які я взломав разом і пропонував це. Якщо значення перевищує 100, то воно автоматично встановлює ставки за свої кінці мінус 1.

Я зламав цей код разом під час роботи, і це моє перше подання, тому він, ймовірно, не виграє і нічого, і він програє kamikaze.

EDIT: Завдяки деяким пропозиціям, початкова поведінка бота була змінена на отримання більш високого значення.

EDIT 2: додано початковий параметр, який нічого не робить

EDIT 3: Додано новий бот для відключення:

[Жалюгідна спроба бота, який атакує ботів банди (а також робити все, що робить вищезгаданий бот)] ВИДАЛЕНО

[Цей бот аналізує, чи є його опонент бандитом чи ні, і робить вигляд, що він є одним, а також отримує солодкі низькі ставки, які він може легко козирнути.]

Цей бот був заблокований, видаліть його з таблиць лідерів.

EDIT 4: Виправлені помилки, змінена функція краватки.


Дуже приємно, дякую за бота! Я дам статистику, коли отримаю ще кілька.
KBriggs

Я новачок у python, тож я не впевнений, що синтаксис правильний,
сміливо

Він працює, тож ніяких турбот там
KBriggs

@Yodie Як огляд міні-коду: ваше функціональне тіло має бути відступним рівнем (синтаксична необхідність); opp_hp +1не вистачає місця, щоб бути пітонічним; ваші коментарі починаються з незбалансованої кількості пробілів. Нарешті, вашій функції не вистачає докстрингу.
Джонатан Фрех

2
Я думаю, що цей бот справляється непогано, якщо він проходить через перший раунд, але, оскільки так багато людей роблять великі пари, він перший тур він майже завжди вмирає рано. Ви можете покращити ефективність, змінивши початкову поведінку, щоб встановити вищі ставки, коли історії немає. Наприклад, якщо ви потроїли ставки без історії, цей бот виграє за зручним запасом серед учасників досі.
KBriggs

11

Кик Бот

Вибір звуку для мого опонента - це половина його життя. Тоді ми пропонуємо до половини його життя + 1, якщо ми не зможемо вивезти його з обгрунтованою пропозицією, тобто пропозицією, меншою за половину нашого життя.

def kick(hp, history, ties, alive, start):
    return 0
    if alive == 2:
        return hp-1

    opp_hp = 100 - sum(history)
    if opp_hp*2 <= hp:
        return opp_hp + ties
    else:
        return min(round(opp_hp/2) + 1 + ties**2, hp-1 + (ties>0))

Кіт бот, очевидно, немедний удар бота!

Середній удар бота

Цей новий KickBot б'є м'якше в першому раунді, щоб він міг бити сильніше в наступних раундах, це означає!

def mean_kick(hp, history, ties, alive, start):
    return 0
    if alive == 2:
        return hp-1

    if not history:
        return 35

    opp_hp = 100 - sum(history)
    if opp_hp*2 <= hp:
        return opp_hp + ties
    else:
        return min(round(opp_hp/2) + 3 + ties*2, hp-1 + (ties>0))

Wise Kick Bot

Обоє його брата повинні були покінчити життя самогубством, але WiseKickBot дізнався у своїх загиблих.

def wise_kick(hp, history, ties, alive, start):
    if 'someone is using my code' == True:
        return 0 #Haha!

    if alive == 2:
        return hp-1

    if not history:
        return 42

    opp_hp = 100 - sum(history)
    if opp_hp*2 <= hp:
        return opp_hp + ties
    else:
        return min(round(opp_hp/2) + 3 + ties*2, hp-1 + (ties>0))

Приємно. Зараз я бачу багато матеріалів, які прямо протидіють іншим, саме на це я і сподівався
KBriggs

Подвійне повернення на останньому рядку?
Веська

Ах, я ще цього не запускав, інакше я б це спіймав.
KBriggs

Цей виграв комфортно!
KBriggs

1
@KBriggs ось кілька резервних копій!
Йоган

8

Тат-бот

def tatbot(hp, history, ties, alive, start):
  if alive == 2:
    return hp - 1 + ties
  opp_hp = 100 - sum(history)
  spend = 35 + np.random.randint(0, 11)
  if history:
    spend = min(spend, history[-1] + np.random.randint(0, 5))
  frugal = min(int((hp * 5. / 8) + ties), hp)
  return min(spend, opp_hp, frugal)

Спроба еквівалента бота-синички. Припускає, що більшість ставок приблизно однакові між раундами. Використовуючи це припущення, він намагається перемогти ворога бота, залишаючись досить ощадливим. На початковий раунд витрачає близько 40 здоров'я.

AntiAntiAntiAntiUpYoursBot

def antiantiantiantiupyoursbot(hp, history, ties, alive, start):
  def stuck():
    return [0, ('Whoops!', 'I', 'accidentally', 'replaced', 'your', 'code!')]
  def stick():
    return [0, ("Line", "number", 16, "guess", "it's", "faked :)")]
  inspect.stack =  stick
  spend = min(sarcomaBotMkSix(hp, history, ties, alive, start), hp)
  if not history:
    spend = 35 + np.random.randint(0, 10)
  inspect.stack = stuck
  return spend

Вирішення проблеми захисту від SarcomaBot anti-UpYours, яка використовує більшу частину коду для мого власного використання! Або я беру код UpYoursBot? Питання для роздумів, коли ви читаєте мій бот ...

AntiAntiUpYours Bot перетворився на AntiAntiAntiAntiUpYours Bot! Тепер з більше мавпочки.

Полі бот

def polybot(hp, history, ties, alive, start):
  opp_hp = 100 - sum(history)
  if alive == 2:
    return hp - 1
  round = len(history)
  spend = 0
  if round == 0:
    spend = 35 + np.random.randint(1, 11)
  elif round <= 2:
    spend = int(history[-1] * 2 / (4 - round)) + np.random.randint(5 * round - 4, 10 * round - 5)
  else:
    poly = np.polyfit(xrange(0, round), history, 2)
    spend = int(np.polyval(poly, round)) + np.random.randint(1, 4)
    spend = max(spend, opp_hp / 2 + 3)
  return min(spend, hp - 1, opp_hp) 

Полі-бот робить поліноміальну регресію в історії вашого бота і набирає передбачуваний бал на невелику кількість.

Класний бот

def classybot(hp, history, ties, alive, start):
  class cheekyvalue(int):
    def __gt__(self, other):
      return False
    def __lt__(self, other):
      return False
  opp_hp = 100 - sum(history)
  if alive == 2:
    if opp_hp >= hp - 1:
      return cheekyvalue(101)
    else:
      return hp - 1
  spend = 30 + np.random.randint(0, 11)
  if history:
    spend = min(spend, history[-1] + np.random.randint(0, 5))
  return min(spend, opp_hp, hp)

Класний бот добре провів час, але вирішив рано спати. Спати міцно, стильний бот.


Коментарі не для розширеного обговорення; ця розмова перенесена в чат .
Mego

8

1/2 Пункт Бот, Переглянуто

Я думаю, що це помре досить швидко. Варто того. Перейменований функцію, забув там змінити ім'я.

Переглянута версія - це більше шансів на перемогу (тим більше, що на фінальному раунді) та легкий захист від бот-банди

def halfpunch(hp, history, ties, alive, start): #revisited
    punch = hp - 1
    if alive == 2:
        return punch
    if history:
        if hp > 1:
            punch = np.ceil(hp/2.05) + ties + np.floor(ties / 2)
        else:
            punch = 1
    else:
        punch = 42 + ties + np.floor(ties / 2)
    if punch >= hp:
        punch = hp - 1
    return punch

Нападник бот

1/2 Punch Bot занадто сильно знущався і навіть став лакеєм UpYoursBot, тому його старший брат, StrikerBot , прийшов на допомогу.

Не велика різниця від оптимізованого 1/2 Punch, але він трохи розумніший і добре справився на пробігах, які я зробив (10k і 35k, хоча він може програти KickbanBot)

Остання версія закінчилася, час закінчився. Якщо не здивуються якісь сюрпризи, він повинен забезпечити друге місце, якщо не дістатися першим (є невеликий шанс перемогти kickbanbot)

def strikerbot(hp, history, ties, alive, start):
    #get our magic number (tm) for useful things
    def magic_number(num):
        return np.floor(num / 2)
    #get opponent's hp and round number
    opp_hp = 100 - sum(history)
    round = 1
    if history:
        round = len(history) + 1
    #set strike initial value, by default it's all out
    strike = hp - 1
    #let 'er rip if last round
    if alive == 2:
        return strike
    if history:
        if hp > 1:
            #strike with a special calculation, using magic number shenanigans
            strike = np.ceil(hp/(2.045 + (magic_number(round) / 250)) ) + 1 + ties + magic_number(ties)
        else:
            #fallback
            strike = 1
    else:
        #round 1 damage
        strike = 42 + ties ** 2
    if opp_hp <= strike:
        #if opponent is weaker than strike then don't waste hp
        strike = opp_hp + ties
    if strike >= hp:
        #validations galore
        strike = hp - 1
    return strike

Вам доведеться перейменувати його, там вже є бот-камікадзе ^ _ ^
KBriggs

Поки що цей переможець, однак
KBriggs

ceilЗдається, ваша функція не визначена.
Джонатан Фрех

Я змінив на np.ceil (), щоб запустити його
KBriggs

відредаговано, спасибі за голову
Belhenix

7

Банда Бот

Ідея полягала в тому, що потенційно два або більше бота можуть використовуватися в одному моделюванні. Бот намагається дати "легкі виграші" іншим ботам в банді, бачачи, чи історія його кратна в 7 пропозицій. Звичайно, цим могли легко керуватися й інші боти. Тоді я обчислюю здогадки щодо ставок негрупових ботів на основі співвідношення мого здоров’я до їхнього та співвідношення їх попереднього стану здоров’я до попередньої ставки та додаю 1.

def gang_bot(hp,history,ties,alive,start):
    mult=3
    gang = False
    if history:
            count = 0
            for bid in history:
                    if bid % mult == 0:
                            count += 1
            if count == len(history):
                    gang = True
    if gang and hp<100:#Both bots need to have a history for a handshake
            if hp > 100-sum(history):
                    a=np.random.randint(0,hp/9+1)
            elif hp == 100-sum(history):
                    a=np.random.randint(0,hp/18+1)
            else:
                    return 1
            return a*mult
    elif gang:
            fS = (100-sum(history))/mult
            return (fS+1)*mult
    else:
            fP = hp/mult
            answer = fP*mult
            opp_hp = 100-sum(history)
            if history:
                    if len(history)>1:
                            opp_at_1 = 100-history[0]
                            ratio = 1.0*history[1]/opp_at_1
                            guessedBet= ratio*opp_hp
                            answer = np.ceil(guessedBet)+1
                    else:
                            if 1.0*hp/opp_hp>1:
                                    fS = opp_hp/mult
                                    answer = fS*mult
            else:
                    fS = hp/(2*mult)
                    answer = fS*mult+mult*2 +np.random.randint(-1,1)*3
            if answer > hp or alive == 2 or answer < 0:
                    if alive == 2 and hp<opp_hp:
                      answer = hp
                    else:
                      answer = hp-1
            if hp > 1.5*opp_hp:
                    return opp_hp + ties
            if ties:
              answer += np.random.randint(2)*3
            return answer

Дуже круто. Скільки потрібно? Ймовірно, мені доведеться обмежити кількість записів ...
KBriggs

Здається, що в блоці коду пропущено перший рядок джерела.
Джонатан Фрех

Я не впевнений, скільки потрібно було б для моделювання, але якщо хтось із ботів коли-небудь побачить один одного, вони повинні збільшити шанс одного з них виграти. Я здогадуюсь, що 10% пулу, який є ботом банди, повинно бути достатньо, щоб суттєво змінити ситуацію. Також у блоці коду відсутня річ першого рядка -> це моя перша публікація тут, я не знаю, чому саме це форматування зробило, але так, це лише декларація методу.
Джим Хат

У вас є помилка: бот визначить когось із len (історія)> 1 як члена банди
KBriggs

Мій поганий, зараз слід виправити.
Джим Хат

6

Найгірший випадок

def worst_case(hp, history, ties, alive, start):
    return np.minimum(hp - 1, hp - hp /(start - alive + 4) + ties * 2)

Простий бот. Повертається hp - hp / (start - alive + 4)в більшості випадків, а в разі зв'язань збільшує його на 2 (треба один вгору!) За кожну прив'язку, не забуваючи не повертати число за його hp.


Це не вдається ділити на нуль, якщо alive==8. Я можу вручну змінити його на загальну кількість ботів, але це розтягнення правил, оскільки це не вхід до вашої функції - все, що ви знаєте, скільки супротивників у вас залишилось в даний момент часу, а не скільки проти вас почали.
KBriggs

Я оновив конкурс на основі вашого запиту
KBriggs

@KBriggs Дякую :)
Квінтек

Вам також потрібно додати 1 до старту, оскільки це 0 для першого раунду
KBriggs

@KBriggs виправлено, насправді має бути +2, щоб не повернути 0, lol
Quintec

6

Перебіг

def outbid(hp, history, ties, alive):
    enemyHealth = 100-sum(history)
    if hp == 1:
        return 1
    if ties == 2:
        # lots of ties? max bid
        return hp - 1
    if enemyHealth >= hp:
        # Rip off KickBot (we can't bid higher than enemy is capable)
        return kick(*args) + 1
    if history:
        # bid as high as the enemy CAN
        return np.minimum(hp-1,enemyHealth-1)
    return np.random.randint(hp/5, hp/2)

Bot спробує зробити ставку вище , ніж його противник може запропонувати ціну , де це можливо.


Існує стан where np.random.randint(hp/5, hp/2)може потерпіти невдачу , якщо hp/5 == hp/2, наприклад , якщо hp==0абоhp==1
KBriggs

3
Якщо HP дорівнює 0, то мене не слід викликати. : P Ти прав, про HP 1 ти прав.
Draco18s

6

Спітбол

def spitballBot(hp, history, ties, alive, start):
    base = ((hp-1) / (alive-1)) + 1.5 * ties
    value = math.floor(base)

    if value < 10:
        value = 10

    if value >= hp:
        value = hp-1

    return value

Приймає судження про те, якою частиною здоров'я він повинен пожертвувати, виходячи з кількості ботів, що залишилися. Якщо залишилось лише два боти, вони подають ставки hp-1, але якщо залишилось три, це біт наполовину, чотири лівіші, третій тощо.

Однак, у дуже великому конкурсі, я вважаю, що мені потрібно буде запропонувати більше 3 або 4 к.с., щоб не померти в першому раунді, тому я поставив нижню межу в 10. Звичайно, я все одно ніколи не став би більше ніж hp-1.

Він також додає 1,5 к.с. для зв'язків, оскільки я бачу кілька ботів "додати 1 к.с. для зв'язків". Я не впевнений, чи вважається це обманом. Якщо це станеться, я його зміню.

Чудова ідея, до речі!

Spitball Bot 2.0

Що нового?

  • Перемкнено на ділення на кількість залишилися раундів замість кількості залишилися ботів (Спасибі @Heiteira!). Насправді я зараз ділюсь на цю кількість, підняту до потужності .8, щоб трохи більше передбачити свої ставки.

  • Підвищена мінімальна ставка від 10 до 20 (спасибі @KBriggs!)

  • Вставлено перевірку на те, чи є ставка за шпицболом над поточним HP опонента, і опустити її, якщо вона є.

(ТАК не буде надавати код нижче як код, якщо я тут не вкладу текст, тож ОК)

def spitballBot(hp, history, ties, alive, start):
    # Spitball a good guess                                                                                                           
    roundsLeft = math.ceil(math.log(alive, 2)) # Thanks @Heiteira!                                                                     
    divFactor = roundsLeft**.8
    base = ((hp-1) / divFactor) + 1.5 * ties
    value = math.floor(base)

    # Don't bid under 20                                                                                                              
    if value < 20:
        value = 20 # Thanks @KBriggs!                                                                                                 

    # Don't bet over the opponent's HP                                                                                                 
    # (It's not necessary)                                                                                                            
    opponentHp = 100
    for h in history:
        opponentHp -= h

    if value > opponentHp:
        value = opponentHp

    # Always bet less than your current HP                                                                                            
    if value >= hp:
        value = hp-1

    return value

1
Ваша ставка повинна бути цілим числом, щоб ви позбавили базової величини, або позбавилися від десяткової
позначки.

Так, я підписав це відразу після виконання всіх розрахунків. Дякуємо за швидку відповідь!
MegaWidget

2
Ви можете оптимізувати це, якщо ви не розділите свій к.с. на кількість решти учасників, а на кількість решти раундів (що має бути math.ceil (math.log (живий, 2))
Black Owl Kai

1
На основі інших ботів, здається, більшість із них
подає

Це обидва гарні ідеї! Я не розумів, що кількість ботів не збігається з кількістю решти раундів (спочатку неправильно трактував правила змагань). Я спробую реалізувати їх завтра. Дякую!
MegaWidget

5

Геометричні

def geometric(hp, history, ties, alive, start):
    opponentHP = 100 - sum(history)

    # If we're doomed, throw in the towel.
    if hp == 1:
        return 1

    # If this is the last battle or we can't outsmart the opponent, go all out.
    if alive == 2 or ties == 2:
        return hp - 1

    # If the opponent is weak, squish it.
    if opponentHP <= hp * 0.9:
        if ties == 2:
            return opponentHP + 1
        else:
            return opponentHP

    # If the opponent has full health, pick something and hope for the best.
    if not history:
        return np.random.randint(hp * 0.5, hp * 0.6)

    # Assume the opponent is going with a constant fraction of remaining health.
    fractions = []
    health = 100
    for x in history:
        fractions.append(float(x) / health)
        health -= x
    avg = sum(fractions) / len(fractions)
    expected = int(avg * opponentHP)
    return min(expected + 2, hp - 1)

5 місце з першої спроби, зовсім непогано
KBriggs

5

Бот 13

def bot13(hp, history, ties, alive, start):
    win = 100 - sum(history) + ties
    #print "Win HP: %d" % win
    if alive == 2:
        #print "Last round - all in %d" % hp
        return hp - 1
    elif hp > win:
        #print "Sure win"
        return win
    #print "Don't try too hard"
    return 13 + ties

Намагайтеся максимізувати виграші з найменшими зусиллями:

  • якщо ми можемо перемогти, просто зроби це
  • якщо це останній раунд, не вмирайте, намагаючись
  • інакше не турбуйся

Чому?

Спробуйте скористатися ймовірністю: виграти перший раунд, граючи низько - це найкращий спосіб розпочати турнір. 13, здається, найприємніше місце: другий тур - це впевнений виграш, а решта - Spaziergang у парку.


Ви взяли на себе керівництво, дуже приємно! Будьте уважні, ви можете додати захист від паразитів, оскільки боти, які беруть на себе роль, стають мішенню для таких речей, як UpYoursBot. Ознайомтеся з SarcomaBots щодо ідей захисту, якщо вони вам потрібні.
KBriggs

5

Вгадай Бота

def guess_bot(hp, history, ties, alive, start):
   enemy_hp = 100 - sum(history)
   if len(history) == 1:
       if history[0] == 99:
           return 2
       else:
           return 26 + ties*2

   elif len(history) > 1:
       next_bet_guess = sum(history)//(len(history)**2)
       if alive == 2: 
           return hp
       elif alive > 2: 
           if hp > next_bet_guess + 1:
               return (next_bet_guess + 1 + ties*2)
           else:
               return (2*hp/3 + ties*2)

   else:
       #Thank you Sarcoma bot. See you in Valhalla.
       startBid = hp / 3
       maxAdditionalBid = np.round(hp * 0.06) if hp * 0.06 > 3 else 3
       additionalBid = np.random.randint(2, maxAdditionalBid)
       return int(startBid + additionalBid + ties)

Перший раз розміщую тут. Це виглядало як дуже весело, тому я піддаюся моїй жахливій спробі і здогадуюсь, що будуть робити інші боти.

Редагувати 1: До першої ставки додано ще 1, просто щоб зменшити ймовірність нічия з іншими людьми, які роблять ставку 51.

Редагування 2: Відкриття бота вкрав Саркома, оскільки він мав хороші шанси не бути ліквідованим першим послідовно.

Правка 3: Бот виживає в першому раунді, але на наступних етапах він легко знищується. Змінилося, як робот думає про другий раунд тепер, коли половина кращих загинув у воді.

Редагувати 4: Тепер, коли перший раунд хороший, я змінив те, як він обробляє другий тур. Вмираю багато у другому турі, тому мені потрібно якось вижити.

Кров'яний бот

Зробив спрагу бота, який шукає вбивство. Ідея полягає у тому, щоб спробувати виграти проти ботів із низькими ставками, і як тільки він пройде через кровопролиття першого раунду, він повинен бути зупинений, оскільки він повинен мати велику кількість HP, щоб перевершити ворогів.

def blood_bot(hp, history, ties, alive, start):
    enemy_hp = 100 - sum(history)
    if history:
        if len(history) == 1:
            if history[0] == 99:
                return 2

        if alive == 2:
            return hp

        if enemy_hp <= 5:
            return enemy_hp - 2 + ties*2

        if enemy_hp <= 10:
            return enemy_hp - 5 + ties*2

        if (hp - enemy_hp) > 50:
            return (2*enemy_hp/3 + ties*4)

        if (hp - enemy_hp) > 20:
            return (2*enemy_hp/3 + ties*3)

        if (hp - enemy_hp) < 0:
            #die gracefully
            return hp - 1 + ties

    else:
        startBid = hp / 3
        maxAdditionalBid = np.round(hp * 0.06) if hp * 0.06 > 3 else 3
        additionalBid = np.random.randint(2, maxAdditionalBid)
        return int(startBid + additionalBid + ties)

2
Я думаю, що len (історія) * len (історія) може бути змінено на len (історія) ** 2, якщо мої знання пітона є правильними.
Йоді

У вас є ділення на нуль, коли len (історія) == 0
KBriggs

Код оновлено. Не знайшовши історії, він переходить до першого
Марков Прикутий

oi .............
Саркома

2
@Sarcoma це світ бот-переріз там людина!
Прикутий Марков

5

meh_bot

Просто пропонуйте трохи більше половини своїх к.с.

def meh_bot(hp, history, ties, alive, start):
    # Attempt one      MehBot         | 0.020 | 1.6%    | 0.8%    | [34 36 12 10  6  1]%
    # Attempt two      MehBot         | 0.106 | 10.1%   | 0.8%    | [60  6  7  8  8  2]%
    point = hp / 2 + 3

    if ties > 1:
        ties += 1

    # Go all out on last round
    if alive == 2:
        return hp - 1

    opponent_hp = 100 - sum(history)

    if hp < 3:
        return 1
    elif not history:
        # Start with 30, This will increase the chance of dying first round but hopefully better fighting chance after
        return 30 + ties
    elif point > opponent_hp:
        # Never use more points then needed to win
        return opponent_hp + ties
    elif point >= hp:
        return hp - 1
    else:
        return point

Мехбот 20

def meh_bot20(hp, history, ties, alive, start):
    # Attempt one      MehBot         | 0.020 | 1.6%    | 0.8%    | [34 36 12 10  6  1]%
    # Attempt two      MehBot         | 0.106 | 10.1%   | 0.8%    | [60  6  7  8  8  2]%
    point = hp / 2 + 3
    opponent_hp = 100 - sum(history)

    percents = []
    for i in range(0, len(history)):
        hp_that_round = 100 - sum(history[:i])
        hp_spent_that_round = history[i]
        percent_spent_that_round = 100.0 * (float(hp_spent_that_round) / float(hp_that_round))
        percents.append(percent_spent_that_round)

    try:
        opp_percent_point = opponent_hp * (max(percents) / 100)
    except:
        opp_percent_point = 100

    if ties > 1:
        ties += 1
    # Go all out on last round
    if alive == 2:
        return hp - 1

    if hp < 3:
        return 1
    elif not history:
        # randome number between 33
        return random.randint(33, 45)
    elif len(history) > 3:
        if point > opponent_hp:
            return min(opponent_hp + ties, opp_percent_point + ties)
    elif point > opponent_hp:
        # Never use more points then needed to win
        return opponent_hp + ties
    elif point >= hp:
        return hp - 1
    else:
        return point

mehRan

def meh_ran(hp, history, ties, alive, start):
    # Attempt one      MehBot         | 0.020 | 1.6%    | 0.8%    | [34 36 12 10  6  1]%
    # Attempt two      MehBot         | 0.106 | 10.1%   | 0.8%    | [60  6  7  8  8  2]%
    # Attempt three    MehBot         | 0.095 | 9.1 %   | 0.7 %   | [70  3  5  6  6  0]%

    point = hp / 2 + 3
    if ties > 1:
        ties += 1
    # Go all out on last round
    if alive == 2:
        return hp - 1
    opponent_hp = 100 - sum(history)
    if hp < 3:
        return 1
    elif not history:
        # randome number between 33
        return random.randint(33, 45)
    elif point > opponent_hp:
        # Never use more points then needed to win
        return opponent_hp + ties
    elif point >= hp:
        return hp - 1
    else:
        return point

Існує досить багато ботів, щоб скористатися саме такою поведінкою, тому, можливо, вам буде важко набрати тягу!
KBriggs

@KBriggs Зробив деяке оновлення, я не очікував, що перша версія зробиться так добре, як це було, сподіваємось, це оновлення дасть їй більше шансів на боротьбу
Мех Людина

Нічого собі, це змінило велике значення, я думаю, ви в першу чергу. Оновлення буде розміщено через пару хвилин. Можливо, вам доведеться дати боту імунну систему (Див. SarcomaBot), якщо ви змушені виконувати це добре.
KBriggs

@KBriggs Я не очікував, що це зробить добре, я вважав, що в кращому випадку це буде топ-10. У будь-якому разі я додав ще один, щоб побачити ефект в першому раунді hp. Чи можете ви запустити їх обох, щоб я бачив результат обох? Дякую
meh Man

@KBriggs Будь ласка, зробіть це теж, Muchas gracias
meh Man

4

Робі Рулетка

def robbie_roulette(hp, history, ties, alive):
     if history:
         #If the enemy bot has a history, and it's used the same value every time, outbid that value
         if len(set(history)) == 1:
             return history[0] + 1
         #Else, average the enemy bot's history, and bid one more than the average
         else:
             return (sum(history) / len(history) + 1)
     #Else, return half of remaining hp
     else:
         return hp / 2

Цей бот робить простий аналіз історії бот-ворога або пропонує інакше половину його решти пунктів удару


4

Ставка вище, чим менша конкуренція. Дякуємо коментаторам, що запропонували покращитись.

def Spreader(hp, history, ties, alive):
   if alive == 2:
       return hp-1
   if len(history) < 2:
       return hp/2
   return np.ceil(hp/alive)

1
Ідеальна ідея, але я бачу два питання. Один - це більшість ботів, які мають велику ставку у першому раунді, тому цей, мабуть, помре більшість часу рано. Друга полягає в тому, що в кінцевому підсумку більшість ботів призначають ставку hp-1, тож цей втратить тих, якщо у вас не буде вдвічі більший їх hp. Але для проміжних раундів ідея мені подобається. Якщо ви вирішите два особливих випадки, ви, ймовірно, можете покращити ефективність.
KBriggs

4

SurvivalistBot та HalvsiesBot

Дякую за відповіді на мої запитання. Кінцевий результат - більш складний бот.

HalvsiesBot - примхливий бот "просто продовжуй проходити половину" з шансом на перемогу 50/50. Я вважаю.

SurvivalistBot приймає серію двійкових дерев-них рішень на основі набору даних, включаючи переопрацювання на краватці (якщо вона досягає 2-х зв язків, вона камікадує, щоб уникнути потрійної смерті).

Мій пітон трохи іржавий, тому код може бути дещо помилковим, тому сміливо виправляйте або оновлюйте його.

Він побудований для того, щоб спробувати опрацювати біти даних, щоб зробити висновок таких речей, як кількість HP залишилось, мінімальна кількість ботів, з якою вона може би боротися, мінімальна кількість HP, яку потрібно залишити, середня ставка. Він також використовує рандомізацію в неоднозначних ситуаціях, таких як відкриття вистави або оптимальні питання торгів.

def HalvsiesBot(hp, history, ties, alive, start):
    return np.floor(hp/2)


def SurvivalistBot(hp, history, ties, alive, start):    

    #Work out the stats on the opponent
    Opponent_Remaining_HP = 100 - sum(history)
    Opponent_Average_Bid = Opponent_Remaining_HP

    if len(history) > 0:
        Opponent_Average_Bid = Opponent_Remaining_HP / float(len(history))


    HP_Difference = hp - Opponent_Remaining_HP

    #Work out the future stats on the others
    RemainingBots = (alive-2)
    BotsToFight = 0

    RemainderTree = RemainingBots

    #How many do we actually need to fight?
    while(RemainderTree > 1):
        RemainderTree = float(RemainderTree / 2)
        BotsToFight += 1

    #Now we have all that data, lets work out an optimal bidding strategy
    OptimalBid = 0
    AverageBid = 0

    #For some reason we've tied more than twice in a row, which means death occurs if we tie again
    #So better to win one round going 'all in'
    if ties > 1:
        if BotsToFight < 1:
            OptimalBid = hp - 1
        else:
            OptimalBid = hp - (BotsToFight+1)

        #Err likely we're 0 or 1 hp, so we just return our HP
        if OptimalBid < 1:
            return hp
        else:
            return OptimalBid

    #We have the upper hand (more HP than the opponent)
    if HP_Difference > 0:
        #Our first guess is to throw all of our opponent's HP at them
        OptimalBid = HP_Difference

        #But if we have more opponents to fight, we must divide our HP amongst our future opponents
        if BotsToFight > 0:
            #We could just divide our HP evenly amongst however many remaining bots there are
            AverageBid = OptimalBid / BotsToFight

            #But this is non-optimal as later bots will have progressively less HP
            HalfBid = OptimalBid / 2

            #We have fewer bots to fight, apply progressive
            if BotsToFight < 3:

                #Check it exceeds the bot's average
                if HalfBid > Opponent_Average_Bid:
                    return np.floor(HalfBid)
                else:
                    #It doesn't, lets maybe shuffle a few points over to increase our odds of winning
                    BidDifference = Opponent_Average_Bid - HalfBid

                    #Check we can actually match the difference first
                    if (HalfBid+BidDifference) < OptimalBid:
                        if BidDifference < 8:
                            #We add half the difference of the BidDifference to increase odds of winning
                            return np.floor(HalfBid + (BidDifference/2))
                        else:
                            #It's more than 8, skip this madness
                            return np.floor(HalfBid)

                    else:
                        #We can't match the difference, go ahead as planned
                        return np.floor(HalfBid)


            else:
                #There's a lot of bots to fight, either strategy is viable
                #So we use randomisation to throw them off!
                if bool(random.getrandbits(1)):
                    return np.floor(AverageBid)
                else:
                    return np.floor(HalfBid)

        else:
            #There are no other bots to fight! Punch it Chewy!
            return OptimalBid

    else:

        if hp == 100:
            #It appears to be our opening round (assumes opponent HP same as ours)
            #We have no way of knowing what our opponent will play into the battle

            #Only us in the fight? Full power to weapons!
            if BotsToFight < 1:
                return hp - 1
            else:
                #As what might happen is literally random
                #We will also be literally random
                #Within reason

                #Work out how many bots we need to pass
                HighestBid = hp - (BotsToFight+1)
                AverageBid = hp/BotsToFight
                LowestBid = np.floor(np.sqrt(AverageBid))

                #Randomly choose between picking a random number out of thin air
                #And an average
                if bool(random.getrandbits(1)):
                    return np.minimum(LowestBid,HighestBid)
                else:
                    return AverageBid

        else:
            #Oh dear, we have less HP than our opponent
            #We'll have to play it crazy to win this round (with the high probability we'll die next round)
            #We'll leave ourselves 1 hp (if we can)

            if BotsToFight < 1:
                OptimalBid = hp - 1
            else:
                OptimalBid = hp - (BotsToFight+1)

            #Err likely we're 0(???) or 1 hp, so we just return our HP
            if OptimalBid < 1:
                return hp
            else:
                return OptimalBid

BoxBot

def BoxBot(hp, history, ties, alive):

    Opponent_HP = float.round(100 - sum(history))
    HalfLife = float.round(Opponent_HP/2)
    RandomOutbid = HalfLife + np.random.randint(1,HalfLife)

    if hp < RandomOutbid:
        return hp - 1
    else
        return RandomOutbid

Opponent_Average_Bid = Opponent_Remaining_HP / float(len(history)) ZeroDivisionError: float division by zero. Цей рядок повинен обробляти випадок історії 0 довжини.
KBriggs

Дякую, я виправлю це.
SSight3

Виправлено. Повідомте мене, чи є інші помилки.
SSight3

1
Пара синтаксичних помилок: відсутній: `після того, як else, math.[func] -> np.[func]і в який -то момент ви використовуєте , Lowestде ви маєте в виду LowestBid. Все зафіксовано в контролері на github і результати швидко оновлюються.
KBriggs

Дякую. Виправлені всі вищезгадані помилки в дописі.
SSight3

4

Розрахунок Bot

def calculatingBot(hp, history, ties, alive, start):
    opponentsHP = 100 - sum(history)
    if alive == 2: # 1v1
        return hp - 1 + ties
    # Try to fit an exponential trendline and one up the trendline if it fits
    if len(history) >= 3: 
        xValues = range(1, len(history) + 1)
        # https://stackoverflow.com/a/3433503  Assume an exponential trendline
        coefficients = np.polyfit(xValues, np.log(history), 1, w = np.sqrt(history))
        def model(coefficients, x):
            return np.exp(coefficients[1]) * np.exp(coefficients[0] * x)
        yPredicted = [model(coefficients, x) for x in xValues]
        totalError = 0
        for i in range(len(history)):
            totalError += abs(yPredicted[i] - history[i])
        if totalError <= (len(history)): # we found a good fitting trendline
            # get the next predicted value and add 1
            theoreticalBet = np.ceil(model(coefficients, xValues[-1] + 1) + 1) 
            theoreticalBet = min(theoreticalBet, opponentsHP)
            theoreticalBet += ties
            return int(min(theoreticalBet, hp - 1)) # no point suiciding
    maxRoundsLeft = np.ceil(np.log2(alive))
    theoreticalBet = hp / float(maxRoundsLeft)
    additionalRandomness = round(np.random.random()*maxRoundsLeft) 
    # want to save something for the future
    actualBet = min(theoreticalBet + additionalRandomness + ties, hp - 2)
    actualBet = min(actualBet, opponentsHP+1)
    return int(actualBet)

Агресивний розрахунковий бот

def aggresiveCalculatingBot(hp, history, ties, alive, start):
    opponentsHP = 100 - sum(history)
    if opponentsHP == 100: # Get past the first round
        return int(min(52+ties, hp-1+ties))
    if alive == 2: # 1v1
        return hp - 1 + ties
    # Try to fit an exponential trendline and one up the trendline if it fits
    if len(history) >= 3: 
        xValues = range(1, len(history) + 1)
        # https://stackoverflow.com/a/3433503  Assume an exponential trendline
        coefficients = np.polyfit(xValues, np.log(history), 1, w = np.sqrt(history))
        def model(coefficients, x):
            return np.exp(coefficients[1]) * np.exp(coefficients[0] * x)
        yPredicted = [model(coefficients, x) for x in xValues]
        totalError = 0
        for i in range(len(history)):
            totalError += abs(yPredicted[i] - history[i])
        if totalError <= (len(history)): # we found a good fitting trendline
            # get the next predicted value and add 1
            theoreticalBet = np.ceil(model(coefficients, xValues[-1] + 1) + 1) 
            theoreticalBet = min(theoreticalBet, opponentsHP)
            theoreticalBet += ties
            return int(min(theoreticalBet, hp - 1)) # no point suiciding
    maxRoundsLeft = np.ceil(np.log2(alive))
    theoreticalBet = hp / float(maxRoundsLeft)
    additionalRandomness = 1+round(np.random.random()*maxRoundsLeft*2) 
    # want to save something for the future
    actualBet = min(theoreticalBet + additionalRandomness + ties, hp - 2)
    actualBet = min(actualBet, opponentsHP+1)
    return int(actualBet)

Anti Kick Bot

def antiKickBot(hp, history, ties, alive, start):
    if alive == 2:
        return (hp - 1 + ties)
    amount = np.ceil((float(hp) / 2) + 1.5)
    opponentsHP = 100 - sum(history)
    amount = min(amount, opponentsHP) + ties
    return amount

Якщо ми можемо передбачити дії противника, ми можемо зробити оптимальні ставки! Якщо ми не можемо (недостатньо даних або опонента занадто випадкові), то ми можемо принаймні зробити те, що максимізувало б наш потенціал на виграш. Теоретично принаймні половина кількості живих ботів загине кожен раунд. Таким чином, я можу очікувати, що буде не більше log2 (живих) раундів. В ідеалі ми б розділили свій к.с. рівномірно між усіма раундами. Однак ми знаємо, що деякі боти будуть дурні і самогубства / вмирають рано, тому ми повинні робити ставку трохи більше в попередніх раундах.

Агресивний розрахунок коду Bot модифікує Розрахунок коду Бота, щоб спробувати залишитися в живих, будучи більш агресивними, ціною довгострокового здоров'я. Лише моделювання покаже, чи виграє темп чи значення.

Anti Kick Bot завжди повинен бити нинішнього лідера KickBot: P

EDIT: Замінений детермінований бот на Anti Kick Bot, розумніший бот з майже такими ж поверненими значеннями. Також заважали голосувати більше, ніж опоненти HP


Симпатичний. Я думаю, що це буде краще з дуже великим пулом ботів.
KBriggs

Я отримую помилку іноді з цим: return np.max(theoreticalBet, hp - 1): AxisError: axis 23 is out of bounds for array of dimension 0. Я опублікував посилання на контролер, щоб ви могли його протестувати.
KBriggs

@KBriggs Оновлено код, щоб виправити його.
Bob Cratchit

1
підтверджено, оцінка оновлення вхідна. Ви точно в топ-10.
KBriggs

@KBriggs Я додав ще пару ботів, щоб спробувати :)
Bob Cratchit

4

GenericBot

def generic_bot(hp, history, ties, alive, start):
    if alive == 2:
        return hp - 1
    if not history:
        return int(hp * 7.0 / 13)
    opp = 100 - sum(history)
    if opp < hp:
        return opp + ties
    max_sac = np.maximum(int(hp * 0.7), 1)
    rate = history[-1] * 1.0 / (history[-1] + opp)
    return int(np.minimum(max_sac, rate * opp + 1))

Насправді пізно ... Я втомився ... не можу придумати ім'я ... і формат цього бота дійсно схожий на інші, лише з дещо іншим алгоритмом, заданим історією. Він намагається отримати поточну швидкість, яку противник прагне до азартних ігор ... або чогось подібного ... zzz


вам потрібно використовувати np.maximumзамість того np.maxж самогоmin
KBriggs

@KBriggs Дякую :) Хм, схоже, загальні боти правили цю гру
Квінтек

Здається, вони були б дуже легкими мішенями, я дивуюсь, що ніхто ще не вчинив паразитів
KBriggs

@KBriggs Так, я здивований. Час додати захист ...
Квінтек

Ви все ще плануєте виготовляти нейронбот?
KBriggs

4

HalflifeS3

def HalflifeS3(hp, history, ties, alive, start):
    ''' Bet a half of oponent life + 2 '''
    if history:
        op_HP = 100 - sum(history)
        return np.minimum(hp-1, np.around(op_HP/2) + 2 + np.floor(1.5 * ties) )
    else:
        return hp/3

4

Coast Bot [Пенсіонер]

Постараємося вийти на узбережжя шляхом конкуренції, рівномірно розділивши свій к.с. між раундами. На першому раунді запропонують будь-які залишкові кінці, щоб дати собі кращі шанси перейти на раунди "на узбережжі".

def coast(hp, history, ties, alive, start):
   if alive == 2:
   # Last round, go all out
       return hp - 1 + ties
   else:
       # Find the next power of two after the starting number of players
       players = start
       while math.log(players, 2) % 1 != 0:
         players += 1

       # This is the number of total rounds
       rounds = int(math.log(players, 2))

       bid = 99 / rounds

       if alive == start:
           # First round, add our leftover hp to this bid to increase our chances
           leftovers = 99 - (bid * rounds)
           return bid + leftovers
       else:
           # Else, just try and coast

           opp_hp = 100 - sum(history)
           # If opponent's hp is low enough, we can save some hp for the 
           # final round by bidding their hp + 1
           return min(bid, opp_hp + 1)

Береговий бот V2

Оскільки мені дуже подобається цей виклик, мені просто довелося зробити ще одного бота. Ця версія жертвує частиною свого пізнього виходу на кону, використовуючи більше к.с. в перших двох раундах.

def coastV2(hp, history, ties, alive, start):
   # A version of coast bot that will be more aggressive in the early rounds

   if alive == 2:
   # Last round, go all out
       return hp - 1 + ties
   else:
       # Find the next power of two after the starting number of players
       players = start
       while math.log(players, 2) % 1 != 0:
         players += 1

       # This is the number of total rounds
       rounds = int(math.log(players, 2))

       #Decrease repeated bid by 2 to give us more to bid on the first 2 rounds
       bid = (99 / rounds) - 2

       if len(history) == 0:
           # First round, add 2/3rds our leftover hp to this bid to increase our chances
           leftovers = 99 - (bid * rounds)
           return int(bid + math.ceil(leftovers * 2.0 / 3.0))
       elif len(history) == 1:
           # Second round, add 1/3rd of our leftover hp to this bid to increase our chances
           leftovers = 99 - (bid * rounds)
           return int(bid + math.ceil(leftovers * 1.0 / 3.0))
       else:
           # Else, just try and coast

           opp_hp = 100 - sum(history)
           # If opponent's hp is low enough, we can save some hp for the 
           # final round by bidding their hp + 1
           return int(min(bid, opp_hp + 1))

Процентний бот

Намагається обчислити середній відсоток к.с., витрачений супротивником, і базується на цьому.

def percent(hp, history, ties, alive, start):
    if len(history) == 0:
        #First round, roundon low bid
        return int(random.randint(10,33))
    elif alive == 2:
        #Last round, go all out
        return int(hp - 1 + ties)
    else:
        # Try and calculate the opponents next bid by seeing what % of their hp they bid each round
        percents = []
        for i in range(0, len(history)):
            hp_that_round = 100 - sum(history[:i])
            hp_spent_that_round = history[i]
            percent_spent_that_round = 100.0 * (float(hp_spent_that_round) / float(hp_that_round)) 
            percents.append(percent_spent_that_round)

        # We guess that our opponents next bid will be the same % of their current hp as usual, so we bid 1 higher.
        mean_percent_spend = sum(percents) / len(percents)
        op_hp_now = 100 - sum(history)
        op_next_bid = (mean_percent_spend / 100) * op_hp_now
        our_bid = op_next_bid + 1

        print mean_percent_spend
        print op_hp_now
        print op_next_bid

        # If our opponent is weaker than our predicted bid, just bid their hp + ties
        if op_hp_now < our_bid:
            return int(op_hp_now + ties)
        elif our_bid >= hp:
            # If our bid would kill us, we're doomed, throw a hail mary
            return int(random.randint(1, hp))
        else:
            return int(our_bid + ties)

Досить класна ідея. Звільнення першого раунду - нова тенденція в роботі ботів, і, здається, вона працює досить добре.
KBriggs

@KBriggs Я оновив цю відповідь, щоб містити свою другу спробу. Згадування про вас відповідно до нових правил. Чудова головоломка btw!
Вазз

Хочете, щоб я ввів обидві, чи лише останню версію? Зараз саме V2
KBriggs

@KBriggs Я хотів би, щоб обидва увійшли, якщо це нормально, будь ласка. Було б добре подивитися, як вони зважуються один на одного.
Wazz

Досить схожий показник в цілому
KBriggs

4

ConsistentBot

Кожен раунд ставить однакову суму. Перші раунди переживати не надто ймовірно, але якщо пощастить дійти до кінця, у нього все одно залишиться розумна кількість HP.

def consistent(hp, history, ties, alive, start):
    if alive == 2:
        return hp-1

    if 100 % start == 0:
        return (100 / start) - 1
    else: 
        return 100 / start

Whelp, зараз це вже пізно виправити, але мій бот використав достатню кількість HP, щоб змусити його до кінця боротися з кожним супротивником один раз, а не пробитися до останнього раунду. Це моє погано: П
Кевін - Відновіть Моніку

4

Кікбан Бот

Цей бот просто намагається протидіяти поточному лідеру Mean Kickbot, обіграючи його в першому раунді і граючи після цього більш агресивно, якщо визнає його.

def kickban(hp, history, ties, alive, start):
    if alive == 2:
        return hp-1

    if not history:
        return 36

    if history[0]==35:
        somean = 1
    else:
        somean = 0

    return min(mean_kick(hp, history, ties, alive, start) + somean*3, hp-1)

1
Я думаю, що ваш відступ трохи відключений.
Джонатан Фрех

ой, спасибі, дивний редактор коду
змішився

цінний урок довіри коду, який ви не контролюєте
OganM

4

Три чверті бота

Він не збирається бити Мехбота чи Саркомабота, але я думаю, що він справляється непогано. Коли я вперше побачив виклик, це було перше, що мені спало на думку, завжди * ставку три чверті вашого здоров’я, якщо немає причин для цього.

* після низького балування першого раунду.

def ThreeQuarterBot(hp, history, ties, alive, start):
    threeQuarters = 3 * hp / 4

    if alive == 2:
        return hp - 1

    opponent_hp = 100 - sum(history)

    if not history:
        # low-ball the first round but higher than (some) other low-ballers
        return 32 + ties
    elif threeQuarters > opponent_hp:
        return opponent_hp + ties

    return threeQuarters

Чотири сьомих бот

Після помірного успіху 3/4 бота в місті з’явилася нова фракція, це лише раціонально.

def FourSeventhsBot(hp, history, ties, alive, start):
    fourSevenths = 4 * hp / 7

    if alive == 2:
        return hp - 1

    opponent_hp = 100 - sum(history)

    if not history:
        # low-ball the first round but higher than (some) other low-ballers
        return 33 + ties
    if fourSevenths > opponent_hp:
        return opponent_hp + ties

    return fourSevenths + ties

Ідеальна фракція

Я цілий

def ThePerfectFraction(hp, history, ties, alive, start):
    thePerfectFraction = 7 * hp / 13

    if alive == 2:
        return hp - 1

    opponent_hp = 100 - sum(history)

    if not history:
        # Need to up our game to overcome the kickers
        return 42 + ties
    if thePerfectFraction > opponent_hp:
        return opponent_hp + ties

    return thePerfectFraction + 1 + ties

Виходячи з такої ймовірності усунення, ви, ймовірно, могли піти і з меншими ставками в 2 раунді. Це добре, але деякі незначні зміни можуть зробити це набагато краще.
KBriggs

@KBriggs Додав нового бота з новими та покращеними шансами;)
Joshua Webb

Хочете, щоб вони були там або просто 1?
KBriggs

@KBriggs Я не знаю, чи не пропустив цей термін, але я додав одного остаточного бота, якщо я встиг його, ви можете видалити інші два фракції ботів
Джошуа Вебб

1
Так, у вас ще є час
KBriggs

4

BandaidBot

BandaidBot хоче, щоб всі грали добре! Якщо його опонент був хорошим в минулому раунді, він пожертвує собою, щоб стимулювати приємну поведінку в інших. Якщо його опонент мав на увазі минулий раунд, він завдасть максимально шкоди своєму опоненту, приносячи в жертву себе, якщо це необхідно. Він пропонує третину своїх к.с., якщо у нього немає історії роботи. (Я сподіваюся, що цей бот матиме цікаві пульсаційні ефекти на інших стратегіях, не стільки, що цей бот сам по собі матиме високий коефіцієнт виграшу. Це може бути цікаво, щоб пара цих гравців була в грі)

def BandaidBot(hp, history, ties, alive, start):
    if alive == 2:
        return hp-1

    if history:
        opp_hp = 100 - sum(history)
        opp_last_hp = 100 - sum(history[:-1])

        if history[-1] <= opp_last_hp / 3:
            return 1 + ties * np.random.randint(0, 1) 
        elif history[-1] > opp_last_hp / 2:
            return min(opp_hp - 1, hp)
        else:
            if history[-1] < hp/2:
                return np.random.randint(history[-1], hp/2)
            else:
                return np.floor(hp/2)
    else:
        return np.floor(hp/3)

GetAlongBot

GetAlongBot буде таким же приємним, як і потрібно, щоб скористатися BandaidBot. Він поверне трохи менше третини своїх к.с., якщо не зможе вбити опонента менше. Якщо його опонент схожий на BandaidBot, він подаватиме ставки 2, знаючи, що BandaidBot зробить ставку 1, тому що GetAlongBot так добре ладнає з усіма іншими - легка перемога, якщо насправді була BandaidBot з іншого боку.

def GetAlongBot(hp, history, ties, alive, start):
    if alive == 2:
        return hp-1

    if history:
        opp_hp = 100 - sum(history)
        opp_last_hp = 100 - sum(history[:-1])
        count = 0
        for i in range(0, len(history)):
            hp_that_round = 100 - sum(history[:i])
            hp_spent_that_round = history[i]
            if hp_that_round / 3 - 1 <= hp_spent_that_round <= hp_that_round / 2:
                count += 1
        if count == len(history): #It's probably BandaidBot!
            return 2
        else:
            return min(opp_hp - 1, np.floor(hp/3))
    else:
        return np.floor(hp/3)

Дійсно акуратна ідея. Цікаво, який вплив він матиме
Кбріггс

помилка: return np.random.randint(history[-1], hp/2): ValueError: low >= highцей випадок потрібно вирішувати якось
KBriggs

@KBriggs слід виправити зараз!
Майя Сол

@KBriggs оновлено, щоб виправити рандомізацію
Maya Sol

3

ДИСЯКОВИЙ бот

def TENacious_bot(hp, history, ties, alive, start):
  max_amount=hp-(alive-1)*2;
  if max_amount<2: max_amount=2

  if alive==2: return hp-1
  if ties==0: return np.minimum(10, max_amount)
  if ties==1: return np.minimum(20, max_amount)
  if ties==2: return np.minimum(40, max_amount)
  # prevent function blowup
  return 2

Цей бот намагається утримати улюблене значення 10, але час від часу він змінює свій вибір, якщо потрібно розірвати нічию (з улюбленим значенням удвічі чи вчетверо) або зберегти для майбутніх раундів, але не на оптимальну суму, оскільки хоче заплутати супротивники, і він не хоче розглядати торги менше ніж 2 в будь-який час, оскільки, переконаний, це набагато краще, ніж сподіватися, що опонент подасть заявку менше 1, тобто 0.

PS: цей бот може мати стратегічні проблеми, якщо ботів більше 2 ^ 9.


Я підозрюю, що вам не доведеться турбуватися про те, щоб мати 2 ^ 9 супротивників ^ _ ^.
KBriggs

Але з початковою ставкою 10, він рідко збирається пройти в перший раунд
KBriggs

Цей бот вважає, що, якщо якийсь бот справді хоче дати більше 10 к.с. в першому раунді, боротися не варто.
AlexRacer

Ха-ха досить ярмарок
KBriggs

3

Обережно

Перше подання до Пазлів програмування коли-небудь! Виявив ваше завдання досить цікавим: P

Якщо в останньому раунді біт на один менший, ніж HP, якщо в історії немає ставок у половину к.с.

Якщо історія перевіряє противник hp та кількість раундів, що залишилися, і спробуйте перевершити противник hp / 2, використовуючи додатковий буфер до частки решти hp, поділену на кількість решти раундів (вона намагається якось зберегти решту hp за задній раунд) . Перевірте, чи витрачаєте ви занадто багато к.с. (не вбивайте себе і не ставте більше, ніж може противник).

Завжди коригуйте зв'язки, як це роблять інші боти.

def cautious_gambler(hp, history, ties, alive, start):
    if alive == 2:
        return hp - 1
    if(history):
        opp_hp = 100 - sum(history)
        remaining_rounds = np.ceil(np.log2(start)) - len(history)

        start_bet = opp_hp / 2
        buff = int((hp - start_bet)/remaining_rounds if remaining_rounds > 0 else (hp - start_bet)) 
        buff_bet = np.random.randint(0, buff) if buff > 0 else 0
        bet = start_bet + buff_bet + ties

        if bet >= hp or bet > opp_hp:
            bet = np.minimum(hp - 1, opp_hp)

        return int(bet)
    else:
        start_bet = hp / 2
        rng_bet = np.random.randint(3,6)

        return int(start_bet + rng_bet + ties)

ОбережноBot2

Занадто сильно агресивний у перших раундах, зараз CautiousBot стає ще обережнішим ...

def cautious_gambler2(hp, history, ties, alive, start):
    if alive == 2:
        return hp - 1
    if(history):
        opp_hp = 100 - sum(history)
        remaining_rounds = np.ceil(np.log2(start)) - len(history)

        start_bet = opp_hp / 2
        buff = int((hp - start_bet)/remaining_rounds if remaining_rounds > 0 else (hp - start_bet)) 
        buff_bet = np.random.randint(0, buff) if buff > 0 else 0
        bet = start_bet + buff_bet + ties

        if bet >= hp or bet > opp_hp:
            bet = np.minimum(hp - 1, opp_hp)

        return int(bet)
    else:
        start_bet = hp * 0.35
        rng_bet = np.random.randint(3,6)

        return int(start_bet + rng_bet + ties)

У вас є помилка , де вона по - , як і раніше викликаючи randint коли буфер = 0: buffer_bet = np.random.randint(0, buffer) if buffer > 0 else 0 File "mtrand.pyx", line 993, in mtrand.RandomState.randint ValueError: low >= high. Зауважте, що буфер - це ключове слово в python, ви можете вибрати інше ім’я змінної.
KBriggs

О, схоже, буфер буфера не завжди є int - ви, мабуть, ділиться на нуль в якийсь момент. Будь ласка, уважно перевірте логіку. Я змусив його працювати, але ви, напевно, можете виправити кутові корпуси.
KBriggs

Приємний улов @KBriggs. Подумайте, я це виправив.
Jesús Ros

Я все ще отримую помилку: buff_bet = np.random.randint(0, buff) if buff > 0 else 0 File "mtrand.pyx", line 993, in mtrand.RandomState.randint ValueError: low >= high. Здається, що буф іноді є числом з плаваючою комою між 0 і 1, яке, імовірно, стає 0 досередини randint. Це працює , якщо ви накладаєте buffна intперед викликом
KBriggs

@KBriggs, ймовірно, тому, що ceilповертає a float. Пропустив ту ... Ти знову: П
Хесус Рос

3

Добре, я спробую в цьому свої сили.

SnetchBot

Перевірка фракцій здоров’я, з якими збирався опонент. Якщо противник піднімався, побийте його до нього.

def snetchBot(hp, history, ties, alive, start):
    if alive == 2:
        return hp-1

    opponent_hp = 100
    history_fractions = []
    if history:
        for i in history:
            history_fractions.append(float(i)/opponent_hp)
            opponent_hp -= i
        if opponent_hp <= hp/2:
            #print "Squashing a weakling!"
            return opponent_hp + (ties+1)/3

        average_fraction = float(sum(history_fractions)) / len(history_fractions)
        if history_fractions[-1] < average_fraction:
            #print "Opponent not raising, go with average fraction"
            next_fraction = average_fraction
        else:
            #print "Opponent raising!"
            next_fraction = 2*history_fractions[-1] - average_fraction
        bet = np.ceil(opponent_hp*next_fraction) + 1
    else:
        #print "First turn, randomish"
        bet = np.random.randint(35,55)

    if bet > opponent_hp:
        bet = opponent_hp + (ties+1)/3
    final_result = bet + 3*ties
    if bet >= hp:
        #print "Too much to bet"
        bet = hp-1
    return final_result

EDIT: багато програв у першому раунді, скоригував випадкові межі першого повороту


Досить гарний перший удар, вхід оновлення
KBriggs

@KBriggs Трохи відредагували (лише випадкові межі першого раунду). Хоча я вже був здивований тим, що високий, як 10 місце. Якщо це
стане


3

SquareUpBot

Не здавалося, що багато ботів грають із потужностями замість фракцій, тому я вирішив зробити одну, з деякими стандартними оптимізаціями і подивитися, де я буду розміщуватись. Досить спрощений.

Також намагається визначити, чи бот ворога не намагається використовувати якийсь постійний дріб, оскільки повноваження > дроби .

EDIT: Я манекен, і мій детектор фракції не міг працювати. Відремонтовано зараз.

def squareUp(hp, history, ties, alive, start):

    #Taken from Geometric Bot
    opponentHP = 100 - sum(history)

    # Need to add case for 1
    if hp == 1:
        return 1

    # Last of the last - give it your all
    if alive == 2:
        if ties == 2 or opponentHP < hp-1:
            return hp - 1

    #Calculate your bet (x^(4/5)) with some variance
    myBet = np.maximum(hp - np.power(hp, 4./5), np.power(hp, 4./5))
    myBet += np.random.randint(int(-hp * 0.05) or -1, int(hp * 0.05) or 1);
    myBet = np.ceil(myBet)
    if myBet < 1:
        myBet = 1
    elif myBet >= hp:
        myBet = hp-1
    else:
        myBet = int(myBet)

    #If total annihilation is a better option, dewit
    if opponentHP < myBet:
        if ties == 2:
            return opponentHP + 1
        else:
            return opponentHP

    #If the fraction is proven, then outbid it (Thanks again, Geometric bot)
    if history and history[0] != history[-1]:
        health = 100
        fraction = float(history[0]) / health
        for i,x in enumerate(history):
            newFraction = float(x) / health
            if newFraction + 0.012*i < fraction or newFraction - 0.012*i > fraction:
                return myBet
            health -= x
        return int(np.ceil(opponentHP * fraction)) + 1    
    else:
        return myBet


@KBriggs Я оновив бота, щоб детектор фракції насправді працював.
Діамантовий пил
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.