Reaperをプレイしましょう-投稿は締め切りました


13

:このコンテストの勝者はJack !!!です。これ以上の提出は受け付けられません。

ここに、この挑戦のためのチャットルームがあります。これは私の最初のものですので、私は提案を受け入れています!

死神は、忍耐と欲を含む問題解決の技術によって開発されたゲームのコンセプトです。KOTHスタイルのコンテストに合うようにゲームを修正した後(提案と改善について@NathanMerrillと@dzaimaに感謝します)、ここに課題があります。

ゲームは次のように機能します。ティックごとに特定の定数で乗算するReapと呼ばれる値があります。各ティックの後、各ボットには「リーピング」オプションがあります。つまり、Reapの現在の値をスコアに追加し、Reapを1に減らします。

ただし、ボットが「リープ」の間に待機しなければならない固定数のティックと、ゲームに勝つために必要な固定数のポイントがあります。

簡単ですか?入力は次のとおりです。

I / O

Python 3で3つの入力を取る関数を作成します。1つはself、クラスオブジェクトの参照に使用されます(後述)。2つ目は、Reap「刈り取る」場合に獲得する刈り取りの現在の値です。3つ目は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=10000multiplier=1.6-(1.2/(1+sqrt(x)))waittime = floor(1.5*x)ここでxケートにおけるボットの数です。

  • プレイヤー(または複数)が勝利スコアに達すると、ゲームは終了します。
  • 複数のボットが一度に刈り取りを要求すると、より長く待機したボットに優先順位が与えられます(同数の場合、最大時間待機したボットはすべて刈り取りでポイントを獲得できます)
  • ボットは、5ティックにわたって平均で100ミリ秒以内である必要があります。
  • ライブラリをインポートする場合は、お問い合わせください!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

バウンティ勝者のジャック、おめでとうございます!! (別名@Renzeee)


たとえば、2つのボットが同時に刈り取られ、待機時間が最も長いボットが勝ったとします。他のボットも、このラウンドを実際に刈り取ることができず、基本的に「刈り取り」を無駄にしたにもかかわらず、待機時間を有効にしますか?また、2つのボットが同じ待機時間で同時に刈り取るとどうなりますか?
ケビンクルーッセン

1
使用は許可されていますlen(BotList)か?
レンジー

1
@Renzeee Oooはそれについて考えませんでした!簡単に修正します。
ドンサウザンド

1
@Renzeeeああ、それは確かに考慮に値するものです。Every 50に似た2番目のボットを作成する場合がありますが、25プレイ中のボットに基づいて説明で行ったのではなく、ボット自体で実際の計算を行います。ただし、最初に他の人のボットを見るのも少し待ちます。Rushabh Mehta、すべてのボットが実行され、勝者が決定される期限/最終日はありますか?
ケビンクルーッセン

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。少し詳しく見ていきます。uが持ちでない場合はチャットに参加
ドン・サウザンド・

少ない優柔不断と@RushabhMehta今; P
Quintec

可能な場合は変更を追加します!
ドンサウザンド

9

スナイパー

悪意に満ちたボット。対戦相手のクールダウンとスコアを追跡します。他の人が勝てないようにします。実際に勝つことはほとんどありませんが、他の人のためにプレイするのはイライラさせられます。

編集:

  • 刈り取ると勝つ場合は、刈り取る。
  • 誰も勝者スコアの70%以上でない場合:

    • 他の全員がクールダウン中の場合は、最後の可能な瞬間が来るまで待ってください。
    • 他の誰かが現在の値を獲得することで勝ち、それらが現在アクティブであるか、次のターンでアクティブになる場合、獲得します。
    • 他のユーザーの少なくとも半分がクールダウン中の場合は、刈り取りを試みてください。 これにより、特定の相手をターゲットにすることが難しくなり、削除されました。
    • それ以外の場合は、25%の時間を獲得します(基本的に、誰もが数ターン待っているような奇妙なことが起こった場合に備えて、このボットがSOMETIMESを獲得することを保証します)。
  • 誰かが勝利スコアの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。これがどのように行われるかを見るのは面白いでしょう。
ドンサウザンド

1
self.obj.opponents[opponent]["time"] += 1最初のforループとself.obj.lastReap2番目のforループの最後で使用する必要があると思います。それに加えて、素晴らしいアイデア。他の多くのボットに対してどのように機能するか興味があります。欲張りでランダムなボットを多く使用している場合、ほとんどの場合、半分のボットは刈り取ることができないため、できるだけ早く刈り取ることになります。しかし、もちろんそれらは現実的な競合他社ではありません。
レンジー

@Triggernometryチャットに参加する必要があります。また、投稿した編集内容も確認してください。ボットに加えた変更が正しいことを確認してください。
ドンサウザンド

7

ジャック

これは4つのルールを持つ単純なボットです。

  • 何もしないときに刈り取らないでください
  • 刈り取りが勝つときは常に刈り取る
  • また、3ティックの収穫がない場合に刈り取る
  • そうでなければ何もしない

