로봇 룰렛 : 고 지능 로봇 도박


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. 스트라이커 봇 | 0.05984 | 5.78 % | 0.41 % | [46 18 11 8 6 5] % |
| 4. 퍼펙트 프랙 션봇 | 0.05336 | 5.16 % | 0.35 % | [49 12 14 10 6 4] % |
| 5. 메란 봇 | 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. 스네 치봇 | 0.04616 | 4.48 % | 0.28 % | [41 29 8 9 5 3] % |
| 8. 킥봇 | 0.04458 | 4.24 % | 0.44 % | [20 38 17 10 6 4] % |
| 9. MehBot | 0.03636 | 3.51 % | 0.25 % | [80 34 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. 육종 봇 Mk3 | 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 11 10 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. 봇 13 | 0.02205 | 2.15 % | 0.11 % | [90 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 0 0] % |
| 27. 계산 봇 | 0.01404 | 1.29 % | 0.22 % | [87 9 11 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. 안티 강봇 | 0.00816 | 0.76 % | 0.11 % | [94 1 1 1 1] % |
| 31. GeometricBot | 0.00776 | 0.74 % | 0.07 % | [19 46 25 7 2 1] % |
| 32. 추측 봇 | 0.00719 | 0.05 % | 1.34 % | [65 17 4 6 5 3] % |
| 33. 경계 랜덤 봇 | 0.00622 | 0.60 % | 0.05 % | [42 39 12 5 2 0] % |
| 34. 스프레더 봇 | 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. 퍼센트 봇 | 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 0 0] % |
| 39. BandaidBot | 0.00297 | 0.29 % | 0.02 % | [76 9 1041 10] % |
| 40. TENaciousBot | 0.00287 | 0.29 % | 0.00 % | [94 4 0 0 0] % |
| 41. 생존자 봇 | 0.00275 | 0.25 % | 0.04 % | [92 6 0 0 0] % |
| 42. 랜덤 봇 | 0.00170 | 0.13 % | 0.07 % | [42 36 14 5 2 1] % |
| 43. 공격적인 경계의 랜덤 봇 V2 | 0.00165 | 0.14 % | 0.06 % | [8 46 34 9 2 1] % |
| 44. 블러드 봇 | 0.00155 | 0.01 % | 0.30 % | [65 28 5 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. 한심한 | 0.00016 | 0.01 % | 0.02 % | [94 0 5 0 0] % |
| 51. OverfittedBot | 0.00014 | 0.01 % | 0.00 % | [58 40 2 0 0] % |
| 52. 로비 봇 | 0.00009 | 0.01 % | 0.00 % | [32 41 24 2 0 0] % |
| 53. 최악의 케이스 봇 | 0.00002 | 0.00 % | 0.00 % | [4 71 23 2 0] % |
| 54. SmartBot | 0.00002 | 0.00 % | 0.00 % | [44 51 5 0 0] % |
| 55. AAAAUpYoursBot | 0.00000 | 0.00 % | 0.00 % | [40 58 2 0 0 0] % |
| 56. 킥 반봇 | 0.00000 | 0.00 % | 0.00 % | [67 32 0 0 0] % |
| 57. OneShotBot | 0.00000 | 0.00 % | 0.00 % | [2 95 3 0 0] % |
| 58. 킥봇 | 0.00000 | 0.00 % | 0.00 % | [100 0 0 0 0] % |
| 59. 카미카제 봇 | 0.00000 | 0.00 % | 0.00 % | [100 0 0 0 0] % |
| 60. MeanKickBot | 0.00000 | 0.00 % | 0.00 % | [100 0 0 0 0] % |
+ ---------------------------------- + --------- + ---- ----- + --------- + ---------------------------- +

참여해 주신 모든 분들께 감사 드리며 @Sarcoma에게 ​​축하를드립니다!

규칙 :

모두 100 마력으로 시작합니다. 각 라운드에서 2 명의 플레이어가 해당 라운드에서 아직 경쟁하지 않은 참가자 풀에서 무작위로 선택됩니다. 두 선수 모두 0과 현재 마력 사이의 숫자를 골라 그 숫자를 동시에 공개합니다. 낮은 숫자를 선택한 플레이어는 즉시 죽습니다. 다른 플레이어는 남은 HP에서 선택한 숫자를 빼고 다음 라운드로 넘어갑니다.

토너먼트는 다음과 같이 작동합니다 :

참가자의 브래킷에서 2가 무작위로 선택됩니다. 그들은 직면하고, 그들 중 하나 또는 둘 다 죽는다. 다음과 같은 경우 플레이어가 사망합니다 :

  1. 그들은 상대의 숫자보다 작은 숫자를 선택합니다
  2. 체력이 0 이하로 떨어집니다
  3. 상대와 3 번 연속으로 묶습니다

동점 인 경우 두 플레이어는 단순히 최대 3 번 새로운 숫자를 생성합니다. 페이스 오프 후 생존자 (있는 경우)는 다음 라운드의 풀로 이동하고 현재 라운드 풀을 모두 사용할 때까지 프로세스가 반복됩니다. 수영장에 홀수 번호가 있으면 홀수 번호가 다음 라운드로 무료로 이동합니다.

당신의 임무는 현재 입력 , 상대의 입찰 목록 및 현재 상대와 이미 묶인 횟수를 알려주 는 정수 및 방법을 알려주 는 정수를 사용 하는 python2.7 의 함수를 작성하는 것입니다 많은 봇은 여전히 당신을 포함하고 있으며 토너먼트 에서 봇의 수를 나열한 정수입니다 . 히스토리에는 타이가 포함되지 않습니다. 이 함수는 0과 현재 총 hp 사이의 정수를 반환해야합니다. 동점을 무시하는 몇 가지 간단한 예는 다음과 같습니다.hphistorytiesalivestart

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 점씩 반을받습니다.

이것은 나의 첫 번째 프로그래밍 퍼즐 시도이므로 비판은 환영합니다!

컨트롤러는 여기 에서 찾을 수 있습니다 .


4
FWIW, 컨트롤러를 설정하면 다른 모든 봇에서 훈련 된 신경망을 사용하여 재미있게 사용할 수 있습니다. :)
Quintec

2
유형 검사는 antiantiantiantiupyoursbot의 이점을위한 것입니다. 다른 방법을 찾을 것입니다
KBriggs

3
@Sarcoma이 경쟁이 심각한 코드 전쟁을 일으킨 것처럼 보입니다. 이 경쟁은 끝나지 않았지만 이미 이것의 진화를 고대하고 있습니다. 아마도 다음 단계 인 AI는 경쟁을 강화했습니다 : P
Markov Chained

3
우 우우우 우우우!
육종

5
세상에. 많은 장소를 사용했을 때 항상 0을 반환하도록 mean_kick을 고의적으로 조정하는 것은 훌륭합니다.
Magua

답변:


12

이진 봇

아무도 아직이 일을 했습니까? 매 라운드마다 체력의 ​​절반을 베팅합니다.

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

육종 봇

마지막 전투에서 HP가 1을 입찰 한 경우-1. 첫 번째 전투 라운드에서 절반 HP에 최대 4 분의 1의 추가 랜덤 금액이 추가됩니다. 해당 플레이어의 입찰 상대 력 +1 이후 상대 입찰을 이길 수있는 경우 상대 입찰보다 체력이 75 %에서 현재의 hp -1보다 낮을 경우

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

육종 봇 Mk2

경미한 조정은 수명 소비를 줄이려고합니다.

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

육종 봇 Mk3

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

미세 조정 업데이트

육종 봇 Mk4

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

육종 봇 Mk5

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

육종 봇 Mk6

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

육종 봇 Mk7

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

육종 봇 Mk8

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

육종 봇 Mk9

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

육종 봇 Mk10

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

최종 입장

육종 봇 Mk11

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


의견은 긴 토론을위한 것이 아닙니다. 이 대화는 채팅 으로 이동 되었습니다 .
Mego

17

UpYours

늦게 들어 와서 나는 기존 봇에 감탄하면서 오랜 시간을 보냈다. 그런 다음 나에게왔다

훌륭한 예술가는 복사하고 훌륭한 예술가는 훔칩니다. - 파블로 피카소


"확실히 도둑질하기 때문에"(때때로 당신의 봇의 입찰에 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


한 번의 기회

가미카제를 만나지 않으면 최소한 한 번이라도 살아남을 것입니다.

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

11
불가피했다 Welp,
KBriggs

나는 또한 평화 주의자 봇을 추가하려고했지만, 나는 두뇌 죽은 봇으로 도전을
피하고

5
몇 가지 빠른 테스트를 기반으로, kamikaze 봇은 크게 변하지 않았습니다. 이것은 라운드에서 다른 봇을 무작위로 제거하는 것입니다. 대량의 토너먼트에서 평균적으로 0에 불과합니다. 그래도 One hot은 깔끔합니다. 그것 없이는 내 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를 계산합니다. 그런 다음 다음 중 하나를 수행합니다.

  • 상대방이 마지막으로 살아있는 사람이라면 HP보다 적은 금액으로 입찰합니다.
  • 상대방이 마지막으로 살아있는 사람이 아니지만 상대방의 체력이 16 마력 미만인 경우 상대방의 체력을 능가합니다.
  • 상대가 마지막 상대가 아니고 동맹의 이력이있는 경우 동맹이 지겨워 hp를 입찰합니다.
  • 그렇지 않으면 상대방을 능가합니다.

역사가 없으면 함께 해킹하여 입찰 한 멋진 계산을 수행합니다. 값이 100을 초과하면 hp에서 1을 뺀 값으로 자동 입찰됩니다.

나는 일하는 동안이 코드를 함께 해킹했으며 이것은 첫 번째 제출물이므로 아마도 이기지 않을 것입니다.

편집 : 몇 가지 제안으로 인해 봇의 시작 동작이 더 높은 값으로 입찰되도록 변경되었습니다.

편집 2 : 아무것도하지 않는 시작 매개 변수 추가

편집 3 : 새로운 스핀 오프 봇 추가 :

[갱봇을 공격하는 로봇에 대한 한심한 시도 (그리고 위의 로봇이하는 모든 일을하는 것)] 제거

[이 봇은 상대가 갱봇인지 아닌지를 분석하고 쉽게 트럼프 할 수있는 달콤한 낮은 입찰을 얻는 척합니다.]

이 로봇은 폐기되었습니다. 리더 보드에서 제거하십시오.

편집 4 : 오류 수정, 타이 기능 변경.


봇 주셔서 감사합니다! 더 얻을 때 몇 가지 통계를 줄 것이다.
KBriggs

나는 파이썬의 초보자이므로 구문이 올바른지 확실하지 않다면, 그 일이 발생하는지 알려주십시오.
Yodie

너무 걱정이, 실행
KBriggs

@Yodie 미니 코드 검토로서 : 함수 본문은 한 수준 씩 들여 써야합니다 (구문 적 필요성). opp_hp +1pythonic 할 공간이 없습니다. 귀하의 의견은 불균형 한 양의 공백으로 시작합니다. 마지막으로 함수에 docstring이 부족합니다.
Jonathan Frech

2
나는이 봇이 1 라운드를 지나면 꽤 잘 작동한다고 생각하지만 많은 사람들이 큰 내기를 걸기 때문에 그는 거의 항상 일찍 죽습니다. 기록이 없을 때 초기 행동을 더 높게 입찰하도록 변경하여 실적을 향상시킬 수 있습니다. 예를 들어, 역사가없는 내기를 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))

