ロボットルーレット:ハイステークスロボットギャンブル


56

最終順位

+ ---------------------------------- + --------- + ---- ----- + --------- + ---------------------------- +
| 名前| スコア| WinRate | タイレート| 除去確率|
+ ---------------------------------- + --------- + ---- ----- + --------- + ---------------------------- +
| 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. MehBot | 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. CautiousGamblerBot2 | 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. CautiousBot | 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. CalculatingBot | 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. DeterminBot | 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. SurvivalistBot | 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. AggressiveBoundedRandomBotV2 | 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. AverageBot | 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. KamikazeBot | 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から現在のHPの間の数字を選び、それらの数字を同時に公開します。低い数字を選んだプレイヤーはすぐに死にます。他のプレイヤーは、選択した数を残りのHPから差し引き、次のラウンドに進みます。

トーナメントは次のように機能します。

出場者のブラケットから、2がランダムに選択されます。彼らは直面し、それらの一方または両方が死にます。次の場合、プレイヤーは死亡します。

  1. 相手の数よりも小さい数を選択します
  2. HPが0以下になる
  3. 彼らは相手と3回連続で結びます

同点の場合、両方のプレイヤーが最大3回まで新しい数字を生成します。対決の後、生存者(存在する場合)は次のラウンドのためにプールに移動され、現在のラウンドプールを使い果たすまでプロセスが繰り返されます。プールに奇数がある場合、奇数のうちの1つが次のラウンドに無料で移動します。

あなたの仕事は、関数書くことです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)

関数がhpよりも大きい数値を返す場合、0にリセットされます。はい、自殺することは可能です。関数は、RouletteBotクラスのオブジェクトのメンバーにアクセスまたは変更しようとしてはなりません。将来の追加ボットに関係なく、相手を明確に識別するアクションを実行することはできません。スタックを検査することは、理論的には、1つのボットしか存在しない場合でも、そこから収集した情報を複数の異なる敵が生成できる可能性がある限り許可されます。つまり、スタックを読んで、どの敵機能が呼び出されたかを確認することはできません。

これらのルールの下では、勝者がいない可能性があり、最後の2人の競技者が互いに殺し合っています。その場合、両方のファイナリストはそれぞれ半分のポイントを獲得します。

これは私の最初のプログラミングパズルの試みなので、批評は大歓迎です!

コントローラはここにあります


4
FWIW、コントローラーをセットアップしたら、他のすべてのボットでトレーニングされたニューラルネットワークを使用して楽しみます:)
Quintec

2
型チェックは、antiantiantiantiupyoursbotの利益のためでした。別の方法を見つけます
-KBriggs

3
@Sarcomaこの競争が深刻なコード戦争を引き起こしたようです。この競争はまだ終わっていませんが、私はすでにこの進化を楽しみにしています。次のステップでさえ、AIは競争を強化しました:P
マルコフ連鎖

3
WOOOOOOOOOOOOOO!
肉腫

5
何てことだ。mean_kickが非常に多くの場所で使用されたときに常にゼロを返すように変更する意図的なトローリングは素晴らしいです。
マグア

回答:


12

BinaryBot

誰もまだこれをしましたか?ラウンドごとにヘルスの半分をベットします。

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

SarcomaBot

最後のバトルが馬力に入札した場合-1.最初のバトルラウンドが半分の馬力に加えて、追加のランダムな量の最大4分の1馬力の場合。対戦相手の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

アップユーアーズ

入るのが遅れて、私はしばらくの間、既存のボットを賞賛し、あなたの仲間のアイデアを過度に複雑にし、それからそれらを過度に複雑にしませんでした。それから私に来ました

良いアーティストはコピーし、素晴らしいアーティストは盗みます。- パブロピカソミー


私は恥ずかしがらずに盗んでいるので「そして、あなたのボットの入札に1つまたは2つのポイントをタックする」

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
明らかにうまくいきますが、それでもキックボットに負けています
-KBriggs

1
ハ、頑張って!
肉腫

1
@Sarcomaあなたなしではできませんでした。;)私もあなたのボットが大好きです。
Qfwfq

1
SarcomabotのUpyoursbot保護はこれを本当に混乱させます
-KBriggs

15

神風

とにかく私たち全員が死ぬつもりなのに、なぜ複雑なロジックに煩わされるのか...

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


ワンショット

神風に出会わなければ、少なくとも1ラウンドは生き残ります。

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

11
Welp

私も平和主義者のボットを追加するつもりでしたが、あなたの挑戦を脳死のボットであふれさせたくはありません
DobromirM

