The Rock, Paper, Scissors, Lizard, Spock Tournament of Epicness


98

กระดานแต้มนำล่าสุด @ 2014-08-02 12:00

| Pos # | Author               | Name                    | Language   | Score | Win   | Draw  | Loss  | Avg. Dec. Time |
+-------+----------------------+-------------------------+------------+-------+-------+-------+-------+----------------+
| 1st   | Emil                 | Pony                    | Python2    | 064   | 064   | 000   | 005   | 0026.87 ms     |
| 2nd   | Roy van Rijn         | Gazzr                   | Java       | 062   | 062   | 001   | 006   | 0067.30 ms     |
| 2nd   | Emil                 | Dienstag                | Python2    | 062   | 062   | 001   | 006   | 0022.19 ms     |
| 4th   | ovenror              | TobiasFuenke            | Python2    | 061   | 061   | 001   | 007   | 0026.89 ms     |
| 5th   | PhiNotPi             | BayesianBot             | Perl       | 060   | 060   | 000   | 009   | 0009.27 ms     |
| 6th   | Claudiu              | SuperMarkov             | Python2    | 058   | 058   | 001   | 010   | 0026.77 ms     |
| 7th   | histocrat            | Alternator              | Ruby       | 057   | 057   | 001   | 011   | 0038.53 ms     |
| 8th   | histocrat            | LeonardShelby           | Ruby       | 053   | 053   | 000   | 016   | 0038.55 ms     |
| 9th   | Stretch Maniac       | SmarterBot              | Java       | 051   | 051   | 002   | 016   | 0070.02 ms     |
| 9th   | Martin Büttner       | Markov                  | Ruby       | 051   | 051   | 003   | 015   | 0038.45 ms     |
| 11th  | histocrat            | BartBot                 | Ruby       | 049   | 049   | 001   | 019   | 0038.54 ms     |
| 11th  | kaine                | ExcitingishBot          | Java       | 049   | 049   | 001   | 019   | 0065.87 ms     |
| 13th  | Thaylon              | UniformBot              | Ruby       | 047   | 047   | 001   | 021   | 0038.61 ms     |
| 14th  | Carlos Martinez      | EasyGame                | Java       | 046   | 046   | 002   | 021   | 0066.44 ms     |
| 15th  | Stretch Maniac       | SmartBot                | Java       | 045   | 045   | 001   | 023   | 0068.65 ms     |
| 16th  | Docopoper            | RoboticOboeBotOboeTuner | Python2    | 044   | 044   | 000   | 025   | 0156.55 ms     |
| 17th  | Qwix                 | Analyst                 | Java       | 043   | 043   | 001   | 025   | 0069.06 ms     |
| 18th  | histocrat            | Analogizer              | Ruby       | 042   | 042   | 000   | 027   | 0038.58 ms     |
| 18th  | Thaylon              | Naan                    | Ruby       | 042   | 042   | 004   | 023   | 0038.48 ms     |
| 20th  | Thaylon              | NitPicker               | Ruby       | 041   | 041   | 000   | 028   | 0046.21 ms     |
| 20th  | bitpwner             | AlgorithmBot            | Python2    | 041   | 041   | 001   | 027   | 0025.34 ms     |
| 22nd  | histocrat            | WereVulcan              | Ruby       | 040   | 040   | 003   | 026   | 0038.41 ms     |
| 22nd  | Ourous               | QQ                      | Cobra      | 040   | 040   | 003   | 026   | 0089.33 ms     |
| 24th  | Stranjyr             | RelaxedBot              | Python2    | 039   | 039   | 001   | 029   | 0025.40 ms     |
| 25th  | JoshDM               | SelfLoathingBot         | Java       | 038   | 038   | 001   | 030   | 0068.75 ms     |
| 25th  | Ourous               | Q                       | Cobra      | 038   | 038   | 001   | 030   | 0094.04 ms     |
| 25th  | Ourous               | DejaQ                   | Cobra      | 038   | 038   | 001   | 030   | 0078.31 ms     |
| 28th  | Luis Mars            | Botzinga                | Java       | 037   | 037   | 002   | 030   | 0066.36 ms     |
| 29th  | kaine                | BoringBot               | Java       | 035   | 035   | 000   | 034   | 0066.16 ms     |
| 29th  | Docopoper            | OboeBeater              | Python2    | 035   | 035   | 002   | 032   | 0021.92 ms     |
| 29th  | Thaylon              | NaanViolence            | Ruby       | 035   | 035   | 003   | 031   | 0038.46 ms     |
| 32nd  | Martin Büttner       | SlowLizard              | Ruby       | 034   | 034   | 004   | 031   | 0038.32 ms     |
| 33rd  | Kyle Kanos           | ViolentBot              | Python3    | 033   | 033   | 001   | 035   | 0032.42 ms     |
| 34th  | HuddleWolf           | HuddleWolfTheConqueror  | .NET       | 032   | 032   | 001   | 036   | 0029.86 ms     |
| 34th  | Milo                 | DogeBotv2               | Java       | 032   | 032   | 000   | 037   | 0066.74 ms     |
| 34th  | Timmy                | DynamicBot              | Python3    | 032   | 032   | 001   | 036   | 0036.81 ms     |
| 34th  | mccannf              | YAARBot                 | JS         | 032   | 032   | 002   | 035   | 0100.12 ms     |
| 38th  | Stranjyr             | ToddlerProof            | Java       | 031   | 031   | 010   | 028   | 0066.10 ms     |
| 38th  | NonFunctional User2..| IHaveNoIdeaWhatImDoing  | Lisp       | 031   | 031   | 002   | 036   | 0036.26 ms     |
| 38th  | john smith           | RAMBOBot                | PHP        | 031   | 031   | 002   | 036   | 0014.53 ms     |
| 41st  | EoinC                | SimpleRandomBot         | .NET       | 030   | 030   | 005   | 034   | 0015.68 ms     |
| 41st  | Martin Büttner       | FairBot                 | Ruby       | 030   | 030   | 006   | 033   | 0038.23 ms     |
| 41st  | Docopoper            | OboeOboeBeater          | Python2    | 030   | 030   | 006   | 033   | 0021.93 ms     |
| 44th  | undergroundmonorail  | TheGamblersBrother      | Python2    | 029   | 029   | 000   | 040   | 0025.55 ms     |
| 45th  | DrJPepper            | MonadBot                | Haskel     | 028   | 028   | 002   | 039   | 0008.23 ms     |
| 46th  | Josef E.             | OneBehind               | Java       | 027   | 027   | 007   | 035   | 0065.87 ms     |
| 47th  | Ourous               | GitGudBot               | Cobra      | 025   | 025   | 001   | 043   | 0053.35 ms     |
| 48th  | ProgramFOX           | Echo                    | .NET       | 024   | 024   | 004   | 041   | 0014.81 ms     |
| 48th  | JoshDM               | SelfHatingBot           | Java       | 024   | 024   | 005   | 040   | 0068.88 ms     |
| 48th  | Trimsty              | Herpetologist           | Python3    | 024   | 024   | 002   | 043   | 0036.93 ms     |
| 51st  | Milo                 | DogeBot                 | Java       | 022   | 022   | 001   | 046   | 0067.86 ms     |
| 51st  | William Barbosa      | StarWarsFan             | Ruby       | 022   | 022   | 002   | 045   | 0038.48 ms     |
| 51st  | Martin Büttner       | ConservativeBot         | Ruby       | 022   | 022   | 001   | 046   | 0038.25 ms     |
| 51st  | killmous             | MAWBRBot                | Perl       | 022   | 022   | 000   | 047   | 0016.30 ms     |
| 55th  | Mikey Mouse          | LizardsRule             | .NET       | 020   | 020   | 007   | 042   | 0015.10 ms     |
| 55th  | ja72                 | BlindForesight          | .NET       | 020   | 020   | 001   | 048   | 0024.05 ms     |
| 57th  | robotik              | Evolver                 | Lua        | 019   | 019   | 001   | 049   | 0008.19 ms     |
| 58th  | Kyle Kanos           | LexicographicBot        | Python3    | 018   | 018   | 003   | 048   | 0036.93 ms     |
| 58th  | William Barbosa      | BarneyStinson           | Lua        | 018   | 018   | 005   | 046   | 0005.11 ms     |
| 60th  | Dr R Dizzle          | BartSimpson             | Ruby       | 017   | 017   | 001   | 051   | 0038.22 ms     |
| 60th  | jmite                | IocainePowder           | Ruby       | 017   | 017   | 003   | 049   | 0038.50 ms     |
| 60th  | ArcticanAudio        | SpockOrRock             | PHP        | 017   | 017   | 001   | 051   | 0014.19 ms     |
| 60th  | Dr R Dizzle          | BetterLisaSimpson       | Ruby       | 017   | 017   | 000   | 052   | 0038.23 ms     |
| 64th  | Dr R Dizzle          | LisaSimpson             | Ruby       | 016   | 016   | 002   | 051   | 0038.29 ms     |
| 65th  | Martin Büttner       | Vulcan                  | Ruby       | 015   | 015   | 001   | 053   | 0038.26 ms     |
| 65th  | Dr R Dizzle          | Khaleesi                | Ruby       | 015   | 015   | 005   | 049   | 0038.29 ms     |
| 67th  | Dr R Dizzle          | EdwardScissorHands      | Ruby       | 014   | 014   | 002   | 053   | 0038.21 ms     |
| 67th  | undergroundmonorail  | TheGambler              | Python2    | 014   | 014   | 002   | 053   | 0025.47 ms     |
| 69th  | cipher               | LemmingBot              | Python2    | 011   | 011   | 002   | 056   | 0025.29 ms     |
| 70th  | Docopoper            | ConcessionBot           | Python2    | 007   | 007   | 000   | 062   | 0141.31 ms     |
+-------+----------------------+-------------------------+------------+-------+-------+-------+-------+----------------+
Total Players: 70
Total Matches Completed: 2415
Total Tourney Time: 06:00:51.6877573

หมายเหตุ Tourney

  • WOO HOO 70 บอท
  • Emil ยังคงเป็น KOTH ด้วยPonyและบอทใหม่ของเขาDienstagเกิดขึ้นที่ 3
  • ขอแสดงความยินดีกับ Roy เพื่อกระโดดเข้าสู่อันดับที่ 2 ด้วยGazzrbot ของเขา
  • William Barbosa ชนะรางวัลQuick DrawสำหรับบอทของเขาBarneyStinson
  • และรางวัลSlow Pokeได้ไปหา Docopoper สำหรับบอทของเขาR.O.B.O.TและConcessionbotผู้ที่ทั้งคู่> 140ms ต่อมือ

  • มีบันทึก @ https://github.com/eoincampbell/big-bang-game/blob/master/tourneys/Tournament-2014-08-01-23-24-00.zip?raw=true

ไม่รวมบอท

  • BashRocksBot - ยังคงไม่มีความสุขกับ. net รันสคริปต์ทุบตี cygwin
  • CounterPreferenceBot - กำลังรอการแก้ไขข้อบกพร่อง
  • น้ำหนักแบบสุ่ม - รอการแก้ไขข้อบกพร่อง
  • CasinoShakespeare - ยกเว้นเพราะต้องใช้การเชื่อมต่ออินเทอร์เน็ต

คำถามที่โพสต์ต้นฉบับ