좋은. 지금 다른 사람들을 직접적으로
대변

마지막 줄에서 두 번 반환?
Veskah

아아 나는 그것을 아직 실행하지 않았거나 그것을 잡았을 것입니다.
KBriggs

이것은 편안한 리드를 가져 왔습니다!
KBriggs

1
@KBriggs는 여기 백업입니다!
Johan

8

문신 봇

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

tat-for-tat 로봇과 동등한 시도. 대부분의 베팅이 라운드간에 거의 같다고 가정합니다. 이 가정을 사용하여 상당히 검소한 상태로 적 로봇을 이길 수 있습니다. 오프닝 라운드에서 약 40의 체력을 소비합니다.

안티 안티 안티 안티 귀하의 봇

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) 

폴리 봇은 봇 기록에서 다항식 회귀 분석을 수행하며 예상 점수를 약간 상회합니다.

고급 봇

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

고급 봇은 좋은 시간을 보냈지 만 일찍 잠자리에 들기로 결정했습니다. 꽉, 고급 봇.


의견은 긴 토론을위한 것이 아닙니다. 이 대화는 채팅 으로 이동 되었습니다 .
Mego

8

1/2 펀치 봇, 재 방문

나는 그것이 꽤 빨리 죽을 것이라고 생각합니다. 그만한 가치가 있습니다. 이름이 변경된 기능으로 이름을 변경하지 않았습니다.