5
いくつかの簡単なテストに基づいて、カミカゼボットはあまり変化しません-ラウンドから別のボットをランダムに削除するだけで、十分な数のトーナメントで平均0になります。しかし、ホットワンはきれいです。それがないと、AverageBotが最善を尽くす傾向がありますが、プレイ中のOneShotsがいくつかある場合、平均が大きな数値に偏り、AverageBotsがすぐに消滅する傾向があります。LastBotでも同じです。独自のベッティングパターンをゆがめることで、他のロボットの動作を本当に混乱させることができます。OneShotをプレイすると、RandomBotが勝ちます。それがなければ、AverageBotが勝ちます。
KBriggs

14

哀れなボットは非常に必要なアップグレードを取得します

他のボットの機能を取り込もうとするボットへの哀れな試み

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

このボットには、サバイバリストボットとジオメトリックボットの機能が組み込まれており、ボットのテイクダウンをより効率的に行えます。

アップグレード前:

敵の歴史を分析するボットへの哀れな試み

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

対戦相手の過去の履歴がある場合、対戦相手のHPを計算します。次に、次のいずれかを実行します。

  • その対戦相手が生きている最後の対戦相手である場合、それはその馬力よりも1つ少ない入札をします。
  • その対戦相手が生きている最後の対戦相手ではないが、その対戦相手が16馬力未満の場合、その対戦相手の馬力を上回る。
  • その対戦相手が生きている最後の対戦相手ではなく、同点の履歴がある場合、それは同点に退屈しているため、その馬力を入札します。
  • それ以外の場合は、相手よりも優先されます。

履歴がない場合、それは私が一緒にハッキングしたいくつかの空想的な計算を行い、それを入札します。値が100を超える場合、HPマイナス1が自動的に入札されます。

私は仕事中にこのコードを一緒にハックしましたが、これは私の最初の提出であるため、おそらく勝つことも何もありませんし、神風に負けるでしょう。

編集:いくつかの提案により、ボットの開始動作が変更され、より高い値が付けられました。

編集2:何もしない開始パラメータを追加

編集3:新しいスピンオフボットを追加しました:

[ギャングボットを攻撃するボットへの哀れな試み(および上記のボットが行うすべてを行う)]削除

[このボットは、相手がギャングボットであるかどうかを分析し、簡単に切り替わることができる甘い低入札を得るために、ギャングボットであるかのように見せかけます。

このボットは破棄されました。リーダーボードから削除してください。

編集4:エラーを修正し、タイ機能を変更しました。


とても素晴らしい、ボットに感謝します!さらにいくつか入手したら、いくつかの統計を提供します。
KBriggs

私は、構文が正しいかどうか、それが起こるなら、私に知らせて自由に感じるかわからないので、私は、Pythonで初心者だ
Yodie

実行されるので心配はありません
-KBriggs

@Yodieミニコードレビューとして:関数の本文はレベル(インデントの必要性)でインデントする必要があります。opp_hp +1pythonicになるスペースがありません。コメントは不均衡な量の空白で始まります。最後に、関数にはdocstringがありません。
ジョナサンフレッチ

2
このボットは、最初のラウンドを過ぎてもうまくいくと思いますが、多くの人が大きな賭けをするので、彼は最初のラウンドでほとんど常に早く死にます。履歴がない場合は、入札単価を高くするように初期動作を変更することにより、パフォーマンスを改善できます。たとえば、履歴なしのベットを3倍にすると、このボットはこれまでの出場者の間で余裕を持って勝ちます。
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))

ワイズキックボット

彼の兄弟は両方とも自殺しなければなりませんでしたが、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

Tatボット

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)

tit-for-tatボットに相当する試み。ほとんどの賭けはラウンド間でほぼ同じであると仮定しています。その仮定を使用して、かなりfru約したまま、敵のボットを倒そうとします。オープニングラウンドで約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ボットは進化してAntiAntiAntiAntiUpYoursボットになりました!モンキーパッチを追加しました。

ポリボット

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) 

Poly botは、ボットの履歴に対して多項式回帰を実行し、予測されたスコアをわずかに打ちます。

上品なボット

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)

上品なボットは楽しい時間を過ごしましたが、早く寝ることに決めました。しっかりと眠る、上品なボット。


コメントは詳細なディスカッション用ではありません。この会話はチャットに移動さました
メゴ

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とそれほど違いはありませんが、彼は少し賢く、私が行った実行でうまくいきました(KickbanBotに負けるかもしれませんが、10kと35k)

