Robot Roulette: Roboter-Glücksspiel mit hohen Einsätzen


56

Endstand

+ ---------------------------------- + --------- + ---- ----- + --------- + ---------------------------- +
| Name | Partitur | WinRate | TieRate | Eliminierungswahrscheinlichkeit |
+ ---------------------------------- + --------- + ---- ----- + --------- + ---------------------------- +
| 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]% |
+ ---------------------------------- + --------- + ---- ----- + --------- + ---------------------------- +

Vielen Dank für die Teilnahme und herzlichen Glückwunsch an @Sarcoma zum Sieg!

Regeln:

Jeder fängt mit 100 PS an. In jeder Runde werden 2 Spieler nach dem Zufallsprinzip aus dem Pool der Teilnehmer ausgewählt, die in dieser Runde noch nicht teilgenommen haben. Beide Spieler wählen eine Zahl zwischen 0 und ihrer aktuellen PS und decken diese Zahlen gleichzeitig auf. Der Spieler, der die niedrigere Zahl gewählt hat, stirbt sofort. Der andere Spieler subtrahiert die gewählte Zahl von seiner verbleibenden HP und geht in die nächste Runde.

Das Turnier funktioniert so:

Aus der Gruppe der Teilnehmer werden 2 zufällig ausgewählt. Sie stehen sich gegenüber und einer oder beide sterben. Ein Spieler stirbt, wenn:

  1. Sie wählen eine Nummer, die kleiner ist als die ihres Gegners
  2. Ihre PS fallen auf oder unter Null
  3. Sie treffen dreimal hintereinander auf ihren Gegner

Bei Gleichstand generieren beide Spieler einfach bis zu dreimal neue Zahlen. Nach dem Anspiel wird der Überlebende (falls vorhanden) für die nächste Runde in den Pool verschoben, und der Vorgang wird wiederholt, bis der Pool der aktuellen Runde erschöpft ist. Befindet sich eine ungerade Zahl im Pool, geht die ungerade umsonst in die nächste Runde.

Ihre Aufgabe ist es, eine Funktion in python2.7 zu schreiben, die Ihre aktuelle Zahl hp, eine Liste der Gebote Ihres Gegners historyund eine Ganzzahl, tiesdie angibt, wie oft Sie bereits mit Ihrem aktuellen Gegner verbunden sind, sowie eine Ganzzahl, die angibt, wie Es gibt noch viele Bots alive(einschließlich Sie) und eine Ganzzahl, die die Anzahl der Bots zum Zeitpunkt startdes Turniers angibt . Beachten Sie, dass der Verlauf keine Bindungen enthält. Die Funktion muss eine Ganzzahl zwischen 0 und Ihrer aktuellen Gesamthöhe zurückgeben. Ein paar einfache Beispiele, die Bindungen ignorieren, sind unten gezeigt:

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)

Wenn Ihre Funktion eine Zahl zurückgibt, die größer als Ihre HP ist, wird sie auf 0 zurückgesetzt. Ja, Sie können sich selbst töten. Ihre Funktion darf nicht versuchen, auf ein Mitglied eines Objekts der RouletteBot-Klasse zuzugreifen oder dieses zu ändern. Sie dürfen keine Maßnahmen ergreifen, die Ihren Gegner eindeutig identifizieren, unabhängig von zukünftigen zusätzlichen Bots. Das Überprüfen des Stapels ist zulässig, solange es theoretisch möglich ist, dass mehr als ein einzelner Gegner die Informationen erzeugt hat, die Sie von ihm erhalten, selbst wenn derzeit nur ein Bot vorhanden ist, der dies könnte. Sie können also nicht einfach den Stapel durchlesen, um zu sehen, welche feindliche Funktion aufgerufen wurde.

Nach diesen Regeln ist es möglich, dass es keinen Gewinner gibt und die letzten beiden Teilnehmer sich gegenseitig töten. In diesem Fall erhalten beide Finalisten jeweils einen halben Punkt.

Dies ist mein erster Versuch, ein Puzzle zu programmieren. Kritik ist willkommen!

Die Steuerung finden Sie hier .


4
FWIW, ich plane, ein neuronales Netzwerk zu verwenden, das für alle anderen Bots trainiert wurde, nur zum Spaß, sobald Sie den Controller eingerichtet haben :)
Quintec,

2
Die Typprüfung war zu Gunsten von antiantiantiupyoursbot. Ich werde einen anderen Weg finden
KBriggs

3
@ Sarkom Scheint, als hätte dieser Wettbewerb einen ernsthaften Codekrieg ausgelöst. Dieser Wettbewerb ist noch nicht zu Ende, aber ich freue mich schon auf die Weiterentwicklung. Möglicherweise sogar der folgende Schritt, AI erhöhte Konkurrenz: P
Markov verkettetes

3
WOOOOOOOOOOOOOO!
Sarkom

5
Oh mein Gott. Das absichtliche Trolling, mean_kick so zu ändern, dass immer Null zurückgegeben wird, wenn es an so vielen Stellen verwendet wurde, ist brillant.
Magua

Antworten:


12

BinaryBot

Hat das schon jemand gemacht? Setzt die Hälfte seiner Gesundheit in jeder Runde auf den Boden.

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

SarcomaBot