คุณได้เหวี่ยงไปที่บ้านเพื่อนของคุณสำหรับการต่อสู้สุดมันส์ครั้งแรกของ Rock, Paper, Scissors, Lizard, Spock ในสไตล์บิ๊กแบงที่น่าเบื่อหน่ายไม่มีผู้เล่นคนใดเล่น แต่สร้างบอทคอนโซลเพื่อเล่นในนามของพวกเขา คุณใช้กุญแจ USB ของคุณและมอบให้กับSheldor the Conquerorเพื่อรวมไว้ในการเปิดไพ่ เพนนี swoons หรืออาจจะเป็นว่าโฮเวิร์ด swoons เราไม่ได้ตัดสินที่นี่ที่อพาร์ตเมนต์ของ Leonard

กฎระเบียบ

มีการใช้ร็อคมาตรฐานกระดาษกรรไกรจิ้งจกสป็อค

  • กรรไกรตัดกระดาษ
  • กระดาษปิดทับหิน
  • หินทับจิ้งจก
  • Lizard พิษ Spock
  • สป็อคแตกกรรไกร
  • กรรไกรประหารจิ้งจก
  • Lizard กิน Paper
  • กระดาษไม่รองรับสป็อค
  • สป็อค vaporizes ร็อค
  • ร็อคกรรไกรทับ

กฎ RPSLV

บอทของผู้เล่นแต่ละคนจะเล่นหนึ่งแมทช์เทียบกับบอตอื่น ๆ ในทัวร์นาเมนต์

แต่ละการแข่งขันจะประกอบด้วย 100 การวนซ้ำของเกม RPSLV

หลังจากการแข่งขันแต่ละครั้งผู้ชนะคือผู้เล่นที่ชนะจำนวนมากที่สุดของเกม / มือจาก 100

หากคุณชนะการแข่งขันคุณจะได้รับ 1 คะแนนในตารางลีก ในผลของการจับสลากผู้เล่นจะไม่ได้รับแต้ม

ข้อกำหนดของบอท

บอทของคุณต้องสามารถรันได้จากบรรทัดคำสั่ง

กล่อง * nix ของ Sheldor เสียชีวิตดังนั้นเราจึงเรียกใช้งานจาก windows 8 Gaming Laptop ของเขาเพื่อให้แน่ใจว่าโซลูชันที่คุณให้ไว้สามารถทำงานบน windows ได้ Sheldor ได้เสนอที่จะติดตั้ง runtimes ที่ต้องการ (ภายในเหตุผล) เพื่อให้สามารถใช้งานโซลูชันของคุณได้ (. NET, Java, Php, Python, Ruby, Powershell ... )

ปัจจัยการผลิต

ในเกมแรกของแต่ละการแข่งขันจะไม่มีการโต้แย้งใด ๆ กับบอทของคุณ ในแต่ละเกมที่ตามมาของการแข่งขันแต่ละครั้ง: - Arg1 จะมีประวัติของบอตมือ / การตัดสินใจในการแข่งขันนี้ - Arg2 จะมีประวัติมือของฝ่ายตรงข้าม / การตัดสินใจของคุณในการแข่งขันนี้

ประวัติจะถูกแสดงโดยลำดับของตัวอักษรใหญ่เดียวแทนมือที่เป็นไปได้ที่คุณสามารถเล่นได้

 | R | Rock     |
 | P | Paper    |
 | S | Scissors |
 | L | Lizard   |
 | V | Spock    |

เช่น

  • เกมที่ 1: MyBot.exe
  • เกมที่ 2: MyBot.exe SV
  • เกม 3: MyBot.exe SS VL
  • เกมที่ 4: MyBot.exe SSR VLS

เอาท์พุต

บอทของคุณจะต้องเขียนคำตอบเดียวที่แสดงถึง "มือ" ของเขาสำหรับแต่ละเกม ผลลัพธ์ควรถูกเขียนไปยัง STDOUT แล้วบอทควรออก อักษรตัวพิมพ์ใหญ่เดียวที่ถูกต้องอยู่ด้านล่าง

 | R | Rock     |
 | P | Paper    |
 | S | Scissors |
 | L | Lizard   |
 | V | Spock    |