재 방문 버전이 올라가고, 승리 확률이 높고 (최종 라운드에서 더 많음) 갱봇으로부터의 약간의 보호

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

스트라이커 봇

1/2 펀치 봇은 너무 많은 괴롭힘을 당했으며 심지어 UpYoursBot의 부족이되어 그의 형 StrikerBot 이 도와주었습니다.

최적화 된 1/2 펀치와 큰 차이는 없지만 조금 똑똑하고 내가 한 달리기에서 잘했습니다 (10k 및 35k, KickbanBot에서 잃을 수도 있음)

마지막 버전은 시간이 다되었습니다. 약간의 놀라움이 일어나지 않는 한, 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가 정의되지 않은 것 같습니다.
Jonathan Frech

나는 그것을 실행하기 위해 np.ceil ()로 변경했다
KBriggs 17:06에

편집 해주셔서 감사합니다
Belhenix

7

갱봇

아이디어는 잠재적으로 둘 이상의 봇이 동일한 시뮬레이션에서 사용될 수 있다는 것입니다. 봇은 역사가 7 개의 입찰의 배수인지 확인하여 갱의 다른 봇에게 "쉬운 승리"를 제공하려고합니다. 물론 이것은 다른 봇들도 쉽게 조작 할 수 있습니다. 그런 다음 내 건강 대 건강 비율과 이전 건강 대 이전 입찰의 비율을 기반으로 비 갱단 봇의 입찰에 대한 추측을 계산하고 1을 추가합니다.

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