最後のバージョンが起動し、時間がなくなりました。何らかの驚きが起きない限り、1位にならなければ2位を確保する必要があります(キックバンボットに勝つチャンスはわずかです)

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

ギャングボット

アイデアは、潜在的に2つ以上のボットを同じシミュレーションで使用できるというものでした。ボットは、その履歴が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

とてもかっこいい。いくつ必要ですか?おそらくエントリの数を
制限する必要が

コードブロックがソースの最初の行を見逃しているようです。
ジョナサンフレッチ

シミュレーションでいくつ必要になるかはわかりませんが、ボットのいずれかがお互いを見た場合、ボットの1つが勝つ可能性を高める必要があります。プールの10%がギャングボットであることは、大きな違いを生むのに十分なはずです。また、最初の行が欠落しているコードブロック->これはここでの最初の投稿です。なぜフォーマットがそれを行ったのかわかりませんが、まさにメソッド宣言です。
ジム・ハット

バグがあります:ボットはlen(history)> 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感謝:)
Quintec

最初のラウンドでは0であるため、start-aliveにも1を追加する必要があります
-KBriggs

@KBriggsが修正されました。実際には+2であるため、0が返されません、笑
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)

ボットは、可能な限り相手入札できるよりも高い入札を試みます。


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

残りのボットの数に基づいて、どれだけのヘルスを犠牲にするかについて判断します。ボットが2つしか残っていない場合は、入札しますがhp-1、3つ残っている場合は、その半分、残り4つ、1/3などです。

ただし、非常に大規模なコンテストでは、最初のラウンドで死ぬことを避けるために3または4 hp以上を入札する必要があると考えているため、下限を10に設定しました。もちろん、これ以上入札することはありませんよりもhp-1

また、いくつかの「タイに1馬力追加」ボットが表示されるため、タイにも1.5馬力追加されます。それが不正行為としてカウントされるかどうかはわかりません。もしそうなら、私はそれを変更します。

ところで、素晴らしいアイデアです!

Spitball Bot 2.0

新着情報?

  • 残っているボットの数ではなく、残っているラウンドの数で割ることに切り替えました(@Heiteiraに感謝!)。実際には.8、入札単価をもう少し先読みするために、累乗した数値で割っています。

  • 最小入札価格を10から20に引き上げました(ありがとう@KBriggs!)

  • spitballの入札が対戦相手の現在のHPを超えているかどうかのチェックを挿入し、それがあればそれを下げます。

(SOは、ここにテキストを入れない限り、以下のコードをコードとしてレンダリングしないので、OK)

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
入札単価は整数である必要があります。そのため、10進数を取り除くためにベース値を下限または
上限に設定していれば問題ありません-KBriggs

うん、すべての計算を行った直後にそれをフロアします。早速のお返事ありがとうございます!
メガウィジェット

2
残りの出場者の数でHPを分割せず、残りのラウンドの数(math.ceil(math.log(alive、2)である必要があります))でこれを最適化できる場合があります
Black Owl Kai

1
他のボットに基づいて、それらのほとんどは入札単価を
前倒し

これらは両方とも良いアイデアです!ボットの数が残りのラウンドの数と同じではないことに気付いていませんでした(最初はコンテストのルールを誤解していました)。明日それらを実装してみます。ありがとう!
メガウィジェット

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はスイートスポットのようです。2回戦は確実な勝利で、残りは公園の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:他の人が51をベットする可能性を減らすために、最初のベットに別の1を追加しました。

編集2:最初に一貫して排除されない可能性が高いため、肉腫ボットの最初の動きを盗みました。

編集3:ボットは最初のラウンドで非常によく生き残りますが、後の段階で簡単に破壊されます。半分のベターが水中で死んだので、ロボットが第2ラウンドについて考える方法を変更しました。

編集4:最初のラウンドがうまくいったので、2回目のラウンドの処理方法を変更しました。第二ラウンドでたくさん死ぬので、どうにか生き残る必要があります。

ブラッドボット

のどが渇いたボットに殺害を求めさせました。アイデアは、低賭けボットに勝つことを試みることであり、それが最初のラウンドの血浴を過ぎると、敵を凌ぐために巨大な量の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
私のpythonの知識が正しい場合、len(history)* len(history)はlen(history)** 2に変更できると思います。
ヨディ

len(history)== 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

MehBot 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

メラン

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になると思っていました。両方を実行して、両方の結果を確認できますか?ありがとう
MEHマン