ในกรณีที่บอตของคุณไม่ส่งคืนมือที่ถูกต้อง (เช่น 1 ใน 5 ตัวอักษรใหญ่ข้างต้นคุณจะเสียมือนั้นโดยอัตโนมัติและการแข่งขันจะดำเนินต่อไป

ในกรณีที่บอททั้งคู่ไม่ส่งคืนมือที่ถูกต้องเกมนั้นถือเป็นเสมอและการแข่งขันดำเนินต่อไป

จับคู่รูปแบบ

บอทที่ส่งมาแต่ละอันจะเล่นการแข่งขันหนึ่งนัดกับบอทอื่น ๆ ในทัวร์นาเมนต์

แต่ละการแข่งขันจะคงอยู่อย่างแน่นอน 100 เกม

การแข่งขันจะถูกเล่นโดยไม่ระบุชื่อคุณจะไม่มีความรู้ขั้นสูงเกี่ยวกับบอทที่คุณเล่นอย่างไรก็ตามคุณสามารถใช้ข้อมูลใด ๆ และทั้งหมดที่คุณสามารถรวบรวมได้จากการตัดสินใจของเขาในช่วงประวัติศาสตร์ของการแข่งขันปัจจุบันเพื่อเปลี่ยนกลยุทธ์ของคุณ คู่แข่ง คุณอาจติดตามประวัติของเกมก่อนหน้าของคุณเพื่อสร้างรูปแบบ / การวิเคราะห์พฤติกรรม ฯลฯ ... (ดูกฎด้านล่าง)

ในระหว่างเกมเดี่ยวเอ็นจิ้น orchestration จะรันบอทของคุณและคู่ต่อสู้ของคุณบอท 100 มิลลิวินาทีแล้วเปรียบเทียบผลลัพธ์เพื่อหลีกเลี่ยงการชน PRNG ในภาษา / รันไทม์เดียวกัน (สิ่งนี้เกิดขึ้นจริงระหว่างการทดสอบ)

การตัดสิน & ข้อ จำกัด

ดร. เชลดอนคูเปอร์ในหน้ากากของเชลดอร์ผู้พิชิตได้เสนอให้ดูแลการแข่งขัน Sheldor the Conqueror นั้นยุติธรรมและเป็นผู้ดูแล (ส่วนใหญ่) การตัดสินใจทั้งหมดของ Sheldor ถือเป็นที่สิ้นสุด

การเล่นเกมจะดำเนินการในลักษณะที่เป็นธรรมและเหมาะสม:

  • สคริปต์ / โปรแกรมบ็อตของคุณจะถูกเก็บไว้ในเอ็นจิ้น orchestration ภายใต้โฟลเดอร์ย่อย Players\[YourBotName]\
  • คุณสามารถใช้โฟลเดอร์ย่อยPlayers\[YourBotName]\dataเพื่อบันทึกข้อมูลหรือประวัติเกมจากทัวร์นาเมนต์ปัจจุบันตามที่ได้รับ ไดเรกทอรีข้อมูลจะถูกกำจัดเมื่อเริ่มการแข่งขันแต่ละครั้ง
  • คุณไม่สามารถเข้าถึงไดเรกทอรีผู้เล่นของผู้เล่นอื่นในทัวร์นาเมนต์
  • บอตของคุณไม่สามารถมีรหัสเฉพาะซึ่งกำหนดเป้าหมายพฤติกรรมการบอทเฉพาะอื่น
  • ผู้เล่นแต่ละคนสามารถส่งบอทมากกว่าหนึ่งอันเพื่อเล่นตราบใดที่พวกเขาไม่ได้มีปฏิสัมพันธ์หรือช่วยเหลือซึ่งกันและกัน

แก้ไข - ข้อ จำกัด เพิ่มเติม

  • เกี่ยวกับการริบพวกเขาจะไม่ได้รับการสนับสนุน บอทของคุณจะต้องเล่นหนึ่งใน 5 มือที่ใช้ได้ ฉันจะทดสอบแต่ละบอทนอกการแข่งขันด้วยข้อมูลสุ่มบางอย่างเพื่อให้แน่ใจว่ามันทำงานได้ดี บอทใด ๆ ที่โยนข้อผิดพลาด (เช่นข้อผิดพลาด forfeits) จะถูกแยกออกจากทัวร์นาเมนต์
  • บอตอาจเป็นอนุพันธ์ตราบใดที่มีความแตกต่างอย่างชัดเจนในพฤติกรรมของพวกเขา บ็อต (รวมถึงภาษาอื่น ๆ ) ที่มีพฤติกรรมเดียวกับบอทที่มีอยู่นั้นจะถูกตัดสิทธิ์
  • มีบอทสแปมอยู่แล้วสำหรับสิ่งต่อไปนี้ดังนั้นโปรดอย่าส่งอีกครั้ง
    • Rock - BartSimpson
    • กระดาษ - LisaSimpson
    • Scissor - EdwardScissorhands
    • Spock - วัลแคน
    • Lizard - Khaleesi
    • Pseudo Random - SimpleRandomBot & FairBot
    • Psuedo Random RPS - ConservativeBot
    • Psuedo Random LV - บาร์นีย์สติน
  • บอตไม่สามารถโทรออกไปยังบริการของบุคคลที่สามหรือทรัพยากรบนเว็บ (หรือสิ่งอื่นใดที่ทำให้ความเร็ว / เวลาในการตัดสินใจของการแข่งขันช้าลงอย่างมาก) CasinoShakespeareเป็นข้อยกเว้นเพียงอย่างเดียวเนื่องจากบอทนั้นถูกส่งก่อนที่จะมีการเพิ่มข้อ จำกัด นี้

Sheldor จะอัปเดตคำถามนี้บ่อยที่สุดเท่าที่จะทำได้กับผลการแข่งขันเนื่องจากมีการส่งบอทมากขึ้น

Orchestration / โปรแกรมควบคุม

โปรแกรม orchestration พร้อมด้วยซอร์สโค้ดสำหรับบอทแต่ละตัวมีอยู่ใน github

https://github.com/eoincampbell/big-bang-game

รายละเอียดการส่ง

การส่งของคุณควรรวมถึง

  • ชื่อบอทของคุณ
  • รหัสของคุณ
  • คำสั่งให้
    • รัน bot ของคุณจากเชลล์เช่น
    • ทับทิม myBot.rb
    • python3 myBot.py
    • หรือ
    • ก่อนอื่นให้คอมไพล์ทั้งสองจากนั้นก็รันมัน เช่น
    • csc.exe MyBot.cs
    • MyBot.exe

ส่งตัวอย่าง

BotName: SimpleRandomBot
Compile: "C:\Program Files (x86)\MSBuild\12.0\Bin\csc.exe" SimpleRandomBot.cs
Run:     SimpleRandomBot [Arg1] [Arg2]

รหัส:

using System;
public class SimpleRandomBot
{
    public static void Main(string[] args)
    {
        var s = new[] { "R", "P", "S", "L", "V" };
        if (args.Length == 0)
        {
            Console.WriteLine("V"); //always start with spock
            return;
        }
        char[] myPreviousPlays = args[0].ToCharArray();
        char[] oppPreviousPlays = args[1].ToCharArray();
        Random r = new Random();
        int next = r.Next(0, 5);
        Console.WriteLine(s[next]);
    }
}

การอธิบาย

คำถามใด ๆ ถามในความคิดเห็นด้านล่าง


7
ประวัติศาสตร์มีลักษณะอย่างไรเมื่อผู้เล่นริบมือ?
ประวัติศาสตร์

1
ฉันจะใช้วิธีการวิเคราะห์อย่างเต็มที่ แต่บอทส่วนใหญ่ที่นี่โง่พอที่จะเอาชนะ AI อัจฉริยะได้
ปุย

1
เพียงเพราะฉันไม่เคยเป็นผู้นำสำหรับความท้าทายของ KotH ใด ๆ ที่ฉันเข้าแข่งขันฉันจึงถ่ายภาพหน้าจอเป็นที่ระลึก
Kyle Kanos

3
ฉันจะเรียกใช้ tourney อีกครั้งในคืนนี้และโพสต์ผลการแข่งขันอย่างเต็มรูปแบบบน Pastebin ... ชุดต่อไปจะมีเกมประมาณ 450 เกม แต่น่าจะเร็วกว่านี้เล็กน้อยในการทำงานเนื่องจากฉันได้ใช้สิ่งที่ขนานกันในโปรแกรมควบคุม
Eoin Campbell

3
หากฉันไม่เข้าใจผิดดูเหมือนว่าจะมีข้อผิดพลาดร้ายแรงในสคริปต์ orchestration: ประวัติของผู้เล่นที่ 1 และ 2 จะถูกส่งไปยังบอทเป็นอาร์กิวเมนต์แรกและอาร์กิวเมนต์ที่สองตามลำดับเสมอตามกฎที่บอทควรได้รับ ประวัติศาสตร์ของตัวเองก่อน ตอนนี้ผู้เล่น 2 พยายามเอาชนะตัวเองอย่างมีประสิทธิภาพ (ฉันมีบิตที่น่าสงสัยเพราะบอทของฉันได้รับรางวัลการแข่งขันทุกเดียวที่มันเป็นผู้เล่นที่ 1 ขณะที่สูญเสียครึ่งหนึ่งของการแข่งขันอื่น ๆ .)
เอมิล

คำตอบ:


26

Pony (Python 2)

แห่งนี้ตั้งอยู่บนพื้นฐานของ ธ ปทเป่ายิ้งฉุบที่ผมเขียนเวลาที่ผ่านมาสำหรับความท้าทายในการเขียนโปรแกรมในตอนท้ายของการเรียนออนไลน์ Udacity ฉันเปลี่ยนเป็น Spock and lizard และทำการปรับปรุงบางอย่าง

โปรแกรมมีกลยุทธ์ง่าย ๆ 11 แบบซึ่งแต่ละแบบมี 5 ตัวแปร มันเลือกจากสิ่งเหล่านี้โดยขึ้นอยู่กับว่าพวกเขาจะแสดงได้ดีแค่ไหนในรอบสุดท้าย

ฉันลบกลยุทธ์ทางเลือกที่เล่นแบบสุ่มกับคู่แข่งที่แข็งแกร่งกว่า ฉันเดาว่ามันสนุกกว่านี้

import sys

# just play Spock for the first two rounds
if len(sys.argv)<2 or len(sys.argv[1])<2: print 'V'; sys.exit()

# initialize and translate moves to numbers for better handling:
my_moves, opp_moves = sys.argv[1], sys.argv[2]
moves = ('R', 'P', 'S', 'V', 'L')   
history = zip([moves.index(i) for i in my_moves],
              [moves.index(i) for i in opp_moves])

# predict possible next moves based on history
def prediction(hist):
    N = len(hist)    

    # find longest match of the preceding moves in the earlier history
    cand_m = cand_o = cand_b = range(N-1)
    for l in xrange(1,min(N, 20)):
        ref = hist[N-l]
        cand_m = ([c for c in cand_m if c>=l and hist[c-l+1][0]==ref[0]]
                  or cand_m[-1:])
        cand_o = ([c for c in cand_o if c>=l and hist[c-l+1][1]==ref[1]]
                  or cand_o[-1:])
        cand_b = ([c for c in cand_b if c>=l and hist[c-l+1]==ref]
                  or cand_b[-1:])

    # analyze which moves were used how often
    freq_m, freq_o = [0]*5, [0]*5
    for m in hist:
        freq_m[m[0]] += 1
        freq_o[m[1]] += 1

    # return predictions
    return ([hist[-i][p] for i in 1,2 for p in 0,1]+   # repeat last moves
            [hist[cand_m[-1]+1][0],     # history matching of my own moves
             hist[cand_o[-1]+1][1],     # history matching of opponent's moves
             hist[cand_b[-1]+1][0],     # history matching of both
             hist[cand_b[-1]+1][1],
             freq_m.index(max(freq_m)), # my most frequent move
             freq_o.index(max(freq_o)), # opponent's most frequent move
             0])                        # good old rock (and friends)


# what would have been predicted in the last rounds?
pred_hist = [prediction(history[:i]) for i in xrange(2,len(history)+1)]

# how would the different predictions have scored?
n_pred = len(pred_hist[0])
scores = [[0]*5 for i in xrange(n_pred)]
for pred, real in zip(pred_hist[:-1], history[2:]):
    for i in xrange(n_pred):
        scores[i][(real[1]-pred[i]+1)%5] += 1
        scores[i][(real[1]-pred[i]+3)%5] += 1
        scores[i][(real[1]-pred[i]+2)%5] -= 1
        scores[i][(real[1]-pred[i]+4)%5] -= 1

# return best counter move
best_scores = [list(max(enumerate(s), key=lambda x: x[1])) for s in scores]
best_scores[-1][1] *= 1.001   # bias towards the simplest strategy    
if best_scores[-1][1]<0.4*len(history): best_scores[-1][1] *= 1.4
strat, (shift, score) = max(enumerate(best_scores), key=lambda x: x[1][1])
print moves[(pred_hist[-1][strat]+shift)%5]

ทำงานเป็น:

python Pony.py

แก้ไข : ฉันทำการเปลี่ยนแปลงเล็กน้อยโดยใส่ความลำเอียงสู่กลยุทธ์ที่ง่ายที่สุด (เช่นเล่นแบบเดียวกันเสมอ) ในกรณีที่ไม่แน่ใจ สิ่งนี้ช่วยได้เล็กน้อยที่จะไม่พยายามค้นหารูปแบบที่ซับซ้อนเกินไปที่ไม่มีเลยเช่นในบ็อตเช่น ConservativeBot

หมายเหตุ : ผมพยายามที่จะอธิบายกลยุทธ์จับคู่ประวัติศาสตร์พื้นฐานที่ ธ ปทนี้ใช้ในการโพสต์สำหรับบอทอื่น ๆ ของฉันอังคาร


3
อัตราส่วนการชนะ 96 เปอร์เซ็นต์โดดเด่น
AndoDaan

ดีมาก. คุณอาจชอบผง Iocaineถ้าคุณยังไม่เคยเห็นมันมาก่อน
wchargin

@WChargin แน่นอน :) เมื่อฉันเขียนรหัสดั้งเดิมฉันได้อ่านเกี่ยวกับ Iocaine Powder เมื่อหลายปีก่อนและจำความคิดทั่วไปได้ไม่ชัดเจน ดังนั้น Pony ได้รับแรงบันดาลใจจากมันจริง ๆ หากไม่ได้โดยตรงมาก เมื่อปรากฎว่าพวกมันคล้ายกันมาก ฉันคิดว่าของฉันมีกลวิธีที่กว้างกว่าในขณะที่ Iocaine Powder มีเมตาดาต้าเมตาดาต้าที่ชาญฉลาดในระดับที่ฉันไม่ได้ใส่
Emil

20

มาร์คอฟ, ทับทิม

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

responses = {
  'R' => ['P', 'V'],
  'P' => ['S', 'L'],
  'S' => ['R', 'V'],
  'L' => ['S', 'R'],
  'V' => ['P', 'L']
}

if ARGV.length == 0 || (history = ARGV[1]).length < 3
    choices = ['R','P','S','L','V']
else
    markov = Hash.new []
    history.chars.each_cons(3) { |chars| markov[chars[0..1].join] += [chars[2]] }

    choices = []
    likely_moves = markov.key?(history[-2,2]) ? markov[history[-2,2]] : history.chars
    likely_moves.each { |move| choices += responses[move] }
end

puts choices.sample

วิ่งเหมือน

markov.rb

จากนั้นฉันใช้โปรแกรมนี้เพื่อพิจารณาการเคลื่อนไหวที่เป็นไปได้มากที่สุดที่ฉันจะทำต่อไปจากนั้นค้นหาสิ่งที่คุณจะทำและในที่สุดก็หาวิธีที่จะเอาชนะสิ่งที่คุณจะทำและวนรอบไม่สิ้นสุด
Jamie

@Jamie คุณหมายถึงชอบผู้ชายคนนี้? codegolf.stackexchange.com/a/35295/8478
Martin Ender

คุณเดามัน (ความคิดเห็นนั้นไม่นานพอที่จะโพสต์)
Jamie

19

ConservativeBot, Ruby

สิ่งใหม่คือสิ่งที่ไม่ดี

puts ['R','P','S'].sample

วิ่งเหมือน

ruby conservative.rb

รุ่น OG เป็นรุ่นที่ดีที่สุด
maxywb

13

Star Wars Fan - Ruby

สกรูคุณสป็อค

puts ['R','P','L','S'].sample

เรียกใช้เช่น:

ruby starwarsfan.rb

เพิ่มใน Controller
Eoin Campbell

คุณสามารถย้อนกลับโดยตอบแก้ไข - ฉันจะแสดงความคิดเห็นที่นี่เมื่อฉันเพิ่มพวกเขา
Eoin Campbell

ทำไมต้อง R และ S? : P
cjfaure

@mardavi เป็นแฟน Star Wars เพราะไม่ได้ใช้ Spock
William Barbosa

อ่าคุณพูดถูก (แน่นอน) ฉันอ่านมันเร็วเกินไปความผิดพลาดของฉัน (แต่ไม่มีโชคดี)
mardavi

13

บาร์นีย์สติน - Lua

ฉันมีเพียงกฎเดียว: ใหม่ดีกว่าเสมอ สกรู Jo Ken Po ตัวเก่าหรืออะไรก็ตามที่คุณเรียกว่า

math.randomseed(os.time())
print(math.random() > 0.5 and "V" or "L")

เรียกใช้เช่น:

lua legenwaitforitdary.lua

8

Boring Bot (Java)

เขาถือว่าทุกคนเล่นในสิ่งเดียวกันและวางแผนตามนั้นเสมอ เขามักจะหยิบหินในความสัมพันธ์แม้ว่าจะเป็นเพราะเหตุใดคนอื่น ๆ ทุกคนถูกต้อง?

public class BoringBot
{
    public static void main(String[] args)
    {
        int Rock=0;
        int Paper=0;
        int Scissors=0;
        int Lizard=0;
        int Spock=0;

        if (args.length == 0)
        {
            System.out.print("P");
            return;
        }

        char[] oppPreviousPlays = args[1].toCharArray();

        for (int j=0; j<oppPreviousPlays.length; j++) {
            switch(oppPreviousPlays[j]){
                case 'R': Rock++; break;
                case 'P': Paper++; break;
                case 'S': Scissors++; break;
                case 'L': Lizard++; break;
                case 'V': Spock++;
            }
        }

        int Best = Math.max(Math.max(Lizard+Scissors-Spock-Paper,
                                     Rock+Spock-Lizard-Scissors),
                            Math.max(Math.max(Paper+Lizard-Spock-Rock,
                                              Paper+Spock-Rock-Scissors),
                                     Rock+Scissors-Paper-Lizard));

        if (Best== Lizard+Scissors-Spock-Paper){
            System.out.print("R"); return;
        } else if (Best== Rock+Spock-Lizard-Scissors){
            System.out.print("P"); return;
        } else if (Best== Paper+Lizard-Spock-Rock){
            System.out.print("S"); return;
        } else if(Best== Paper+Spock-Rock-Scissors){
            System.out.print("L"); return;
        } else {
            System.out.print("V"); return;
        }
    }
}