매우 시원합니다. 몇 개가 필요합니까? 아마도 항목 수를 제한해야 할 것입니다.
KBriggs

코드 블록이 소스의 첫 줄을 놓친 것 같습니다.
Jonathan Frech

시뮬레이션에 몇 명이 필요한지 잘 모르겠지만 봇 중 하나가 서로를 본다면 그들 중 하나가 이길 확률을 높여야합니다. 풀의 10 %가 갱 봇인 것만으로도 큰 차이를 만들 수있을 것으로 생각됩니다. 또한 코드 블록에 첫 번째 줄이 빠져 있습니다.-> 여기에 대한 첫 번째 게시물입니다. 포맷이 왜 그런지 모르지만 그래도 메서드 선언 만 있습니다.
Jim Hat

버그가 있습니다 : 봇은 len (history)> 1을 가진 사람을 갱 멤버로 식별합니다
KBriggs

나의 나쁜, 지금 고쳐야한다.
Jim Hat

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 (1을 올리십시오!) 씩 증가 시키므로을 (를) 초과하여 숫자를 반환하지 마십시오 hp.


if 인 경우 0으로 나누면 실패합니다 alive==8. 수동으로 총 봇 수로 변경할 수는 있지만 규칙에 따라 기능에 대한 입력이 아니기 때문에 규칙을 확장하고 있습니다.
KBriggs

귀하의 요청에 따라 공모전을 업데이트했습니다
KBriggs

@KBriggs 감사합니다 :)
Quintec


@KBriggs 수정, 실제로 0을 반환하지 않도록 +2해야 함, lol
Quintec

6

입찰자

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

봇은 가능한 경우 상대방 입찰 할 수있는 것보다 더 높은 입찰을 시도 합니다.