Wenn der letzte Kampf HP bietet - 1. Wenn es der erste Kampf ist, bieten Sie eine halbe HP plus einen zusätzlichen Zufallsbetrag von bis zu einem Viertel HP. Wenn es ein Gegengebot nach diesem Gebot überbieten kann, erhält der Gegner HP + 1. Wenn es weniger Gesundheit als das Gegengebot hat, liegt der zufällige Betrag zwischen 75% und der aktuellen 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

Kleinere Optimierungen versuchen, den Lebensaufwand zu reduzieren.

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

Feineinstellung aktualisieren

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

Letzter Eintrag

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

Update
UpYoursBot-Schutz hinzugefügt

Update
AntiAntiUpYoursBot-Schutz hinzugefügt

Update
AntiAnitAntiAntiUpYoursBot Ich bin besiegt


Kommentare sind nicht für längere Diskussionen gedacht. Diese Unterhaltung wurde in den Chat verschoben .
Mego

17

UpYours

Da ich mich verspätet habe, habe ich einige Zeit damit verbracht, die vorhandenen Bots zu bewundern, die Ideen Ihrer Jungs zu komplizieren und sie dann zu entschärfen. Dann kam es zu mir

Gute Künstler kopieren, große Künstler stehlen. - Pablo Picasso ich


"Up Yours", weil ich unverschämt klaue (und manchmal ein oder zwei Punkte auf die Gebote Ihrer Bots geheftet habe, um sie zu erhöhen).

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

Aber für den Ernstfall ist dies ein großartiger Wettbewerb. Ich liebe diese Community an solchen Tagen.


1
Hahahaha das ist wunderschön. Ich bin unschlüssig, ob ich es zulassen soll, aber ich lasse es erst einmal spielen, da ich nicht daran gedacht habe, zu sagen, dass es nicht erlaubt ist. Sie haben die Funktionsnamen an einigen Stellen falsch angegeben - siehe Controller auf Github.
KBriggs

1
Es macht sich natürlich sehr gut, aber es verliert immer noch gegen Kick Bot
KBriggs

1
Ha, gute Mühe!
Sarkom

1
@ Sarkom Ich hätte es ohne dich nicht geschafft. ;) Ich mag deinen Bot auch sehr, Kumpel.
Qfwfq

1
Der Upyoursbot-Schutz von Sarcomabot ist ein echtes
Problem

15

Kamikaze

Warum sich mit komplizierter Logik herumschlagen, wenn wir alle sowieso sterben werden?

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


Ein Schuss

Es wird mindestens eine Runde überleben, wenn es nicht auf die Kamikaze trifft.

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

11
Welp, das war unvermeidlich
KBriggs

Ich wollte auch einen pazifistischen Bot hinzufügen, aber ich möchte Ihre Herausforderung nicht mit gehirntoten Bots überschwemmen
DobromirM

5
Aufgrund einiger schneller Tests ändert sich an den Kamikaze-Bot-Deos nicht viel. Es wird lediglich ein weiterer Bot nach dem Zufallsprinzip aus der Runde entfernt, der bei einer ausreichend großen Anzahl von Turnieren einfach auf Null gemittelt wird. Das One Hot ist aber ordentlich. Ohne das macht mein AverageBot normalerweise das Beste - aber wenn ein paar OneShots im Spiel sind, wird der Durchschnitt zu großen Zahlen verschoben und die AverageBots sterben schnell ab. Gleiches gilt für LastBot. Sie können sich wirklich mit dem Verhalten anderer Roboter anlegen, indem Sie Ihre eigenen Wettmuster verzerren. Mit OneShot im Spiel gewinnt RandomBot. Ohne sie gewinnt AverageBot.
KBriggs

14

Pathetic Bot bekommt ein dringend benötigtes Upgrade:

Der erbärmliche Versuch eines Bots, der versucht, die Funktionen anderer Bots einzubeziehen

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

Dieser Bot enthält Funktionen von Survivalist Bot und Geometric Bot für effizientere Bot-Takedowns.

Vor dem Upgrade:

Der erbärmliche Versuch eines Bots, der die Geschichte seines Gegners analysiert

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

Wenn es eine Vorgeschichte seines Gegners gibt, berechnet er die HP seines Gegners. Dann führt es eine der folgenden Aktionen aus:

  • Wenn sein Gegner der letzte noch lebende Gegner ist, bietet er einen weniger als seine PS.
  • Wenn sein Gegner nicht der letzte lebende Gegner ist, aber der Gegner weniger als 16 PS hat, überbietet er die PS seines Gegners.
  • Wenn sein Gegner nicht der letzte noch lebende Gegner ist und es eine Geschichte von Unentschieden gibt, bietet er seine HP, weil er von Unentschieden gelangweilt ist.
  • Andernfalls wird es seinen Gegner überbieten.

Wenn es keine Geschichte gibt, werden einige ausgefallene Berechnungen durchgeführt, die ich zusammen gehackt habe und die geboten haben. Wenn der Wert 100 überschreitet, bietet er automatisch seine HP minus 1.

Ich habe diesen Code während der Arbeit zusammen gehackt und dies ist meine erste Vorlage, daher wird er wahrscheinlich weder gewinnen noch irgendetwas gewinnen und gegen die Kamikaze verlieren.

BEARBEITEN: Aufgrund einiger Vorschläge wurde das Startverhalten des Bots geändert, um einen höheren Wert zu bieten.

EDIT 2: Startparameter hinzugefügt, der nichts bewirkt

EDIT 3: Neuer Spinoff-Bot hinzugefügt:

[Der erbärmliche Versuch eines Bots, der Gang Bots angreift (und alles tut, was der obige Bot tut)] ENTFERNT

[Dieser Bot analysiert, ob sein Gegner ein Gangbot ist oder nicht und gibt vor, einer zu sein, um die süßen niedrigen Gebote zu erhalten, die er leicht übertreffen kann.]

Dieser Bot wurde verschrottet, bitte entfernen Sie ihn aus den Bestenlisten.

EDIT 4: Fehler behoben, Bindefunktion geändert.


Sehr schön, danke für den Bot! Ich werde ein paar Statistiken geben, wenn ich ein paar mehr bekomme.
KBriggs

Ich bin ein Anfänger in Python, daher bin ich mir nicht sicher, ob die Syntax korrekt ist.
Bitte teilen

Es läuft, also keine Sorge
KBriggs

@Yodie Zur Überprüfung des Mini-Codes: Ihr Funktionskörper sollte durch eine Ebene eingerückt sein (syntaktische Notwendigkeit). opp_hp +1fehlt ein Raum, um pythonisch zu sein; Ihre Kommentare beginnen mit unausgeglichenen Leerzeichen. Schließlich fehlt Ihrer Funktion ein Docstring.
Jonathan Frech

2
Ich denke, dieser Bot macht sich recht gut, wenn er es nach der ersten Runde schafft, aber weil so viele Leute darauf wetten, dass er in der ersten Runde groß ist, stirbt er fast immer früh. Sie können die Leistung verbessern, indem Sie das ursprüngliche Verhalten ändern und ein höheres Gebot abgeben, wenn kein Verlauf vorliegt. Wenn Sie beispielsweise Ihre No-History-Wette verdreifachen, gewinnt dieser Bot unter den bisherigen Teilnehmern mit einem komfortablen Vorsprung.
KBriggs

11

Kick Bot

Die gesunde Wahl für meinen Gegner ist, die Hälfte seines Lebens zu bieten. Dann bieten wir bis zur Hälfte seines Lebens + 1, wenn wir ihn nicht mit einem vernünftigen Gebot herausholen können, das ist ein Gebot, das kleiner als die Hälfte unseres Lebens ist.

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))

Der Kick Bot ist offensichtlich die Nemesis des Punch Bot!

Mean Kick Bot

Dieser neue KickBot tritt in der ersten Runde weicher aus, nur damit er in den nächsten Runden härter treten kann, das ist gemein!

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

Sein Bruder musste sich beide umbringen, aber WiseKickBot lernte von seinen Gefallenen.

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))

Nett. Ich sehe viele Einreichungen, die sich jetzt direkt gegen andere
richten.

Doppelte Rückkehr in der letzten Zeile?
Veskah

Ah, ich war noch nicht damit gefahren, sonst hätte ich das mitbekommen.
KBriggs

Dieser hat eine komfortable Führung übernommen!
KBriggs

1
@KBriggs hier ist ein Backup!
Johan

8

Tat bot

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)

Ein Versuch, ein Äquivalent zu einem Tit-for-Tat-Bot zu finden. Angenommen, die meisten Wetten sind zwischen den Runden ungefähr gleich. Mit dieser Annahme versucht es, den feindlichen Bot zu besiegen und dabei ziemlich sparsam zu bleiben. Verbraucht ungefähr 40 Gesundheit in der Eröffnungsrunde.

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

Ein Workaround für SarcomaBots Anti-UpYours-Schutz, bei dem der größte Teil des Codes für mich selbst verwendet wird! Oder nehme ich den Code von UpYoursBot? Eine Frage zum Nachdenken, während Sie meinen Bot lesen ...

AntiAntiUpYours Bot hat sich zu AntiAntiAntiAntiUpYours Bot entwickelt! Jetzt mit mehr Affen-Patching.

Poly 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) 

Poly-Bot führt eine polynomielle Regression in der Geschichte Ihres Bots durch und übertrifft die vorhergesagte Punktzahl um einen kleinen Betrag.

Nobler 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)

Nobler Bot hat eine gute Zeit gehabt, aber hat sich dafür entschieden, früh zu Bett zu gehen. Schlaf gut, edler Bot.


Kommentare sind nicht für längere Diskussionen gedacht. Diese Unterhaltung wurde in den Chat verschoben .
Mego

8

1/2 Punch Bot, überarbeitet

Ich denke, es wird ziemlich schnell sterben. Es ist es wert. Funktion umbenannt, vergessen dort den Namen zu ändern.

Die überarbeitete Version ist fertig, es gibt bessere Gewinnchancen (vor allem in der letzten Runde) und es gibt leichten Schutz vor Gang-Bots

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

Stürmer Bot

1/2 Punch Bot wurde zu sehr gemobbt und wurde sogar ein Lakai für den UpYoursBot, so dass sein älterer Bruder, der StrikerBot , kam, um zu helfen.

Kein großer Unterschied zum optimierten 1/2 Punch, aber er ist ein bisschen schlauer und hat sich in meinen Läufen gut geschlagen (10 km und 35 km, obwohl er möglicherweise gegen KickbanBot verliert).

Die letzte Version ist abgelaufen. Sofern nicht einige Überraschungen auftauchen, sollte es den zweiten Platz sichern, wenn es nicht den ersten gibt (es gibt eine geringe Chance, Kickbanbot zu besiegen).

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

Du musst ihn umbenennen, es gibt bereits einen Kamikaze-Bot ^ _ ^
KBriggs