現在の既存のボット(Sniper、grim_reaper、Every50、mess、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を超えています。以来Reap1にボットを刈り取るたびにリセットされ、かつます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十分に低いです。

より多くの人がもっと多くのボットを追加することを願っています。; p


def Every49(self, Reap, prevReap): return Reap > 49 あなたの動き。
Quintec

@Quintec Hehe。25個のボットがプレイされているということは、まだ13番目のティックであり、私たち2人ともReapに勝っているということです。; p
ケビンクルーッセン

あなたは置きたいかもしれないint1が本当のコマンドであることから、不平等を中心に
ドン・サウザンド・

私は認識してウルの冗談だけど、私は1アップまたは重複ボット許可されません@Quintec
ドン・サウザンド・

@RushabhMehta私はPythonでプログラミングすることはあまりないので、キャストを追加してTrue明示的にする必要があるかどうかはすでに疑っていました1。私のボットがTrue == 1チェックを関数のTrueリストに追加するためにチェックがまだ戻ると考えましたがReapers、あなたnextが提案したようにキャストをintに追加しました。
ケビンクルーッセン

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
ドンサウザンド

私はこのような単純なアルゴリズムが誰よりも便利であることに非常に腹を立て、感銘を受けました。よくやった!
トリガー測定

3

死神

このボットは、以前のすべてのリープの値と各ボットが待機していた時間の移動平均を保持します。他のボットの4分の3より長く待機しているときに刈り取りが行われ、これまでに見られた平均刈り取りのサイズの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.reapsandのself.obj代わりにself.objectandのprevReap代わりに使用prevLeapし、()をself.obj.players.values2回追加する必要があります。そして、オブジェクトでself.obj.reaps = []ない限り機能しないと思いself.objます。すべてが意図したとおりに機能するかどうか、また、私が言ったことがすべて正しいかどうかは完全にはわかりませんが、これらの変更の後、self.objまだ存在しない場合にダミーオブジェクトを使用すると、コードがコンパイルされます。
レンジー

@ZacharyColton数学をインポートする必要はありません。すでにインポートされています
ドンサウザンド

@RushabhMehta一番上にclass Object(object):[改行] を追加しpass、で使用しself.obj = Object()ましたif not hasattr(..)(正しく覚えている場合)。
レンジー

@Renzeee aha ic
ドンサウザンド

@ZacharyCottonチャットに参加する必要があります。
ドン・サウザンド・

3

ベターランダム

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

ボットは、ポイントはいつ取得されてもポイントであるため、リープの機会はリープサイズに比例するという前提に基づいています。刈り取る可能性は常に非常に小さいため、この振る舞いが悪用される可能性があります。最初に、私はそれが直接比例するだろうと思い、比例定数がその周りにと仮定しましたが、1/mult^waittime、いくつかのシミュレーションを実行した後(少なくとも1つのボットが貪欲にプレイすると仮定した最大刈り取り)であると仮定しました。しかし、ボットはまだランダムでアウトパフォームされていたので、関係は直接比例していないと結論付け、関係を計算するために定数を追加しました。いくつかのシミュレーションの後、ボットのテストセットに対して-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常に1を超えているように見えます。つまり、self.getRandom()は決して高くなりません。
レンジー

@fejfoには、以前のラウンドのデータを使用することもできます。それself.objが目的です。使用方法の例を確認するには、それを使用している他のボットをご覧ください。
ドンサウザンド

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

締め切り直前の2番目のボットの時間だと思います。

このボットは:

  • 最後のReapの待機時間にある場合はスキップします
  • それが勝つことができるときに刈り取る
  • 誰も少なくともため刈り取らない場合享受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

私はPythonでプログラミングすることはあまりないので、間違いがあったら教えてください。


神聖な長い変数名。(また、PEP:python.org/dev/peps/pep-0008
Quintec

@Quintec 2スペースのインデントを4に変更しました。subsequentRoundsWithoutReapstoを短縮しましたroundsWithoutReaps。メソッド名にアンダースコア付きの小文字を使用しました。if文の括弧を削除しました。ありがとう。
ケビンクルイッセン

問題ない!(技術的には、rounds_without_reapsである必要がありますが、この課題ではmixedCamelCaseも使用されるため、実際には問題ではありません)
Quintec

@Quintecあぁ prevReapand を見て、そのlenBotsような変数と仮定された変数はJavaのようなcamelCaseです。;)ああ、まあ、どんなケースを使っても、とにかく動作するはずです。ただし、4つのインデントされたスペースではなく2つのスペースが問題を引き起こす可能性があります。
ケビンクルーイッセン

2

進行中:すべてのオープンKOTHにT4Tを拡張する私のプロジェクト。

Tatのシジュウカラ

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タッツ

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からインスピレーションを得て、誰かが刈り取り、それより1ターン前に刈り取りを試みるまでに平均で何ターンかかるかを計算するボットを作成しました。

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

これを明日追加します。
ドンサウザンド

1

ハードコード

はい、そうです。

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

過去の収穫で平均化する代わりに、通常の実行で事前に計算された平均を使用します。とにかく時間とともに良くなることはありません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.