다음과 같은 경우 조건 where np.random.randint(hp/5, hp/2)이 실패 할 수 있습니다 ( hp/5 == hp/2예 : if hp==0또는hp==1
KBriggs

3
HP가 0이면 호출되지 않아야합니다. : P 당신은 HP 1에 대해 옳습니다.
Draco18s

6

스피트 볼 봇

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

    if value < 10:
        value = 10

    if value >= hp:
        value = hp-1

    return value

남은 봇 수에 따라 건강을 얼마나 희생해야하는지 판단합니다. 봇이 두 개만 남아 있으면 입찰 hp-1하지만, 세 개가 남아 있으면 왼쪽 절반, 네 개 왼쪽, 세 번째 등의 비트가됩니다.

그러나 매우 큰 대회에서는 1 라운드에서 죽지 않기 위해 3 마력 또는 4 마력 이상을 입찰해야하므로 10에 하한선을 두었습니다. 물론 더 이상 입찰하지 않습니다 보다 hp-1.

또한 여러 "타이에 1hp 추가"봇이 있으므로 1.5hp를 추가합니다. 그것이 부정 행위로 간주되는지 확실하지 않습니다. 그렇다면 변경하겠습니다.

그건 그렇고, 좋은 생각입니다!

스피트 볼 봇 2.0

새로운 소식

  • 남은 봇 수 대신 남은 라운드 수로 나누기로 전환했습니다 (@Heiteira에게 감사합니다!). 실제로, 나는 이제 .8입찰을 조금 더 많이로드 하기 위해 power로 올린 숫자로 나누고 있습니다.

  • 최소 입찰가를 10에서 20으로 올렸습니다 (감사 @KBriggs!)

  • 스핏볼 입찰이 상대방의 현재 HP를 초과하는지 여부를 확인하고 삽입 한 경우 낮 춥니 다.

(여기에 텍스트를 넣지 않으면 아래 코드를 코드로 렌더링하지 않으므로 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
입찰은 정수 여야합니다. 따라서 소수를 없애기 위해 기본 값을 바닥에 두거나 as는 한 괜찮습니다
KBriggs

네, 모든 계산을 마친 후 바로 바닥에 올랐습니다. 빠른 답변 감사합니다!
MegaWidget

2
hp를 남은 참가자 수로 나누지 않고 남은 라운드 수 (math.ceil (math.log (alive, 2) 여야 함)로 나눠서 계산할 경우이를 최적화 할 수 있습니다.
Black Owl Kai

1
다른 봇을 기반으로 대부분의 봇은로드 입찰을
앞둔

둘 다 좋은 생각입니다! 나는 봇의 수가 남은 라운드 수와 같지 않다는 것을 몰랐습니다 (처음에는 컨테스트 규칙을 잘못 해석했습니다). 내일 구현해 보겠습니다. 감사!
MegaWidget

5

기하

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

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

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

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

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

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

첫 시도에서 5 위, 전혀 나쁘지 않음
KBriggs

5

봇 13

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

최소한의 노력으로 승리를 극대화하십시오.

  • 우리가 이길 수 있다면 그냥 해
  • 마지막 라운드라면 죽지 마
  • 그렇지 않으면 귀찮게하지 마십시오

왜?

확률을 활용 해보십시오. 토너먼트를 시작하는 가장 좋은 방법은 낮게 플레이하여 첫 라운드를 승리하는 것입니다. 13은 좋은 자리 인 것 같습니다. 두 번째 라운드는 확실한 승리이고 나머지는 공원의 Spaziergang입니다.


당신은 선두를 차지했습니다, 아주 좋은! 리드를 취하는 봇은 UpYoursBot과 같은 대상이되기 때문에 기생충 보호 기능을 추가 할 수 있습니다. 필요한 경우 SarcomaBots에서 보호 아이디어를 확인하십시오.
KBriggs

5

봇 추측

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

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

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

여기에 처음으로 게시하십시오. 이것은 많은 재미처럼 보였으므로 나는 끔찍한 시도를 제출하고 다른 봇이 베팅 할 것을 추측하고 있습니다.

편집 1 : 첫 번째 베팅에 다른 1을 추가하여 단순히 다른 사람들과 베팅하는 51의 가능성을 줄였습니다.

편집 2 : Stole Sarcoma 봇의 오프닝 동작은 처음부터 일관되게 제거되지 않을 가능성이 높기 때문에 시작되었습니다.

편집 3 : 봇은 첫 번째 라운드에서 매우 잘 살아남지 만 나중에 쉽게 파괴됩니다. 로봇이 2 라운드에 대해 생각하는 방식이 바뀌 었습니다.

편집 4 : 이제 첫 번째 라운드가 좋았으므로 두 번째 라운드를 처리하는 방식을 변경했습니다. 두 번째 라운드에서 많이 죽어서 어떻게 든 살아남 아야합니다.

블러드 봇

목숨을 잃은 봇을 만들었습니다. 아이디어는 낮은 베팅 봇에 맞서 싸우는 것입니다. 첫 번째 라운드의 혈통을 지나면 적을 물리 칠 수있는 HP가 필요하기 때문에 막을 수 없습니다.

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

        if alive == 2:
            return hp

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

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

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

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

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

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

2
파이썬에 대한 지식이 정확하다면 len (history) * len (history)는 len (history) ** 2로 변경 될 수 있다고 생각합니다.
Yodie

len (history) == 0
KBriggs

코드가 업데이트되었습니다. 역사를 찾지 못했을 때 그것은 첫 번째로갑니다
Markov Chained

oi .............
Sarcoma

2
@Sarcoma 그것은 거기에 남자의 목구멍 봇 세계입니다!
Markov Chained

5

meh_bot

HP의 절반 이상을 입찰하십시오.

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

    if ties > 1:
        ties += 1

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

    opponent_hp = 100 - sum(history)

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

메봇 20

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

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

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

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

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

mehRan

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

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

정확히이 동작을 이용하기 위해 존재하는 봇이 상당히 많기 때문에 견인력을 얻는 데 어려움을 겪을 수 있습니다!
KBriggs

@KBriggs 약간의 업데이트가 있었지만, 첫 번째 버전이 기대했던 것과는 달리 기대하지 않았지만,이 업데이트가 더 많은 전투 기회를 줄 수 있기를 바랍니다.
meh Man

와우, 그것은 큰 차이를 만들었습니다. 당신이 처음이라고 생각합니다. 몇 분 안에 업데이트가 게시됩니다. 이 작업을 잘 수행하기 위해 봇에게 면역 체계를 제공해야 할 수도 있습니다 (SarcomaBot 참조).
KBriggs

@KBriggs 나는 이것을 잘 할 것으로 기대하지 않았다. 나는 최고 10이 될 것이라고 생각했다. 어쨌든 나는 첫번째 라운드 hp의 효과를보기 위해 다른 것을 추가했다. 둘 다 결과를 볼 수 있도록 둘 다 실행할 수 있습니까? 감사합니다
meh Man

@KBriggs이 작업도 수행하십시오. Muchas gracias
meh Man

4

로비 룰렛

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

이 봇은 적 봇의 역사를 간단히 분석하거나 나머지 적중 지점의 절반을 입찰합니다.


4

경쟁이 적을수록 입찰가가 높아집니다. 개선 제안에 대한 의견 제시 자에게 감사드립니다.

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

1
깔끔한 아이디어이지만 두 가지 문제가 있습니다. 하나는 대부분의 다른 봇이 첫 라운드에서 큰 입찰을하기 때문에 아마도 대부분의 시간에 일찍 죽을 것입니다. 두 번째는 최종적으로 대부분의 봇이 hp-1을 입찰하므로 hp가 두 배가 아니라면 잃어 버릴 것입니다. 그러나 중간 라운드에서는 아이디어가 마음에 듭니다. 두 가지 특별한 경우를 해결하면 성능을 향상시킬 수 있습니다.
KBriggs

4

생존자 봇과 HalvsiesBot

내 질문에 답변 해 주셔서 감사합니다. 최종 결과는 더 복잡한 봇입니다.

HalvsiesBot은 50/50의 승리 확률로 기발한 '반쯤 지나가는'봇입니다. 나는 추측한다.

SurvivalistBot은 넥타이에 대한 재정의를 포함하여 데이터 세트를 기반으로 일련의 이진 트리 if-else 결정을 내립니다 (2 넥타이에 도달하면 트리플 넥타이로 인한 사망을 피하기 위해 kamikazes).

내 파이썬은 조금 녹슬 기 때문에 코드가 약간 버그 일 수 있으므로 수정하거나 업데이트하십시오.

HP가 남은 양, 싸울 가능성이 가장 적은 봇 수, 떠날 최소 HP 수, 평균 입찰과 같은 정보를 추론하기 위해 약간의 데이터를 처리하려고 제작되었습니다. 또한 오프닝 플레이 또는 최적의 입찰 문제와 같은 모호한 상황에서 무작위 배정을 이용합니다.

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


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

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

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


    HP_Difference = hp - Opponent_Remaining_HP

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

    RemainderTree = RemainingBots

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

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

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

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

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

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

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

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

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

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

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


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

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

    else:

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

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

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

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

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

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

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

BoxBot

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

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

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

Opponent_Average_Bid = Opponent_Remaining_HP / float(len(history)) ZeroDivisionError: float division by zero. 이 줄은 길이가 0 인 사건을 처리해야합니다.
KBriggs

고마워, 내가 고칠 게
SSight3

결정된. 다른 오류가 있으면 알려주세요.
SSight3

1
구문 오류의 커플 : 실종`후 else, math.[func] -> np.[func]그리고 한 지점에서 사용 Lowest어디를 의미한다 LowestBid. 모두 github의 컨트롤러에서 수정되었으며 점수가 곧 업데이트되었습니다.
KBriggs

감사. 게시물에서 언급 된 모든 오류를 수정했습니다.
SSight3

4

봇 계산

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 (alive) 라운드가있을 것으로 예상 할 수 있습니다. 이상적으로는 모든 라운드에서 HP를 균등하게 분할합니다. 그러나 우리는 일부 봇이 어리 석고 자살 / 죽을 것이므로 초기 라운드에서 약간 더 내기를해야합니다.

공격적인 계산 봇의 수정의 계산 봇의 코드는 장기적인 건강을 희생시키면서 더욱 공격적으로 살아남 으려고 노력합니다. 템포 나 값이이기는지 시뮬레이션 만 알 수 있습니다.

안티 킥 봇은 항상 현재 리더 킥봇을 이겨야합니다. : P

편집 : 결정적 봇을 거의 동일한 반환 값을 가진 똑똑한 봇 인 Anti Kick Bot으로 대체했습니다. 또한 상대 HP보다 더 많은 투표를 방지


귀엽다. 나는 이것이 큰 봇 풀에서 더 잘할 것이라고 생각합니다.
KBriggs

이 오류가 가끔 발생합니다 : return np.max(theoreticalBet, hp - 1): AxisError: axis 23 is out of bounds for array of dimension 0. 컨트롤러에 대한 링크를 게시하여 테스트 할 수 있습니다.
KBriggs

@KBriggs 코드를 수정하여 수정했습니다.
Bob Cratchit

1
확인, 점수 업데이트 수신. 당신은 확실히 톱 10에 있습니다.
KBriggs 16

@KBriggs 나는 :) 시도 할 수있는 몇 가지 더 봇 추가
밥 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))

정말 늦었습니다. 피곤합니다 ... 이름을 생각할 수 없습니다 ... 그리고이 로봇의 형식은 역사에 따라 약간 다른 알고리즘으로 다른 것과 비슷합니다. 상대방이 도박을하려고하는 현재의 속도를 얻으려고합니다.


당신은 사용할 필요가 np.maximum대신 np.max들어, 같은min
KBriggs

@KBriggs 감사합니다 :) 흠, 그것은 일반적인 봇이이 게임을 지배하는 것 같습니다
Quintec

아주 쉬운 목표물 인 것
같지만

@KBriggs 그래, 놀랐어. 보호 기능 추가시기
Quintec

아직도 neuralbot을 계획하고 계십니까?
KBriggs

4

반감기

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를 균등하게 나누어 경쟁을 통해 진행하려고 시도합니다. 첫 라운드에서 남은 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

이 도전을 너무 좋아하기 때문에 다른 봇을 만들어야했습니다. 이 버전은 처음 두 라운드에서 더 많은 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))

봇 퍼센트

상대방이 소비 한 평균 HP 비율을 계산하고이를 기준으로 입찰합니다.

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

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

        print mean_percent_spend
        print op_hp_now
        print op_next_bid

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

아주 멋진 생각입니다. 첫 번째 라운드를 차지하는 것은 봇의 새로운 트렌드이며 합리적으로 잘 작동하는 것 같습니다.
KBriggs

@KBriggs 두 번째 시도를 포함하도록이 응답을 업데이트했습니다. 새로운 규칙에 따라 귀하를 언급하십시오. 훌륭한 퍼즐 btw!
Wazz

둘 다 최신 버전 만 입력 하시겠습니까? 바로 지금은 V2입니다
KBriggs

@KBriggs 괜찮 으면 둘 다 입력하고 싶습니다. 그들이 서로 어떻게 무게를 측정하는지 보는 것이 좋을 것입니다.
Wazz

전체적으로 비슷한 성능
KBriggs

4

일관된 봇

매 라운드마다 같은 금액을 베팅합니다. 첫 번째 라운드에서 살아남을 가능성은 적지 만 끝까지 갈 수있을 정도로 운이 좋으면 여전히 충분한 양의 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
Kevin

4

킥반 봇

이 봇은 단순히 현재 리더 인 평균 킥봇을 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
나는 당신의 들여 쓰기가 약간 떨어져 있다고 생각합니다.
Jonathan Frech

죄송합니다. 이상한 코드 편집기가 첫 번째 줄을 엉망으로
만들었

제어하지 않는 코드를 신뢰하는 귀중한 교훈
OganM

4

3 쿼터 봇

그는 MehBot 또는 SarcomaBot (s)를 이길 수는 없지만, 그는 꽤 잘한다고 생각합니다. 내가 처음 도전을 보았을 때, 이것이 내 마음에 떠오른 첫 번째 일이었습니다. 이유가 없다면 항상 건강의 3/4을 걸었습니다.

* 1 라운드 로우 볼링 후

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

    if alive == 2:
        return hp - 1

    opponent_hp = 100 - sum(history)

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

    return threeQuarters

네 일곱 번째 봇

3/4 봇이 적당히 성공한 후에는 마을에 새로운 부분이 생겨 났으며 합리적입니다.

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

    if alive == 2:
        return hp - 1

    opponent_hp = 100 - sum(history)

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

    return fourSevenths + ties

완벽한 분수

나는 전체입니다

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

    if alive == 2:
        return hp - 1

    opponent_hp = 100 - sum(history)

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

    return thePerfectFraction + 1 + ties

이 제거 확률에 따라 2 라운드에서 더 작은 입찰가로 벗어날 수도 있습니다. 이것은 잘하지만 약간의 미세 조정으로 훨씬 더 잘 할 수 있습니다.
KBriggs

@KBriggs 새롭고 개선 된 확률로 새로운 봇 추가;)
Joshua Webb

그들 모두 또는 1을 원하십니까?
KBriggs

@KBriggs 당신이 다른 두 분수 봇 제거 할 수 있습니다, 내가 기한을 놓친 나도 몰라,하지만 난 시간에 그것을 만든 경우 나, 마지막으로 봇을 추가 한
여호수아 웹의

1
네, 아직 시간이 있습니다
KBriggs

4

BandaidBot

BandaidBot은 모두가 즐겁게 놀기를 원합니다! 상대가 마지막 라운드에 좋았다면 다른 사람들에게 좋은 행동을 장려하기 위해 스스로 희생 할 것입니다. 상대가 마지막 라운드라면 평균적으로 상대에게 피해를 입히고 필요한 경우 스스로 희생합니다. 작업 기록이없는 경우 hp의 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을 활용하는 데 필요한만큼 훌륭합니다. 적을 죽일 수 없다면 HP의 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가 수정되었습니다!
Maya Sol

@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을 유지하려고 시도하지만, 넥타이를 끊거나 (좋아하는 값을 두 배 또는 네 배로 늘린) 향후 라운드를 위해 저장해야 할 경우 때때로 선택을 변경하지만 혼란을 원하기 때문에 최적의 금액은 아닙니다. 상대방이 1 미만, 즉 0 미만으로 입찰하기를 희망하는 것보다 훨씬 낫다고 확신하기 때문에 언제든지 2 미만의 입찰을 고려하고 싶지 않습니다.

추신 : 봇이 2 ^ 9 개 이상인 경우이 봇에는 전략적 문제가있을 수 있습니다.


2 ^ 9 명의 상대가 ^ _ ^ 인 것에 대해 걱정할 필요가 없습니다.
KBriggs

그러나 오프닝 베팅 10으로, 그는 거의 1 라운드를 넘어 가지 않을 것입니다
KBriggs

이 봇은 일부 봇이 실제로 1 라운드에서 10 마력 이상을주고 싶다면 싸울 가치가 없다고 생각합니다.
AlexRacer

충분히 하하
KBriggs

3

신중한 봇

프로그래밍 퍼즐에 대한 첫 번째 제출! 당신의 도전이 아주 흥미로 웠습니다 : P

마지막 라운드 비트가 hp보다 1이 적 으면, 이력에 베팅에 반 hp를 더한 금액과 작은 임의의 금액이 없습니다.

히스토리가 상대 hp와 남은 라운드 수를 확인하고 남은 hp의 일부를 남은 라운드 수로 나눈 추가 버퍼를 사용하여 상대 hp / 2를 앞당기려고 시도하는 경우 (후반 라운드를 위해 남은 hp를 보존하려고 시도합니다) . 당신이 너무 많은 HP를 소비하고 있는지 확인하십시오 (자신을 죽이거나 적보다 더 많이 입찰하지 마십시오).

다른 봇과 마찬가지로 항상 관계를 수정하십시오.

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

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

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

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

        return int(start_bet + rng_bet + ties)

CautiousBot2

1 라운드에서 너무 공격적이어서 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. buffer는 파이썬의 키워드이므로 다른 변수 이름을 선택할 수 있습니다.
KBriggs

아 버퍼가 항상 정수가 아니기 때문에 보입니다. 어쩌면 어느 시점에서 0으로 나눌 것입니다. 논리를주의 깊게 확인하십시오. 나는 그것을 실행했지만 코너 사례를 해결할 수 있습니다.
KBriggs

@KBriggs의 멋진 캐치. 내가 고쳤다 고 생각해
Jesús Ros 15

여전히 오류가 발생합니다 : 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 inside로 캐스팅됩니다 randint. 통화 전에 캐스트 buff할 경우 작동합니다.int
KBriggs

@KBriggs는 아마도 ceila를 반환 하기 때문 float입니다. 그 중 하나를 놓쳤다 ... 다시 한 번 : P
Jesús Ros

3

좋아, 나는 이것에 손을 시도합니다.

스네 치봇

상대방이 겪고있는 체력의 일부를 확인합니다. 상대방이 키우고 있다면 그를이기십시오.

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
snetch

당신은 그에게서 조금 더 주스를 짜내
KBriggs

3

SquareUpBot

많은 봇이 분수 대신에 힘을 가지고 노는 것처럼 보이지 않았기 때문에 표준 최적화를 사용하여 봇을 만들어서 어디에 배치할지 결정했습니다. 꽤 간단합니다.

또한 power > 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.