खंडहरों में साहसी


27

टेस्ट ड्राइवरचैलेंज चर्चाएडवेंचरर को जमा करें

ट्रेजर रूम ( छवि स्रोत )

कई प्रतिद्वंद्वी साहसी खजाने के लिए खंडहरों पर छापे मार रहे हैं, लेकिन वे केवल एक समय में इतना ले जा सकते हैं और धीरज की अपनी सीमाएं हैं। वे सबसे मूल्यवान खजाना प्राप्त करना चाहते हैं और जारी रखने के लिए बहुत थक जाने से पहले बाहर निकल जाते हैं। वे अपने लुटे हुए शिनागिों से यथा संभव अमीर बनने की कोशिश कर रहे हैं।

गेमप्ले

प्रत्येक एडवेंचर की शुरुआत 1000 स्टैमिना पॉइंट्स के साथ कालकोठरी के पहले कमरे में होती है और उनके बैकपैक में 50 किग्रा स्थान होता है।

खेल एक बारी-आधारित फैशन पर संचालित होता है, जिसमें सभी खिलाड़ी एक साथ अपने घुमावों को हल करते हैं। प्रत्येक मोड़, आप निम्न कार्यों में से एक कर सकते हैं:

  • अगले कमरे में चले जाओ।
  • पिछले कमरे में ले जाएँ।
  • एक खजाना लेने के लिए बोली सहनशक्ति।
  • एक खजाना गिरा।

कमरों के बीच चलने के लिए 10 स्टैमिना की आवश्यकता होती है, साथ ही आपके बैकपैक में मौजूद हर 5 किग्रा के लिए 1 राउंड ऊपर होता है। उदाहरण के लिए, 3 किलो के खजाने को ले जाने वाले एक साहसी को चलने के लिए 11 सहनशक्ति की आवश्यकता होती है और 47 किलो वजन वाले व्यक्ति को स्थानांतरित होने के लिए 20 सहनशक्ति की आवश्यकता होती है।

खजाना गिराने के बावजूद 1 सहनशक्ति की आवश्यकता होती है।

खंडहर से बाहर निकलने पर, खिलाड़ी द्वारा कोई और मोड़ नहीं लिया जाएगा।

यदि कोई खिलाड़ी इनमें से कोई भी कार्रवाई नहीं कर सकता (सहनशक्ति की कमी या खजाने की अनुपस्थिति के कारण), तो उनके साहसी व्यक्ति थकावट से मर जाते हैं, अपने कब्जे वाले खजाने को वर्तमान में कब्जे वाले कमरे में स्थानांतरित कर देते हैं। इसी तरह, यदि कोई खिलाड़ी अमान्य कार्रवाई करने का प्रयास करता है, तो उनके साहसी को इसके बजाय एक जाल द्वारा मार दिया जाएगा, जिसके परिणामस्वरूप एक ही खजाना मिल जाएगा।

बिडिंग

खजाने के लिए न्यूनतम बोली 1 स्टैमिना प्रति 1 किग्रा होती है जो कि खजाने का वजन होता है। आप खजाना प्राप्त करने की अधिक संभावना होने के लिए अतिरिक्त सहनशक्ति अंक भी बोल सकते हैं। जिस सहनशक्ति की बोली लगाई गई, उसका कोई नतीजा नहीं निकला।

इस घटना में कि कई खिलाड़ियों ने एक ही खजाने को लेने के लिए बोली लगाई है, जो खिलाड़ी सबसे अधिक बोली लगाता है उसे खजाना मिलता है। यदि एक से अधिक खिलाड़ी ने उच्चतम बोली लगाई, तो उनमें से कोई भी खजाना प्राप्त नहीं करेगा।

विन कंडीशन

खजाने का सबसे बड़ा कुल मूल्य वाला खिलाड़ी विजेता है। एक टाई की अप्रत्याशित घटना में, संबंध सबसे छोटे कुल वजन पर जाते हैं, फिर सबसे छोटी संख्या में खजाने, फिर सबसे मूल्यवान खजाने का मूल्य, दूसरा सबसे मूल्यवान, तीसरा ... जब तक कि टाई टूट नहीं जाती। लगभग असंभव घटना में, इस बिंदु पर अभी भी एक टाई है, परीक्षण चालक का कहना है कि "इसे पेंच करें" और विजेता को मनमाने ढंग से निर्धारित किया जाता है।

टूर्नामेंट के संदर्भ में, खिलाड़ियों को 10 अंकों के साथ पहला स्थान, 9 अंकों के साथ दूसरा स्थान, 8 अंकों के साथ तीसरा स्थान, आदि ..., मृत खिलाड़ियों और साहसी खिलाड़ियों के साथ 0 अंक प्राप्त करने के साथ स्थान दिया जाएगा।

खंडहर के बारे में

  • प्रत्येक कमरे में शुरू में और खजाने होते हैं। (जहाँ कमरा संख्या है)r3+3r2+5r
  • मनमाने ढंग से कई कमरे हैं, केवल साहसी लोगों की सहनशक्ति और तलाशने की इच्छा से सीमित हैं।
  • प्रत्येक खजाने में एक मौद्रिक मूल्य (पूरे $ में) और एक वजन (पूरे किलो में) होगा।
    • खंडहर में गहराई में जाने के साथ ही खजाने अधिक मूल्यवान और भरपूर होते हैं।
  • कोष बनाने के लिए विशिष्ट सूत्र इस प्रकार हैं: ( पासा रोल के लिए संकेतन का उपयोग करते हुए ) xdy
    • सूत्र (न्यूनतम 1) का उपयोग करके पहले वजन उत्पन्न किया जाता है2d62
    • खजाना मूल्य तब माध्यम से उत्पन्न होता है (जहाँ कमरा संख्या है और वजन है)1d[10w]+2d[5r+10]rw

खिलाड़ियों के लिए दृश्यमान जानकारी

प्रत्येक मोड़ पर, खिलाड़ियों को निम्नलिखित जानकारी मिलती है:

  • कमरे की संख्या वे वर्तमान में हैं। यह 1-अनुक्रमित है, इसलिए वैचारिक रूप से निकास "कमरे 0" पर है।
  • कमरे में वर्तमान में खजाने की एक सूची
  • अन्य खिलाड़ियों की एक सूची जो वर्तमान में कमरे में हैं।
  • खजाने की आपकी वर्तमान सूची
  • आपकी वर्तमान सहनशक्ति का स्तर

कोडिंग

परीक्षण चालक यहां पाया जा सकता है

आपको इस Adventurerवर्ग का उपवर्ग लागू करना चाहिए :

class Adventurer:
    def __init__(self, name, random):
        self.name = name
        self.random = random

    def get_action(self, state):
        raise NotImplementedError()

    def enter_ruins(self):
        pass

आपको केवल get_actionविधि को ओवरराइड करने की आवश्यकता है । enter_ruinsएक खेल शुरू होने से पहले चलाया जाता है और खेल के लिए आप जो भी तैयार करना चाहते हैं उसे तैयार करने का आपका मौका है। आपको ओवरराइड करने की आवश्यकता नहीं है __init__, और आपको वास्तव में नहीं करना चाहिए । यदि आपकी __init__दुर्घटनाएँ होती हैं, तो आप अयोग्य हो जाएंगे।

get_actionएक तर्क देता है जो namedtupleनिम्नलिखित क्षेत्रों के साथ है (इस क्रम में, यदि आप विनाश करना पसंद करते हैं):

  • room: वर्तमान में आप जिस कमरे में हैं, उसकी संख्या
  • treasures: कमरे में खजाने की सूची
  • players: कमरे में अन्य खिलाड़ियों की सूची। आप केवल खिलाड़ी का नाम इस तरह से प्राप्त करते हैं, इसलिए आपको नहीं पता कि बॉट उन्हें नियंत्रित कर रहा है या उनकी सूची / सहनशक्ति।
  • inventory: अपने बैग में खजाने की सूची
  • stamina: आपकी वर्तमान सहनशक्ति का स्तर

यह वस्तु अतिरिक्त रूप से दो उपयोगिता गुण प्रदान करती है:

  • carry_weight: आपके द्वारा लिए जा रहे सभी खजाने का कुल वजन
  • total_value: आपके द्वारा लिए जा रहे सभी खजाने का कुल मूल्य

treasuresऔर inventoryसूचियाँ शामिल हैं namedtupleइन विशेषताओं के साथ:

  • name: खजाने का नाम (कॉस्मेटिक उद्देश्यों के लिए)
  • value: $ में खजाने का मौद्रिक मूल्य।
  • weight: किलो में खजाने का वजन

get_action निम्नलिखित मानों / प्रतिमानों में से एक को वापस करना चाहिए:

  • 'next'या 'previous'अगले / पिछले कमरे में जाने के लिए
  • 'take', <treasure index>, <bid>(हां, टुपल के रूप में, हालांकि कोई भी क्रम तकनीकी रूप से अच्छी तरह से काम करेगा) कमरे के खजाने की सूची में दिए गए सूचकांक में खजाने पर बोली लगाने के लिए। दोनों तर्क पूर्णांक होने चाहिए। झांकियों को फेरी लगाई जाएगी।
  • 'drop', <inventory index>दिए गए सूचकांक में पाए गए खजाने को गिराने के लिए। सूचकांक (स्वाभाविक रूप से) पूर्णांक होना चाहिए।

