Reaper를 해보자-제출 마감


13

참고 :이 대회의 우승자는 Jack !!!입니다. 더 이상 제출이 접수되지 않습니다.

도전을 위한 대화방이 여기 있습니다. 이것은 나의 첫 번째이므로 제안에 개방적입니다!

Reaper는 Art of Problem Solving에서 개발 한 게임 컨셉으로 인내심과 탐욕을 포함합니다. KOTH 스타일 콘테스트에 맞게 게임을 수정 한 후 (제안과 개선을 위해 @NathanMerrill과 @dzaima에게 감사드립니다) 도전은 다음과 같습니다.

이 게임은 다음과 같이 작동합니다. 우리는 Reap으로 알려진 값을 매 틱마다 주어진 상수로 곱합니다. 각 틱 후, 각 봇에는 "리핑"옵션이 있습니다. 즉, 현재 Reap 값을 점수에 더하고 Reap을 1로 줄입니다.

그러나 봇이 "리프"사이에서 기다려야하는 고정 된 틱 수와 게임에서 승리하기 위해 필요한 고정 된 수의 포인트가 있습니다.

충분히 간단합니까? 입력 내용은 다음과 같습니다.

I / O

파이썬 3에서 3 개의 입력을받는 함수를 작성해야합니다. 첫 번째는 self클래스 객체를 참조하는 데 사용됩니다 (나중에 표시). 두 번째는, Reap"수거"할 경우 얻을 수있는 현재 수확량입니다. 세 번째는 prevReap이전 진드기 동안 거둔 봇 목록입니다.

함수에서 액세스 할 수있는 다른 객체 :

self.obj: An object for your use to store information between ticks.
self.mult: The multiplier that Reap is multiplied by each tick
self.win: The score you need to win
self.points: Your current set of points
self.waittime: The amount of ticks that you must wait between reaps during the game
self.time: The number of ticks since your last reap
self.lenBots: The number of bots (including you) in the game.
self.getRandom(): Use to produce a random number between 0 and 1.

를 제외하고 이러한 객체의 내용을 편집 해서는 안됩니다 self.obj.

1수확 하려면 출력해야 하고 수확하지 않으려면 그 밖의 다른 것 (또는 아무것도없는 것)을 출력해야합니다 . 진드기를 충분히 기다리지 않았을 때 수확하면 수확하기로 선택한 사실을 무시합니다.

규칙

내가 사용됩니다 매개 변수는 winning_score=10000, multiplier=1.6-(1.2/(1+sqrt(x))), waittime = floor(1.5*x)어디 xKOTH에서 봇의 수입니다.

  • 플레이어 (또는 복수)가 승리 점수에 도달하면 게임이 종료됩니다.
  • 여러 봇이 한 번에 수확을 요청하면 더 오래 기다린 봇에 우선 순위가 부여됩니다 (동점의 경우 최대 시간을 기다린 봇은 모두 수확 할 수 있으며 Reap에서 점수를 얻습니다)
  • 봇은 5 틱에 걸쳐 평균 100ms를 넘지 않아야합니다.
  • 라이브러리를 가져 오려면 물어보십시오! 데스크톱 버전의 Python에서 실행할 수있는 라이브러리를 추가하려고합니다 (수학은 이미 가져 왔습니다 : 자유롭게 사용하십시오)
  • 중복 봇, 1- 업 봇 등과 같은 KoTH의 모든 표준 허점은 유사하게 금지됩니다.
  • 임의의 종류의 임의성을 사용하는 모든 봇은 getRandom내가 제공 한 기능을 사용해야합니다 .

아래의 TIO 링크에서 컨트롤러를 찾을 수 있습니다. 사용하려면 함수 이름을 BotList문자열로 추가 한 다음 함수를 코드에 추가하십시오. 수정 multiplier, 수정 무엇 각 틱을 곱 심 변경할 winning_score게임을 종료 할 필요가 점수 무엇을 변경, 수정 waittime거둔다 사이에 대기 틱의 수를 변경할 수 있습니다.