@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
きちんとしたアイデアですが、2つの問題があります。1つは、他のほとんどのボットが最初のラウンドで大きな値をつけるため、ほとんどのボットはほとんどの時間で早く死んでしまいます。2つ目は、最終的には、ほとんどのボットがhp-1を入札するため、hpを2倍にしない限り、このボットはそれらを失います。しかし、中間ラウンドでは、アイデアが好きです。2つの特殊なケースに対処すると、おそらくパフォーマンスを改善できます。
KBriggs

4

SurvivalistBotおよびHalvsiesBot

私の質問に答えてくれてありがとう。最終結果は、より複雑なボットです。

HalvsiesBotは、50/50の確率で勝つ可能性のある気まぐれな「ただ通過し続ける」ボットです。私は推測する。

SurvivalistBotは、データセットに基づいて一連のバイナリツリーif-else決定を行います。これには、タイのオーバーライド(2つのタイにヒットした場合、三重のタイの死を避けるために神風がかかります)も含まれます。

私のpythonは少し錆びているので、コードに少しバグがある可能性がありますので、自由に修正または更新してください。

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に: ` がありません。すべてがgithubのコントローラーで修正され、スコアが間もなく更新されました。math.[func] -> np.[func]LowestLowestBid
KBriggs

ありがとう。投稿の前述のエラーをすべて修正しました。
-SSight3

4

ボットの計算

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)

アンチキックボット

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(アライブ)ラウンドになると予想できます。理想的には、すべてのラウンドでHPを均等に分割します。ただし、一部のボットは愚かで自殺/早期に死亡することがわかっているため、以前のラウンドではもう少し賭けるべきです。

攻撃的な計算ボットの修正の計算ボットのコードは、長期的な健康を犠牲にして、より攻撃的になることで生き続けようとします。テンポまたは値が勝つかどうかは、シミュレーションでのみわかります。

アンチキックボットは常に現在のリーダーであるキックボットを打ち負かす必要があります:P

編集:決定論的ボットをアンチキックボットに置き換えました。これは、ほぼ同じ戻り値を持つよりスマートなボットです。また、対戦相手のHPよりも多くの投票を防ぎました


可愛い。これは、非常に大きなボットプールを使用するほうがうまくいくと思います。
KBriggs

これで時々エラーが発生します:return np.max(theoreticalBet, hp - 1): AxisError: axis 23 is out of bounds for array of dimension 0。あなたがテストできるように、コントローラーへのリンクを投稿しました。
KBriggs

@KBriggsは、コードを修正して修正しました。
ボブクラチット

1
確認済み、スコア更新の着信。確かにトップ10に入っています。
KBriggs

@KBriggsいくつかのボットを追加して試してみました:)
ボブクラチット

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ありがとう:)うーん、一般的なボットがこのゲームを支配しているようです
Quintec

彼らは非常に簡単なターゲットのようです、私は誰もまだ寄生虫を作っていないことに驚いています
KBriggs

@KBriggsうん、驚いたよ。保護を追加する時間
...-Quintec

まだニューラルボットの作成を計画していますか?
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

コーストボット[引退]

ラウンド間でHPを均等に分割することにより、競争の方法を試してみてください。残りの馬力を最初のラウンドで入札し、「コースト可能な」ラウンドに参加するチャンスを増やします。

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

私はこのチャレンジがとても好きなので、別のボットを作らなければなりませんでした。このバージョンでは、最初の2ラウンドでより多くのHPを使用することで、後のコースティングHPを犠牲にします。

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この応答を更新して、2回目の試行を含めるようにしました。新しいルールに従ってあなたに言及する。素晴らしいパズルところで!
ワズ

両方を入力するか、最新バージョンのみを入力しますか?現在はV2のみです
KBriggs

@KBriggsよろしければ両方入力してください。それらがお互いにどのように重くなるかを見るのは良いでしょう。
ワズ

全体的にかなり似たパフォーマンス
-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を使用して、最後のラウンドに到達するのではなく、各対戦相手との戦いの最後まで到達しました。それは私の悪いです:P
ケビン-モニカを

4

キックバンボット

このボットは、現在のリーダーであるMean Kickbotをラウンド1で破り、それを認識した場合はその後より積極的にプレイすることで、単純に対抗しようとします。

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
インデントは少しずれていると思います。
ジョナサンフレッチ

おっと、ありがとう、奇妙なコードエディターが最初の行を台無しに
HRSE

あなたがコントロールしていないコードを信頼する上で貴重な教訓
OganM

4

スリークォーターボット

彼はMehBotやSarcomaBotに勝つつもりはありませんが、私は彼がかなりうまくいくと思います。私が最初にチャレンジを見たとき、これは私の頭に浮かんだ最初のものでした。理由がない限り、常にあなたの健康の4分の3を賭けました。

*最初のラウンドのローボール後。

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オッズが新しく改善された新しいボットを追加しました;)
ジョシュアウェッブ

両方とも欲しいですか、それとも1つだけですか?
KBriggs

@KBriggsあなたは他の二つの分数ボット削除することができ、私は締め切りを逃した場合、私は知らないが、私は時間内にそれを作った場合、私は、1つの最終ボットを追加しました
ジョシュア・ウェッブ

1
うん

4

BandaidBot

BandaidBotは、みんなに素敵なプレイをしてもらいたい!相手が最後のラウンドでいい人だった場合、他の人の素晴らしい行動を促すために自分自身を犠牲にします。相手が最後のラウンドを意味していた場合、それは相手に可能な限りのダメージを与え、必要であれば自分自身を犠牲にします。使用する履歴がない場合は、馬力の3分の1を入札します。(このボットが他の戦略に興味深い波及効果をもたらすことを望んでいますが、このボット自体が高い勝率を持つことはあまりありません。これらのいくつかをプレイするのは楽しいかもしれません)

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を利用するために必要なものと同じくらい優れています。敵をそれ以下で殺すことができない限り、馬力の3分の1未満を返します。対戦相手がBandaidBotのように見える場合、GetAlongBotは他のすべての人とうまくやっているのでBandaidBotが1を入札することを知って、2を入札します。

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)

本当にすてきなアイデア。どのくらいの影響があるのだろうか
-KBriggs

エラー:return np.random.randint(history[-1], hp/2): ValueError: low >= highこのケースは何らかの方法で処理する必要があります
-KBriggs

@KBriggsは今修正する必要があります!
マヤソル

ランダム化を修正するために更新された@KBriggs
Maya Sol

3

TENaciousボット

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倍または4倍にする)か、将来のラウンドのために保存する必要がある場合、選択を時々変更しますが、混乱させるために最適な量ではありません相手が1未満、つまり0で入札することを期待するよりもはるかに優れていると確信しているため、いつでも2未満の入札を検討することは望んでいません。

PS:このボットには、2個以上のボットがある場合、戦略的な問題が発生する可能性があります。


^^^ 2 ^ 9人の対戦相手を心配する必要はないと思います。
KBriggs

しかし、10のオープニングベットで、彼は最初のラウンドを過ぎて勝ちとなることはめったにありません
KBriggs

このボットは、一部のボットが最初のラウンドで実際に10馬力以上を与えたい場合、戦う価値はないと考えています。
AlexRacer

ハハは十分
KBriggs

3

CautiousBot

プログラミングパズルへの最初の投稿!あなたの挑戦は非常に興味深いことがわかりました:P

最後のラウンドが馬力より1少ない場合、履歴が馬力の半分と小さなランダムな量を賭けていない場合。

履歴が対戦相手のHPと残りのラウンド数を確認し、残りのHPを残りのラウンド数で割った割合までの追加バッファーを使用して、敵のHP / 2を上回るようにします(何らかの方法で後のラウンドで残りの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)

CautiousBot2

最初のラウンドでは攻撃的すぎて、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)

buffer = 0:のときにまだrandintを呼び出しているバグがあります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。私はそれを修正したと思います。
ヘスス・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。buffは時々0から1の間の浮動小数点数であり、おそらく内部で0にキャストされるようrandintです。これは、呼び出しの前にキャストbuffした場合に機能しますint
-KBriggs

@KBriggsはおそらくをceil返すためfloatです。P:その1 ...のTyは再び逃した
ヘスス・ロス

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

編集:最初のラウンドで多くを失い、最初のターンのランダムな制限を調整しました


かなり良い最初のショット、スコア更新の着信
-KBriggs

@KBriggs少し編集しました(最初のラウンドのランダムな境界のみ)。私はすでに10位と同じくらい高いことに驚いていましたが。これが悪化した場合は、最初のロールバックに戻ります:D
18年

あなたは彼からもう少しジュースを絞ります
-KBriggs

3

SquareUpBot

多くのボットが分数の代わりに力で遊んでいるようには見えなかったので、私は標準的な最適化を行い、どこに配置するかを見て、それを作ることにしました。かなり単純です。

また、powers > fractionsであるため、敵ボットが一定の割合を使用しようとしていないかどうかを判断しようとします。

編集:私はダミーであり、私のフラクション検出器は動作しませんでした。今すぐ修理。

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

@KBriggsフラクション検出器が実際に動作するようにボットを更新しました。
ダイヤモンドダスト
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.