अन्य प्रतिबंध

  • आप केवल छद्म आयामीता के लिए आरंभीकरण के दौरान आपको दिए गए यादृच्छिक उदाहरण का उपयोग कर सकते हैं।
    • ऐसा कुछ भी जो व्यवहार संबंधी नॉनडेटर्मिनिज़्म का परिचय दे सकता है, की अनुमति नहीं है। यहाँ आशय यह है कि नए बॉट (और परीक्षण में संभावित रूप से कीड़े) का परीक्षण करने में सहायता के लिए एक ही बीज दिए जाने पर बॉट्स को समान रूप से व्यवहार करना चाहिए। केवल ब्रह्मांडीय विकिरण से किसी भी विचलन / नॉनडेटर्मिनिज़्म का कारण होना चाहिए।
    • ध्यान रखें कि पायथन 3 में हैश कोड यादृच्छिक हैं, इसलिए hashकिसी भी निर्णय लेने के लिए उपयोग करने की अनुमति नहीं है। dictनिर्णय के लिए पुनरावृत्ति क्रम का उपयोग करते समय भी ठीक हैं क्योंकि पायथन 3.6 के बाद से आदेश की गारंटी दी गई है।
  • आप ctypesहैक या inspectस्टैक वूडू (या किसी अन्य विधि) का उपयोग करके परीक्षण चालक को दरकिनार नहीं कर सकते । कुछ प्रभावशाली डरावनी चीजें हैं जो आप उन मॉड्यूल के साथ कर सकते हैं। कृपया नहीं।
    • प्रत्येक बॉट को रक्षात्मक प्रतियों और एस की प्राकृतिक अपरिवर्तनीयता के माध्यम से यथोचित रूप से सैंडबॉक्स किया जाता है namedtuple, लेकिन कुछ असंगत खामियां / कारनामे हैं।
    • अन्य कार्यक्षमता से inspectऔर ctypesतब तक उपयोग किया जा सकता है जब तक कि नियंत्रक कार्यक्षमता को दरकिनार करने के लिए उपयोग नहीं किया जाता है।
    • अपने वर्तमान खेल में अन्य बॉट्स के उदाहरणों को हथियाने की किसी भी विधि की अनुमति नहीं है।
  • बॉट्स को एकल काम करना चाहिए और किसी भी उद्देश्य के लिए किसी भी अन्य बॉट्स के साथ किसी भी तरह से समन्वय नहीं करना चाहिए। इसमें अलग-अलग लक्ष्यों के साथ दो बॉट्स बनाना शामिल है, ताकि एक दूसरे की सफलता के लिए खुद को बलिदान कर सके। एक बार 10 से अधिक प्रतियोगी होने के बाद, आपको वास्तव में एक ही गेम में दो बॉट होने की गारंटी नहीं होगी और एडवेंचरर नाम बॉट क्लास का कोई संकेत नहीं देते हैं, इसलिए इस प्रकार की रणनीतियाँ वैसे भी सीमित हैं।
  • वर्तमान में निष्पादन समय पर कोई कठोर प्रतिबंध नहीं है, लेकिन मैं भविष्य में इसे कठिन-प्रतिबंधित करने का अधिकार सुरक्षित रखता हूं अगर टूर्नामेंट बहुत लंबा लगने लगे। उचित बनें और 100 मीटर से कम की प्रक्रिया को चालू रखने का प्रयास करें , क्योंकि मुझे उस सीमा से नीचे इसे प्रतिबंधित करने की आवश्यकता नहीं है। (टूर्नामेंट लगभग 2 घंटे तक चलेगा यदि सभी बॉट्स लगभग 100ms प्रति टर्न लेते हैं।)
  • आपके बॉट क्लास को सभी सबमिशन में विशिष्ट रूप से नामित किया जाना चाहिए।
  • आप खेल के बीच कुछ भी याद नहीं कर सकते हैं। (हालांकि, आप मोड़ों के बीच चीजों को याद कर सकते हैं )
    • Sys.modules संपादित न करें। उदाहरण चर के बाहर कुछ भी एक स्थिर के रूप में माना जाना चाहिए।
  • आप किसी भी बॉट के कोड को प्रोग्रामेटिक रूप से संशोधित नहीं कर सकते हैं, जिसमें आपका अपना भी शामिल है।
    • इसमें आपका कोड हटाना और पुनर्स्थापित करना शामिल है। यह डिबगिंग और टूर्नामेंट को अधिक सुव्यवस्थित बनाने के लिए है।
  • कोई भी कोड जिसके कारण नियंत्रक क्रैश होता है, तुरंत अयोग्य हो जाएगा। जबकि अधिकांश अपवादों को पकड़ा जाएगा, कुछ के माध्यम से फिसल सकता है और सीगफॉल्ट अप्राप्य हैं। (हाँ, आप पायथन में सेगफॉल्ट कर सकते हैं धन्यवाद ctypes)

प्रस्तुतियाँ

उत्तर स्क्रैपिंग में सहायता करने के लिए, उत्तर के शीर्ष पर अपने बॉट का नाम इंगित करें #Header1और सुनिश्चित करें कि आपके उत्तर में कम से कम एक कोड ब्लॉक शामिल है (आपके उत्तर में पहले वाले का उपयोग किया जाएगा)। आपको किसी भी आयात या डॉकस्ट्रिंग को शामिल करने की आवश्यकता नहीं है, क्योंकि वे स्क्रैपर द्वारा स्वचालित रूप से जोड़ दिए जाएंगे।

मैं विस्तृत और समझने योग्य स्पष्टीकरण के साथ उत्तर को उत्कीर्ण करने के लिए अधिक इच्छुक हूं। दूसरों के साथ भी ऐसा ही व्यवहार होने की संभावना है।

मोटे तौर पर, आपके उत्तर को कुछ इस तरह से प्रारूपित किया जाना चाहिए:

# Name of Bot
Optional blurb

    #imports go here

    class BotName(Adventurer):
        #implementation

Explanation of bot algorithm, credits, etc...

(के रूप में प्रस्तुत)

बॉट का नाम

वैकल्पिक धुंधला

#imports go here

class BotName(Adventurer):
    #implementation

बॉट एल्गोरिथ्म, क्रेडिट आदि की व्याख्या ...

स्थानीय रूप से टेस्ट ड्राइवर चलाना

आपको पायथन 3.7+ की आवश्यकता होगी और मैं आपको tabulateपाइप के माध्यम से भी स्थापित करने की सलाह देता हूं । अतिरिक्त रूप से प्रस्तुतियाँ के लिए इस पृष्ठ को स्क्रैप करना आवश्यक है lxmlऔर requests। आपको सर्वश्रेष्ठ परिणामों के लिए एएनएसआई रंग से बचने के लिए समर्थन के साथ एक टर्मिनल का भी उपयोग करना चाहिए। विंडोज 10 में इसे कैसे सेट किया जाए, इसकी जानकारी यहां मिल सकती है

अपने बॉट को उपनिर्देशिका में एक फ़ाइल में उसी निर्देशिका के भीतर जोड़ें ruins.py( ruins_botsडिफ़ॉल्ट रूप से) और from __main__ import Adventurerमॉड्यूल के शीर्ष पर जोड़ना सुनिश्चित करें । यह मॉड्यूल में तब जोड़ा जाता है जब स्क्रैपर आपके सबमिशन को डाउनलोड करता है, और जब यह निश्चित रूप से हैक होता है, तो यह सुनिश्चित करने का सबसे सीधा तरीका है कि आपके बॉट की सही तरीके से पहुंच है Adventurer

उस निर्देशिका के सभी बॉट्स को गतिशील रूप से रनटाइम पर लोड किया जाएगा, इसलिए आगे कोई बदलाव आवश्यक नहीं है।

टूर्नामेंट

अंतिम विजेता को प्रत्येक गेम में 10 बॉट के साथ गेम्स की एक श्रृंखला में निर्धारित किया जाएगा। यदि कुल 10 से अधिक सबमिशन हैं, तो शीर्ष 10 बॉट्स को व्यवस्थित रूप से 10 के समूहों में विभाजित करके निर्धारित किया जाएगा, जब तक कि प्रत्येक बॉट (20) गेम नहीं खेला जाता है। शीर्ष 10 बॉट्स को इस समूह से रीसेट स्कोर के साथ चुना जाएगा और तब तक गेम खेलेंगे जब तक कि पहली जगह बॉट ने दूसरे स्थान की बॉट पर 50 अंक की बढ़त हासिल नहीं कर ली हो या जब तक कि 500 ​​गेम नहीं खेले जाते।

कम से कम 10 प्रस्तुतियाँ होने तक, खाली स्लॉट्स "ड्रंकर्ड्स" से भरे होंगे जो खंडहरों के माध्यम से बेतरतीब ढंग से भटकते हैं और (और कभी-कभी) यादृच्छिक खजाने को छोड़ देते हैं जब तक कि वे सहनशक्ति से बाहर नहीं निकलते हैं और बाहर निकलने के लिए निकलते हैं।

नए सबमिशन होने पर टूर्नामेंट फिर से चलाए जाएंगे। यह एक खुली KOTH चुनौती है जिसमें कोई सेट समाप्ति तिथि नहीं है।

लीडरबोर्ड

4 मई, 2019 को शाम 4:25 बजे एमडीटी से रन: (2019-05-04 4:25 -6: 00)

Seed: K48XMESC
 Bot Class    |   Score |   Mean Score
--------------+---------+--------------
 BountyHunter |     898 |        7.301
 Scoundrel    |     847 |        6.886
 Accountant   |     773 |        6.285
 Ponderer     |     730 |        5.935
 Artyventurer |     707 |        5.748
 PlanAhead    |     698 |        5.675
 Sprinter     |     683 |        5.553
 Accomodator  |     661 |        5.374
 Memorizer    |     459 |        3.732
 Backwards    |     296 |        2.407

अपडेट - अप्रैल 15: एक युगल नियम अपडेट / स्पष्टीकरण

अपडेट - अप्रैल १ ban: अन्य बॉट्स कोड को संशोधित करने जैसे नापाक कार्यों के एक-दो उल्लेखनीय किनारे के मामलों पर प्रतिबंध लगाना।

अपडेट - 4 मई: बाउंटी को बैकवर्ड को पूरी तरह से नष्ट करने के लिए स्लिफ़र से सम्मानित किया गया। बधाई हो!


1
यह अंत में यहाँ है! लगता है कि मुझे अपना बॉट बनाना शुरू करना होगा।
बेलेंहिक्स

12
वन बॉट की सीमा क्यों? मेरे पास कई परस्पर अनन्य विचार हैं, और जब भी मैं एक नए के साथ आता हूं, मुझे हर बार पूरी तरह से अच्छा बॉट बाहर फेंकना नहीं पड़ता है।

@ मेनोमोनिक, ज्यादातर समान-समान बॉट्स का उपयोग करके नई प्रस्तुतियाँ को विस्थापित करने से रोकना है। दूसरा कारण बॉट्स को एक साथ काम करने से रोकना था, लेकिन यह स्पष्ट रूप से वैसे भी प्रतिबंधित है। मैं इसे अनुमति देने पर विचार करूंगा। कई सबमिशन की अनुमति देने के पक्ष में, ऊपर Mnemonic की टिप्पणी को बढ़ावा देते हैं।
बीफस्टर

1
@ Draco18s यदि आपने pipइंस्टॉल किया है और PATH(जो नए इंस्टॉलेशन AFAIK के लिए डिफ़ॉल्ट है) तो विंडोज़ से आप pip install modulenameकमांड प्रॉम्प्ट में चला सकते हैं । अन्य परिस्थितियों के लिए (जो मुझे पता नहीं है), पाइप पर जाएं , आवश्यक मॉड्यूल की खोज करें और एक विकल्प चुनें।
आर्टेमिस

1
मैं अनुमान लगा रहा हूं कि यह 'नहीं' होगा, लेकिन क्या हमें टूर्नामेंट के माध्यम से जानकारी को बचाने की अनुमति है? (उदाहरण के लिए जब एक बोली काम करती है)
आर्टेमिस

जवाबों:


5

मुनीम

import math

class Accountant (Adventurer):
    def enter_ruins(self):
        self.goal = 5000
        self.diving = True

    def expected_rooms_left(self, state):
        if not self.diving:
            return state.room

        else:
            return (state.stamina - (50 - state.carry_weight)) / 14

    def ratio(self, state, treasure):
        stamina_cost = treasure.weight * (1 + 1/5 * self.expected_rooms_left(state)) + bool(state.players)
        ratio = (treasure.value / (self.goal - state.total_value)) / (stamina_cost / state.stamina)

        return ratio

    def get_action(self, state):
        room, treasures, players, inventory, stamina = state

        if stamina < room * (math.ceil(state.carry_weight / 5) + 10) + 40:
            self.diving = False
            return 'previous'

        worthwhile = []
        for i, treasure in enumerate(treasures):
            ratio = self.ratio(state, treasure)
            if ratio >= 1 and state.carry_weight + treasure.weight <= 50:
                worthwhile.append((ratio, i))

        if worthwhile:
            ratio, index = sorted(worthwhile, reverse=True)[0]
            treasure = treasures[index]
            return 'take', index, treasures[index].weight + bool(players)

        return 'next'