귀하의 편의를 위해 다음은 샘플 봇입니다. 이와 유사한 봇을 제출하는 것은 허용되지 않습니다. 그러나 컨트롤러 작동 방식을 보여줍니다.

def Greedybot(self,Reap, prevReap):
    return 1
def Randombot(self,Reap, prevReap):
    if self.obj == None:
        self.obj=[]
    self.obj.append(prevReap)
    if self.getRandom()>0.5:
        return 1

관심있는 분들을 위해 15 개의 제출물이 내장 된 컨트롤러는 다음과 같습니다. 온라인 사용해보기

최종 결과

우와 그들은 마침내 여기에 있습니다! 최종 순위를 생성하는 데 사용한 코드를 확인하려면 위의 TIO 링크를 확인하십시오. 결과는별로 흥미롭지 않습니다. 다른 무작위 씨앗으로 1000 회 이상 실행 한 결과는

1000 wins - Jack
0 wins - everyone else

바운티 수상자 Jack에게 축하드립니다! (일명 @ 렌제)


두 개의 봇이 동시에 수확되고 대기 시간이 가장 긴 봇이 승리한다고 가정 해 봅시다. 다른 봇도 기본적으로 '수확'을 낭비하면서 이번 라운드에서 실제로 수확 할 수 없었음에도 불구하고 대기 시간이 활성화됩니까? 그리고 두 대기 시간이 같은 대기 시간으로 두 봇이 동시에 수확되면 어떻게됩니까?
Kevin Cruijssen

1
사용할 수 len(BotList)있습니까?
Renzeee

1
@Renzeee Ooo는 그것에 대해 생각하지 않았습니다! 빠른 수정을하겠습니다.
Don Thousand

1
@Renzeee 오, 그것은 확실히 고려해야 할 유용한 것입니다. 두 번째 봇을 내 모든 50과 비슷하게 만들 수 있지만, 봇 자체를 기반으로 한 설명 대신 봇 자체에서 실제 계산을 수행 할 수 25있습니다. 그러나 먼저 다른 사람들의 봇을 보자. Rushabh Mehta , 모든 봇이 운영되고 승자가 결정될 때 마감일 / 마지막 날짜가 있습니까?
Kevin Cruijssen

1
@Rushabh Mehta Gotcha는 삼가겠습니다. 나는 방금 b / c에게 다른 봇의 점수와 대기 시간을 독립적으로 추적하여 도청하기를 요청했으며 게으르다. :)
트리거 노메 트리

답변:


9

결백 한 속임수

def mess(self, Reap, prevReap):
    if not hasattr(self.obj, "start"):
            self.obj.start = False
    if self.time < self.waittime:
        return 0
    if self.points + Reap >= self.win:
            return 1
    if Reap >= self.waittime / (self.lenBots + 2):
        self.obj.start = True
    if self.obj.start:
        return 1 if self.getRandom() > 0.2 else 0
    return 1 if self.getRandom() > 0.8 else 0

이 봇은 일반적인 점검 (먼저 거둘 수 있습니까, 이길 수 있습니까?)을 수행 한 다음 목표 값을 찾아서 거두기 전에 봅니다. 그러나 결정적이지 않기 때문에 목표에 도달 한 후 얼마나 오래 기다릴 수 있을지 궁금해하며 즉시 거두지 않습니다. 또한, 그것은 엉망이어서 실수로 "버튼을 쳐서"타겟보다 앞서 나올 수 있습니다.

재미있는 사실 : 이것은 기본적으로 내가 인간으로서 사신을하는 방법입니다.


좋은 봇 +1. 조금 더 자세히 살펴 보겠습니다. 아직 채팅하지 않았다면 채팅에 참여하세요
Don Thousand

@RushabhMehta 이제는 덜 부정확하다; p
Quintec

가능하면 변경 사항을 추가하겠습니다.
Don Thousand

9

저격병