Bisher ist dies jedoch der Gewinner
KBriggs

Ihre Funktion ceilscheint nicht definiert zu sein.
Jonathan Frech

Ich habe zu np.ceil () gewechselt, um es
auszuführen

bearbeitet, danke für das Heads-up
Belhenix

7

Gang Bot

Die Idee war, dass möglicherweise zwei oder mehr der Bot in derselben Simulation verwendet werden könnten. Der Bot versucht, anderen Bots in der Gruppe "leichte Gewinne" zu geben, indem er prüft, ob sein Verlauf ein Vielfaches von 7 Geboten ist. Natürlich kann dies auch von anderen Bots leicht manipuliert werden. Dann berechne ich eine Schätzung für Gebote von Nicht-Gang-Bots basierend auf dem Verhältnis meiner Gesundheit zu ihrer und dem Verhältnis ihrer vorherigen Gesundheit zu ihrem vorherigen Gebot und addiere 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

Sehr cool. Wie viele braucht man? Ich werde wahrscheinlich die Anzahl der Einträge
begrenzen müssen

Ihr Codeblock scheint die erste Zeile Ihrer Quelle zu verfehlen.
Jonathan Frech

Ich bin mir nicht sicher, wie viele in einer Simulation benötigt würden, aber wenn sich einer der Bots jemals sieht, sollten sie die Gewinnchance eines dieser Bots erhöhen. Ich vermute, dass 10% des Pools als Gangbots ausreichen sollten, um einen signifikanten Unterschied zu bewirken. Auch im Codeblock fehlt die erste Zeile -> dies ist mein erster Beitrag hier Ich weiß nicht, warum die Formatierung das getan hat, aber ja, es ist nur die Methodendeklaration.
Jim Hat

Sie haben einen Fehler: Der Bot identifiziert jeden mit len ​​(history)> 1 als Gangmitglied
KBriggs

Mein schlechtes, sollte jetzt behoben sein.
Jim Hat

6

Schlimmsten Fall

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

Einfacher Bot. Gibt hp - hp / (start - alive + 4)in den meisten Fällen zurück und erhöht im Falle von Unentschieden den Wert für jedes Unentschieden um 2 (muss um eins erhöht werden!) hp.


Dies scheitert beim Teilen durch Null, wenn alive==8. Ich kann es manuell in die Gesamtzahl der Bot ändern, aber es ist eine Überlastung der Regeln, da dies keine Eingabe für Ihre Funktion ist - Sie wissen nur, ob Sie zu einem bestimmten Zeitpunkt noch so viele Gegner übrig haben, und nicht, gegen wie viele Sie gestartet sind.
KBriggs

Ich habe den Wettbewerb basierend auf Ihrer Anfrage aktualisiert
KBriggs

@KBriggs Dank :)
Quintec

Sie müssen auch 1 hinzufügen, um zu starten, da dies 0 für die erste Runde ist
KBriggs

@KBriggs behoben, sollte eigentlich +2, damit es nicht 0
zurückgibt

6

Überbieter

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 wird versuchen , höher zu bieten als sein Gegner kann bieten , soweit möglich.


Es gibt eine Bedingung, where np.random.randint(hp/5, hp/2)die fehlschlagen kann hp/5 == hp/2, dh if hp==0oderhp==1
KBriggs

3
Wenn HP 0 ist, sollte ich nicht aufgerufen werden. : P Sie haben Recht mit HP 1.
Draco18s

6

Spitball Bot

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

Beurteilt anhand der Anzahl der verbleibenden Bots, wie viel von ihrer Gesundheit sie opfern sollte. Wenn nur noch zwei Bots übrig sind, wird geboten hp-1, wenn jedoch noch drei übrig sind, werden die Hälfte, vier übrig, ein Drittel usw. geboten.

In einem sehr großen Wettbewerb muss ich jedoch mehr als 3 oder 4 PS bieten, um zu vermeiden, dass ich in der ersten Runde sterbe. Deshalb habe ich eine Untergrenze von 10 festgelegt. Natürlich werde ich immer noch nie mehr bieten als hp-1.

Es fügt auch 1,5 PS für Krawatten hinzu, da ich mehrere "Add 1 PS für Krawatten" -Bots sehe. Ich bin mir nicht sicher, ob das als Betrug gilt. Wenn ja, werde ich es ändern.

Tolle Idee übrigens!

Spitball Bot 2.0

Was gibt's Neues?

  • Auf Teilen durch die Anzahl der verbleibenden Runden anstatt der Anzahl der verbleibenden Bots umgestellt (Danke an @Heiteira!). Tatsächlich dividiere ich jetzt durch diese Zahl, die an die Macht gebracht wurde .8, um meine Gebote ein bisschen mehr vorab zu laden.

  • Erhöhtes Mindestgebot von 10 auf 20 (Danke @KBriggs!)

  • Eingefügte Überprüfung, ob das Spitball-Gebot über den aktuellen HP des Gegners liegt, und ggf. Reduzierung.