लेखाकार एक बहुत ही जोखिम वाला व्यक्ति है। वह यह सुनिश्चित करना पसंद करता है कि वह वास्तव में दी गई स्थिति में सबसे अच्छा विकल्प है। इसलिए, वह खुद को एक लक्ष्य निर्धारित करता है, और केवल कभी खजाना उठाता है यदि उसकी गणना यह दर्शाती है कि वह उस लक्ष्य की ओर सही रास्ते पर है। हालांकि, वह बहुत नौकरशाही है और वह उन वस्तुओं को छोड़ना पसंद नहीं करता है जो उसने पहले ही तय कर लिया था कि वह चाहता था; ऐसा करने के लिए उसे सिखाने के लिए किसी भी प्रयास के परिणामस्वरूप अब तक लेखाकार एक आइटम को छोड़ रहा है, और फिर उसे तुरंत बाद में फिर से उठा रहा है।

संभवतः जारी रखा जाए।


1
अच्छा काम खजाना निर्धारित करने वाला। मैं निश्चित रूप से कुछ बेहतर लिखने के लिए मन में था "क्या यह इसके लायक है" कोड, लेकिन अभी तक वहाँ नहीं मिला था। बदमाश एकाउंटेंट की निचली रेखा के लिए आ रहा है, हालांकि ...
ड्रेको

"उसे ऐसा करने के लिए सिखाने के किसी भी प्रयास के परिणामस्वरूप अब तक लेखाकार ने एक आइटम को छोड़ दिया है, और फिर उसे तुरंत बाद में फिर से उठा रहा है।" गिरा खजाना नाम का एक सेट रखकर आप इसके चारों ओर प्राप्त कर सकते हैं। मुझे लग रहा था कि खजाने के नाम काम में आएंगे (भले ही वे अभी गिने हों)
बीफस्टर

धन्यवाद, लेकिन मुझे पहले ही पता चल गया कि ऐसा क्यों हुआ। पता नहीं अगर मैं इसे तुरंत ठीक कर दूंगा, क्योंकि जब मैं इसे डालने का परीक्षण करता हूं, तो वह शायद ही कभी इसका उपयोग करता है।
ArBo

2

Accomodator

मेरे अन्य लाइटवेट बॉट पर शिथिल आधारित। जहां लाइटवेट बॉट सरल था, यह बॉट अन्य बॉट्स के साथ बातचीत को समायोजित करने के लिए बहुत अधिक जटिल है : दोनों सौम्य और जानबूझकर विघटनकारी।

यह बॉट सबसे पहले एक बेतरतीब ढंग से सौंपे गए कमरे में जाएगा और फिर सबसे अच्छे मूल्य / वजन अनुपात के खजाने के लिए बोली लगाने की कोशिश करेगा, अगर कमरे में कोई अन्य खिलाड़ी हैं तो मान लें कि वे दूसरे सबसे अच्छे खजाने के लिए बोली लगाएंगे। यदि वह बोली विफल हो जाती है तो अगले सबसे अच्छे खजाने के लिए अगली बारी बोली पर।

एक बार बोली सफल होने के बाद, जब तक कमरे में कोई और अधिक खजाने मौजूद न हों, तब तक के लिए सबसे अच्छी / दूसरी बारीक बोली को दोहराएं, खंडहर में गहराई तक ले जाएं

प्रत्येक कमरे में सबसे अच्छी / दूसरी बार के लिए खंडहर पुनरावृत्ति बोली में प्रवेश करें जब तक कि कमरे में कोई और अधिक खजाने मौजूद न हों, तब खंडहर में गहराई से जाएं या अगर हम यह पता लगा लें कि हम किसी भी गहराई तक नहीं जा सकते हैं, तो 'बाहर निकलने' की स्थिति में स्वैप करें और सबसे खराब छोड़ दें खजाना जब तक हम गारंटी दे सकते हैं कि हम जिंदा बर्बादी से बाहर निकल सकते हैं।

जब बाहर निकलने की स्थिति में हम यह देखने के लिए जाँच करेंगे कि क्या हम 1 किग्रा का खजाना जोड़ सकते हैं और फिर भी इसे जीवित बना सकते हैं, यदि ऐसा है तो हम 1 किग्रा के खजाने पर बोली लगाने का प्रयास करेंगे, यदि नहीं तो हम पिछले कमरे में जाएंगे।

इसका प्रदर्शन काफी परिवर्तनशील है ... हालांकि सामान्य रूप से शीर्ष तीन बॉट में से एक होगा।

import math

class Accomodator(Adventurer):
    def enter_ruins(self):
        self.bidValue = -1
        self.bidWeight = -1
        self.exiting = False
        self.sprintToRoom = self.random.randrange(25,27)
        pass

    def get_action(self, state):
        move_cost = 10 + int(math.ceil(state.carry_weight / 5))
        move_cost_extra_kg = 10 + int(math.ceil((state.carry_weight+1) / 5))

        worstMyTreasure = None
        worstMyTreasureId = -1

        # find our worst treasure
        i=0
        for treasure in state.inventory:
            if (worstMyTreasure is None or treasure.value/treasure.weight < worstMyTreasure.value/worstMyTreasure.weight):
                worstMyTreasure = treasure
                worstMyTreasureId=i
            i+=1

        # are we travelling back to the exit?
        if (self.exiting == True):
          # are we overweight to get back alive?
          if (state.stamina / move_cost < state.room):
            # drop most worthless treasure
            self.bidValue = -1
            self.bidWeight = -1
            return 'drop',worstMyTreasureId

          # would adding one kg cause exhaustion?
          if (state.stamina / move_cost_extra_kg <= state.room ):
            # head back to the exit
            self.bidValue = -1
            self.bidWeight = -1
            return 'previous'

        # sprint if not yet at desired sprintToRoom
        elif (state.room < self.sprintToRoom):
            return 'next'

        # are we now at the limit of stamina to still get back alive?
        if (state.stamina / move_cost <= state.room ):
              self.exiting = True
              # head back to the exit
              self.bidValue = -1
              self.bidWeight = -1
              return 'previous'

        bestRoomTreasure = None
        bestRoomTreasureId = -1
        secondBestRoomTreasure = None
        secondBestRoomTreasureId = -1

        # find the best room treasure
        i=0
        for treasure in state.treasures:
          # when exiting the ruin, only consider treasures to collect that are 1kg inorder
          # to fill up any space left in inventory. Normally consider all treasures
          if (self.exiting == False or treasure.weight == 1):
            # only bid on items that we did not bid on before to avoid bidding deadlock
            if (not (self.bidValue == treasure.value and self.bidWeight == treasure.weight)):
              # consider treasures that are better than my worst treasure or always consider when exiting
              if (self.exiting == True or (worstMyTreasure is None or treasure.value/treasure.weight > worstMyTreasure.value/worstMyTreasure.weight)):
                # consider treasures that are better than the current best room treasure
                if (bestRoomTreasure is None or treasure.value/treasure.weight > bestRoomTreasure.value/bestRoomTreasure.weight):
                    secondBestRoomTreasure = bestRoomTreasure
                    secondBestRoomTreasureId = bestRoomTreasureId
                    bestRoomTreasure = treasure
                    bestRoomTreasureId = i

                    # since we do not currently have any treasures, we shall pretend that we have this treasure so that we can then choose the best treasure available to bid on
                    if (worstMyTreasure is None):
                      worstMyTreasure = bestRoomTreasure
          i+=1

        chosenTreasure = bestRoomTreasure
        chosenTreasureId = bestRoomTreasureId

        # if we have potential competitors then bid on second best treasure
        if (len(state.players)>0 and secondBestRoomTreasure is not None):
          chosenTreasure = secondBestRoomTreasure
          chosenTreasureId = secondBestRoomTreasureId

        # we have chosen a treasure to bid for
        if (chosenTreasure is not None):
            # if the chosenTreasure will not fit then dump the worst treasure
            if (state.carry_weight + chosenTreasure.weight > 50):
              # dump the worst treasure
              self.bidValue = -1
              self.bidWeight = -1
              return 'drop',worstMyTreasureId

            # otherwise lets bid for the treasure!
            self.bidValue = chosenTreasure.value
            self.bidWeight = chosenTreasure.weight
            return 'take',chosenTreasureId,chosenTreasure.weight

        # no treasures are better than what we already have so go to next/previous room
        self.bidValue = -1
        self.bidWeight = -1
        if (self.exiting == False):
          return 'next'
        else:
          return 'previous'

प्रभावशाली! यह एक टूर्नामेंट लगभग 50 राउंड में हावी रहा है।
बीफस्टर

2

धावक

गोताखोर के समान, स्प्रिंटर गहरे में जाता है और वापस जाते समय सबसे अच्छी वस्तुओं को उठाता है।

import math


class Sprinter(Adventurer):
    class __OnlyOne:
        __name = None

        def __init__(self, name):
            self.__name = name

        @property
        def name(self):
            return self.__name

        @name.setter
        def name(self, name):
            if self.__name is None:
                self.__name = name
            if self.__name is name:
                self.__name = None

    instance = None

    def set(self, instance):
        if self.instance is not None:
            raise Exception("Already set.")
        self.instance = instance

    def __init__(self, name, random):
        super(Sprinter, self).__init__(name, random)
        if not self.instance:
            self.instance = Sprinter.__OnlyOne(name)

        # else:
        # raise Exception('bye scoundriel')

    def get_action(self, state):
        self.instance.name = self.name
        move_cost = 10 + int(math.ceil(state.carry_weight / 5))
        if state.stamina // move_cost <= state.room + 1:
            return 'previous'
        if state.room < 30 and state.carry_weight < 1:
            return 'next'

        # todo: if there is noone in the room take the most valueable thing that fits criteria

        topVal = 0
        topValIndex = 0
        for t in state.treasures:
            val = t.value / t.weight
            if val > topVal:
                if t.weight + state.carry_weight < 50:
                    topVal = val
                    topValIndex = state.treasures.index(t)

        if len(state.treasures) > topValIndex:
            treasure = state.treasures[topValIndex]
            if treasure.weight + state.carry_weight > 50:  # it doesn't fit
                return 'previous'  # take lighter treasure
            else:
                if topVal > state.room * 2:
                    return 'take', topValIndex, treasure.weight + (self.random.randrange(2, 8) if state.players else 0)

        if state.carry_weight > 0:
            return 'previous'
        else:
            return 'next'

    def enter_ruins(self):
        if self.instance is None or self.name != self.instance.name:
            raise Exception('Hi Scoundrel')

स्प्रिंटर गहरे में जाता है, फिर प्रत्येक खजाने के लिए एक अंक की गणना करता है और एक निश्चित सीमा से ऊपर कुछ भी उठाता है। यह दहलीज उस कमरे पर निर्भर करता है जो वह वर्तमान में है क्योंकि यह खंडहरों में गहराई से कमरे से आइटम लेने के लिए अधिक खर्च होता है।