침을 뱉은 봇. 상대의 쿨 다운과 점수를 추적합니다. 다른 사람들이 이기지 못하도록 시도합니다. 실제로 실제로이기는 것은 아니지만 다른 사람들을 위해 게임을하는 것은 좌절합니다.

편집하다:

  • 거두는 것이 승리를 거두면 거두십시오.
  • 아무도 승리 점수의 70 %를 초과하지 않는 경우 :

    • 다른 사람이 모두 재사용 대기 중이면 마지막 순간까지 기다립니다.
    • 다른 사람이 현재 가치를 거두어 이기고 현재 활성화되어 있거나 다음 턴에 활성화되면
    • 다른 사용자의 절반 이상이 휴지 상태 인 경우 다시 시도하십시오. 이로 인해 특정 상대를 타겟팅하기가 어려워 제거되었습니다.
    • 그렇지 않으면, 25 %의 시간을 거두십시오 (본질적으로 모든 사람이 몇 차례를 기다리는 것처럼 이상한 일이 발생할 경우를 대비하여이 봇이 때때로 수시를 거두도록 보장하기 위해).
  • 누군가가이기는 점수의 70 % 이상인 경우 :

    • 스나이퍼가 순위 결정을 이길 수 있고 다음 라운드가 최고 득점 상대의 평균 수확량 값보다 높을 경우, 수확
    • 가장 높은 점수를 얻은 상대가 다음 턴에 재사용 대기 시간을 남길 경우 거두십시오.
def Sniper(self, Reap, prevReap):
    # initialize opponents array
    if not hasattr(self.obj, "opponents"):
        self.obj.opponents = {}

    # initialize previous Reap value
    if not hasattr(self.obj, "lastReap"):
        self.obj.lastReap = 0

    # increment all stored wait times to see who will be "active" this turn
    for opponent in self.obj.opponents:
        self.obj.opponents[opponent]["time"] += 1

    # update opponents array
    for opponent in prevReap:
        # don't track yourself, since you're not an opponent
        if opponent != "Sniper":
            # initialize opponent
            if opponent not in self.obj.opponents:
                self.obj.opponents[opponent] = {"time": 0, "points": 0, "num_reaps": 0, "avg": 0}
            self.obj.opponents[opponent]["time"] = 0
            self.obj.opponents[opponent]["points"] += self.obj.lastReap
            self.obj.opponents[opponent]["num_reaps"] += 1
            self.obj.opponents[opponent]["avg"] = self.obj.opponents[opponent]["points"] / self.obj.opponents[opponent]["num_reaps"]

    # done "assigning" points for last round, update lastReap
    self.obj.lastReap = Reap

    # get current 1st place(s) (excluding yourself)
    winner = "" if len(self.obj.opponents) == 0 else max(self.obj.opponents, key=lambda opponent:self.obj.opponents[opponent]["points"])

    # you are ready now
    if self.time >= self.waittime:
        # current Reap is sufficient for you to win
        if self.points + Reap >= self.win:
            return 1

        if (
                # a 1st place exists
                winner != ''
                # if current 1st place is close to winning
                and self.obj.opponents[winner]["points"] / self.win >= .7
        ):
            if (
                    # next round's Reap value will be above opponent's average Reap
                    (Reap * self.mult >= self.obj.opponents[winner]["avg"])
                    # we have been waiting at least as long as our opponent (tiebreaker)
                    and self.time >= self.obj.opponents[winner]["time"]
            ):
                return 1

                # current 1st place opponent will be active next round
            if self.obj.opponents[winner]["time"] + 1 >= self.waittime:
                return 1

        else:
            if (
                    # everyone is waiting for their cooldown
                    all(values["time"] < self.waittime for key, values in self.obj.opponents.items())
                    # and we're tracking ALL opponents
                    and len(self.obj.opponents) == self.lenBots - 1
                    # at least one person will be ready next turn
                    and any(values["time"] + 1 >= self.waittime for key, values in self.obj.opponents.items())
            ):
                return 1

            if (
                    # opponent will be active next round
                    any( (values["time"] + 1 >= self.waittime)
                         # current Reap value would allow opponent to win
                         and (values["points"] + Reap >= self.win) for key, values in self.obj.opponents.items())
            ):
                return 1

            if (
                    # a 1st place exists
                    winner != ''
                    # current 1st place opponent will be active next round
                    and (self.obj.opponents[winner]["time"] + 1 >= self.waittime)
                    # next round's Reap value will be above their average Reap
                    and (Reap * self.mult >= self.obj.opponents[winner]["avg"])

            ):
                return 1

            # # at least half of opponents are waiting for their cooldown
            # if sum(values["time"] < self.waittime for key, values in self.obj.opponents.items()) >= (self.lenBots - 1) / 2:
            #     return 1

            # 25% of the time
            if self.getRandom() <= .25:
                return 1

    # default return: do not snipe
    return 0