(SO wird der unten stehende Code nicht als Code gerendert, es sei denn, ich füge hier Text ein, also 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
Ihr Gebot sollte eine ganze Zahl sein. Solange Sie Ihren Basiswert unterschreiten oder überschreiten, um die Dezimalstelle zu
entfernen, ist

Ja, ich habe gleich nach den Berechnungen das Wort ergriffen. Danke für die schnelle Antwort!
MegaWidget

2
Sie können dies möglicherweise optimieren, wenn Sie Ihre HP nicht durch die Anzahl der verbleibenden Teilnehmer, sondern durch die Anzahl der verbleibenden Runden teilen (dies sollte math.ceil (math.log (alive, 2))
Black Owl Kai

1
Basierend auf anderen Bots scheinen die meisten von ihnen Gebote nach vorne zu bringen. Dies könnte sich also verbessern, wenn Sie das Gebot für die erste Runde über 10
KBriggs

Das sind beide gute Ideen! Ich hatte nicht bemerkt, dass die Anzahl der Bots nicht mit der Anzahl der verbleibenden Runden übereinstimmt (ich habe die Wettbewerbsregeln zuerst falsch interpretiert). Ich werde versuchen, sie morgen umzusetzen. Vielen Dank!
MegaWidget

5

Geometrisch

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. Platz beim ersten Versuch, überhaupt nicht schlecht
KBriggs

5

Bot 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

Versuchen Sie, Gewinne mit dem geringsten Aufwand zu maximieren:

  • Wenn wir gewinnen können, tun Sie es einfach
  • Wenn es die letzte Runde ist, stirb nicht beim Versuch
  • Ansonsten mach dir keine Sorgen

Warum?

Versuche die Wahrscheinlichkeit auszunutzen: Die erste Runde zu gewinnen, indem du niedrig spielst, ist der beste Weg, um das Turnier zu starten. 13 scheint der Sweet Spot zu sein: Die zweite Runde ist ein sicherer Sieg, und der Rest ist ein Spaziergang im Park.


Sie haben die Führung übernommen, sehr nett! Seien Sie vorsichtig, Sie möchten möglicherweise Parasitenschutz hinzufügen, da Bots, die die Führung übernehmen, Ziele für Dinge wie UpYoursBot werden. Informieren Sie sich in SarcomaBots über mögliche Schutzmaßnahmen.
KBriggs

5

Ratet mal, Bot

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)

Zum ersten Mal hier posten. Das sah nach einer Menge Spaß aus, also reiche ich meinen überaus schrecklichen Versuch ein und rate, was die anderen Bots wetten werden.

Edit 1: Der ersten Wette wurde eine weitere 1 hinzugefügt, um die Wahrscheinlichkeit eines Gleichstands mit anderen Spielern zu verringern, die 51 setzen.

Edit 2: Hat den Eröffnungszug des Sarkom-Bots gestohlen, da die Wahrscheinlichkeit groß war, dass er nicht immer zuerst eliminiert wurde.

Edit 3: Bot überlebt in der ersten Runde sehr gut, wird aber später leicht zerstört. Die Art und Weise, wie der Roboter an die zweite Runde denkt, wurde geändert, da die Halbbetter jetzt tot im Wasser sind.

Edit 4: Jetzt, da die erste Runde gut ist, habe ich die Art und Weise geändert, wie die zweite Runde gehandhabt wird. In der zweiten Runde viel gestorben, also muss ich irgendwie überleben.

Blood Bot

Machte einen durstigen Bot auf der Suche nach einem Kill. Die Idee ist, zu versuchen, gegen Bots mit niedrigen Einsätzen zu gewinnen, und sobald das Blutbad der ersten Runde überschritten ist, sollte es nicht mehr aufzuhalten sein, da es gewaltige Mengen an HP haben sollte, um Gegner zu überbieten.

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
Ich denke, len (history) * len (history) könnte in len (history) ** 2 geändert werden, wenn meine Pythonkenntnisse korrekt sind.
Yodie

Sie haben eine Division durch Null, wenn len (history) == 0
KBriggs

Code wurde aktualisiert. Nachdem wir keine Geschichte gefunden haben, geht es zum ersten anderen
Markov Chained

oi .............
Sarkom

2
@ Sarkom es ist ein Halsabschneider Bot Welt da draußen Mann!
Markov Chained

5

meh_bot

Bieten Sie einfach etwas mehr als die Hälfte seiner PS

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

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

Es gibt eine ganze Reihe von Bots, die genau dieses Verhalten ausnutzen, sodass es für Sie möglicherweise schwierig ist, die Traktion zu erlangen!
KBriggs

@KBriggs Einige Updates gemacht, ich hatte nicht damit gerechnet, dass die erste Version so gut läuft wie sie, hoffentlich gibt dieses Update ihr eine bessere Chance
meh Man

Wow, das hat einen großen Unterschied gemacht, ich denke du bist an erster Stelle. Das Update wird in ein paar Minuten veröffentlicht. Möglicherweise müssen Sie Ihrem Bot ein Immunsystem geben (siehe SarcomaBot), wenn Sie weiterhin gute Ergebnisse erzielen möchten.
KBriggs

@KBriggs Ich hatte nicht damit gerechnet, das gut zu machen, ich dachte bestenfalls, es wird Top 10. Wie auch immer, ich habe ein weiteres hinzugefügt, nur um den Effekt in der ersten Runde zu sehen, PS. Können Sie beide ausführen, damit ich das Ergebnis von beiden sehen kann? Vielen Dank
meh Man

@KBriggs Bitte mach das auch, Muchas gracias
meh Man

4

Robbie Roulette

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

Dieser Bot analysiert auf einfache Weise die Geschichte des feindlichen Bots oder bietet die Hälfte der verbleibenden Trefferpunkte


4

Bieten Sie höher, je weniger Konkurrenz Sie haben. Vielen Dank an die Kommentatoren für die Verbesserungsvorschläge.

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
Gute Idee, aber ich sehe zwei Probleme. Die meisten anderen Bots bieten in der ersten Runde ein hohes Gebot, daher wird dieser wahrscheinlich die meiste Zeit zu früh sterben. Die zweite ist, dass im Finale die meisten Bots HP-1 bieten, also verliert dieser Bots diese, es sei denn, Sie haben die doppelte HP. Aber für die Zwischenrunden gefällt mir die Idee. Wenn Sie die beiden Sonderfälle ansprechen, können Sie wahrscheinlich die Leistung verbessern.
KBriggs

4

SurvivalistBot und HalvsiesBot

Vielen Dank für die Beantwortung meiner Fragen. Das Endergebnis ist ein komplexerer Bot.

HalvsiesBot ist ein skurriler "nur die Hälfte weitergeben" -Bot mit einer 50/50-Gewinnchance. Ich vermute.

SurvivalistBot trifft eine Reihe von binären Baum-If-else-Entscheidungen basierend auf dem Datensatz, einschließlich eines Overrides bei einem Gleichstand (wenn es 2 Gleichstände trifft, wird es mit Kamikazes behandelt, um den Tod von Dreifachgleichständen zu vermeiden).

Meine Python ist etwas verrostet, daher ist der Code möglicherweise etwas fehlerhaft. Sie können ihn also jederzeit korrigieren oder aktualisieren.

Es wurde entwickelt, um zu versuchen, Datenbits zu ermitteln, um daraus zu schließen, wie viel HP noch übrig ist, wie viele Bots es voraussichtlich mindestens geben wird, wie viel HP mindestens noch übrig ist und wie hoch die durchschnittlichen Gebote sind. Es nutzt auch die Randomisierung in mehrdeutigen Situationen aus, z. B. beim Öffnen von Spielen oder bei Problemen mit optimalen Geboten.

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. Diese Zeile muss den Verlaufsfall der Länge 0 behandeln.
KBriggs

Danke, ich werde es korrigieren.
SSight3

Fest. Lassen Sie mich wissen, wenn andere Fehler vorliegen.
SSight3

1
Einige Syntaxfehler: Fehlen: `nach else, math.[func] -> np.[func]und an einer Stelle verwenden Sie, Lowestwo Sie meinen LowestBid. Alle im Controller auf Github behoben und die Ergebnisse in Kürze aktualisiert.
KBriggs

Vielen Dank. Alle oben genannten Fehler im Beitrag wurden behoben.
SSight3

4

Berechnung von 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)

Aggressiver Rechenbot

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

Wenn wir die Aktionen des Gegners vorhersagen können, können wir die optimalen Einsätze machen! Wenn wir nicht können (nicht genug Daten oder der Gegner ist zu zufällig), können wir zumindest das tun, was unser Gewinnpotential maximieren würde. Theoretisch stirbt in jeder Runde mindestens die Hälfte der lebenden Bots. Daher kann ich davon ausgehen, dass es höchstens log2 (lebendige) Runden gibt. Im Idealfall würden wir unsere PS gleichmäßig auf alle Runden verteilen. Wir wissen jedoch, dass einige Bots dumm sind und frühzeitig sterben werden, daher sollten wir in den früheren Runden etwas mehr setzen.

Aggressives Berechnen des Bots-Codes Berechnen des Bots-Codes, um zu versuchen, am Leben zu bleiben, indem man aggressiver ist, auf Kosten der langfristigen Gesundheit. Nur Simulationen zeigen, ob Tempo oder Wert gewinnen.

Anti Kick Bot sollte immer den aktuellen Anführer KickBot: P schlagen

EDIT: Deterministischer Bot durch Anti-Kick-Bot ersetzt, ein intelligenterer Bot mit fast genau den gleichen Rückgabewerten. Auch verhinderte die Abstimmung mehr als die Gegner HP


Süß. Ich denke, dass dies mit einem sehr großen Bot-Pool besser tun wird.
KBriggs

Ich erhalte eine Fehlermeldung manchmal mit dieser: return np.max(theoreticalBet, hp - 1): AxisError: axis 23 is out of bounds for array of dimension 0. Ich habe einen Link zum Controller gepostet, damit Sie ihn testen können.
KBriggs

@KBriggs Aktualisiert den Code, um es zu beheben.
Bob Cratchit

1
Bestätigt, Punktestand wird aktualisiert. Sie sind sicher in den Top 10.
KBriggs

@KBriggs Ich habe ein paar weitere Bots zum Ausprobieren hinzugefügt :)
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))

Es ist wirklich spät ... ich bin müde ... kann mir keinen Namen vorstellen ... und das Format dieses Bots ist wirklich ähnlich wie bei anderen, nur mit einem etwas anderen Algorithmus in der Vorgeschichte. Es versucht, die aktuelle Rate zu ermitteln, die der Gegner zum Spielen neigt ... oder so ähnlich ... zzz


Sie müssen np.maximumanstelle von verwenden np.max, das gleiche fürmin
KBriggs

@KBriggs Danke :) Hmm, es scheint, als ob die generischen Bots dieses Spiel
regieren

Scheint, als wären sie ziemlich einfache Ziele, ich bin überrascht, dass noch niemand einen Parasiten gemacht hat
KBriggs

@ KBriggs Ja, ich bin überrascht. Es ist Zeit, Schutzmaßnahmen hinzuzufügen ...
Quintec

Planen Sie immer noch, Neuralbot zu machen?
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 [im Ruhestand]

Werde versuchen, den Wettbewerb zu meistern, indem du die PS gleichmäßig auf die Runden verteilst. Bietet in der ersten Runde übrig gebliebene PS, um sich eine bessere Chance zu geben, in die "küstentauglichen" Runden zu kommen.

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)

Coast Bot V2

Da mir diese Herausforderung so gut gefällt, musste ich einfach einen anderen Bot machen. In dieser Version wird ein Teil der später auslaufenden PS geopfert, indem in den ersten beiden Runden mehr PS verbraucht werden.

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))

Prozent Bot

Versucht, die durchschnittlichen prozentualen PS-Ausgaben des Gegners zu berechnen, und bietet darauf basierend.

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)

Ziemlich coole Idee. Die Entlassung der ersten Runde ist ein neuer Trend bei Bots und scheint einigermaßen gut zu funktionieren.
KBriggs

@KBriggs Ich habe diese Antwort so aktualisiert, dass sie meinen zweiten Versuch enthält. Erwähnen Sie nach den neuen Regeln. Tolles Puzzle übrigens!
Wazz

Soll ich beide oder nur die neueste Version eingeben? Im Moment ist es nur V2
KBriggs

@KBriggs Ich hätte gerne beide eingetragen, wenn das in Ordnung ist, bitte. Wäre gut zu sehen, wie sie gegeneinander abwägen.
Wazz

Ziemlich ähnliche Leistung insgesamt
KBriggs

4

ConsistentBot

Setzt in jeder Runde den gleichen Betrag. Es ist nicht sehr wahrscheinlich, dass er die ersten Runden überlebt. Wenn er jedoch das Glück hat, das Ende zu erreichen, sollte noch eine angemessene Menge HP übrig sein.

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

Welpe, es ist zu spät, um es jetzt zu reparieren, aber mein Bot hat genug HP eingesetzt, um es bis zum Ende des Kampfes gegen jeden Gegner zu schaffen, nicht um es in die letzte Runde zu schaffen. Das ist mein schlechtes
Wort

4

Kickban Bot

Dieser Bot versucht einfach, dem aktuellen Anführer Mean Kickbot entgegenzuwirken, indem er ihn in Runde eins schlägt und danach aggressiver spielt, wenn er ihn erkennt.

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
Ich denke, Ihre Einrückung ist ein bisschen ab.
Jonathan Frech

Hoppla, danke, seltsamer Code-Editor hat die erste Zeile durcheinander gebracht
HRSE

Eine wertvolle Lektion in vertrauenswürdigem Code, den Sie nicht kontrollieren können
OganM

4

Dreiviertel-Bot

Er wird weder MehBot noch SarcomaBot (s) schlagen, aber ich denke, er macht es ziemlich gut. Als ich die Herausforderung zum ersten Mal sah, war dies das erste, was mir in den Sinn kam. Wetten Sie immer auf drei Viertel Ihrer Gesundheit, es sei denn, es gibt keinen Grund dazu.

* Nach dem Low-Balling der ersten Runde.

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

Vier-Siebtel-Bot

Nach dem mäßigen Erfolg von 3/4 bot gibt es eine neue Fraktion in der Stadt, es ist nur rational.

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

Die perfekte Fraktion

Ich bin ganz

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

Aufgrund dieser Eliminierungswahrscheinlichkeiten könnten Sie wahrscheinlich auch in Runde 2 mit kleineren Geboten davonkommen. Dies tut gut, aber einige kleine Verbesserungen können es viel besser machen.
KBriggs

@KBriggs Hinzugefügt einen neuen Bot mit neuen und verbesserten Quoten;)
Joshua Webb

Wollen Sie beide da drin haben oder nur 1?
KBriggs

@KBriggs Ich weiß nicht, ob ich die Deadline verpasst habe, aber ich habe einen letzten Bot hinzugefügt. Wenn ich es rechtzeitig geschafft habe, kannst du die anderen beiden Fraktions-Bots entfernen
Joshua Webb

1
Ja, Sie haben noch Zeit
KBriggs

4

BandaidBot

BandaidBot möchte, dass alle nett spielen! Wenn sein Gegner in der letzten Runde nett war, wird er sich selbst opfern, um Anreize für nettes Verhalten bei anderen zu schaffen. Wenn sein Gegner in der letzten Runde gemein war, fügt er seinem Gegner so viel Schaden wie möglich zu und opfert sich gegebenenfalls selbst. Es bietet ein Drittel seiner PS, wenn es keine Geschichte hat, mit der es arbeiten kann. (Ich hoffe, dass dieser Bot interessante Welligkeitseffekte auf andere Strategien hat, nicht so sehr, dass dieser Bot selbst eine hohe Gewinnrate hat. Es könnte Spaß machen, ein paar davon im Spiel zu haben.)

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 wird genauso schön sein, wie es sein muss, um BandaidBot zu nutzen. Es wird knapp ein Drittel seiner PS zurückgeben, es sei denn, es kann seinen Gegner für weniger als das töten. Wenn sein Gegner wie BandaidBot aussieht, bietet er 2, in dem Wissen, dass BandaidBot 1 bietet, weil GetAlongBot mit allen anderen so gut zurechtkommt - ein einfacher Gewinn, solange es wirklich BandaidBot war.

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)

Wirklich nette Idee. Ich frage mich, wie viel Einfluss es haben wird
KBriggs

Fehler: return np.random.randint(history[-1], hp/2): ValueError: low >= highDieser Fall muss irgendwie behandelt werden
KBriggs

@KBriggs sollte jetzt behoben sein!
Maya Sol

@KBriggs aktualisiert, um Randomisierung zu beheben
Maya Sol

3

Nervöser Bot

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

Dieser Bot versucht, seinen Lieblingswert von 10 beizubehalten, ändert jedoch gelegentlich seine Auswahl, um ein Unentschieden zu lösen (wobei sich sein Lieblingswert verdoppelt oder vervierfacht) oder für zukünftige Runden zu speichern, jedoch nicht um den optimalen Betrag, weil er verwirren möchte Gegner und es möchte nicht in Betracht ziehen, zu jedem Zeitpunkt weniger als 2 zu bieten, da es davon überzeugt ist, dass es viel besser ist, als zu hoffen, dass der Gegner weniger als 1, dh 0, bietet.

PS: Dieser Bot kann strategische Probleme haben, wenn es mehr als 2 ^ 9 Bots gibt.


Ich vermute, Sie müssen sich keine Sorgen machen, 2 ^ 9 Gegner zu haben ^ _ ^.
KBriggs

Aber mit einer Eröffnungswette von 10
schafft

Dieser Bot denkt, wenn ein Bot in der ersten Runde wirklich mehr als 10 PS geben will, ist es den Kampf nicht wert.
AlexRacer

Haha fair genug
KBriggs

3

CautiousBot

Erste Einreichung bei Programming Puzzles! Fanden Sie Ihre Herausforderung sehr interessant: P

Wenn die letzte Runde eins weniger als PS ist, wenn in der Vergangenheit keine Wette mit einer halben PS plus einem kleinen Zufallsbetrag abgeschlossen wurde.

Wenn der Verlauf des Gegners HP und die Anzahl der verbleibenden Runden überprüft und versucht, den Gegner HP / 2 mit einem zusätzlichen Puffer von bis zu dem Bruchteil der verbleibenden HP geteilt durch die Anzahl der verbleibenden Runden zu überbieten (es wird versucht, die verbleibenden HP für hintere Runden irgendwie zu konservieren). . Überprüfen Sie, ob Sie zu viel PS verbrauchen (töten Sie sich nicht und bieten Sie nicht mehr, als Ihr Gegner kann).

Korrigieren Sie Krawatten immer wie andere Bots.

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

Zu aggressiv in den ersten Runden, jetzt wird CautiousBot noch vorsichtiger ...

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)

Sie haben einen Fehler , wo es noch randint Aufruf wird , wenn Puffer = 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. Beachten Sie, dass buffer ein Schlüsselwort in Python ist. Möglicherweise möchten Sie einen anderen Variablennamen auswählen.
KBriggs

Oh, es sieht so aus, als wäre es so, weil der Puffer nicht immer ein Int ist - Sie teilen wahrscheinlich irgendwann durch Null. Bitte überprüfen Sie die Logik sorgfältig. Ich habe es zum Laufen gebracht, aber Sie können wahrscheinlich die Eckfälle reparieren.
KBriggs

Schöner Fang @KBriggs. Denke, ich habe es behoben.
Jesús Ros

Ich bekomme immer noch eine Fehlermeldung: buff_bet = np.random.randint(0, buff) if buff > 0 else 0 File "mtrand.pyx", line 993, in mtrand.RandomState.randint ValueError: low >= high. Es scheint, dass Buff manchmal eine Gleitkommazahl zwischen 0 und 1 ist, die vermutlich im Inneren auf 0 gesetzt wird randint. Dies funktioniert , wenn Sie werfen buffauf intvor dem Aufruf
KBriggs

@KBriggs wahrscheinlich, weil a ceilzurückgibt float. Das habe ich verpasst ... Ty nochmal: P
Jesús Ros

3

Okay, ich werde mich bemühen.

SnetchBot

Überprüfung der Gesundheitsanteile, mit denen der Gegner gereist ist. Wenn der Gegner erhöht hat, schlagen Sie ihn dazu.

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

BEARBEITEN: In der ersten Runde viel verlieren, die Zufallsgrenzen für die erste Runde angepasst


Ziemlich guter erster Schuss, Score Update eingehend
KBriggs

@KBriggs Bearbeitet ein wenig (nur die erste Runde zufällige Grenzen). Obwohl ich schon überrascht war, als ich den zehnten Platz erreichte. Wenn dies noch schlimmer wird,
kehre

Sie drücken ein wenig mehr Saft aus ihm heraus
KBriggs

3

SquareUpBot

Es schien nicht so, als würden viele Bots mit Kräften statt mit Brüchen spielen, also habe ich beschlossen, einen mit einigen Standardoptimierungen zu machen und zu sehen, wo ich platzieren werde. Ganz simpel.

Versucht auch festzustellen, ob der feindliche Bot nicht versucht, einen konstanten Bruch zu verwenden, da Kräfte > Brüche .

EDIT: Ich bin ein Dummy und mein Fraktionsdetektor konnte nicht funktionieren. Jetzt repariert.

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

Kein schlechter erster Schuss, die Punktzahlen wurden aktualisiert
KBriggs

@KBriggs Ich habe den Bot so aktualisiert, dass der Bruchdetektor tatsächlich funktioniert.
Diamond Dust
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.