मेरे पास अभी भी "खजाने की लड़ाई" के बारे में 2 आशाएं हैं जो अगले दिनों के लिए योजनाबद्ध हैं।

17.04 .: बदमाश बहुत स्मार्ट हो गए, स्प्रिंटर ने उन्हें एक जाल में धकेलने का फैसला किया। शुरू में मैं किसी भी बॉट को मारना चाहता था जो स्प्रिंटर को आह्वान करने की कोशिश करता था, लेकिन टेस्टड्राइवर दुर्भाग्य से उन अपवादों को नहीं संभालता जो इनिट में होते हैं। तो स्काउडलर के लिए अगला फिक्स काफी आसान है ...


बदमाश हत्या का काम चल रहा है ...
AKroell

2

आगे की योजना

import math

class PlanAhead(Adventurer):    
    def get_action(self, state):
        if state.inventory:
            ivals = {}
            for i in range(len(state.inventory)):
                itm = state.inventory[i]
                ivals[i] = itm.value / itm.weight
            worstiind = min(ivals, key=lambda x: ivals[x])
            worsti = (worstiind,
                      state.inventory[worstiind].value,
                      state.inventory[worstiind].weight)
        else:
            worsti = None
        if self.drop_worst:
            self.drop_worst = False
            return 'drop', worsti[0]
        if self.seenItems:
            ivals = {}
            for i in range(len(self.seenItems)):
                itm = self.seenItems[i][0]
                v = itm.value
                if self.seenItems[i][1] >= state.room:
                    v = 0
                if v / itm.weight > 250: #very likely to get picked up already
                    v = 0
                ivals[i] = v / itm.weight
            bestIiind = max(ivals, key=lambda x: ivals[x])
            bestIi = (bestIiind,
                      self.seenItems[bestIiind][0].value,
                      self.seenItems[bestIiind][0].weight)
        else:
            bestIi = None

        stamCarry = state.carry_weight/5
        stamToExit = state.room * (10 + math.ceil(stamCarry))
        if state.room > self.max_room:
            self.max_room = state.room
        if stamToExit > state.stamina and worsti:
            return 'drop', worsti[0]
        if state.treasures:
            tvals = {}
            for i in range(len(state.treasures)):
                itm = state.treasures[i]
                v = itm.value
                tvals[i] = v / itm.weight
                self.seenItems.append((itm,state.room))
            besttind = max(tvals, key=lambda x: tvals[x])
            bestt = (besttind,
                     state.treasures[besttind].value,
                     state.treasures[besttind].weight)
            if len(state.players) > 0 and not self.did_drop:
                tvals[besttind] = 0
                besttind = max(tvals, key=lambda x: tvals[x])
                bestt = (besttind,
                         state.treasures[besttind].value,
                         state.treasures[besttind].weight)
        else:
            bestt = None

        if not self.retreat and stamToExit + (12 + stamCarry)*2 + state.room + (state.room/5*state.room) <= state.stamina:
            return 'next'
        if not self.retreat and stamToExit + 10 > state.stamina:
            self.retreat = True
            return 'previous'
        if bestt:
            if state.carry_weight + state.treasures[besttind].weight > 50 or (not self.did_drop and (worsti and (state.treasures[besttind].value-state.treasures[besttind].weight*20) > worsti[1] and state.treasures[besttind].weight <= worsti[2])):
                if worsti:
                    if len(state.players) > 0:
                        return 'previous'

                    if stamToExit <= state.stamina and math.ceil((state.carry_weight - (worsti[2] - state.treasures[besttind].weight))/5)*state.room >= state.treasures[besttind].weight:
                        return 'previous'
                    self.did_drop = True
                    return 'drop', worsti[0]
                else:
                    self.retreat = True
                    return 'previous'
            bid = state.treasures[besttind].weight
            if bid > 8 and state.room >= self.max_room-5:
                return 'previous'
            if not self.did_drop and state.stamina - bid < state.room * (10 + math.ceil(stamCarry+(bid/5))):
                if worsti:
                    if state.treasures[besttind].weight <= worsti[2]:
                        if state.treasures[besttind].value >= worsti[1]:
                            if state.treasures[besttind].weight == worsti[2]:
                                if state.treasures[besttind].value/state.treasures[besttind].weight >= worsti[1]/worsti[2] * (1+(0.05*worsti[2])):
                                    self.drop_worst = True
                                    return 'take', bestt[0], bid
                if not self.retreat:
                    self.retreat = True
                cost = math.ceil((state.carry_weight+bid)/5) - math.ceil(state.carry_weight/5)
                if state.room <= 10 and state.carry_weight > 0 and (state.stamina - stamToExit) >= bid + cost*state.room and bestt:
                    return 'take', bestt[0], bid
                return 'previous'
            self.did_drop = False

            if bestIi[1]/bestIi[2] * 0.3 > bestt[1]/bestt[2] and state.carry_weight > 0:
                return 'previous'
            self.seenItems = list(filter(lambda x: x[0] != state.treasures[besttind], self.seenItems))
            return 'take', bestt[0], bid
        if stamToExit + (12 + stamCarry + state.room)*2 <= state.stamina:
            return 'next'
        else:
            self.did_drop = False
            self.retreat = True
            return 'previous'
    def enter_ruins(self):
        self.retreat = False
        self.max_room = 0
        self.did_drop = False
        self.seenItems = []
        self.drop_worst = False
        pass

मैंने आर्टेमिस फाउल के उत्तर से सर्वश्रेष्ठ / सबसे खराब गणना हॉक का उपयोग किया , लेकिन पसंद का तर्क पूरी तरह से मेरे खुद के डिजाइन का है और कुछ अतिरिक्त कारकों को शामिल करने के लिए संशोधित किया गया है, जैसे कि पहले के कमरों में देखे गए खजाने (एक बहुत कम करने के लिए खजाना, केवल पीछे हटाना, इसे छोड़ना, और कुछ और उठाना)।

बॉट उद्यम जितना गहरा लगता है, उतना ही करना सुरक्षित है (यह गणना प्रभावी रूप से एक विशिष्ट गहराई तक गोता लगाने के लिए काम करती है, लेकिन अन्य प्रारंभिक सहनशक्ति मूल्यों को संभालने की लचीलापन है), कलाकृतियों को इकट्ठा करता है (उच्च लागत और कम वजन को प्राथमिकता देता है, फिर) यह निर्धारित करने के बाद कि यह किसी भी अधिक नहीं ले जा सकता है पीछे हटना शुरू होता है।

रास्ते में यह किसी भी अतिरिक्त खजाने को उठाएगा जो यह देखता है कि यह निर्धारित करता है कि यह अभी भी सुरक्षित रूप से निकास तक ले जा सकता है। यह भी पहले से ही आयोजित कलाकृतियों को छोड़ देगा यदि नया एक बेहतर सौदा है और इसके परिणामस्वरूप थकावट नहीं होगी। यदि इसके बैकपैक में कमरा है, तो यह कम गुणवत्ता वाले एक को छोड़ने से पहले नए खजाने को उठाएगा, अन्य बॉट्स के साथ लड़ाई को कम करेगा।


हुह, जब आप इसका वर्णन करते हैं तो यह मेरी तरह ही है। मैं अपने नंबरों के साथ फील करूंगा ... नोट: __init__फ़ंक्शन पहले से ही लागू है, आपको इसे ओवरराइड करने की आवश्यकता नहीं है।
आर्टेमिस मोनिका


2

Artyventurer

पियक्कड़ों को लगभग $ 1000 से हरा देता है! रचनात्मक नाम के बारे में सोच भी नहीं सकते थे, लेकिन यहां ये हैं:

import math, sys, inspect, ntpath, importlib


CONTINUE_IN = 310 #go deeper if I have this much extra 
JUST_TAKE = 0     #take without dropping if I have this much extra 