지루한

재미로,이 봇은 친구가 가져 왔고 실제로 여기에 있고 싶지 않습니다. 그들은 1-9에서 숫자를 얻을 때까지 d16을 굴린 다음 숫자에 선택한 숫자가 포함될 때마다 다시 시도합니다. (d10을 찾으러 가면 무례한 게임이 중단되고 0은 너무 쉽습니다!)

def Bored(self, Reap, prevReap):
    # if this is the first round, determine your fav number
    if not hasattr(self.obj, "fav_int"):
        r = 0

        while r == 0:
            # 4 bits are required to code 1-9 (0b1001)
            for i in range(0, 4):
                # flip a coin. Puts a 1 in this bit place 50% of the time
                if self.getRandom() >= .50:
                    r += 2**i
            # if your random bit assigning has produced a number outside the range 1-9, try again
            if not (0 < r < 10):
                r = 0

        self.obj.fav_int = r

    # you are ready now
    if self.time >= self.waittime:
        # current Reap is sufficient for you to win
        if self.points + Reap >= self.win:
            return 1
        # do you like this value?
        if str(self.obj.fav_int) in str(Reap):
            return 1
        # do you like your wait time?
        if self.time % int(self.obj.fav_int) == 0:
            return 1

    # default return: do not reap
    return 0

좋은 봇! +1. 이것이 어떻게되는지 보는 것이 흥미로울 것입니다.
Don Thousand

1
self.obj.opponents[opponent]["time"] += 1첫 번째 for-loop와 self.obj.lastReap두 번째 for-loop의 끝에 사용해야한다고 생각합니다 . 그 외에도 좋은 아이디어. 나는 그것이 다른 많은 봇에 대해 어떻게 작동하는지 궁금합니다. 욕심 많고 무작위적인 봇을 많이 사용하는 경우 봇의 절반이 수확 할 수 없기 때문에 최대한 빨리 거둘 것입니다. 그러나 물론 이들은 현실적인 경쟁자가 아닙니다.
Renzeee

@Triggernometry 채팅에 참여해야합니다. 또한 내가 게시 한 수정 사항을 확인하십시오. 내가 봇에서 변경 한 내용이 올바른지 확인하십시오.
Don Thousand

7

이것은 4 가지 규칙을 가진 간단한 봇입니다 :

  • 아무것도하지 않을 때 거두지 마십시오
  • 거둘 때 항상 거두어 승리
  • 3 틱 동안 수확하지 않은 경우에도 수확
  • 그렇지 않으면 아무것도 하지마

현재 기존 봇 (스나이퍼, grim_reaper, Every50, 엉망, BetterRandom, Averager 등)에 비해 3 개의 진드기를 최적화했습니다.

def Jack(self, Reap, prevReap):
    if self.time < self.waittime:
        return 0
    if self.win - self.points < Reap:
        return 1
    if self.mult ** 3 <= Reap:
        return 1
    return 0