โปรดทราบว่านี่เป็นกลยุทธ์ที่คนอื่นใช้อยู่แล้วให้ฉันรู้และฉันจะลบ มันรู้สึกเหมือนเห็นได้ชัดว่าฉันไม่ได้เห็น
kaine

นี่คือ C # คุณ. คุณสมบัติความยาวผิด และไม่มีวิธีการใด ๆmax
Eoin Campbell

@EoinCampbell มันเป็นจาวาฉันได้เล่นกับทั้งคู่และดูเหมือนว่าลืมคำสั่งที่เป็นของ
kaine

อาเย็น ทิ้งไว้กับฉันและฉันจะเอามันมารวม
Eoin Campbell

ยังหักอยู่ วิ่ง jre8 - java BoringBot.java - ข้อผิดพลาด: ไม่สามารถค้นหาหรือโหลดคลาสหลัก D: \ My Software Dev \ big-bang-game \ BigBang.Orchestrator \ bin \ Debug \ Players \ BoringBot \ BoringBot.java -
Eoin Campbell

8

IocainePowder, Ruby

ป้อนคำอธิบายรูปภาพที่นี่

ตามออก (ขโมยลงคอ) จากกลยุทธ์ RPS ที่นี่ บอทดูเหมือนจะเดาว่าเหมือนกับบอตมาร์คอฟ แต่จากนั้นสมมติว่าฝ่ายตรงข้ามเดาได้ว่าจะเลือกอะไรและเลือกท่าที่จะเอาชนะท่านั้น

โปรดทราบว่าฉันเพิ่งปรับเปลี่ยนแนวคิดพื้นฐานของกลยุทธ์ที่เชื่อมโยงไม่ใช่ตามรายละเอียด

responses = {
  'R' => ['P', 'V'],
  'P' => ['S', 'L'],
  'S' => ['R', 'V'],
  'L' => ['S', 'R'],
  'V' => ['P', 'L']
}

if ARGV.length == 0 || (history = ARGV[1]).length < 3
    choices = ['R','P','S','L','V']
else
    markov = Hash.new []
    history.chars.each_cons(3) { |chars| markov[chars[0..1].join] += [chars[2]] }

    choices = []
    likely_moves = markov.key?(history[-2,2]) ? markov[history[-2,2]] : history.chars
    likely_moves.each { |move| choices += responses[move] }
end

myChoice = choices.sample 
theirChoice = responses[myChoice].sample
actualChoice = responses[theirChoice].sample
puts actualChoice

วิ่งเหมือน

iocaine.rb

5
คุณใช้คำนั้นต่อไป ฉันไม่คิดว่ามันหมายถึงสิ่งที่คุณคิดว่ามันหมายถึง
JoshDM

2
พลังที่แท้จริงของผง Iocaine คือการสลับระหว่างการใช้มาร์คอฟและการตี - มาร์คอฟ มันเริ่มต้นจากสมาร์ทมาร์คอฟ แต่เมื่อรู้สึก (เริ่มสูญเสีย) มันก็จะเข้าสู่โหมดการตีมาร์คอฟ ควรเพิ่มง่าย ๆ
Roy van Rijn

อ่าฉลาด! ไม่ต้องโกหกหรอกฉันได้ยิน แต่เพียงว่า Iocaine อธิบายให้ฉันฟังเท่านั้น อย่าลังเลที่จะแก้ไขรหัสของฉันหากคุณต้องการหรือส่งของคุณเองและรับเครดิต!
jmite

8

HuddleWolfTheConqueror - C #

HuddleWolf กลับมาและดีขึ้นกว่าเดิม เขาจะเอาชนะ Sheldor the Conqueror ในเกมที่โง่ของเขา HuddleWolf ฉลาดพอที่จะระบุและต่อต้านสแปมบอทบอท สำหรับฝ่ายตรงข้ามที่ฉลาดกว่านี้ HuddleWolf ใช้ความรู้ของเขาเกี่ยวกับสถิติชั้นประถมศึกษาปีที่ 5 พื้นฐานและใช้ลูกเต๋าแบบถ่วงน้ำหนักตามประวัติความเป็นมาของฝ่ายค้าน

using System;
using System.Collections.Generic;
using System.Linq;

public class HuddleWolfTheConqueror
{

    public static readonly char[] s = new[] { 'R', 'P', 'S', 'L', 'V' };

    public static void Main(string[] args)
    {
        if (args.Length == 0)
        {
            Console.WriteLine(pickRandom());
            return;
        }

        char[] myPlays = args[0].ToCharArray();
        char[] oppPlays = args[1].ToCharArray();

        char tryPredict = canPredictCounter(oppPlays);
        if (tryPredict != '^')
        {
            Console.WriteLine(tryPredict);
        }
        else
        {
            Console.WriteLine(pickRandom());
        }
        return;
    }


    public static char canPredictCounter(char[] history)
    {
        // don't predict if insufficient data
        if (history.Length < 5)
        {
            return '^';
        }

        // calculate probability of win for each choice
        Dictionary<char, double> dic = getBestProabability(history);

        // get item with highest probability of win
        List<char> maxVals = new List<char>();
        char maxVal = '^';
        double mostFreq = 0;
        foreach (var kvp in dic)
        {
            if (kvp.Value > mostFreq)
            {
                mostFreq = kvp.Value;
            }
        }
        foreach (var kvp in dic)
        {
            if (kvp.Value == mostFreq)
            {
                maxVals.Add(kvp.Key);
            }
        }

        // return error
        if (maxVals.Count == 0)
        {
            return maxVal;
        }

        // if distribution is not uniform, play best play
        if (maxVals.Count <= 3)
        {
            Random r = new Random(Environment.TickCount);
            return maxVals[r.Next(0, maxVals.Count)];
        }

        // if probability is close to uniform, use weighted dice roll
        if (maxVals.Count == 4)
        {
            return weightedRandom(dic);
        }

        // if probability is uniform, use random dice roll
        if (maxVals.Count >= 5)
        {
            return pickRandom();
        }

        // return error
        return '^';
    }

    public static Dictionary<char, double> getBestProabability(char[] history)
    {
        Dictionary<char, double> dic = new Dictionary<char, double>();
        foreach (char c in s)
        {
            dic.Add(c, 0);
        }
        foreach (char c in history)
        {
            if (dic.ContainsKey(c))
            {
                switch(c)
                {
                    case 'R' : 
                        dic['P'] += (1.0/(double)history.Length);
                        dic['V'] += (1.0/(double)history.Length);
                        break;
                    case 'P' : 
                        dic['S'] += (1.0/(double)history.Length);
                        dic['L'] += (1.0/(double)history.Length);
                        break;
                    case 'S' : 
                        dic['V'] += (1.0/(double)history.Length);
                        dic['R'] += (1.0/(double)history.Length);
                        break;
                    case 'L' : 
                        dic['R'] += (1.0/(double)history.Length);
                        dic['S'] += (1.0/(double)history.Length);
                        break;
                    case 'V' : 
                        dic['L'] += (1.0/(double)history.Length);
                        dic['P'] += (1.0/(double)history.Length);
                        break;
                    default : 
                        break;

                }
            }
        }
        return dic;
    }

    public static char weightedRandom(Dictionary<char, double> dic)
    {
        Random r = new Random(Environment.TickCount);
        int next = r.Next(0, 100);
        int curVal = 0;
        foreach (var kvp in dic)
        {
            curVal += (int)(kvp.Value*100);
            if (curVal > next)
            {
                return kvp.Key;
            }
        }
        return '^';
    }

    public static char pickRandom()
    {
        Random r = new Random(Environment.TickCount);
        int next = r.Next(0, 5);
        return s[next];
    }
}

8

ToddlerProof

บอทที่โง่เง่าพอสมควรนี้สมมติว่ามันกำลังเล่นเด็กวัยหัดเดินที่จะ "ไล่" การเคลื่อนไหวของมันพยายามที่จะเอาชนะทุกสิ่งที่ถูกโยนทิ้งไป หากบอทถูกตีหลายครั้งติดต่อกันมันจะข้ามไปยังจุดใหม่ในรูปแบบ มันขึ้นอยู่กับกลยุทธ์ของฉันเสมอฉันเต้นมากน้องชาย :)

แก้ไข:เปลี่ยนความยาวของแนวการสูญเสียที่จำเป็นในการกระโดดเข้าสู่การโยนแบบสุ่ม แก้ไขข้อผิดพลาดที่สำคัญด้วยการกระโดดแบบสุ่ม

บันทึกเป็นToddlerProof.javaรวบรวมแล้วเรียกใช้ด้วยjava ToddlerProof [me] [them]

import java.util.HashMap;
public class ToddlerProof
{
    char[] moves = new char[]{'R', 'P', 'S', 'L', 'V'};
    public static void main(String[] args)
    {
        if(args.length<1) //first Round
        {
            System.out.print('V');//Spock is best
            return;
        }
        else
        {
            String them = args[1];
            String me = args[0];
            int streak = 0;

            HashMap<Character, Character> nextMove = new HashMap<Character, Character>();
            //Next move beats things that beat my last move
            nextMove.put('L', 'V');
            nextMove.put('V', 'S');
            nextMove.put('S', 'P');
            nextMove.put('P', 'R');
            nextMove.put('R', 'L');
            //Check if last round was a tie or the opponent beat me
            int lastResult = winner(me.charAt(me.length()-1), them.charAt(them.length()-1));
            if(lastResult == 0)
            {
                //tie, so they will chase my last throw
                System.out.print(nextMove.get(me.charAt(me.length()-1)));

                return;
            }
            else if(lastResult == 1)
            {
                //I won, so they will chase my last throw
                System.out.print(nextMove.get(me.charAt(me.length()-1)));


                return;
            }

            else{
                //I lost
                //find streak
                for(int i = 0; i<me.length(); i++)
                {
                    int a = winner(me.charAt(i), them.charAt(i));
                    if(a >= 0) streak = 0;
                    else streak++;
                }
                //check lossStreak
                //If the streak is 2, then a rotation will make it even.
                //if it is >2, something bad has happened and I need to adjust.
                if(streak>2)
                {
                    //if they are on to me, do something random-ish
                    int r = (((them.length()+me.length()-1)*13)/7)%4;
                    System.out.print(move[r]);
                    return;
                }
                //otherwise, go on with the plan
                System.out.print(nextMove.get(me.charAt(me.length()-1)));
                return;
            }
        }
    }
    public static int winner(char me, char them)
    {
        //check for tie
        if(me == them) return 0;
        //check if they won
        if(me=='V' && (them == 'L' || them == 'P')) return -1;
        if(me=='S' && (them == 'V' || them == 'R')) return -1;
        if(me=='P' && (them == 'S' || them == 'L')) return -1;
        if(me=='R' && (them == 'P' || them == 'V')) return -1;
        if(me=='L' && (them == 'R' || them == 'S')) return -1;
        //otherwise, I won
        return 1;
    }
}