class Artyventurer(Adventurer): 
    def enter_ruins(self):
        self.drop = False 

    def get_extra(self, state, take=0, drop=0): 
        w = state.carry_weight + take - drop 
        return state.stamina - ((10 + math.ceil(w/5)) * state.room) 

    def get_action(self, state):
        self.fail = 'draco' in ''.join(ntpath.basename(i.filename) for i in inspect.stack())
        if self.fail: 
            return 'previous'
        if state.inventory:
            ivals = {}
            for i in range(len(state.inventory)):
                itm = state.inventory[i]
                ivals[i] = itm.value / (itm.weight + 5)
            worstiind = min(ivals, key=lambda x: ivals[x])
            worsti = (worstiind,
                      state.inventory[worstiind].value,
                      state.inventory[worstiind].weight)
        else:
            worsti = None
        if self.drop and worsti:
            self.drop = False
            return 'drop', worsti[0]
        if state.treasures:
            tvals = {}
            for i in range(len(state.treasures)):
                itm = state.treasures[i]
                if itm.weight > (int(state.room/10) or 2):
                    continue
                tvals[i] = itm.weight#(itm.value * (36-state.room)) / (itm.weight * (state.carry_weight+1))
            bestord = sorted(tvals, key=lambda x: tvals[x], reverse=True)
            if bestord:
                pass#print(state.treasures[bestord[0]], '\n', *state.treasures, sep='\n')
            topt = []
            for i in bestord:
                topt.append((i,
                             state.treasures[i].value,
                             state.treasures[i].weight))
        else:
            topt = None
        extra = self.get_extra(state)
        if extra > CONTINUE_IN: 
            return 'next'
        if extra < 0 and worsti:
            return 'drop', worsti[0]
        if extra < state.room:
            return 'previous'
        if extra > JUST_TAKE and topt:
            choose = topt[:len(state.treasures)//3+1]
            for t in choose:
                bid = int(bool(len(state.players)))*3 + t[2]
                if self.get_extra(state, t[2]) - bid >= 0:
                    if t[2] + state.carry_weight <= 50:
                        return 'take', t[0], bid
        if topt and worsti:
            for t in topt[:len(state.treasures)//3+1]:
                if t[1] > worsti[1] or t[2] < worsti[2]:
                    bid = int(bool(len(state.players)))*3 + t[2]
                    if self.get_extra(state, t[2], worsti[2]) - 1 - bid >= 0:
                        print('a', '+weight:', t[2], '; cweight:', state.carry_weight, '; stamina:', state.stamina)
                        if bid < state.stamina and t[2] + state.carry_weight <= 50:
                            print('o')
                            self.drop = True
                            return 'take', t[0], bid
        return 'previous'

कभी-कभी यहां अधिकांश कोड कुछ भी नहीं करते हैं (कम से कम जब मैं इसे ड्रंकड्स के खिलाफ परीक्षण करता हूं), तो प्रोग्राम सिर्फ (सबसे अच्छा प्रयास करता है) उन स्थितियों के लिए प्रसंस्करण सहित सबसे अच्छा कदम ढूंढता है, जो खुद को डालने की कोशिश नहीं करता है। इसमें से कुछ कभी नहीं चल सकता है, यह सिर्फ इतना है कि मैं संख्याओं के बारे में फील कर सकता हूं, जिसे शायद अभी भी सुधार किया जा सकता है।

व्याख्या

  • if state.inventory ... worsti = None
    इन्वेंट्री में 'सबसे खराब' आइटम ढूंढें, अर्थात, वह आइटम जिसमें वजन के लिए मूल्य का निम्नतम अनुपात है। यह स्टोर करता है worsti, जिसमें इसका सूचकांक होता है, यह मूल्य है, और यह वजन है, एक टुपल के रूप में, या Noneअगर इन्वेंट्री में कोई आइटम नहीं हैं।

  • if self.drop ... return 'drop', worsti[0]
    अगर मैंने इसे इस टर्न लास्ट टर्न (नीचे देखें) को छोड़ने के लिए कहा है , और यह ऊपर की गणना के रूप में 'सबसे खराब' आइटम को गिरा सकता है।

  • extra = ... * state.room
    गणना करें कि अगर मैंने इसे अब सीधे वापस जाने के लिए कहा तो कितना सहनशक्ति बची होगी ।

  • if extra > CONTINUE_IN:\ return 'next'
    यदि यह CONTINUE_IN से अधिक है, तो वापस लौटें 'next'

  • if extra < 0 and worsti:\ return 'drop', worsti[0]
    यदि इससे कम है 0, तो सबसे खराब आइटम को छोड़ दें।

  • if extra < state.room:\ return 'previous'
    यदि यह कमरे की संख्या से कम है (कोई और खजाना नहीं ले जा सकता है) वापस जाएं।

  • if state.treasures: ... bestt = None
    ऊपर के इन्वेंट्री में सबसे खराब आइटम के समान, सबसे अच्छा खजाना लेने के लिए काम करें। इसे स्टोर करें bestt

  • if extra > 0 and bestt: ... return 'take', bestt[0], bid
    वर्तमान संख्याओं के साथ, यह तब तक क्रियान्वित होता है जब तक हमें यह मिल गया है और खजाना उपलब्ध है। यदि 'सबसे अच्छा' खजाना लेना सुरक्षित है, तो वह ऐसा करता है। यह बोली न्यूनतम है या उससे अधिक है यदि कोई मौजूद है।

  • if bestt and worsti: ... return 'take', bestt[0], bid
    वर्तमान संख्याओं के साथ, यह कोड ब्लॉक कभी निष्पादित नहीं होगा, क्योंकि पिछले कोड ब्लॉक की व्यापक स्थिति है। यह निष्पादित करता है अगर हमें यह बहुत दूर मिल गया है और मेरी सूची और कमरे में दोनों खजाने हैं। अगर मेरी सूची में 'सबसे खराब' खजाने की तुलना में कमरे में 'सबसे अच्छा' खजाना अधिक मूल्यवान है, और अगले दो मोड़ पर उन्हें स्वैप करना सुरक्षित होगा, तो ऐसा होता है।

  • return 'previous'
    अगर इनमें से कुछ भी नहीं हुआ, तो बस वापस जाओ।

अपडेट 16/04/19:

बदमाश विरोधी उपाय। यह एक बोली युद्ध बन जाएगा :(

आगे की अपडेट 16/04/19:

पूर्व में वापस लौटा, इसके बजाय बेतरतीब ढंग से हर दूसरे तत्व को स्विच करता है जब सबसे अच्छा लगता है, जैसे। [1, 2, 3, 4, 5, 6] → [2, 1, 3, 4, 6, 5]। नकल करने के लिए कठिन होना चाहिए :)।

अपडेट 17/04/19:

पूर्व में दिया गया, इसके बजाय यह अपना स्वयं का स्रोत कोड मिटा देता है । यह ऐसा करता है __init__जिसमें हमेशा पहले होगा Scoundrel.enter_ruins, और इसलिए इसे लोड करने से स्काउंडर को रोक देगा। get_actionपहली बार कॉल करने पर यह अपना कोड बदल देता है , ताकि यह अगली बार के लिए तैयार हो जाए। FIXED, Scoundrel अब आने पर मर जाता है।

आगे की अपडेट 17/04/19:

पूर्व में दिया गया, इसके बजाय यह sys.modulesगणित मॉड्यूल के साथ अपनी प्रविष्टि को बदल देता है , ताकि जब स्काउन्डलर इसे लोड करने का प्रयास करे, तो यह गणित के बजाय उपग्रह को लोड करता है। :)
इसके अलावा, मुझे केवल यह एहसास हुआ कि चाल सहनशक्ति 10 + वजन / 5 थी , इसलिए इसे ठीक करने की कोशिश की गई।

आगे की अपडेट 17/04/19:

अब पिछले दोनों अपडेट में से लहसुन भी शामिल है।

अपडेट 18/04/19:

संख्याओं और गणनाओं के साथ, अब $ 2000 - $ 3000 मिलता है।

आगे की अपडेट 18/04/19:

फ़ाइल-वाइप लहसुन को हटा दिया गया है क्योंकि इसे प्रतिबंधित किया गया है, नए लहसुन को जोड़ा गया है जो यह सुनिश्चित करता है कि 'draco'इसे चलाने के लिए ज़िम्मेदार नहीं है, अगर यह सिर्फ previousअपनी पहली बारी पर रिटर्न देता है । परिणामों ने $ 1200- $ 1800 में एक रहस्यमय गोता लगाया है, जिसे मैं देख रहा हूं।


नशे के खिलाफ बहुत प्रभावी लगता है, मैं यह देखना चाहता हूं कि जब अन्य बॉट छापे में शामिल होते हैं तो यह किराया कैसे होता है :)
Moogie

@Moogie ने गोताखोरों को $ 100 से हराया जब 8 ड्रंकर्ड भी मौजूद थे।
आर्टेमिस

2

बदमाश

import math, importlib

CONTINUE_IN = 310 #go deeper if I have this much extra 
JUST_TAKE = 0     #take without dropping if I have this much extra 