나는 오래된 해결책 (5 틱)을 유지하려고 노력했지만 X 틱보다 더 오랫동안 수확하지 않은 경우 수확하고 비 낫는 동안 적은 틱이 지나간 후에 수확합니다 (예 : 자기보다 오래 기다린 경우 5) .waittime + 5, 4 틱 동안 거두지 않으면 거둔다). 그러나 이것은 항상 5 대신 4 틱 후에 수확하는 것이 향상되지 않았습니다.


5

매 50

이 봇은 Reap금액이 50을 초과 할 때마다 거두게됩니다 .

왜 50?

제가 25 개의 봇을 플레이 할 것이라고 가정하면, 그리고을 의미 multiplier = 1.6-(1.2/(1+sqrt(25))) = 1.4합니다 waittime = floor(1.5*25) = 37. 에서 Reap시작한 후 1다음과 같이 올라갑니다.

Round: 1  2    3     4      5      6      7      8       9       10      11      12      13      14      15       16       17       18       19       20       etc.
Reap:  1  1.4  1.96  2.744  ~3.84  ~5.39  ~7.53  ~10.54  ~14.76  ~20.66  ~28.92  ~40.50  ~56.69  ~79.37  ~111.12  ~155.57  ~217.79  ~304.91  ~426.88  ~597.63  etc.

보시다시피 13 틱 후 50 이상에 도달합니다. 는 이후 Reap봇이 거둔다 일에 모든 시간을 재설정하고, waittime거둔다 37, 봇이 거둔다 조만간 가능성 것을 봇에 대한, 특히 예와 유사 봇으로 꽤 높은 GreedyBot그들의 즉시 얻을 것이다, waittimeIS 다시 사용할 수 있습니다. 처음에 나는 17 개의 틱인 200을하고 싶었다. 37 개의 틱 타임 틱 중간에 다소 있지만, 25 개의 봇이 있다는 가정하에 누군가 다른 사람이 내 Reap앞에 몰려 올 가능성이 매우 높다 . 그래서 나는 그것을 50으로 낮췄습니다. 그것은 여전히 ​​좋은 반올림 숫자입니다. 그러나 특히 그것은 13 번째 틱 (25 봇 포함)이고 13과 '리핑'도 같은 '악'장르에 약간 맞기 때문입니다.

암호:

이 코드는 웃기만하다 ..

def Every50(self, Reap, prevReap):
  return int(Reap > 50)

노트:

이 봇은 플레이중인 봇 수가 적어서 매우 나쁩니다. 지금은 그대로두고 더 나은 봇을 실제로 가장 좋은 시간으로 계산할 수 Reap있습니다. 극도로 적은 수의 봇을 사용하면 waittime물론 훨씬 낮습니다. 따라서 충분히 낮 으면 GreedyBot이 봇에서 쉽게 이길 수 있습니다 waittime.

더 많은 사람들이 더 많은 봇을 추가하기를 바랍니다. ;피


def Every49(self, Reap, prevReap): return Reap > 49 당신의 움직임.
Quintec

@Quintec Hehe. 25 개의 봇이 플레이되면 여전히 13 번째 틱이며 우리는 모두 Reap을 이깁니다. ; p
Kevin Cruijssen

int1은 실제 명령이기 때문에 불평등을 피하고 싶을 수도 있습니다
Don Thousand

@Quintec 난 농담을 알고 있지만 1 업 또는 중복 봇은 허용하지 않습니다
Don Thousand

@RushabhMehta 나는 파이썬으로 자주 프로그래밍하지 않기 때문에 이미 True명시 적으로 캐스팅을 추가 해야하는지 의심하고있었습니다 1. 생각 True == 1검사는 여전히 반환 True의 목록에 추가 내 봇에 대한 Reapers당신의 next기능,하지만 당신은 제안 어쨌든 INT로 캐스팅을 추가했습니다.
Kevin Cruijssen

5

평균 기

def Averager(self,Reap,prevReap):
    returner = 0
    if not hasattr(self.obj,"last"):
        self.obj.last = Reap
        self.obj.total = 0
        self.obj.count = 0
        returner = 1
    else:
        if len(prevReap) > 0:
            self.obj.total += self.obj.last
            self.obj.count += 1
        self.obj.last = Reap
    if self.obj.count > 0 and Reap > self.obj.total / self.obj.count:
        returner = 1
    return returner