1
เราควรจะใช้การพิมพ์หรือการพิมพ์หรือไม่ ... ฉันไม่แน่ใจ
kaine

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

@Stranjyr มีข้อบกพร่องบางอย่างในระยะสุดท้ายของคุณ มันไม่ได้ระเบิดโปรแกรมควบคุม แต่ถ้าคุณค้นหาประวัติของ "ToddlerProof plays n" ดูเหมือนว่าบอทของคุณคืนมือให้เป็นโมฆะแล้วจึงหมุนมือโดยอัตโนมัติ เกมตัวอย่างคือ "Echo & ToddlerProof" โดยที่ Echo เล่น "LVSPRLV" ก่อนที่บอทของคุณจะเริ่มอึ
Eoin Campbell

@Eion Campbell ขอบคุณที่พูดถึงมัน ฉันเห็นว่าก่อนหน้านี้เมื่อคุณโพสต์บันทึกจากทัวร์นาเมนต์ที่ล้มเหลวและฉันคิดว่าฉันได้รับการแก้ไขแล้ว มันเกิดข้อผิดพลาดซึ่งถ้ามันหายไปมากกว่า 5 เส้นตรงแทนที่จะกระโดดไปเล่นแบบสุ่มมันแค่โยนค่าที่ไม่ถูกต้อง จากนั้นเพราะนั่นทำให้สูญเสียมันจึงโยนค่าที่ไม่ถูกต้องอีกอัน วงจรอุบาทว์
Stranjyr

เย็น. มีการอัพเดทใน control prog ทันที
Eoin Campbell

8

บาร์ตซิมป์สัน

"หินเก่าดี! ไม่มีอะไรเต้นเลย!"

puts 'R'

ทำงานเป็น

ruby DoTheBartman.rb

Lisa Simpson

"บาร์ตแย่คาดเดาได้เลือกหินเสมอ"

puts 'P'

ทำงานเป็น

ruby LisaSimpson.rb

ดีกว่าลิซ่าซิมป์สัน

ฉันรู้สึกไม่ดีเกี่ยวกับการทำให้ Lisa ค่อนข้างงี่เง่าดังนั้นฉันจึงอนุญาตให้เธอสุ่มเลือกระหว่างมือทั้งสองข้างที่จะทุบหิน ยังงี่เง่า แต่เธอก็เป็นซิมป์สัน อาจจะมีดินสอสีติดอยู่ในสมองของเธอ?

puts ['P','V'].sample

ทำงานเป็น

ruby BetterLisaSimpson.rb

2
ชื่อการปะทะกันเล็ก ๆ น้อย ๆ +1 อยู่ดี
Martin Ender

@ MartinBüttnerประณามไม่ได้สังเกตว่า รายการยังคงดูเหมือนจะทำสิ่งที่แตกต่างกัน - และอย่างน้อยลิซ่าที่นี่สามารถรู้สึกดีกว่าโดยตีสองรุ่นที่แตกต่างกันของพี่ชายของเธอ
Dr R Dizzle

1
เชลเดอร์เห็นด้วย ... จะมี BartBot และ BartSimpson :)
Eoin Campbell

3
เรามี BortBot เท่านั้น
JoshDM

1
เหล่านี้จะได้รับการฆ่าโดยมาร์คอฟ :)
Cruncher

7

เสียงสะท้อน

เขียนใน C # csc Echo.csคอมไพล์ด้วย Echo.exe ARG1 ARG2ทำงานเหมือน

การเรียกใช้ครั้งแรก Echo ใช้ตัวเลือกแบบสุ่ม ทุกการวิ่งหลังจากครั้งแรก Echo จะทำซ้ำการกระทำล่าสุดของฝ่ายตรงข้ามซ้ำ

using System;

namespace Echo
{
    class Program
    {
        static void Main(string[] args)
        {
            if (args.Length == 0)
            {
                Random r = new Random();
                string[] options = new string[] { "R", "P", "S", "L", "V" };
                Console.WriteLine(options[r.Next(0, options.Length)]);
            }
            else if (args.Length == 2)
            {
                string opponentHistory = args[1];
                Console.WriteLine(opponentHistory[opponentHistory.Length - 1]);
            }
        }
    }
}

7

วัลแคน, ทับทิม

นิ้วของฉันติดกัน

puts 'V'

วิ่งเหมือน

ruby vulcan.rb

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


ต้องย้อนกลับไปดูตอนต่างๆเพื่อดูว่าใครเกิดมาพร้อมกับลิ้น LizardMan FTW !!!
Eoin Campbell

3
แต่นี่ไม่ใช่วิธีที่ทุกคนในบิ๊กแบงเล่นกันอยู่ดี?
kaine

2
@ อีกคนหนึ่งนั่นคือสิ่งที่ฉันหมายถึงโดย "นี่เป็นเพียงกลยุทธ์ในตัวละคร"
Martin Ender

6

Tyrannosaurus, Godzilla, Barney ... Lizards Rule บางครั้งพวกเขาก็มีปัญหาและต้องโทรหาสป็อคหรือขว้างก้อนหิน

using System;
public class LizardsRule
{
    public static void Main(string[] args)
    {
        if (args.Length == 0)
        {
            Console.WriteLine("L");
            return;
        }
        char[] oppPreviousPlays = args[1].ToCharArray();
        var oppLen = oppPreviousPlays.Length;
        if (oppPreviousPlays.Length > 2
            && oppPreviousPlays[oppLen - 1] == 'R'
            && oppPreviousPlays[oppLen - 2] == 'R'
            && oppPreviousPlays[oppLen - 3] == 'R')
        {
            //It's an avalance, someone call Spock
            Console.WriteLine("V");
            return;
        }

        if (oppPreviousPlays.Length > 2
                && oppPreviousPlays[oppLen - 1] == 'S'
                && oppPreviousPlays[oppLen - 2] == 'S'
                && oppPreviousPlays[oppLen - 3] == 'S')
        {
            //Scissors, Drop your tail and pick up a rock
            Console.WriteLine("R");
            return;
        }

        //Unleash the Fury Godzilla
        Console.WriteLine("L");     
    }
}

6

BayesianBot, Perl (ตอนนี้ v2!)

เหนือสิ่งอื่นใดนี่เป็นโปรแกรมพิเศษ ในนั้นคุณจะเห็นฟิวชั่นที่ยอดเยี่ยมของสถิติและรูปแบบการเขียนโปรแกรมที่น่ากลัว นอกจากนี้บ็อตนี้อาจละเมิดกฎหลายข้อของสถิติแบบเบย์ แต่ชื่อฟังดูเย็นกว่า

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

ในแต่ละเทิร์นการคาดการณ์ของโมเดลที่สามารถใช้งานได้ทั้งหมด (โดยทั่วไปคือ 10) จะถูกคูณเข้าด้วยกันเพื่อสร้างการทำนายโดยรวม

แก้ไข 1: ในรุ่นนี้ฉันเปลี่ยนการกระจายก่อนหน้านี้และทำให้บอทสุ่มมากขึ้นเมื่อสูญเสีย

มีบางสิ่งที่อาจมีการปรับปรุงเช่นจำนวนรุ่น (250 เป็นเพียงตัวเลข 3 หลัก) ทางเลือกของการกระจายก่อนหน้านี้ (ปัจจุบัน Dir (3,3,3,3,3)) และ วิธีการหลอมรวมการทำนาย นอกจากนี้ฉันไม่เคยสนใจที่จะทำให้การแจกแจงความน่าจะเป็นปกติใด ๆ กลายเป็นปกติซึ่งก็โอเคสำหรับตอนนี้เพราะฉันคูณมัน

ฉันไม่มีความคาดหวังสูงมาก แต่ฉันหวังว่าบอทนี้จะสามารถทำได้ดี

my ($phist, $ohist) = @ARGV;

my %text2num = ('R',0,'V',1,'P',2,'L',3,'S',4);  #the RVPLS ordering is superior
my @num2text = ('R','V','P','L','S');