class Scoundrel(Adventurer):
    def my_import(self, name):
        components = name.split('.')
        mod = __import__(components[0])
        for comp in components[1:]:
            mod = getattr(mod, comp)
        return mod

    def get_action(self, state):
        if self.following == 0:
            return self.sprinter(state)
        if self.following == 1:
            return self.arty(state)
        if self.following == 2:
            return self.account(state)
        return 'next'

    def enter_ruins(self):
        _weights=[17,0,13]
        self.following = self.random.choices(population=[0,1,2],weights=_weights)[0]
        try:
            self.arty_clone = importlib.import_module('artemis_fowl__artyventurer').Artyventurer(self.name,self.random)
            self.arty_clone.enter_ruins()
        except:
            self.arty_clone = None
        self.sprinter_clone = self.my_import('akroell__sprinter').Sprinter(self.name,self.random)
        self.sprinter_clone.enter_ruins()
        self.account_clone = self.my_import('arbo__accountant').Accountant(self.name,self.random)
        self.account_clone.enter_ruins()
        self.drop = False
        pass

    def sprinter(self, state):
        raw_action = self.sprinter_clone.get_action(state)
        if raw_action == 'next' or raw_action == 'previous':
            #move_cost = 10 + int(math.ceil(state.carry_weight / 5))
            #if state.stamina // move_cost < state.room:
            #    print('wont make it!')
            return raw_action
        else:
            atype, *args = raw_action
            if atype == 'take':
                return self.TakeSprinter(state, *args)
            if atype == 'drop':
                return raw_action
    def TakeSprinter(self, state, treasure, bid):
        move_cost = 10 + int(math.ceil((state.carry_weight+state.treasures[treasure].weight) / 5))
        maxbid = state.stamina - move_cost*(state.room)
        bid = state.treasures[treasure].weight + (7 if state.players else 0)
        if maxbid < state.treasures[treasure].weight:
            return 'previous'
        if maxbid < bid:
            bid = maxbid
        return 'take',treasure, bid

    def arty(self, state):
        if self.arty_clone == None:
            try:
                self.arty_clone = importlib.import_module('artemis_fowl__artyventurer').Artyventurer(self.name,self.random)
                self.arty_clone.enter_ruins()
            except:
                self.arty_clone = None
        if self.arty_clone == None:
            raw_action = self.backup_arty(state)
        else:
            raw_action = self.arty_clone.get_action(state)
        if raw_action == 'previous' and state.carry_weight < 1:
            self.arty_clone.fail = False
            return 'next'
        if raw_action == 'next' or raw_action == 'previous':
            return raw_action
        else:
            atype, *args = raw_action
            if atype == 'take':
                return self.TakeArty(*args)
            if atype == 'drop':
                return raw_action
    def TakeArty(self, treasure, bid):
        return 'take', treasure, bid + self.random.randrange(0, 2)

    def account(self, state):
        raw_action = self.account_clone.get_action(state)
        if raw_action == 'next' or raw_action == 'previous':
            return raw_action
        else:
            atype, *args = raw_action
            if atype == 'take':
                return self.TakeAcc(*args)
            if atype == 'drop':
                return raw_action
    def TakeAcc(self, treasure, bid):
        return 'take',treasure,bid + self.random.randrange(0, 2)

    def get_extra(self, state, take=0, drop=0):
        w = state.carry_weight + take - drop
        return state.stamina - ((10 + math.ceil(w/5)) * state.room)
    def backup_arty(self, state):
        if state.inventory:
            ivals = {}
            for i in range(len(state.inventory)):
                itm = state.inventory[i]
                ivals[i] = itm.value / (itm.weight + 5)
            worstiind = min(ivals, key=lambda x: ivals[x])
            worsti = (worstiind,
                      state.inventory[worstiind].value,
                      state.inventory[worstiind].weight)
        else:
            worsti = None
        if self.drop and worsti:
            self.drop = False
            return 'drop', worsti[0]
        if state.treasures:
            tvals = {}
            for i in range(len(state.treasures)):
                itm = state.treasures[i]
                if itm.weight > (int(state.room/12) or 2):
                    continue
                tvals[i] = (itm.value * (25-state.room)) / (itm.weight * (state.carry_weight+1))
            bestord = sorted(tvals, key=lambda x: tvals[x])
            topt = []
            for i in bestord:
                topt.append((i,
                             state.treasures[i].value,
                             state.treasures[i].weight))
        else:
            topt = None
        extra = self.get_extra(state)
        if extra > CONTINUE_IN: 
            return 'next'
        if extra < 0 and worsti:
            return 'drop', worsti[0]
        if extra < state.room:
            return 'previous'
        if extra > JUST_TAKE and topt:
            choose = topt[:len(state.treasures)//3+1]
            for t in choose:
                bid = int(bool(len(state.players)))*3 + t[2]
                if self.get_extra(state, t[2]) - bid >= 0:
                    if t[2] + state.carry_weight <= 50:
                        return 'take', t[0], bid
        if topt and worsti:
            for t in topt[:len(state.treasures)//3+1]:
                if t[1] > worsti[1] or t[2] < worsti[2]:
                    bid = int(bool(len(state.players)))*3 + t[2]
                    if self.get_extra(state, t[2], worsti[2]) - 1 - bid >= 0:
                        if bid < state.stamina and t[2] + state.carry_weight <= 50:
                            self.drop = True
                            return 'take', t[0], bid
        return 'previous'

स्काउंडर मुख्य रूप से अन्य प्रतियोगियों के साथ हस्तक्षेप करने के लिए काम करता है। वर्तमान में यह Sprinter, Artyventurer, और Accountant के साथ हस्तक्षेप करता है (यह सूची समय के साथ बढ़ेगी बशर्ते कि यह Scoundrel के सर्वोत्तम हित में हो)। यह अन्य बॉट्स की नकल करके और फिर आउट-बिडिंग, अंडर-कटिंग, या अन्यथा अवशेषों पर लड़ने के द्वारा करता है। जैसे, यह संभावना नहीं है कि यह प्रविष्टि लीडरबोर्ड पर कभी भी हावी हो जाएगी और इसके बजाय एक खराब शक्ति के रूप में काम करती है। इस पोस्टिंग के समय वर्तमान संशोधन इसे लगभग 7 के औसत स्कोर के साथ 2 वें स्थान पर रखता है।

बदमाश दूसरे बीओटी के कोड को एक अप्रभेद्य क्लोन कॉपी के रूप में सीधे निष्पादित करके स्काउट के खिलाफ बचाव के लिए अन्य बॉट के प्रयासों को विफल करता है। आयात किए गए मुद्दों के साथ डुप्लिकेट किए गए प्रवेशकों के परिणामस्वरूप मुद्दों को चिंतन के माध्यम से क्लोन बनाने के माध्यम से हल किया गया था (संपादित करें जिसमें गणितीय निर्धारण के बारीक विवरण शामिल हैं, स्टैक एक्सचेंज के दृष्टिकोण से वांछनीय नहीं है, लेकिन उसी परिणाम में परिणाम होगा)। KOTH चुनौतियों के साथ ही इसे अनुमति देने का इतिहास है।

दिलचस्प होने के लिए टीम के खिलाड़ियों को रखने के लिए बदमाश टीम की जगह लेते हैं। इस संपादन के बाद, टीमस्टर्स को नियंत्रक द्वारा स्क्रैप नहीं किया जाना चाहिए।

4/17/2019 अपडेट करें: आगे काउंटर-काउंटर उपाय।

द टीमस्टर्स (गैरकानूनी रूप से प्रस्तुत)

लेकिन स्थानीय रूप से चलाने के लिए स्वतंत्र महसूस करें जहां 8 से अधिक अन्य प्रतियोगी नहीं हैं!

class TeamsterA(Adventurer):
    def get_action(self, state):
        if state.room < 25 and state.carry_weight == 0:
            return 'next'
        if state.room == 25 and len(state.players) == 0 and len(state.inventory) <= 1:
            if state.treasures and len(state.inventory) == 0:
                tvals = {}
                for i in range(len(state.treasures)):
                    itm = state.treasures[i]
                    if itm.weight == 1:
                        return 'take',i,1
                for i in range(len(state.treasures)):
                    itm = state.treasures[i]
                    if itm.weight == 2:
                        return 'take',i,2
            if state.carry_weight > 0 and len(state.inventory) == 1 and int(state.inventory[0].name.strip('Treasure #')) < 500:
                return 'drop',0
            return 'previous'
        if state.room >= 25:
            if (((state.carry_weight+4) / 5) + 10) * state.room >= state.stamina:
                return 'previous'
            if len(state.inventory) == 1 and int(state.inventory[0].name.strip('Treasure #')) < 500:
                return 'drop',0
            if state.treasures:
                tvals = {}
                for i in range(len(state.treasures)):
                    itm = state.treasures[i]
                    if int(itm.name.strip('Treasure #')) > 500:
                        if (((state.carry_weight+3+itm.weight) / 5) + 10) * state.room >= state.stamina:
                            return 'previous'
                        return 'take',i,itm.weight
                for i in range(len(state.treasures)):
                    itm = state.treasures[i]
                    if itm.weight == 1:
                        return 'take',i,1
                for i in range(len(state.treasures)):
                    itm = state.treasures[i]
                    if itm.weight == 2:
                        return 'take',i,2
                if len(state.inventory) > 0:
                    return 'previous'
                return 'next'
        return 'previous'

class TeamsterB(Adventurer):
    def get_action(self, state):
        if state.treasures:
            tvals = {}
            for i in range(len(state.treasures)):
                itm = state.treasures[i]
                w = itm.weight
                v = itm.value
                if w + state.carry_weight > self.max_total_weight or w > self.max_single_weight:
                    w = 100
                if v / w < state.room * self.min_value_ratio:
                    v = 0
                tvals[i] = v / w
            besttind = max(tvals, key=lambda x: tvals[x])
            bestt = (besttind,
                     state.treasures[besttind].value,
                     state.treasures[besttind].weight)
        else:
            bestt = None
        if state.room < self.max_dive_dist and state.carry_weight == 0:
            return 'next'
        if state.room > 25 and bestt and state.carry_weight + bestt[2] <= self.max_total_weight and bestt[1] > 0 and bestt[2] <= self.max_single_weight and len(state.players) == 0:
            return 'take',bestt[0],bestt[2]
        if state.carry_weight > 0 and state.room > 25 and len(state.players) == 0:
            return 'previous'
        if state.carry_weight > 0:
            return 'drop',0
        if state.carry_weight > 0:
            return 'take',bestt[0],bestt[2]
        return 'previous'
    def enter_ruins(self):
        self.max_single_weight = 3
        self.max_total_weight = 20
        self.min_value_ratio = 2.5
        self.max_dive_dist = 55
        pass

यह प्रविष्टि (जबकि अब स्पष्ट रूप से अमान्य है), वास्तव में, दो बॉट हैं, और नियंत्रक खुशी से उन दोनों को परिमार्जन करेगा और उन्हें प्रतियोगी सूची में जोड़ देगा (क्योंकि हुर्रे पायथन?)

चरण 1:

  • टीमस्टरए 25 (ईश) 1 के स्तर तक नीचे जाता है और बार-बार उठाता है और सबसे हल्के खजाने को छोड़ता है जो वह पा सकता है। यह दूसरे चरण तक 1 स्टैमिना की बारी है।
  • टीमस्टरबी 55 के स्तर तक नीचे जाती है और चारों ओर बिछाने वाले सभी कीमती सामानों को चुनती है और फिर 25 (ईश) के स्तर तक वापस जाती है। 2 फिर चरण 2 शुरू होता है।

1. यदि किसी मंजिल पर 3 से कम वजन का खजाना नहीं है, तो वह नीचे जाता है।
2. जब तक वह आखिरी साहसी सतह पर वापस आने की गारंटी नहीं देता , तब तक उसे कुछ करना होगा।

2 चरण:

  • थकावट से मरने के लिए रेंगने से पहले टीमस्टरब अपनी जेब खाली कर देता है। हमें पता था कि आप इसे कर सकते हैं।
  • TeamsterA सोचता है "वे कुछ चमकदार ट्रिंकेट हैं, अच्छे दोस्त ol 'पाल!" और बाहर निकलने के लिए आगे बढ़ने से पहले कमरे में अन्य कबाड़ की तुलना में बहुत अधिक मूल्यवान खजाने पर भार, सोने से भरा जेब।

खजाने का नाम वास्तव में काम में आया ताकि तर्क को फर्श पर 25 रद्दी पर लोड न करने और जल्दी छोड़ने में मदद मिल सके क्योंकि दोनों बॉट्स के बीच संवाद करने का कोई तरीका नहीं था (और टीमस्टरए हमेशा खुद को किसी और के साथ एक कमरे में पाएंगे। TeamsterB वापस आ गया था)।

अगला तार्किक निष्कर्ष: एक सेना बनाना

सिद्धांत रूप में, इसका उपयोग गहराई को गिराने और कमरे 98 के रूप में गहरे से खजाने को प्राप्त करने के लिए किया जा सकता है, हालांकि, जैसा कि 2 बॉट से अधिक की आवश्यकता होगी, उन बॉट्स वाले तर्क तेजी से जटिल हो जाएंगे, और जैसा कि मैं निश्चित हूं कि यह है एक अलिखित नियम का उल्लंघन करने के लिए एक अवैध सबमिशन, इसलिए मैं परेशान नहीं होने जा रहा हूं।

प्रभावी रूप Aसे 30 पर Bप्रतीक्षा करता है, 50 पर प्रतीक्षा करता है ... n98 तक गोता लगाता है, एक खज़ाना उठाता है, 97 पर जाता है, इसे गिराता है (और फिर मर जाता है), n-1इसे उठाता है और 96 तक ले जाता है ... Cइसे छोड़ता है (मर जाता है), Bइसे उठाता है। ऊपर और 30 तक जाता है, Aइसे छोड़ देता है (मर जाता है), इसे उठाता है और निकास पर लौटता है।

मेरा अनुमान है कि इसमें 11 बॉट लगेंगे।

हालाँकि, यह तब तक करने योग्य नहीं है जब तक कि आप प्लायाहेड या आर्टीवांट जैसे प्रविष्टियों के साथ प्रतिस्पर्धा करने के लिए उस गहराई से लगभग 4 खजाने की वसूली नहीं कर सकते, क्योंकि लागत बढ़ने के लिए सहनशक्ति की लागत और खजाने के औसत मूल्य के बीच स्केलिंग के कारण।

नमूना परिणाम

$ 4000 के तहत दुर्लभ स्कोर, कभी-कभी $ 6000 का लाभ होता है।

[Turn 141] Homer the Great (TeamsterA) exited the ruins with 286 stamina
    and 16 treasures, totaling $4900 in value.
[Game End] The game has ended!
[Game End] Homer the Great (TeamsterA) won the game

[Turn 145] Samwell Jackson DDS (TeamsterA) exited the ruins with 255 stamina
    and 20 treasures, totaling $6050 in value.
[Game End] The game has ended!
[Game End] Samwell Jackson DDS (TeamsterA) won the game

[Turn 133] Rob the Smuggler (TeamsterA) exited the ruins with 255 stamina
    and 12 treasures, totaling $3527 in value.
[Game End] The game has ended!
[Game End] Eliwood the Forgettable (PlanAhead) won the game

1
मुझे लगता है कि जब केवल एक बॉट प्रति व्यक्ति होने जा रहा था तो इस तरह के स्पष्ट नियम की कोई आवश्यकता नहीं थी। लेकिन एक विशेष बॉट को नीरस कारणों से लक्षित करने के बारे में नियम वास्तव में एक साथ कई बॉट को भंग करने के समान नहीं है। इसलिए ओपी से स्पष्ट निर्णय लेने की जरूरत है।
Moogie

हाँ, यह मेरे से नहीं, dawg होने वाला है। इस तरह की चीज़ों के बारे में मेरे मन में एक साथ काम करने वाली बॉट्स थी।
बीफस्टर

1
@Beefster यही मुझे लगा। मुझे हालांकि इसे बनाने में मज़ा आया। मैं आज शाम को एड-टू-रोकथाम-समावेशन संभालूंगा।
ड्रेको

मैं इस पर विचार करने की अनुमति देता हूं जब एक बार 11 से अधिक प्रतियोगी होते हैं क्योंकि इसकी प्रभावशीलता वैसे भी टैंक होगी। ज्यादातर इसलिए कि मैं ऑटोबैन सबमिशन के लिए कोड नहीं बनाना चाहता।
बीफस्टर

यदि आप पहले से ही पहले कोड ब्लॉक को स्क्रैप कर रहे हैं, तो मुझे केवल इतना करना होगा कि शीर्ष पर एक अलग बॉट में संपादित किया जाए।
ड्रेको

2

पीछे की ओर

क्योंकि यह रिवर्स में संचालित होता है

import math

class Backwards (Adventurer):
    def enter_ruins(self):
        self.goal = 5000
        self.diving = True

    def expected_rooms_left(self, state):
        if not self.diving:
            return state.room
        else:
            return state.stamina / 18

    def ratio(self, state, treasure):
        stamina_cost = treasure.weight * (1 + 1/5 * self.expected_rooms_left(state)) + math.ceil(len(state.players)/2.9)
        ratio = (treasure.value / (self.goal - state.total_value)) / (stamina_cost / state.stamina)
        return ratio

    def get_action(self, state):
        room, treasures, players, inventory, stamina = state
        if stamina < room * (math.ceil(state.carry_weight / 5) + 10) + 40 or stamina < (room+2.976) * (math.ceil(state.carry_weight / 5) + 11):
            self.diving = False
        if stamina < (room+0.992) * (math.ceil(state.carry_weight / 5) + 10.825):
            return 'previous'

        worthwhile = []
        for i, treasure in enumerate(treasures):
            ratio = self.ratio(state, treasure)
            if ratio >= 1 and state.carry_weight + treasure.weight <= 50:
                worthwhile.append((ratio, i))

        if worthwhile:
            ratio, index = sorted(worthwhile, reverse=True)[0]
            treasure = treasures[index]
            bid = treasures[index].weight + math.ceil(len(players)/2.9)
            if (not self.diving or ratio > 2.8) and stamina >= bid + (room) * (math.ceil((state.carry_weight+treasures[index].weight) / 5) + 10):
                return 'take', index, bid
        return 'next' if self.diving else 'previous'

इसे पिछड़ा क्यों कहा जाता है?

क्योंकि मैंने द अकाउंटेंट को लिया और इसे अपना तर्क बनाने की कोशिश की, जैसे कि यह गहरा डुबकी लगाएगा, फिर अपनी पसंदीदा लूट को रास्ते से हटाकर (एकाउंटेंट के पीछे की तरफ) उठाएगा।

अंत में यह अभी भी रास्ते में अपने बहुत से पुरस्कार इकट्ठा करता है (पारंपरिक इन-कलेक्ट करने वाले साधकों से पहले उन्हें स्कूपिंग करता है, सभी को पीछे की ओर संचालित करता है), लेकिन इसके बारे में और अधिक चयनात्मक जिसके बारे में वह लेता है, हालांकि अभी भी वापस रास्ते पर चीजों को उठाता है।

अंतिम परिणाम यह है कि सहनशक्ति को उस तरह से संरक्षित किया जाता है, जबकि अभी भी उच्च-मूल्य के खजाने को प्राथमिकता दी जाती है, फिर चारों ओर एक गहरी बारी का लाभ उठाते हैं और रास्ते में आसान उठाते हैं। बैकवर्ड को कमरे 41 के नीचे से खजाने को इकट्ठा करने के लिए जाना जाता है (और विकास के दौरान प्रवेश करेगा, फिर तुरंत छोड़ दें, कक्ष 42)।


2

इनाम के लिए शिकार करने वाला शिकारी

सरल विधि सबसे अच्छी है। जितना संभव हो उतना गहरा और मूल्यवान खजाने को पकड़ो। वापस रास्ते पर कम मूल्यवान खजाने को पकड़ो।

import math

class BountyHunter(Adventurer):
    def move_cost(self, state, additional_weight):
        return 10 + int(math.ceil((state.carry_weight + additional_weight) / 5))

    def get_action(self, state):
        can_go_deeper = state.stamina > (state.room + 2) * self.move_cost(state, 0)
        if state.treasures:
            best_ratio = 0
            best_index = 0
            best_weight = 0
            for i, treasure in enumerate(state.treasures):
                ratio = treasure.value / treasure.weight
                if ratio > best_ratio:
                    best_ratio = ratio
                    best_index = i
                    best_weight = treasure.weight
            limit = 160 if can_go_deeper else 60
            bid = best_weight + 2 if len(state.players) >= 1 else best_weight
            if state.carry_weight + best_weight <= 50 and best_ratio >= limit and state.stamina >= bid + state.room * self.move_cost(state, best_weight):
                return 'take', best_index, bid
        if can_go_deeper:
            return 'next'
        else:
            return 'previous'

लगता है कि आपको इनाम मिल रहा है। न केवल यह बैकवर्ड की तुलना में बेहतर प्रदर्शन करता है, बल्कि यह बैकवर्ड को टैंक के लिए भी कारण बनता है। बहुत बढ़िया।
बीफस्टर

1

हल्के

एक साधारण बॉट जो अभी भी काफी अच्छा प्रदर्शन करता है।

खंडहर (वर्तमान में 21 कमरे) में जाने के बाद, यह उस कमरे में सबसे अच्छा खजाना लेगा जो केवल 1 किग्रा (इसलिए बॉट का नाम) है और इन्वेंट्री में कम से कम मूल्यवान खजाने से अधिक मूल्यवान है। यदि इन्वेंट्री भरी हुई है, तो कम से कम मूल्यवान खजाना छोड़ें। यदि कोई अन्य कार्रवाई नहीं की जाती है, तो खंडहर में चला जाता है। यदि हम अपनी सहनशक्ति की सीमा पर हैं कि जीवित बाहर निकलने में सक्षम हों तो बाहर निकलें

import math

class LightWeight(Adventurer):

    def get_action(self, state):
        move_cost = 10 + int(math.ceil(state.carry_weight / 5))

        # are we now at the limit of stamina to still get back alive?
        if (state.stamina / move_cost <= state.room + 3):
            # head back to the exit
            return 'previous'

        if (state.room < 21):
            return 'next'

        bestRoomTreasure = None
        bestRoomTreasureId = -1
        worstMyTreasure = None
        worstMyTreasureId = -1

        # find our worst treasure
        i=0
        for treasure in state.inventory:
            if (worstMyTreasure is None or treasure.value < worstMyTreasure.value):
                worstMyTreasure = treasure
                worstMyTreasureId=i
            i+=1

        # we have hit our carrying capacity... we are now going to dump least valuable treasure
        if (state.carry_weight==50):

            # dump the worst treasure
            return 'drop',worstMyTreasureId

        # find the best room treasure
        i=0
        for treasure in state.treasures:
            if (treasure.weight == 1 and (worstMyTreasure is None or treasure.value > worstMyTreasure.value)):
                if (bestRoomTreasure is None or treasure.value > bestRoomTreasure.value):
                    bestRoomTreasure = treasure
                    bestRoomTreasureId = i
            i+=1

        # we have found a treasure better than we already have!
        if (bestRoomTreasure is not None):
            return 'take',bestRoomTreasureId,1

        # no treasures are better than what we already have so go to next room
        return 'next'

मैं विधि dumpingमें डालने की सलाह दूंगा enter_ruins। यह वास्तव में खेल के बीच इसे याद रखेगा और खेल 2 पर काम नहीं करेगा। तकनीकी रूप से अनुमति नहीं है, लेकिन मैंने अभी नियम जोड़ा (मैं इसे पहले भूल गया था लेकिन यह मेरा इरादा था), इसलिए मैं कुछ सुस्त कटौती करूंगा। : पी
बीफस्टर

@ बीफ़स्टर मैंने डंपिंग स्टेट फ्लैग को हटा दिया है, इसकी ज़रूरत नहीं है क्योंकि बॉट केवल एक ही खजाने को डंप करता है। यह अपने खजाने का आधा हिस्सा डंप करता था। इसलिए नए नियम के अनुकूल होना चाहिए।
मोगी

1

Memorizer

मैं अपने खुद के कोठरी में बॉट जमा कर सकता हूं, है ना?

from __main__ import Adventurer
import math
from collections import namedtuple

class TooHeavy(Exception):
    pass

TreasureNote = namedtuple(
    'TreasureNote',
    ['utility', 'cost', 'room', 'name', 'value', 'weight']
)

def find_treasure(treasures, name):
    for i, t in enumerate(treasures):
        if t.name == name:
            return i, t
    raise KeyError(name)

EXPLORE_DEPTH = 30
TRINKET_MINIMUM_VALUE = 60

class Memorizer(Adventurer):
    def enter_ruins(self):
        self.seen = []
        self.plan = []
        self.backups = []
        self.diving = True
        self.dive_grab = False

    def plan_treasure_route(self, state):
        self.plan = []
        self.backups = []
        weight = state.carry_weight
        for treasure in self.seen:
            if weight + treasure.weight <= 50:
                self.plan.append(treasure)
                weight += treasure.weight
            else:
                self.backups.append(treasure)
        room_utility = lambda t: (t.room, t.utility)
        self.plan.sort(key=room_utility, reverse=True)

    def iter_backups(self, state):
        names = {t.name for t in state.treasures}
        owned = {t.name for t in state.inventory}
        for treasure in self.backups:
            if (treasure.room == state.room
                    and treasure.name in names
                    and treasure.name not in owned):
                yield treasure

    def take(self, state, name):
        index, treasure = find_treasure(state.treasures, name)
        if state.carry_weight + treasure.weight > 50:
            raise TooHeavy(name)
        if state.players:
            bid_bonus = self.random.randrange(len(state.players) ** 2 + 1)
        else:
            bid_bonus = 0
        return 'take', index, treasure.weight + bid_bonus

    def get_action(self, state):
        take_chance = 0.9 ** len(state.players)

        if self.diving:
            if self.dive_grab:
                self.dive_grab = False
            else:
                self.seen.extend(
                    TreasureNote(
                        value / weight,
                        weight + math.ceil(weight / 5) * state.room,
                        state.room,
                        name, value, weight
                    )
                    for name, value, weight in state.treasures
                )
            if state.room < EXPLORE_DEPTH:
                if len(state.inventory) < 5:
                    trinkets = [
                        t for t in state.treasures
                        if t.weight == 1
                        and t.value >= TRINKET_MINIMUM_VALUE
                    ]
                    trinkets.sort(key=lambda t: t.value, reverse=True)
                    for candidate in trinkets:
                        if self.random.random() < 0.99 ** (len(state.players) * state.room):
                            try:
                                action = self.take(state, candidate.name)
                            except (KeyError, TooHeavy):
                                pass # WTF!
                            else:
                                self.dive_grab = True
                                return action
                return 'next'
            else:
                self.diving = False
                self.seen.sort(reverse=True)
                self.plan_treasure_route(state)

        carry_weight = state.carry_weight
        if carry_weight == 50:
            return 'previous'

        if self.plan:
            next_index = 0
            next_planned = self.plan[next_index]
            if state.room > next_planned.room:
                return 'previous'

            try:
                while state.room == next_planned.room:
                    if self.random.random() < take_chance:
                        try:
                            return self.take(state, next_planned.name)
                        except (KeyError, TooHeavy):
                            self.plan.pop(next_index)
                            next_planned = self.plan[next_index]
                    else:
                        next_index += 1
                        next_planned = self.plan[next_index]
            except IndexError:
                pass
        else:
            next_planned = TreasureNote(0, 0, 0, 0, 0, 0)

        for candidate in self.iter_backups(state):
            if candidate.utility * 2 > next_planned.utility and self.random.random() < take_chance:
                try:
                    return self.take(state, candidate.name)
                except (KeyError, TooHeavy):
                    pass

        return 'previous'

यह बॉट 30 कमरे में रहता है और इसके द्वारा देखे गए सभी खजाने को याद करता है। उस समय, यह प्रवेश द्वार पर वापस अपना ट्रेक शुरू करता है, जो पहले के कमरों में याद किए गए अच्छे खजाने को लेने की कोशिश करता है।

मुझे उम्मीद थी कि यह बेहतर करेगा। संभावित सुधार बेहतर योजना और अधिक गतिशील होने के कारण हो सकता है कि यह किस कमरे में डाइविंग को रोकता है और बैकअप विकल्पों का पता लगाने के लिए अधिक इच्छुक है।

अपडेट: अब रास्ते में $ 60 या उससे अधिक मूल्य के 1 किलो के खजाने को पकड़ लेता है।


मुझे लगता है कि सभी अच्छे खजाना बस उस बिंदु से चले गए हैं, जहां बॉट वहां वापस आ गया है ... शायद आप एक कॉम्बो की कोशिश कर सकते हैं जहां यह अपने रास्ते पर वास्तव में अच्छा सामान ले जाएगा, औसत दर्जे के खजाने को ध्यान में रखते हुए इसे उठा सकता है। अपने रास्ते पर वापस?
ArBo

यह बहुत दूर तक जा सकता है
बीफस्टर

FYI करें, ऐसा लगता है कि यह कभी-कभी गलतफहमी पैदा कर देता है, अगर इसे वापस पाने के लिए पर्याप्त सहनशक्ति हो: [Turn 072] Ryu Ridley (Memorizer) collapsed in the doorway to room #1 and died of exhaustion
Larkeith 7

1

ponderer

मुझे लगता है कि यह मेमोराइज़र से काफी मिलता-जुलता है, यह चुने हुए कमरों के ज्ञान का उपयोग करता है कि कौन से कमरे और खजाने को वापस बाहर निकलने के रास्ते से इकट्ठा करना है, हालांकि इसे स्वतंत्र रूप से प्राप्त किया गया है।

यह बॉट एक यादृच्छिक गहरे कमरे तक जाता है जो रास्ते में पाए जाने वाले खजाने का रिकॉर्ड लेता है। एक बार टारगेट रूम में फिर निकास के रास्ते पर ले जाने के लिए खजाने के आदर्श चयन पर विचार करना होगा । प्रत्येक बारी यह लेने के लिए खजाने की सबसे अधिक संभावना सबसे अच्छा चयन निर्धारित करने के लिए फिर से विचार करेगा ।

वर्तमान में एक साधारण एल्गोरिथ्म (कमरे की संख्या का व्युत्क्रम शक्ति) है जो प्रत्येक कमरे के लिए ग्रहण किए गए खजाने की अनुमानित संख्या (या इस बॉट द्वारा जाने पर ली गई होगी) की पैदावार करता है और इसलिए इन खजानों / कमरों पर विचार करते समय इन खजाने की अनदेखी की जाती है। से लेना है। मेरे पास अन्य उन्नत एल्गोरिदम के लिए विचार हैं कि कौन से खजाने रहते हैं। लेकिन मुझे यह देखना होगा कि क्या लाभ इसके लायक है।

import math

class Ponderer(Adventurer):

  class PondererTreasure:
    def __init__(self):
        self.weight = 0
        self.value = 0
        self.id = -1
        pass

  class PondererRoom:
    def __init__(self):
        self.treasures = []
        pass

  def enter_ruins(self):
      self.exiting = False
      self.sprintToRoom = self.random.randrange(30,33)
      self.rooms = {}
      self.roomsToSkip = 0
      pass

  def getBestEstimatedFinalValue(self, roomId, carry_weight, stamina, action, valueCache):
    if (roomId<=0):
      return 0

    roomValueCache = valueCache.get(roomId)

    if (roomValueCache is None):
      roomValueCache = {}
      valueCache[roomId] = roomValueCache

    value = roomValueCache.get(carry_weight)
    if (value is None):
      room = self.rooms.get(roomId)

      bestTreasureValue = 0
      bestTreasure = None
      treasures = []
      treasures.extend(room.treasures)
      skipRoomTreasure = Ponderer.PondererTreasure()
      treasures.append(skipRoomTreasure)

      roomFactor = 0.075*roomId
      estimatedTreasuresTakenAtCurrentRoom =  int(min(0.5 * len(room.treasures), max(1, 0.5 * len(room.treasures)*(1.0/(roomFactor*roomFactor)))))

      j=0
      for treasure in treasures:
        if (j>=estimatedTreasuresTakenAtCurrentRoom):
          staminaAfterBid = stamina - treasure.weight
          carry_weightAfterBid = carry_weight + treasure.weight
          move_costAfterBid = 10 + int(math.ceil(carry_weightAfterBid/5))

          if (carry_weightAfterBid <=50 and (staminaAfterBid/move_costAfterBid > roomId+1)):
            bestAccumulativeValue = self.getBestEstimatedFinalValue(roomId-1, carry_weightAfterBid, staminaAfterBid - move_costAfterBid, None, valueCache)

            if (bestAccumulativeValue >= 0):
              bestAccumulativeValue += treasure.value
              if (bestTreasure is None or bestAccumulativeValue > bestTreasureValue):
                bestTreasureValue = bestAccumulativeValue
                bestTreasure = treasure
        j+=1

      if (bestTreasure == skipRoomTreasure):
        if (action is not None):
          newAction = []
          newAction.append('previous')
          action.append(newAction)
        value = 0

      elif (bestTreasure is not None):
        if (action is not None):
          newAction = []
          newAction.append('take')
          newAction.append(bestTreasure.id)
          newAction.append(bestTreasure.weight)
          action.append(newAction)
        value = bestTreasureValue

      else:
        if (action is not None):
          newAction = []
          newAction.append('previous')
          action.append(newAction)
        value = -1

      roomValueCache[carry_weight] = value
    return value

  def get_action(self, state):
    room = Ponderer.PondererRoom()

    i=0
    for treasure in state.treasures:
      pondererTreasure = Ponderer.PondererTreasure()
      pondererTreasure.weight = treasure.weight
      pondererTreasure.value = treasure.value
      pondererTreasure.id = i

      room.treasures.append(pondererTreasure)
      i+=1

    room.treasures.sort(key=lambda x: x.value/x.weight, reverse=True)

    self.rooms[state.room] = room

    if (self.exiting == False and state.room < self.sprintToRoom):
      return 'next'

    self.exiting = True

    action = []
    valueCache = {}

    self.getBestEstimatedFinalValue(state.room, state.carry_weight, state.stamina, action, valueCache)

    if (action[0][0] == 'take'):
      return 'take', action[0][1], action[0][2]

    return action[0][0]

1

hoarder

import math

class Hoarder(Adventurer):
  def canGoOn(self, state):
    costToMove = 10 + math.ceil(state.carry_weight / 5)
    return (state.room + 2) * costToMove <= state.stamina

  def canTakeTreasure(self, state, treasure):
    costToMove = 10 + math.ceil(state.carry_weight / 5)
    treasureCost = treasure.weight + 1
    return treasureCost + state.room * costToMove <= state.stamina

  def get_action(self, state):
    if (len(state.treasures) == 0):
      if (self.canGoOn(state)):
        return "next"
      else:
        return "previous"
    else:
      bestTreasure = -1
      for i, treasure in enumerate(state.treasures):
        if self.canTakeTreasure(state, treasure):
          if (bestTreasure == -1):
            bestTreasure = i
          elif state.treasures[bestTreasure].value < state.treasures[i].value:
            bestTreasure = i
      if (bestTreasure == -1):
        return "previous"
      return "take", bestTreasure, state.treasures[bestTreasure].weight+1

होर्डर एक कमरे में तब तक रहता है जब तक कि यह कमरे के सभी खजाने को नहीं ले जाता (या गणना करता है कि इसमें ले जाने / आगे बढ़ने के लिए पर्याप्त सहनशक्ति नहीं है)। जब सभी खजाने चले गए हैं, अगर बॉट सुरक्षित रूप से आगे बढ़ सकता है, और सभी खजाने को लेने की प्रक्रिया जारी रख सकता है।


यह अपने बैकपैक को ओवरफ्लो करके हर गेम को मरता है।
बीफस्टर

मेरे जैसा Minecraft में (͜ʖ ° in This °) यह बॉट लूट जाएगा, गहराई तक जाएगा, और फिर मूल्यवान लूट पाएगा। तो यह वही होगा जो उसने सोचा था कि पहले अच्छी लूट थी। तो इस कारण से Backwardsकी, Sprinterकी और Memorizerकी रणनीति काम; क्योंकि वे जानते हैं कि उनके द्वारा देखे गए प्रत्येक खजाने के सापेक्ष मूल्य क्या हैं।
वी। कोर्टोइस

0

ग़ोताख़ोर

(फिलहाल परीक्षण नहीं कर सकते, इसलिए मुझे बताएं कि क्या यह टूट गया है)

class Diver(Adventurer):
    def get_action(self, state):
        # Don't take anything on the way in.
        if state.stamina > 700:
            return 'next'

        # Take the most valuable thing we can take without dying.
        for treasure in sorted(state.treasures, key=lambda x: x.value, reverse=True):
            total = treasure.weight + state.carry_weight
            if total <= 50 and (10 + (total + 4) // 5) * state.room + treasure.weight <= state.stamina:
                return 'take', state.treasures.index(treasure), treasure.weight

        # If there's nothing else we can do, back out.
        return 'previous'

खंडहरों में सबसे अच्छा खजाना गहरा है, इतना गहरा गोता लगाओ, फिर हम बाहर निकलने के रास्ते पर क्या कर सकते हैं।


मैं अजगर के साथ बहुत अनुभवी नहीं हूं, लेकिन divingपरिभाषित कहां है ?
अज्ञानता का अवतार

1
@EmbodimentofIgnorance Enter_ruins () में, जिसे खेल के चलने से पहले कहा जाता है और क्रियाएं की जाती हैं।

Jacob the Orphan (Diver) was sliced in half by a swinging blade trap.सुनिश्चित नहीं है कि आपने क्या गलत किया है, लेकिन इसका मतलब है 'अमान्य वापसी' AFAIK।
आर्टेमिस मोनिका

@ArtemisFowl उन्होंने खजाने के लिए बहुत कम बोली लगाई। इसे लेने के लिए खजाने के वजन का खर्च आता है।
बीफस्टर

@ बीफ़स्टर ओह यूप।
आर्टेमिस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.