이 봇은 현재 수확 값이 평균 수확 값을 초과 할 때마다 수확하려고합니다.


아주 좋은 봇! +1
Don Thousand

나는 그런 간단한 알고리즘이 모든 사람을 너무나 능가한다는 매우 짜증나고 감동했습니다. 잘 했어!
Triggernometry

3

저승 사자

이 봇은 각 봇이 대기 한 시간뿐만 아니라 이전의 모든 수확량의 평균 값을 유지합니다. 다른 봇의 3/4보다 오래 기다렸을 때 거두게되며, 거두는 지금까지 본 평균 거두의 크기의 3/4 이상입니다. 목표는 합리적으로 규모가 작고 위험이 낮은 결과를 얻는 것입니다.

def grim_reaper(self, Reap, prevReap):
    if self.obj == None:
        self.obj = {}
        self.obj["reaps"] = []
        self.obj["prev"] = 1
        self.obj["players"] = {i:0 for i in range(math.ceil(self.waittime / 1.5))}
    if Reap == 1 and len(prevReap) > 0:
        self.obj["reaps"].append(self.obj["prev"])
        for player in prevReap:
            self.obj["players"][player] = 0

    retvalue = 0
    if (len(self.obj["reaps"]) > 0 
         and Reap > sum(self.obj["reaps"]) / len(self.obj["reaps"]) * 3. / 4.
         and sum([self.time >= i for i in self.obj["players"].values()]) >= len(self.obj["players"].values()) * 3 / 4):
        retvalue = 1

    for player in self.obj["players"]:
        self.obj["players"][player] += 1
    self.obj["prev"] = Reap
    return retvalue

편집 : 일부 난처한 구문 오류가 수정되었습니다.

온라인으로 사용해보십시오


1
당신은 사용해야 self.obj.reaps대신 self.reapsself.obj대신 self.objectprevReap대신 prevLeap과 후 () 추가 self.obj.players.values를 두 번 누릅니다. 그리고 나는 객체가 self.obj.reaps = []아니면 작동하지 않을 것이라고 생각 self.obj합니다. 모든 것이 여전히 의도 한대로 작동하는지, 내가 말한 모든 것이 사실인지는 확실하지 않지만, 이러한 변경 후에 더미 객체를 사용하여 self.obj존재하지 않을 때 코드를 컴파일합니다.
Renzeee

@ZacharyColton 수학을 가져올 필요는 없습니다. 그것은 이미 수입
돈 천 1

@RushabhMehta 상단 에 class Object(object):[newline] pass을 추가 self.obj = Object()하고 if not hasattr(..)(정확하게 기억하는 경우)에 사용했습니다.
Renzeee

@Renzeee aha ic
Don Thousand

@ZacharyCotton 채팅에 참여해야합니다.
Don Thousand

3

BetterRandom

def BetterRandom(self,reap,prevReap):
    return self.getRandom()>(reap/self.mult**self.waittime)**-0.810192835

봇은 획득 시점에 관계없이 포인트가 포인트이기 때문에 수확 기회가 수확량에 비례해야한다는 가정을 기반으로합니다. 항상 얻을 수있는 기회는 아주 적습니다. 이렇게하면 행동을 악용 할 수 있습니다. 먼저 1/mult^waittime시뮬레이션에 직접 비례한다고 생각하고 일부 상수를 실행 한 후 비례 상수가 (최소 한 봇이 욕심이 있다고 가정 할 때 최대 수확량) 있다고 가정했습니다. 이것은 실제로 최적의 상수라는 것을 알았습니다. 그러나 봇은 여전히 ​​랜덤보다 성능이 뛰어 났으므로 관계가 직접 비례하지 않고 관계를 계산하기 위해 상수를 추가했습니다. 몇 가지 시뮬레이션을 한 후에 테스트 봇 세트 -1.5가 최적 이라는 것을 알았습니다 . 이것은 실제로 수확 확률과 수익률 간의 반비례 관계에 해당합니다.reap*sqrt(reap)놀랍습니다. 그래서 나는 이것이 특정 봇에 크게 의존한다고 생각하므로 재생하는 동안 k를 계산하는이 봇의 버전이 더 좋을 것입니다. (그러나 이전 라운드의 데이터를 사용할 수 있는지는 모르겠습니다).