@phist = map($text2num{$_},split(//,$phist));
@ohist = map($text2num{$_},split(//,$ohist));

$lowerlimit = 0;
for($lowerlimit..~~@phist-3){$curloc=$_;
 $result = $ohist[$curloc+2];
 @moveset = ($ohist[$curloc],$ohist[$curloc+1],$phist[$curloc],$phist[$curloc+1]);
 for(0..3){$a=$_;
  for(0..$a){$b=$_;
   $predict[$a][$b][$moveset[$a]][$moveset[$b]][$result]++;
  }
 }
}

@recentmoves = ($ohist[-2],$ohist[-1],$phist[-2],$phist[-1]);

@curpred = (1,1,1,1,1);

for(0..3){$a=$_;
 for(0..$a){$b=$_;
  for(0..4){$move=$_;
   $curpred[$move] *= $predict[$a][$b][$recentmoves[$a]][$recentmoves[$b]][$move]/3+1;
  }
 }
}

@bestmove = (0,0,0,0,0);
for(0..4){
 $bestmove[$_] = $curpred[$_]/2+$curpred[$_-1]+$curpred[$_-2];
}

$max = 0;
for(0..4){
 if($bestmove[$_]>$max){
  $max = $bestmove[$_];
 }
}
@options=();
$offset=0;
if(($ohist[-1] - $phist[-1])%5 < 2 && ($ohist[-2] - $phist[-2])%5 < 2 && ($ohist[-3] - $phist[-3])%5 < 2){  #frequentist alert!
 $offset=int(rand(3));
}
for(0..4){
 if($bestmove[$_] == $max){
  push(@options,$num2text[($_+$offset)%5]);
 }
}
$outputb = $options[int(rand(~~@options))];

print "$outputb";

ฉันใช้โปรแกรมนี้เช่น:

perl BayesianBot.plx

5

DynamicBot

บอทไดนามิกเปลี่ยนแปลงเกือบตลอดเวลา มันเกลียดการทำซ้ำตัวเองจริงๆ

import sys, random
choices = ['L','V','S','P','R'] * 20
if len(sys.argv) > 1:
    my_history = sys.argv[1]
    [choices.remove(my_history[-1]) for i in range(15)]
print(choices[random.randrange(len(choices))])

ภาษา: Python 3.4.1

คำสั่ง: python dynamicbot.py <history>หรือpython3 dynamicbot.py <history>ขึ้นอยู่กับระบบของคุณ


ใช่คิดเกี่ยวกับเรื่องนั้น
seequ

5

SmartBot - Java

การเข้าครั้งแรกของฉันสำหรับสิ่งใดในไซต์นี้!

แม้ว่าจะไม่ใช่ชื่อที่สร้างสรรค์มาก ...

SmartBot ค้นหาลำดับของการเคลื่อนไหวที่คู่ต่อสู้และ / หรือการเคลื่อนไหวของตัวเองคล้ายกับการเคลื่อนไหวที่ทำล่าสุดและวางแผนตามลำดับ

name = SmartBot

ฉันคิดว่าจะใช้มันแก้ไขฉันถ้าฉันผิด

java -jar SmartBot.jar

import java.util.ArrayList;
public class SmartBot {
    public static void main(String[] args) {
        if(args.length ==0){
            System.out.print("L");
            return;
        }
        if(args[0].length()<3){
            String[] randLetter = new String[]{"R","P","S","L","V"};
            System.out.print(randLetter[(int) Math.floor(Math.random()*5)]);
            return;
        }
        String myHistory = args[0];
        String otherHistory = args[1];

        double rScore,pScore,sScore,lScore,vScore;//score - highest = highest probability of next opponent move
        rScore = pScore = sScore = lScore = vScore = 0;
        lScore = .001;
        ArrayList<ArrayList<Integer>> moveHits = new ArrayList<ArrayList<Integer>>();
        for(int g = 0;g<2;g++){
            for(int i=1;i<(myHistory.length() / 2) + 1;i++){
                if(g==0){
                    moveHits.add(findAll(myHistory.substring(myHistory.length() - i),myHistory));
                }
                else{
                    moveHits.add(findAll(otherHistory.substring(otherHistory.length() - i),otherHistory));
                }
            }
            for(int i = 0; i < moveHits.size();i++){
                int matchingMoves = i+1;
                ArrayList<Integer> moveIndexes = moveHits.get(i);
                for(Integer index:moveIndexes){
                    if(index+matchingMoves +1<= otherHistory.length()){
                        char nextMove = otherHistory.charAt(index + matchingMoves-1);
                        if(nextMove=='R'){rScore = rScore + matchingMoves;}
                        if(nextMove=='P'){pScore = pScore + matchingMoves;}
                        if(nextMove=='S'){sScore = sScore + matchingMoves;}
                        if(nextMove=='L'){lScore = lScore + matchingMoves;}
                        if(nextMove=='V'){vScore = vScore + matchingMoves;}
                    }
                }
            }
        }
        if(rScore >= pScore && rScore >= sScore && rScore >= lScore && rScore >= vScore){
            System.out.print("V");
            return;
        }
        if(pScore >= rScore && pScore >= sScore && pScore >= lScore && pScore >= vScore){
            System.out.print("L");
            return;
        }
        if(sScore >= pScore && sScore >= rScore && sScore >= lScore && sScore >= vScore){
            System.out.print("R");
            return;
        }
        if(vScore >= pScore && vScore >= sScore && vScore >= lScore && vScore >= rScore){
            System.out.print("L");
            return;
        }
        if(lScore >= pScore && lScore >= sScore && lScore >= rScore && lScore >= vScore){
            System.out.print("S");
        }
        return;
    }
    public static ArrayList<Integer> findAll(String substring,String realString){
        ArrayList<Integer> ocurrences = new ArrayList<Integer>();
        Integer index = realString.indexOf(substring);
        if(index==-1){return ocurrences;}
        ocurrences.add(index+1);
        while(index!=-1){
            index = realString.indexOf(substring,index + 1);
            if(index!=-1){
                ocurrences.add(index+1);
            }
        }
        return ocurrences;
    }
}

มันกำหนดคะแนนสำหรับการย้ายครั้งต่อไปที่เป็นไปได้ตามจำนวนครั้งที่มีรูปแบบคล้ายกันเกิดขึ้น

มันชอบจิ้งจกเล็กน้อย


ฉันเชื่อว่าเป็นวิธีที่คุณเรียกใช้ถ้าคุณไหมันก่อน ถ้าคุณเพียงแค่รวบรวมไว้ก่อนแล้วjava ABotควรจะทำงาน (อย่าลืมตั้งชื่อไฟล์เช่นเดียวกับชั้นสาธารณะ)
จัสติน

ขอบคุณ! ในฐานะโปรแกรมเมอร์ที่ค่อนข้างใหม่ฉันไม่ได้ตระหนักถึงสิ่งนี้
ยืด Maniac

5

SpockOrRock - PHP

SpockOrRock

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

ทำงานด้วย php spockorrock.php

<?php

//Pick either Spock or Rock
if (rand(0,1) == 0)     echo("R\n");
else                    echo("V\n");


?>

4

SlowLizard, Ruby

หลังจากเริ่มต้นด้วย Lizard มันจะสุ่มเลือกท่าที่เต้นก่อนหน้าของคู่ต่อสู้เสมอ

responses = {
  'R' => ['P', 'V'],
  'P' => ['S', 'L'],
  'S' => ['R', 'V'],
  'L' => ['S', 'R'],
  'V' => ['P', 'L']
}

if ARGV.length == 0
  puts 'L'
else
  puts responses[ARGV[1][-1]].sample
end

วิ่งเหมือน

ruby slowlizard.rb

4

LexicographicBot

บอทชอบสั่งจดหมายของเขาดังนั้นเขาจะเลือกคำตอบที่สูงกว่าคู่ต่อสู้ของเขาที่ให้ไว้ในรอบก่อนหน้านี้ - ยกเว้นว่าฝ่ายตรงข้ามเลือก Vulcan จากนั้นเขาก็สุ่มเลือกคำตอบ

import sys
import random

choices = ["L", "P", "R", "S", "V"]

total = len(sys.argv)
if total==1:
    print("L")
    sys.exit()

opponent = sys.argv[2]
opponent_last = opponent[-1]

if opponent_last == choices[-1]:
    print(random.choice(choices))
else:
    next = choices.index(opponent_last)+1
    print(choices[next])

สิ่งนี้คาดว่ามือของฝ่ายตรงข้ามจะได้รับการแจกไพ่ที่สอง:

                           me
                            v
python LexicographicBot.py SR RV
                              ^
                            opponent

@ MartinBüttner: เพิ่มคำสั่งแล้ว! ฉันยุ่งอยู่กับการทำงานเพื่อพยายามตีพิมพ์บางสิ่งดังนั้นการหายตัวไปของฉัน
Kyle Kanos

หยุดพักในการวิ่งครั้งแรกโดยไม่มีสิ่งกีดขวาง Traceback (การโทรล่าสุดครั้งล่าสุด): ไฟล์ "LexicographicBot \ LexicographicBot.py", บรรทัดที่ 10, ใน <module> ฝ่ายตรงข้าม = sys.argv [2] IndexError: ดัชนีดัชนีอยู่นอกช่วง
Eoin Campbell

@EoinCampbell: ฉันลืมประโยคออกเมื่อเรียกใช้ครั้งแรกมันถูกเพิ่มและควรจะทำงานได้ดีในขณะนี้
Kyle Kanos

4

Werevulcan - Ruby

ทำงานเป็น ruby werevulcan.rb

@rules = {

  'L' => %w[V P],
  'P' => %w[V R],
  'R' => %w[L S],
  'S' => %w[P L],
  'V' => %w[R S]
}

@moves = @rules.keys

def defeats?(move1, move2)
  @rules[move1].include?(move2)
end

def score(move1, move2)
  if move1 == move2
    0
  elsif defeats?(move1, move2)
    1
  else
    -1
  end
end

def move
  player, opponent = ARGV

  # For the first 30 rounds, pick a random move that isn't Spock
  if player.to_s.size < 30
    %w[L P R S].sample
  elsif opponent.chars.to_a.uniq.size < 5
    exploit(opponent)
  else
    # Pick a random move that's biased toward Spock and against lizards
    %w[L P P R R S S V V V].sample
  end

end

def exploit(opponent)
  @moves.shuffle.max_by{ |m| opponent.chars.map{|o| score(m,o) }.reduce(:+) }
end

puts move

มนุษย์หมาป่าดูเหมือนปกติทุกวัน แต่เมื่อดวงจันทร์ขึ้นหูของมันก็จะแหลมและการเคลื่อนไหวของมันก็จะเติบโตอย่างมีเหตุผลมากขึ้น


4

Analogizer - ทับทิม

ruby analogizer.rbทำงานด้วย ฉันได้ทำการแก้ไขลอจิกกับโค้ด แต่ก็ไม่รู้ว่าทำไมถึงมีข้อผิดพลาดเกิดขึ้น

@rules = {

  'L' => %w[V P],
  'P' => %w[V R],
  'R' => %w[L S],
  'S' => %w[P L],
  'V' => %w[R S]
}

@moves = @rules.keys

def defeats?(move1, move2)
  @rules[move1].include?(move2)
end

def score(move1, move2)
  if move1 == move2
    0
  elsif defeats?(move1, move2)
    1
  else
    -1
  end
end

def move
  player, opponent = ARGV

  case player.to_s.size
  # Throw six lizards in the beginning to confuse opponent
  when 0..5
    'L'
  when 6
    'V'
  when 7
    'S'
  when 8
    'P'
  when 9
    'R'
  else
    analyze_history(player.chars.to_a, opponent.chars.to_a)
  end

end

def analyze_history(player, opponent)
  my_last_move = player.last
  predicted_moves = Hash.new {0}
  opponent_reactions = player.zip(opponent.drop(1))

  # Check whether opponent tended to make a move that would've beaten, lost, or tied my last move
  opponent_reactions.each do |my_move, reaction|
    score = score(reaction, my_move)
    analogous_moves = @moves.select { |move| score == score(move, my_last_move) }
    analogous_moves.each { |move| predicted_moves[move] += 1 }
  end

  # Assume if an opponent has never made a certain move, it never will
  @moves.each { |m| predicted_moves[m] = 0 unless opponent.include?(m) }

  # Pick the move with the best score against opponent's possible moves, weighted by their likelihood, picking randomly for ties
  @moves.shuffle.max_by{ |m| predicted_moves.map { |predicted, freq| score(m, predicted) * freq }.reduce(0,:+) }

end

puts move

สมมติว่าบอทที่ต่อต้านอยู่เสมอตอบสนองต่อการเคลื่อนไหวก่อนหน้าของฉันและเลือกสิ่งที่จะเอาชนะมันสิ่งที่จะสูญเสียมันหรือย้ายเดียวกันอาจเป็นไปได้จากชุด จำกัด ของการเคลื่อนไหวที่เป็นไปได้ จากนั้นจะเลือกการเคลื่อนไหวที่ดีที่สุดตามสมมติฐาน

ยกเว้นว่าการเคลื่อนไหวสิบครั้งแรกนั้นฮาร์ดโค้ด: ครั้งแรกที่ฉันแสร้งว่าฉันรู้จักจิ้งจกเท่านั้นฉันคิดว่าคู่ต่อสู้ของฉันจะขว้างบางสิ่งบางอย่างเพื่อเอาชนะสิ่งสุดท้ายที่ฉันขว้างจนกว่าจะมีข้อมูลเพียงพอสำหรับการวิเคราะห์ที่เหมาะสม


4

Java - SelfLoathingBot

BotName: SelfLoathingBot
Compile: Save as 'SelfLoathingBot.java'; compile.
Run:     java SelfLoathingBot [me] [them]

ธ ปท. เริ่มสุ่มจากนั้น 33% ในการสุ่มหรือ ~ 33% เพื่อเล่นแทคติคที่ชนะเมื่อเทียบกับการเล่นก่อนหน้าทันทีทั้งสองทางเลือก 50% ในการชนะแทคติค

import java.util.Random;

public class SelfLoathingBot {

    static final Random RANDOM = new Random();

    private static char randomPlay() {

        switch (RANDOM.nextInt(5)) {

            case 0 : return 'R';

            case 1 : return 'P';

            case 2 : return 'S';

            case 3 : return 'L';

            default : return 'V';
        }
    }

    private static char antiPlay(String priorPlayString) {

        char[] priorPlays = priorPlayString.toCharArray();

        int choice = RANDOM.nextInt(2);

        switch (priorPlays[priorPlays.length - 1]) {

            case 'R' : return choice == 0 ? 'P' : 'V'; 

            case 'P' : return choice == 0 ? 'S' : 'L';

            case 'S' : return choice == 0 ? 'V' : 'R';

            case 'L' : return choice == 0 ? 'R' : 'S';

            default : return choice == 0 ? 'L' : 'P'; // V        
        }
    }

    public static void main(String[] args) {

        int choice = args.length == 0 ? 0 : RANDOM.nextInt(3);

        char play;

        switch (choice) {

            case 1 :

                // 33.3% chance Play myself
                play = antiPlay(args[0]);
                break;

            case 2 :

                // 33.3% chance Play opponent just in case opponent is screwy like that
                play = antiPlay(args[1]);
                break;

            default :

                // 33.3% chance 100% Random
                play = randomPlay();
        }

        System.out.print(play);
        return;
    }
}

4

นักวิเคราะห์

นักวิเคราะห์วิเคราะห์บางสิ่งและพยายามเอาชนะคุณ

รวบรวมjavac Analyst.javaและเรียกใช้เป็นjava Analyst

import java.util.Random;

public class Analyst{
    public static void main(String[] args){
        char action = 'S';

        try{
            char[] enemyMoves = null, myMoves = null;

            //first move is random
            if(args.length == 0){
                System.out.print(randomMove());
                System.exit(0);
            //moves 2-3 will beat their last move
            }else if(args[0].length() < 8){
                System.out.print(counterFor(args[1].charAt(args[1].length()-1)));
                System.exit(0);
            //following moves will execute some analyzation stuff
            }else{
                //get previous moves
                myMoves = args[0].toCharArray();
                enemyMoves = args[1].toCharArray();
            }

            //test if they're trying to beat our last move
            if(beats(enemyMoves[enemyMoves.length-1], myMoves[myMoves.length-2])){
                action = counterFor(counterFor(myMoves[myMoves.length-1]));
            }
            //test if they're copying our last move
            else if(enemyMoves[enemyMoves.length-1] == myMoves[myMoves.length-2]){
                action = counterFor(myMoves[myMoves.length-1]);
            }
            //else beat whatever they've done the most of
            else{
                action = counterFor(countMost(enemyMoves));
            }

            //if they've beaten us for the first 40 moves, do the opposite of what ive been doing
            if(theyreSmarter(myMoves, enemyMoves)){
                action = counterFor(action);
            }

        //if you break my program do something random
        }catch (Exception e){
            action = randomMove();
        }

        System.out.print(action);
    }

    private static char randomMove(){
        Random rand = new Random(System.currentTimeMillis());
        int randomMove = rand.nextInt(5);

        switch (randomMove){
            case 0: return 'R';
            case 1: return 'P';
            case 2: return 'S';
            case 3: return 'L';
            default: return 'V';
        }
    }

    private static char counterFor(char move){
        Random rand = new Random(System.currentTimeMillis());
        int moveSet = rand.nextInt(2);

        if(moveSet == 0){
            switch (move){
                case 'R': return 'P'; 
                case 'P': return 'S'; 
                case 'S': return 'R'; 
                case 'L': return 'R'; 
                default: return 'P';
            }
        }else{
            switch (move){
                case 'R': return 'V'; 
                case 'P': return 'L'; 
                case 'S': return 'V'; 
                case 'L': return 'S'; 
                default: return 'L';
            }
        }
    }

    private static boolean beats(char move1, char move2){
        if(move1 == 'R'){
            if((move2 == 'S') || (move2 == 'L')){
                return true;
            }else{
                return false;
            }
        }else if(move1 == 'P'){
            if((move2 == 'R') || (move2 == 'V')){
                return true;
            }else{
                return false;
            }
        }else if(move1 == 'S'){
            if((move2 == 'L') || (move2 == 'P')){
                return true;
            }else{
                return false;
            }
        }else if(move1 == 'L'){
            if((move2 == 'P') || (move2 == 'V')){
                return true;
            }else{
                return false;
            }
        }else{
            if((move2 == 'R') || (move2 == 'S')){
                return true;
            }else{
                return false;
            }
        }
    }

    private static char countMost(char[] moves){
        int[] enemyMoveList = {0,0,0,0,0};

        for(int i=0; i<moves.length; i++){
            if(moves[i] == 'R'){
                enemyMoveList[0]++;
            }else if(moves[i] == 'P'){
                enemyMoveList[1]++;
            }else if(moves[i] == 'S'){
                enemyMoveList[2]++;
            }else if(moves[i] == 'L'){
                enemyMoveList[3]++;
            }else if(moves[i] == 'V'){
                enemyMoveList[4]++;
            }
        }

        int max = 0, maxIndex = 0;
        for(int i=0; i<5; i++){
            if(enemyMoveList[i] > max){
                max = enemyMoveList[i];
                maxIndex = i;
            }
        }

        switch (maxIndex){
            case 0: return 'R';
            case 1: return 'P';
            case 2: return 'S';
            case 3: return 'L';
            default: return 'V';
        }
    }

    private static boolean theyreSmarter(char[] myMoves, char[] enemyMoves){
        int loseCounter = 0;

        if(enemyMoves.length >= 40){
            for(int i=0; i<40; i++){
                if(beats(enemyMoves[i],myMoves[i])){
                    loseCounter++;
                }
            }
        }else{
            return false;
        }

        if(loseCounter > 20){
            return true;
        }else{
            return false;
        }
    }
}

4

นักพนัน - Python 2

import sys
import random

MODE = 1

moves = 'RSLPV'

def element_sums(a, b):
    return [a[i] + b[i] for i in xrange(len(a))]

def move_scores(p):
    def calc(to_beat):
        return ['LDW'.find('DLLWW'[moves.find(m)-moves.find(to_beat)]) for m in moves]

    return dict(zip(moves, element_sums(calc(p[0]), calc(p[1]))))

def move_chooser(my_history, opponent_history):
    predict = sorted(moves, key=opponent_history.count, reverse=MODE)[-2:]
    scores = move_scores(predict)
    return max(scores, key=lambda k:scores[k])

if __name__ == '__main__':
    if len(sys.argv) == 3:
        print move_chooser(*sys.argv[1:])
    elif len(sys.argv) == 1:
        print random.choice(moves)

ตรงกันข้ามกับชื่อการสุ่มเวลาครั้งเดียวเท่านั้นที่ใช้ในโปรแกรมนี้คือในรอบแรกเมื่อไม่มีข้อมูล แต่มันถูกตั้งชื่อเพื่อการเข้าใจผิดของนักพนันความเชื่อที่ว่าหากเหตุการณ์แบบสุ่มเกิดขึ้นน้อยครั้งในอดีตมันมีแนวโน้มที่จะเกิดขึ้นในอนาคต ตัวอย่างเช่นหากคุณพลิกเหรียญที่ยุติธรรม 20 ครั้งและ 15 อันดับแรกคือความผิดพลาดของนักการพนันระบุว่าอัตราเดิมพันของการโยนที่เหลือจะถูกก้อยเพิ่มขึ้น แน่นอนว่านี่เป็นเรื่องจริง โดยไม่คำนึงถึงการโยนครั้งก่อนอัตราต่อรองที่เหรียญขึ้นมาอยู่ที่ 50% เสมอ

โปรแกรมนี้วิเคราะห์ประวัติของฝ่ายตรงข้ามพบว่ามีการเคลื่อนไหว 2 ครั้งที่มันใช้ไปจนสุดและสันนิษฐานว่าการเคลื่อนไหวของฝ่ายตรงข้ามในครั้งนี้จะเป็นหนึ่งในสองอย่างนั้น การกำหนด 2 ถึงชัยชนะ 1 ถึงเสมอและ 0 ถึงการสูญเสียพบว่าการเคลื่อนที่มีคะแนนสูงสุดเทียบกับการเคลื่อนไหวทั้งสองที่คาดการณ์ไว้และโยนมันไป

พี่ชายของนักพนัน - Python 2

import sys
import random

MODE = 0

moves = 'RSLPV'

def element_sums(a, b):
    return [a[i] + b[i] for i in xrange(len(a))]

def move_scores(p):
    def calc(to_beat):
        return ['LDW'.find('DLLWW'[moves.find(m)-moves.find(to_beat)]) for m in moves]

    return dict(zip(moves, element_sums(calc(p[0]), calc(p[1]))))

def move_chooser(my_history, opponent_history):
    predict = sorted(moves, key=opponent_history.count, reverse=MODE)[-2:]
    scores = move_scores(predict)
    return max(scores, key=lambda k:scores[k])

if __name__ == '__main__':
    if len(sys.argv) == 3:
        print move_chooser(*sys.argv[1:])
    elif len(sys.argv) == 1:
        print random.choice(moves)

โดยการเปลี่ยนMODEตัวแปรเป็น 0 โปรแกรมนี้จะทำงานตามการเข้าใจผิดที่เกี่ยวข้องซึ่งบางครั้งเรียกว่าการเข้าใจผิดของนักพนัน ระบุว่าหากเหตุการณ์สุ่มเกิดขึ้นบ่อยครั้งในอดีตก็มีแนวโน้มที่จะเกิดขึ้นในอนาคต ตัวอย่างเช่นหากคุณพลิกเหรียญ 20 ครั้งและ 15 ครั้งแรกเป็นหัวการเข้าใจผิดนี้ระบุว่าการโยนที่เหลือมีแนวโน้มที่จะเป็นหัวมากกว่าเนื่องจากมีแนวในปัจจุบัน ในโหมด 0 โปรแกรมนี้ทำงานในลักษณะเดียวกันยกเว้นว่ามันถือว่าฝ่ายตรงข้ามจะโยนหนึ่งในสองการเคลื่อนไหวที่มันถูกโยนบ่อยที่สุด

ใช่สองโปรแกรมนี้แยกจากกันเพียงตัวเดียว :)


TheGambler เปลี่ยน MODE เป็นอย่างไร?
Dr R Dizzle

@DRRDizzle มันไม่ได้ดูเหมือนว่านี่คือการส่งของสองบอทในที่เดียว
Paŭlo Ebermann

2
โปรแกรมนี้จะไม่มีประสิทธิภาพมากกว่านี้หรือไม่หาก MODE เปลี่ยนไปหากคุณเสียเวลาติดต่อกันเกินจำนวนที่กำหนดหรือไม่
Dr R Dizzle

4

Dienstag (Python 2)

Ponyรายการแรกของฉันดูเหมือนว่าจะค่อนข้างดีกับการคาดเดาครั้งที่สอง (การคาดเดา tripple, ... ) และการให้เหตุผลเมตาดาต้า แต่นั่นเป็นสิ่งที่จำเป็นแม้แต่?

ดังนั้นนี่คือ Dienstag เพื่อนตัวเล็ก ๆ ของ Pony โดยมีเพียงหนึ่งใน 55 กลยุทธ์: ทำนายการเคลื่อนที่ต่อไปของฝ่ายตรงข้ามและเอาชนะได้

ในระยะยาว Dienstag ชนะหรือผูกติดกับ Bot ทุกตัวในสิบอันดับแรกของกระดานผู้นำปัจจุบัน ยกเว้นสำหรับ Pony นั่นคือ

import sys
if len(sys.argv)<2 or len(sys.argv[1])<2: print 'L'; sys.exit()
hist = [map('RPSVL'.index, p) for p in zip(sys.argv[1], sys.argv[2])]
N = len(hist)
cand = range(N-1)
for l in xrange(1,N):
    cand = ([c for c in cand if c>=l and hist[c-l+1]==hist[-l]] or cand[-1:])
print 'RPSVL'[(hist[cand[-1]+1][1]+(1,3)[N%2==0])%5]

ทำงานเป็น:

python Dienstag.py

ฉันยอมรับว่ารหัสนั้นค่อนข้างสับสน หากใครสนใจรู้เพิ่มเติมเกี่ยวกับมันฉันอาจเพิ่มคำอธิบาย

แก้ไข:นี่เป็นตัวอย่างสั้น ๆเพื่ออธิบายแนวคิด:

  • โปรแกรมรับประวัติของมันเองและการเคลื่อนไหวของคู่ต่อสู้:

    sys.arg[1] = 'LLVLLVL', sys.arg[2] = 'RPSPSSP'

  • ประวัติรวมอยู่ในรายการคู่และการเคลื่อนไหวจะถูกแปลเป็นตัวเลข (R = 0, ... ):

    hist = [[4, 0], [4, 1], [3, 2], [4, 1], [4, 2], [3, 2], [4, 1]]

  • จำนวนรอบที่เล่นจนถึงตอนนี้ถูกกำหนดไว้แล้ว:

    N = 7

  • แนวคิดพื้นฐานตอนนี้คือการมองหาห่วงโซ่ที่ไม่ขาดระยะยาวที่สุดของการเคลื่อนไหวครั้งสุดท้ายในประวัติศาสตร์ก่อนหน้านี้ โปรแกรมติดตามว่าห่วงโซ่ดังกล่าวสิ้นสุดลงในรายการcand(สำหรับ 'ผู้สมัคร') ในการเริ่มต้นโดยไม่มีการตรวจสอบทุกตำแหน่งในประวัติศาสตร์ยกเว้นตำแหน่งสุดท้ายจะถูกพิจารณา:

    cand = [0, 1, 2, 3, 4, 5]

  • ตอนนี้ความยาวของเชนที่เป็นไปได้เพิ่มขึ้นทีละขั้นตอน สำหรับความยาวโซ่จะมองหาที่เกิดขึ้นก่อนหน้านี้ทั้งคู่ย้ายล่าสุดl = 1 [4, 1]นี้สามารถพบได้ในตำแหน่งที่ประวัติศาสตร์และ1 3รายการเหล่านี้เท่านั้นที่จะถูกเก็บไว้ในcandรายการ:

    cand = [1, 3]

  • ถัดไปสำหรับมันจะตรวจสอบว่าผู้สมัครที่เป็นไปได้ก็นำโดยสองคู่ย้ายที่ผ่านมาl = 2 [3, 2]นี่เป็นเพียงกรณีสำหรับตำแหน่ง3:

    cand = [3]

  • สำหรับl = 3และไม่มีโซ่ก่อนหน้าของความยาวนั้นและcandจะว่างเปล่า ในกรณีนี้องค์ประกอบสุดท้ายของcandจะถูกเก็บไว้:

    cand = [3]

  • ตอนนี้ ธ ปท. สันนิษฐานว่าประวัติศาสตร์จะทำซ้ำ ครั้งสุดท้ายที่คาอินที่เกิดขึ้นก็จะตามมาด้วย[3, 2], [4, 1] [4, 2]ดังนั้นฝ่ายตรงข้ามเล่น2(กรรไกร) ซึ่งสามารถเอาชนะได้(2+1)%5 = 3(Spock) หรือ(2+3)%5 = 0(ร็อค) บอตตอบด้วยตัวเลือกแรกหรือตัวเลือกที่สองขึ้นอยู่กับว่าNเป็นเลขคี่หรือเพียงเพื่อแนะนำความแปรปรวนบางอย่าง

  • นี่คือการเคลื่อนไหวที่3เลือกซึ่งจะถูกแปลกลับมาแล้ว:

    print 'V'

หมายเหตุ: Dienstag มีความซับซ้อนของเวลา O ( N 2 ) สำหรับการคืนการย้ายครั้งต่อไปหลังจากรอบN Pony มีความซับซ้อนของเวลา O ( N 3 ) ดังนั้นในแง่นี้พวกเขาอาจจะแย่กว่านั้นอีกรายการส่วนใหญ่


โปรดทำ นี่เป็นประสบการณ์การเรียนรู้ที่ยอดเยี่ยมสำหรับฉัน ฉันมักจะอาศัยอยู่ในดินแดน C # / Java ดังนั้นทั้งหมด lua, ruby, python, haskell madnessนั้นน่าสนใจมากสำหรับฉัน
Eoin Campbell

ฉันยังอยากที่จะเพิ่มอินสแตนซ์พิเศษของ Pony ลงในเกม มันจะเหมือนกับการต่อสู้กับกระจกเงาของคุณในระดับที่ 3 ถึงระดับสุดท้าย Mortal Combat ;-)
Eoin Campbell

@EoinCampbell :-) อย่างน้อยการจับคู่โดยตรงกับ Pony vs. Pony น่าจะเป็นการจับที่สมบูรณ์แบบ ไม่มีองค์ประกอบของการสุ่มทั้งในบอทของฉัน
Emil

3

Bash Rocks

cygwin มากเกินไปที่จะถามเป็นรันไทม์หรือไม่?

bashrocks.sh:

#!/bin/bash
HAND=(R P S L V)
RAND=`od -A n -t d -N 1 /dev/urandom | xargs`
echo ${HAND[ $RAND  % 5 ]}

และเรียกใช้เช่น:

sh bashrocks.sh

5
หลังจากอ่านชื่อฉันผิดหวังเล็กน้อยที่คุณทำอะไรRนอกจาก ;)
Martin Ender

