ลองเล่น Reaper - ปิดเพื่อส่ง


13

หมายเหตุ : ผู้ชนะการแข่งขันนี้คือแจ็ค !!! จะไม่มีการส่งข้อมูลเพิ่มเติมอีก

นี่คือห้องแชทสำหรับท้าทายที่ท้าทาย นี่เป็นครั้งแรกของฉันดังนั้นฉันจึงเปิดรับข้อเสนอแนะ!

Reaper เป็นแนวคิดเกมที่พัฒนาโดย Art of Problem Solving ซึ่งเกี่ยวข้องกับความอดทนและความโลภ หลังจากปรับเปลี่ยนเกมให้เหมาะกับการประกวดสไตล์ KOTH (ขอบคุณ @NathanMerrill และ @dzaima สำหรับคำแนะนำและการปรับปรุงของคุณ) นี่คือความท้าทาย

เกมทำงานดังต่อไปนี้: เรามีค่าที่รู้จักกันในชื่อ Reap ที่คูณด้วยค่าคงที่ที่กำหนดทุกติ๊ก หลังจากแต่ละเห็บแต่ละบอทมีตัวเลือก "รับผล" ซึ่งหมายถึงการเพิ่มมูลค่าปัจจุบันของการเก็บเกี่ยวให้กับคะแนนของตัวเองและลดการเรียบลงถึง 1

อย่างไรก็ตามมีการทำเครื่องหมายจำนวนคงที่ที่บอตต้องรอระหว่าง "reaps" และจำนวนคะแนนคงที่ที่จำเป็นในการชนะเกม

ง่ายพอหรือยัง นี่คืออินพุตของคุณ:

I / O

คุณต้องเขียนฟังก์ชันใน Python 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)ที่xคือจำนวนของบอทใน KOTH ที่

  • เกมจะจบลงเมื่อผู้เล่น (หรือหลายคน) บรรลุคะแนนที่ชนะ
  • เมื่อบอทจำนวนมากขอให้เก็บเกี่ยวได้ในครั้งเดียวจะได้รับการจัดลำดับความสำคัญกับบอทที่รออีกต่อไป (ในกรณีที่มีความสัมพันธ์กันบอทที่รอเวลาสูงสุดทั้งหมดจะได้รับอนุญาตให้เก็บเกี่ยวและรับคะแนนในการเรียบ)
  • บอทของคุณต้องใช้เวลาโดยเฉลี่ยไม่เกิน 100 มิลลิวินาทีใน 5 ขีด
  • หากคุณต้องการนำเข้าห้องสมุดถาม! ฉันจะพยายามเพิ่มไลบรารี่ใด ๆ ที่ฉันสามารถรันบน Python เวอร์ชันเดสก์ท็อปของฉัน (นำเข้าคณิตศาสตร์แล้ว: อย่าลังเลที่จะใช้มัน)
  • ช่องโหว่มาตรฐานทั้งหมดสำหรับ KoTHs เช่นบ็อตซ้ำ, บอต 1 ครั้ง ฯลฯ ถูกแบนในทำนองเดียวกัน
  • บ็อตใด ๆ ที่ใช้การสุ่มใด ๆ จะต้องใช้getRandomฟังก์ชั่นที่ฉันได้จัดเตรียมไว้

คุณสามารถค้นหาคอนโทรลเลอร์ได้จากลิงค์ TIO ด้านล่าง หากต้องการใช้งานให้เพิ่มชื่อฟังก์ชันของคุณBotListเป็นสตริงแล้วเพิ่มฟังก์ชันลงในโค้ด ปรับเปลี่ยนmultiplierเพื่อเปลี่ยนแปลงสิ่งที่จะถูกคูณด้วยจำนวนของแต่ละเห็บแก้ไขwinning_scoreเพื่อเปลี่ยนคะแนนที่จำเป็นในการจบเกมและปรับเปลี่ยนwaittimeเพื่อเปลี่ยนจำนวนของเห็บเพื่อรอระหว่าง reaps

เพื่อความสะดวกของคุณนี่คือตัวอย่างบอท (และค่อนข้างโง่) การส่งบ็อตที่คล้ายกับสิ่งเหล่านี้จะไม่ได้รับอนุญาต อย่างไรก็ตามพวกเขาสาธิตวิธีการทำงานของคอนโทรลเลอร์

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 ด้านบนเพื่อดูว่าฉันใช้รหัสใดในการสร้างอันดับสุดท้าย ผลลัพธ์ไม่น่าสนใจอย่างยิ่ง กว่า 1,000 ครั้งที่ฉันทำกับเมล็ดสุ่มที่แตกต่างกันผลลัพธ์ก็คือ

1000 wins - Jack
0 wins - everyone else

ขอแสดงความยินดีกับแจ็คผู้ชนะรางวัล !! (aka @Renzeee)