편집 : 비례의 종류를 자동으로 찾는 프로그램을 만들었습니다. 테스트 세트 ["myBot("+str(k)+")","Randombot","Greedybot","Every50","Jack","grim_reaper","Averager","mess"]에서 새로운 값을 찾았습니다.


곧 봇을 사용하여 새로운 통계를 추가
Don Thousand

1
것 같습니다 (reap/self.mult**self.waittime)**-0.810192835즉 self.getRandom ()가 결코 높은없고, 항상 1 위입니다.
Renzeee

@fejfo 당신은 또한 이전 라운드의 데이터를 사용할 수 있습니다. 그게 다야 self.obj. 사용 방법에 대한 몇 가지 예를 보려면 사용중인 다른 봇을 살펴보십시오.
Don Thousand

3

표적

def target(self,Reap,prevReap):
    if not hasattr(self.obj, "target_time"):
        self.obj.target_time = -1
        self.obj.targeting = False
        self.obj.target = None
    if self.obj.target_time >= 0:
        self.obj.target_time += 1

    if self.time < self.waittime:
            return 0
    if self.points + Reap >= self.win:
        return 1
    if len(prevReap) > 0:
        if not self.obj.targeting:
            self.obj.target_time = 0
            self.obj.target = prevReap[int(self.getRandom() * len(prevReap))]
            self.obj.targeting = True
    if self.waittime <= self.obj.target_time + 1:
        self.obj.targeting = False
        self.obj.target = None
        self.obj.target_time = -1
        return 1
    return 0

엉망으로 이길 수있는 기회는 거의 없었으므로 가능한 한 많은 방법으로 다른 모든 봇을 엉망으로 만들 시간입니다! :)

이 봇은 저격 기와 비슷한 기능을합니다. 누군가가 거둘 때마다, 거둔 사람에게서 무작위 대상을 선택합니다. 그런 다음 대상이 거의 다시 거두어 질 때까지 기다립니다. 그러나 초점이 바뀌지 않습니다. 일단 선택하고 잠그면 탈출 할 수 없습니다 :)


2

EveryN

마감 시간 직전에 두 번째 봇을위한 시간 인 것 같습니다.

이 봇은 :

  • 마지막 수확을 기다리는 시간이 아직 지나면 건너 뛰기
  • 이길 수있을 때 거두다
  • 아무도 적어도에 대한 수확하지 않을 때 수확 n라운드 곳 n으로 계산n = 3 + ceil(self.waittime / self.lenBots)

암호:

def every_n(self, Reap, prevReap):
    # Initialize obj fields
    if not hasattr(self.obj, "roundsWithoutReaps"):
        self.obj.roundsWithoutReaps = 0

    # Increase the roundsWithoutReaps if no bots reaped last round
    if len(prevReap) < 1:
        self.obj.roundsWithoutReaps += 1
    else
        self.obj.roundsWithoutReaps = 0

    # Skip if you're still in your waiting time
    if self.time < self.waittime:
        return 0
    # Reap if you can win
    if self.win - self.points < Reap:
        return 1

    # i.e. 25 bots: 3 + ceil(37 / 25) = 5
    n = 3 + math.ceil(self.waittime / self.lenBots)

    # Only reap when no bots have reaped for at least `n` rounds
    if self.obj.roundsWithoutReaps >= n:
        self.obj.roundsWithoutReaps = 0
        return 1

    return 0

나는 파이썬으로 자주 프로그래밍하지 않으므로 실수가 있으면 알려주십시오.