@mccannf มีปัญหาบางอย่างกับอันนี้ ... ฉันได้ติดตั้ง cygwin และแก้ไขสคริปต์ของคุณด้วยพา ธ ที่ผ่านการรับรองไปยัง C: \ Cygwin \ bin สำหรับ od.exe, xargs.exe & echo.exe ยังคงได้รับข้อผิดพลาดต่อไปนี้ C: / Cygwin / bin / xargs: echo: ไม่มีข้อผิดพลาดทางไวยากรณ์ของไฟล์หรือไดเรกทอรี% 5 "): ถูกดำเนินการ (ตัวรับข้อผิดพลาดคือ"
Eoin Campbell

@EoinCampbell - เมื่อคุณสร้างไฟล์ใน windows คุณสามารถเรียกใช้dos2unixไฟล์ใน cygwin ก่อนที่จะดำเนินการได้หรือไม่?
mccannf

แน่ใจ ฉันจะลองดูสิ
Eoin Campbell

ฉันคิดว่าปัญหาอาจเกิดจากคำสั่ง / dev / urandom
Eoin Campbell

3

ขั้นตอนวิธี

อัลกอริทึมเพื่อประโยชน์ในการมี

เพราะมันรู้สึกปลอดภัยกว่าเสมอที่จะทำอะไรให้มันซับซ้อนยิ่งขึ้น