สมมติว่าบอทสองคนเก็บเกี่ยวได้ในเวลาเดียวกันและอีกอันที่รอเวลานานที่สุดจะเป็นผู้ชนะ บอทคนอื่นจะเปิดใช้งานเวลารอคอยหรือไม่แม้ว่าจะไม่สามารถเก็บเกี่ยวได้ในรอบนี้ และจะเกิดอะไรขึ้นเมื่อสองบอทเก็บเกี่ยวในเวลาเดียวกันด้วยเวลารอเดียวกัน
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 ฉันกำลังติดตามคะแนนบอทและเวลาอิสระอื่น ๆ อย่างอิสระเพื่อที่จะทำการตรวจสอบและฉันก็ขี้เกียจ :)
Triggernometry

คำตอบ:


9

Twitchy Mess ที่ไม่เด็ดขาด

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% ของเวลา (เป็นหลักในการรับประกันว่าบอทนี้จะเก็บเกี่ยว SOMETIMES ในกรณีที่มีบางสิ่งแปลก ๆ เกิดขึ้นเช่นทุกคนกำลังรอผลัดกันหลายรอบ)
  • หากมีคน>> 70% ของคะแนนที่ชนะ:

    • หาก Sniper สามารถชนะ tiebreaker และรอบต่อไปจะสูงกว่าค่า Reap เฉลี่ยสำหรับฝ่ายที่ทำคะแนนสูงสุด
    • หากฝ่ายตรงข้ามให้คะแนนสูงสุดจะทิ้งคูลดาวน์ของพวกเขาในเทิร์นถัดไปให้เก็บเกี่ยว
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

เบื่อ

เพียงเพื่อความสนุกบอทนี้ถูกพาไปโดยเพื่อนและไม่ต้องการอยู่ที่นี่จริงๆ พวกเขาหมุน d16 ​​จนกว่าพวกเขาจะได้รับหมายเลข 1-9 จากนั้นพวกเขาพยายามที่จะเก็บเกี่ยวทุกครั้งที่มีตัวเลขที่มีตัวเลขที่เลือก (การมองหา 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 เห็บ
  • ไม่ทำอะไรเลย

ฉันได้เพิ่มประสิทธิภาพ 3 เห็บกับบอทที่มีอยู่ในปัจจุบัน (Sniper, grim_reaper, Every50, ระเบียบ, BetterRandom, Averager และอื่น ๆ อีกมากมาย)

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 ขีด) แต่สิ่งนี้ไม่ได้รับการปรับปรุงให้ดียิ่งขึ้นหลังจากที่ทำ 4 เห็บแทน 5 เสมอ


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.

อย่างที่คุณเห็นมันสูงถึง 50 หลังจาก 13 เห็บ เนื่องจากReapจะรีเซ็ต 1 ทุกครั้งที่ ธ ปท Reaps และwaittimeสำหรับบอทที่เก็บเกี่ยวผลผลิต 37 โอกาสบอ Reaps เร็วกว่าในภายหลังสวยสูงโดยเฉพาะอย่างยิ่งกับบอทคล้ายกับตัวอย่างGreedyBotซึ่งจะเก็บเกี่ยวเร็วที่สุดเท่าที่พวกเขาwaittimeมี สามารถใช้ได้อีกครั้ง ตอนแรกฉันต้องการทำ 200 ซึ่งเป็นเห็บที่ 17 ค่อนข้างตรงกลางของเห็บเวลารอ 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 และเราทั้งคู่ชนะการเรียบเรียงดังนั้นฉันไม่รังเกียจที่จะแบ่งปันชัยชนะกับคุณฮ่า ๆ ; p
Kevin Cruijssen

คุณอาจต้องการintหลีกเลี่ยงความไม่เท่าเทียมเนื่องจาก 1 คือคำสั่งที่แท้จริง
Don Thousand

@Quintec ฉันรู้แล้วว่าคุณล้อเล่น แต่ฉันจะไม่อนุญาตให้บอท 1 หรืออัพที่ซ้ำกัน
Don Thousand

@RushabhMehta ฉันไม่ได้เขียนโปรแกรมใน Python บ่อยนักดังนั้นฉันจึงสงสัยอยู่แล้วว่าฉันควรจะเพิ่มนักแสดงลงไปเพื่อให้Trueชัดเจน1หรือไม่ คิดว่าTrue == 1เช็คจะยังคงกลับมาTrueให้บอทของฉันเพิ่มไปยังรายการของReapersในnextฟังก์ชั่นของคุณแต่ฉันเพิ่มนักแสดงลงใน int ตามที่คุณแนะนำ
Kevin Cruijssen

5

averager

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

มัจจุราช