거룩한 긴 변수 이름. (또한 PEP : python.org/dev/peps/pep-0008 )
Quintec

@Quintec 2 칸 들여 쓰기를 4로 변경했습니다. 단축 subsequentRoundsWithoutReaps한다 roundsWithoutReaps; 메소드 이름에 밑줄과 함께 소문자를 사용했습니다. if 문에서 괄호를 제거했습니다. 감사.
Kevin Cruijssen

문제 없어요! (기술적으로 rounds_without_reaps 여야하지만,이 문제는 mixedCamelCase를 사용하므로 실제로 문제가되지 않기 때문에 실제로 문제가되지는 않습니다)
Quintec

@Quintec 아 알았어. 나는 보았다 prevReaplenBots및 및 가정 변수 자바처럼 낙타 표기법이다. ;) 아, 우리가 어떤 경우를 사용하더라도 어쨌든 작동합니다. 4 개의 들여 쓰기 된 공간 대신 ​​2는 아마도 몇 가지 문제를 일으켰을 것입니다.
Kevin Cruijssen

2

진행 중 : 공개 프로젝트마다 T4T를 확장하는 프로젝트.

문신에 대한 젖꼭지

def t4t(self, r, p):
    if(not hasattr(self.obj,"last")): self.obj.last = self.win
    if(p):
        self.obj.last = r
        return 0

    # The usual checks
    if self.time < self.waittime:
        return 0
    if self.points + r >= self.win:
        return 1

    if(r >= self.obj.last):
        return 1

N Tats에 대한 젖꼭지

def t4nt(self, r, p):
    n = 5 # Subject to change
    if(not hasattr(self.obj,"last")): self.obj.last = [self.win]*n

    if(p):
        self.obj.last.append(r)
        self.obj.last.pop(0)
        return 0

    # The usual checks
    if(self.time < self.waittime):
        return 0
    if(self.points + r >= self.win):
        return 1

    if(r >= self.obj.last[0]):
        return 1

케빈

발끝에 눕히기 위해서

def kevin(just, a, joke):
    return 0

기억하십시오, self.last물건은 아니지만, 물건을 만들 수 있습니다 self.obj.last!. 어쨌든, 나는 밈에 대한 세 가지 봇을 모두 추가합니다 +1
Don Thousand

그래, 난 바보 야 결정된.
SIGSTACKFAULT

@RushabhMehta 그냥 가서 실제로 작동하게 만들었습니다. pls는 편집합니다.
SIGSTACKFAULT

좋은 소리! GC의에 참여, 나는 거기에 약간의 부분적인 결과를 게시합니다
돈 천

1

평범한 사람

나는 Averager에서 영감을 얻어 누군가가 수확하기 전에 걸리는 평균 턴 수를 계산하고 그 전에 한 턴을 시도하는 봇을 만들었습니다.

def average_joe(self, Reap, prevReap):

    if not hasattr(self.obj, "average_turns"):
        self.obj.turns_since_reap = 1
        self.obj.total_turns = 0
        self.obj.total_reaps = 0
        return 1

    if len(prevReap) > 0:
        self.obj.total_turns = self.obj.total_turns + self.obj.turns_since_reap
        self.obj.total_reaps += 1
        self.obj.turns_since_reap = 0
    else:
        self.obj.turns_since_reap += 1

    # Don't reap if you are in cooldown
    if self.time < self.waittime:
        return 0

    # Reap if you are going to win
    if self.win - self.points < Reap:
        return 1

    # Reap if it is one turn before average
    average_turns = self.obj.total_turns / self.obj.total_reaps

    if average_turns - 1 >= self.obj.turns_since_reap:
        return 1
    else:
        return 0

내일에 추가하겠습니다.
Don Thousand

1

하드 코딩

그렇습니다.

def HardCo(self,reap,prevReap):
    return reap > 2

과거의 결과를 평균화하는 대신 일반적인 실행에서 사전 계산 된 평균을 사용하십시오. 어쨌든 시간이 지나면 나아지지 않을 것입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.