ยังไม่ได้ทำการคำนวณทางคณิตศาสตร์อย่างจริงจังดังนั้นอัลกอริทึมนี้อาจไม่มีประสิทธิภาพ

import random, sys

if __name__ == '__main__':

    # Graph in adjacency matrix here
    graph = {"S":"PL", "P":"VR", "R":"LS", "L":"VP", "V":"SR"}
    try:
        myHistory = sys.argv[1]
        opHistory = sys.argv[2]
        choices = ""

        # Insert some graph stuff here. Newer versions may include advanced Math.
        for v in graph:
            if opHistory[-1] == v:
                for u in graph:
                    if u in graph[v]:
                        choices += graph[u]

        print random.choice(choices + opHistory[-1])

    except:
        print random.choice("RPSLV")

โปรแกรม Python 2: python algorithm.py


1
สรุปอัลกอริทึมนี้: ดูสิ่งที่คู่ต่อสู้เล่นล่าสุดจากนั้นสุ่มเล่นหนึ่งในสองการเคลื่อนไหวที่จะแพ้การเคลื่อนไหวครั้งสุดท้ายของฝ่ายตรงข้ามหากพวกเขาเล่นอีกครั้ง ดังนั้นจะดีกว่าสำหรับบ็อตที่ไม่เล่นแบบเดียวกันสองครั้งติดต่อกัน
Rory O'Kane

ฮ่าฮ่า ฉันไม่รู้จริงๆว่าฉันทำแบบนั้นหรือเปล่า ถ้าฉันไม่ผิดมันเป็นเพียงวิธีสุ่มเลือก 5 อย่างใดอย่างหนึ่งที่ซับซ้อน ;)
Vectorized

3

FairBot, Ruby

มาเริ่มกันง่ายๆ

puts ['R','P','S','L','V'].sample

วิ่งเหมือน

ruby fairbot.rb

ตัวพิมพ์เล็ก ๆ บนพารามิเตอร์ 'V' ที่ผ่านมา มีการแก้ไขบน myside ถ้าคุณต้องการที่จะปรับปรุงเพื่อความสมบูรณ์
เอียนแคมป์เบล

@EoinCampbell ขอบคุณคงที่!
Martin Ender

1
สิ่งที่น่าสนใจคือมันมีอัตราต่อรองที่เท่าเทียมกันในการชนะกับทุกกลยุทธ์
Cruncher

3

ViolentBot

บอทนี้เลือกตัวเลือกที่มีความรุนแรงมากที่สุดตามตัวเลือกก่อนหน้าของฝ่ายตรงข้าม:

import sys

choice_dict = {"L" : "S", "P" : "S", "R" : "V", "S" : "V", "V" : "L"}

total = len(sys.argv)
if total==1:
    print("L")
    sys.exit()

opponent = sys.argv[2]
opponent_last = opponent[-1]

print(choice_dict[opponent_last])

ทำงานเป็น

python ViolentBot.py (me) (opp)

พักโดยไม่มี params Traceback (การโทรล่าสุดครั้งล่าสุด): ไฟล์ "ViolentBot \ ViolentBot.py", บรรทัดที่ 9, ใน <module> ฝ่ายตรงข้าม = sys.argv [2] ดัชนีข้อผิดพลาด: ดัชนีรายการอยู่นอกช่วง
Eoin Campbell

แบ่งกับ params Traceback (การโทรล่าสุดครั้งล่าสุด): ไฟล์ "ViolentBot \ ViolentBot.py", บรรทัดที่ 12, ใน <module> พิมพ์ (choice_dict [rival_last]) KeyError: 'S'
Eoin Campbell

@EoinCampbell: ฉันได้เพิ่มอนุประโยคทางออกสำหรับการเรียกใช้ครั้งแรกคุณควรจะสามารถรันได้ทันที
Kyle Kanos

3

Haskell - MonadBot

ฉันไม่รู้ว่า ghc ถูกพิจารณาว่า "อยู่ในเหตุผล" แต่ลองสมมติว่ามันเป็น กลยุทธ์ของบอทนี้คือการต่อต้านการเคลื่อนไหวที่เป็นที่นิยมมากที่สุดของฝ่ายตรงข้าม

Compile: ghc monadbot.hs
Run:     ./monadbot [Arg1] [Arg2]

รหัส:

import System.Environment
import Data.List
import Data.Ord

main :: IO ()
main = do
  args <- getArgs
  let moves = if not (null args) then args !! 1 else ""
      fave = if not (null moves) then head $ maximumBy (comparing length) (group $ sort moves) else 'V'
  putChar $ case fave of 'R' -> 'P'
                         'P' -> 'S'
                         'S' -> 'R'
                         'L' -> 'R'
                         'V' -> 'P'
                         _   -> 'V'
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.