บอทนี้เก็บค่าเฉลี่ยของค่าของ reaps ก่อนหน้านี้ทั้งหมดรวมถึงเวลาที่ bot แต่ละตัวรออยู่ มันจะเก็บเกี่ยวเมื่อรอนานกว่า 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.reapsและself.objแทนself.objectและprevReapแทนprevLeapและเพิ่ม () หลังจากself.obj.players.valuesสองครั้ง และฉันคิดว่าself.obj.reaps = []จะไม่ทำงานเว้นแต่self.objจะมีวัตถุ ฉันไม่แน่ใจว่าทุกอย่างยังคงทำงานตามที่ตั้งใจและถ้าทั้งหมดที่ฉันพูดนั้นเป็นความจริง แต่หลังจากการเปลี่ยนแปลงเหล่านี้และใช้วัตถุจำลองเพื่อself.objเมื่อมันยังไม่มีอยู่รหัสของคุณจะรวบรวมให้ฉัน
Renzeee

@ZacharyColton คุณไม่จำเป็นต้องนำเข้าคณิตศาสตร์ นำเข้าแล้ว
Don Thousand

@RushabhMehta ฉันเพิ่มclass Object(object):[newline] passด้านบนและใช้self.obj = Object()ในif not hasattr(..)(ถ้าฉันจำได้อย่างถูกต้อง)
Renzeee

@Renzeee aha ic
Don Thousand

@ ZacharyCotton คุณควรเข้าร่วมการแชท
อย่าพัน

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"]ฉันพบค่าใหม่


ฉันจะเพิ่มสถิติใหม่ ๆ โดยใช้บอทของคุณในไม่ช้า
4258 Don

1
ดูเหมือนว่า(reap/self.mult**self.waittime)**-0.810192835เหนือกว่า 1 เสมอนั่นคือ self.getRandom () จะไม่สูงกว่านี้
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

โอกาสที่ฉันจะชนะด้วยความยุ่งเหยิงแทบจะไม่มีเลยดังนั้นเวลาที่จะจัดการกับบ็อตอื่น ๆ ทั้งหมดให้ได้มากที่สุด! :)

บอทนี้ทำหน้าที่คล้ายกับมือปืน เมื่อใดก็ตามที่มีคน reaps มันจะเลือกเป้าหมายแบบสุ่มจากใครก็ตามที่เก็บเกี่ยว จากนั้นมันจะรอจนกระทั่งเป้าหมายนั้นเกือบจะสามารถเก็บเกี่ยวได้อีกครั้ง อย่างไรก็ตามมันไม่เปลี่ยนโฟกัส - เมื่อคุณถูกเลือกและล็อคคุณจะหนีไม่พ้น :)


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

ฉันไม่ได้เขียนโปรแกรมใน Python บ่อยนักดังนั้นหากคุณเห็นข้อผิดพลาดใด ๆ แจ้งให้เราทราบ


ชื่อตัวแปรยาวศักดิ์สิทธิ์ (นอกจากนี้ PEP: python.org/dev/peps/pep-0008 )
Quintec

@Quintec เปลี่ยนการเยื้องพื้นที่ 2 เป็น 4; สั้นลงsubsequentRoundsWithoutReapsเพื่อroundsWithoutReaps; ใช้ตัวพิมพ์เล็กพร้อมกับขีดล่างสำหรับชื่อเมธอด และลบวงเล็บที่คำสั่ง if ขอบคุณ
Kevin Cruijssen

ไม่มีปัญหา! (ในทางเทคนิคมันควรจะเป็น rounds_without_reaps แต่ที่ไม่ได้จริงๆปัญหาตั้งแต่ความท้าทายนี้ยังใช้ mixedCamelCase ดังนั้นมันไม่ได้เรื่องจริงๆ)
Quintec

@Quintec Ah ตกลง ฉันดูprevReapและlenBotsและเช่นและตัวแปรสันนิษฐานว่าเป็น camelCase เช่นใน Java ;) อ่าไม่ว่ากรณีใด ๆ ก็ตามที่เราใช้มันก็น่าจะใช้ได้ 2 แทนการเว้นวรรค 4 เยื้องอาจทำให้เกิดปัญหาบางอย่างดังนั้นขอบคุณทั้งสองวิธี
Kevin Cruijssen

2

อย่างต่อเนื่อง: โครงการของฉันที่จะขยาย T4T ไปยังทุก KOTH ที่เปิดอยู่

หัวนมสำหรับตาด

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

Tit สำหรับ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 เพิ่งผ่านมาและทำให้พวกเขาใช้งานได้จริง กรุณาแก้ไข
SIGSTACKFAULT

ฟังดูเข้าท่า! เข้าร่วม GC ฉันจะโพสต์ผลลัพธ์บางส่วนที่นั่น
Don Thousand

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

hardcoded

ใช่แล้ว.

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

แทนที่จะหาค่าเฉลี่ยในการเก็บเกี่ยวที่ผ่านมาให้ใช้ค่าเฉลี่ยที่คำนวณไว้ล่วงหน้าในการดำเนินการตามปกติ มันจะไม่ดีขึ้นเมื่อเวลาผ่านไป

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.