Lab Rat Race: การออกกำลังกายในขั้นตอนวิธีเชิงพันธุกรรม


113

นี่คือความท้าทายรายปักษ์ # 3 ชุดรูปแบบ: อัลกอริทึมทางพันธุกรรม

ความท้าทายนี้เป็นส่วนหนึ่งของการทดลอง เราต้องการที่จะเห็นสิ่งที่เราสามารถทำได้ท้าทายด้วยปัญญาขั้นตอนวิธีทางพันธุกรรม ไม่ใช่ทุกอย่างอาจจะดีที่สุด แต่เราพยายามอย่างดีที่สุดเพื่อให้สามารถเข้าถึงได้ ถ้าสิ่งนี้ใช้ได้ผลใครจะรู้ว่าเราจะเห็นอะไรในอนาคต อาจเป็น King of the Hill ทางพันธุกรรมหรือไม่?

สเป็คค่อนข้างยาว! เราได้พยายามแยกข้อมูลจำเพาะออกเป็นพื้นฐาน - ขั้นต่ำเปล่าที่คุณต้องรู้เพื่อเริ่มเล่นกับกรอบงานและส่งคำตอบ - และรายละเอียด The Gory - ข้อมูลจำเพาะทั้งหมดพร้อมรายละเอียดทั้งหมดเกี่ยวกับตัวควบคุมตามที่คุณ สามารถเขียนของคุณเอง
หากคุณมีคำถามใด ๆอย่าลังเลที่จะเข้าร่วมกับเราในการแชท!

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

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

ตัวอย่างภาพบอร์ดที่ใช้งาน

† 84,465 ตัวอย่างถูกทำร้ายในการสร้างความท้าทายนี้

พื้นฐาน

เกมนี้เป็นเกมที่เล่นคนเดียว (คุณและเพื่อนร่วมงานของคุณไม่ต้องการรวมประชากรเพื่อให้แต่ละคนสร้างเส้นทางการแข่งขันของตัวเอง) สนามแข่งเป็นตารางสี่เหลี่ยมสูง15เซลล์และกว้าง50เซลล์ คุณเริ่มต้นด้วย 15 ตัวอย่างบนเซลล์สุ่ม (ไม่จำเป็นต้องแตกต่างกัน) ที่ขอบซ้าย (โดยที่x = 0 ) ตัวอย่างของคุณควรพยายามไปให้ถึงเป้าหมายซึ่งเป็นเซลล์ใด ๆ ที่x ≥ 49และ0 ≤ y ≤ 14 (ชิ้นงานอาจเกินเส้นทางไปทางขวา) ทุกครั้งที่เกิดเหตุการณ์นี้คุณจะได้รับคะแนน คุณเริ่มเกมด้วย 1 แต้ม คุณควรพยายามที่จะเพิ่มคะแนนของคุณหลังจาก10,000รอบ

ตัวอย่างหลายรายการอาจครอบครองเซลล์เดียวกันและจะไม่ทำงาน

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

  • 8สีจะแสดงเซลล์ว่าง
  • 4สีจะเป็นตัวแทนของเครื่องเคลื่อนย้ายมวลสาร เครื่องเคลื่อนย้ายมวลสารจะส่งชิ้นงานไปยังเซลล์ที่ต้องการภายในพื้นที่ใกล้เคียงขนาด 9x9 ออฟเซ็ตนี้จะเหมือนกันสำหรับเครื่องเคลื่อนย้ายมวลสารที่มีสีเดียวกันทั้งหมด
  • 2สีจะเป็นตัวแทนของผนัง การเคลื่อนย้ายเข้าไปในกำแพงก็เหมือนกับการหยุดนิ่ง
  • 2สีจะแสดงถึงกับดัก กับดักระบุว่าหนึ่งใน 9 เซลล์ในพื้นที่ใกล้เคียงนั้นเป็นอันตรายถึงตาย (ไม่จำเป็นต้องเป็นเซลล์ดักจับเอง) ออฟเซ็ตนี้จะเหมือนกันสำหรับกับดักที่มีสีเดียวกันทั้งหมด

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

นี่คือหน้าที่ของคุณ:คุณจะเขียนฟังก์ชั่นเดียวซึ่งได้รับเป็นอินพุตของตารางสี 5x5 ที่ชิ้นงานเห็นและจีโนม ฟังก์ชั่นของคุณจะคืนค่าการย้าย (Δx, Δy) สำหรับชิ้นงานทดสอบโดยที่ΔxและΔyแต่ละคนจะเป็นหนึ่งใน{-1, 0, 1}นั้น คุณต้องไม่ยืนยันข้อมูลใด ๆ ระหว่างการเรียกใช้ฟังก์ชัน ซึ่งรวมถึงการใช้เครื่องสร้างตัวเลขสุ่มของคุณเอง ฟังก์ชั่นของคุณจะได้รับ RNG ที่มีค่าซึ่งคุณสามารถใช้ได้ฟรีตามที่คุณต้องการ

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

เราได้จัดทำโปรแกรมควบคุมในภาษาต่างๆ ขณะนี้คุณสามารถเขียนส่งของคุณในหลาม (2 หรือ 3), ทับทิม , C ++ , C #หรือJava ตัวควบคุมสร้างบอร์ดเรียกใช้เกมและให้กรอบสำหรับอัลกอริทึมทางพันธุกรรม สิ่งที่คุณต้องทำคือให้ฟังก์ชั่นการเคลื่อนที่

เดี๋ยวก่อนฉันจะทำยังไงกับจีโนม?

ความท้าทายคือการคิดออก!

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

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

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

อ่านต่อหากคุณต้องการทั้งหมด ...

รายละเอียดเลือด

ข้อกำหนดนี้เสร็จสมบูรณ์ ตัวควบคุมทั้งหมดต้องใช้กฎเหล่านี้

การสุ่มทั้งหมดใช้การแจกแจงแบบสม่ำเสมอเว้นแต่จะระบุไว้เป็นอย่างอื่น

ติดตามรุ่น:

  • แทร็กเป็นตารางสี่เหลี่ยมกว้างX = 53เซลล์และสูงY = 15เซลล์ เซลล์ที่มีx ≥ 49เป็นเซลล์เป้าหมาย (โดยที่xเป็นศูนย์)
  • แต่ละเซลล์มีสีเดียวและอาจจะหรืออาจจะไม่ตาย - เซลล์ไม่ได้ตายนอกจากที่ระบุไว้โดยหนึ่งในเซลล์ชนิดที่อยู่ด้านล่าง
  • มีสีของเซลล์ที่แตกต่างกัน16สีติดป้ายจาก0เป็น15ซึ่งความหมายจะเปลี่ยนจากเกมหนึ่งเป็นอีกเกม นอกจากนี้ยัง-1แสดงให้เห็นถึงเซลล์ที่อยู่นอกขอบเขต - เหล่านี้เป็นตาย
  • เลือก8 สีแบบสุ่ม สิ่งเหล่านี้จะเป็นเซลล์ว่าง (ซึ่งไม่มีผลกระทบ)
  • เลือก4 สีแบบสุ่มมากขึ้น นี่คือเครื่องเคลื่อนย้ายมวลสาร สำหรับสองสีเหล่านี้ให้เลือกการชดเชยที่ไม่เป็นศูนย์ในพื้นที่ใกล้เคียง9x9 (ตั้งแต่ (-4, -4) ถึง (4,4) ยกเว้น (0,0)) สำหรับอีกสองสีให้สลับการชดเชยเหล่านั้น หากชิ้นงานทดสอบไปที่เครื่องเคลื่อนย้ายมวลสารมันจะถูกเคลื่อนย้ายทันทีโดยการชดเชยนั้น
  • เลือก2 สีแบบสุ่มมากขึ้น นี่คือกับดัก สำหรับแต่ละสีเหล่านี้ให้เลือกการชดเชยในพื้นที่ใกล้เคียง 3x3 (จาก (-1, -1) ถึง (1,1)) กับดักแสดงให้เห็นว่าเซลล์ที่ว่าชดเชยตาย หมายเหตุ:เซลล์กับดักนั้นไม่จำเป็นว่าจะต้องตาย
  • 2 สีเหลือผนังซึ่งเป็นอุปสรรคต่อการเคลื่อนไหว ความพยายามที่จะย้ายไปยังเซลล์ผนังจะทำให้การเคลื่อนไหวยังคงอยู่ เซลล์ผนังตัวเองตาย
  • สำหรับแต่ละเซลล์ที่ไม่ใช่เป้าหมายของตารางให้เลือกสีแบบสุ่ม สำหรับแต่ละเซลล์เป้าหมายให้เลือกสีที่ว่างเปล่าแบบสุ่ม
  • สำหรับแต่ละเซลล์ที่ขอบด้านซ้ายของแทร็กตรวจสอบว่าสามารถเข้าถึงเป้าหมายได้ภายใน100 ตาแหน่ง (ตามกฎของลำดับการเลี้ยวด้านล่าง) ถ้าเป็นเช่นนั้นเซลล์นี้เป็นเซลล์เริ่มต้นที่ยอมรับได้ หากมีเซลล์เริ่มต้นน้อยกว่า 10 เซลล์ให้ทิ้งแทร็กและสร้างเซลล์ใหม่
  • สร้าง15ตัวอย่างแต่ละคนมีจีโนมแบบสุ่มและอายุ0 วางชิ้นงานแต่ละชิ้นบนเซลล์เริ่มต้นแบบสุ่ม

เปิดคำสั่ง:

  1. ขั้นตอนต่อไปนี้จะดำเนินการตามลำดับสำหรับแต่ละตัวอย่าง ตัวอย่างไม่โต้ตอบหรือเห็นซึ่งกันและกันและอาจครอบครองเซลล์เดียวกัน
    1. หากอายุของตัวอย่างเท่ากับ100มันจะตาย มิฉะนั้นเพิ่มอายุโดย 1
    2. ชิ้นงานจะได้รับมุมมองของมัน - ตารางสี 5x5 โดยมีศูนย์กลางอยู่ที่ชิ้นงาน - และคืนค่าการเคลื่อนที่ในพื้นที่ใกล้เคียง 3x3 การย้ายที่อยู่นอกช่วงนี้จะทำให้คอนโทรลเลอร์หยุดทำงาน
    3. หากเซลล์เป้าหมายเป็นผนังการเคลื่อนที่จะเปลี่ยนเป็น (0,0)
    4. หากเซลล์เป้าหมายเป็นเครื่องเคลื่อนย้ายมวลสารตัวอย่างจะถูกเคลื่อนย้ายโดยการชดเชยของเครื่องเคลื่อนย้ายมวลสาร หมายเหตุ:ขั้นตอนนี้จะดำเนินการเพียงครั้งเดียวไม่ใช่ซ้ำ ๆ
    5. หากในปัจจุบันเซลล์ครอบครองโดยชิ้นงาน (อาจเกิดขึ้นหลังจากใช้เครื่องเคลื่อนย้ายมวลสารหนึ่งอัน) จะทำให้ชิ้นงานตายลง นี่เป็นเพียงครั้งเดียวที่ชิ้นงานจะตาย (นอกเหนือจากขั้นตอนที่ 1.1 ด้านบน) โดยเฉพาะตัวอย่างใหม่ที่วางไข่บนเซลล์ที่ตายแล้วจะไม่ตายทันที แต่มีโอกาสที่จะย้ายออกจากเซลล์อันตรายก่อน
    6. หากชิ้นทดสอบครอบครองเซลล์เป้าหมายให้คะแนนจุดย้ายชิ้นตัวอย่างไปยังเซลล์เริ่มต้นสุ่มและรีเซ็ตอายุของมันเป็น 0
  2. หากเหลือตัวอย่างน้อยกว่าสองตัวบนกระดานเกมจะจบลง
  3. สร้าง10ตัวอย่างใหม่กับอายุ0 จีโนมแต่ละตัวจะถูกกำหนด (แยก) โดยกฎการผสมพันธุ์ด้านล่าง วางชิ้นงานแต่ละชิ้นบนเซลล์เริ่มต้นแบบสุ่ม

การปรับปรุงพันธุ์:

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

    1 + x + 50 * จำนวนครั้งที่ไปถึงเป้าหมาย

    โดยที่xคือดัชนีแนวนอน 0-based ไม่สามารถเลือกตัวอย่างที่สร้างในเทิร์นเดียวกันได้ในฐานะผู้ปกครอง

  • ในพ่อแม่ทั้งสองให้เลือกหนึ่งสุ่มเพื่อรับจีโนมบิตแรกจาก

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

เกณฑ์การให้คะแนน:

  • เกมหนึ่งใช้เวลา10,000รอบ
  • ผู้เล่นเริ่มเกมด้วย 1 แต้ม (เพื่ออนุญาตให้ใช้ค่าเฉลี่ยทางเรขาคณิต)
  • ทุกครั้งที่ชิ้นงานไปถึงเป้าหมายผู้เล่นจะทำคะแนน
  • สำหรับตอนนี้การส่งผู้เล่นแต่ละคนจะถูกเรียกใช้สำหรับ50เกมแต่ละเกมมีแทร็กสุ่มแตกต่างกัน
  • วิธีการข้างต้นส่งผลให้เกิดความแปรปรวนมากกว่าที่ต้องการ เมื่อความท้าทายนี้สิ้นสุดลงจะมีการประกาศกำหนดเวลา ในตอนท้ายของกำหนดส่ง 100 บอร์ดจะถูกสุ่มเลือกและการส่งทั้งหมดจะได้รับการช่วยเหลือใน 100 บอร์ด
  • คะแนนโดยรวมของผู้เล่นคือค่าเฉลี่ยทางเรขาคณิตของคะแนนของแต่ละเกม

ผู้ควบคุม

คุณสามารถเลือกตัวควบคุมต่อไปนี้ได้ (เนื่องจากเทียบเท่ากับการใช้งาน) เราได้ทดสอบทั้งหมดแล้ว แต่ถ้าคุณพบจุดบกพร่องต้องการปรับปรุงโค้ดหรือประสิทธิภาพหรือเพิ่มคุณสมบัติเช่นเอาท์พุทกราฟิกโปรดส่งปัญหาหรือส่งคำขอดึงบน GitHub! คุณยังสามารถเพิ่มคอนโทรลเลอร์ใหม่ในภาษาอื่น!

คลิกชื่อภาษาสำหรับแต่ละคอนโทรลเลอร์เพื่อไปยังไดเรกทอรีที่ถูกต้องบน GitHub ซึ่งมีREADME.mdคำสั่งการใช้งานที่แน่นอน

หากคุณไม่คุ้นเคยกับ git และ / หรือ GitHub คุณสามารถดาวน์โหลดที่เก็บทั้งหมดเป็น ZIP จากหน้าแรก (ดูปุ่มในแถบด้านข้าง)

หลาม

  • ผ่านการทดสอบอย่างละเอียดที่สุด นี่คือการดำเนินการอ้างอิงของเรา
  • ใช้งานได้กับทั้ง Python 2.6+ และ Python 3.2+!
  • มันช้ามาก เราขอแนะนำให้รันด้วยPyPyเพื่อการเร่งความเร็วที่ดีเยี่ยม
  • รองรับผลกราฟิกโดยใช้หรือpygametkinter

ทับทิม

  • ทดสอบกับ Ruby 2.0.0 ควรทำงานกับเวอร์ชันที่ใหม่กว่า
  • มันค่อนข้างช้าเช่นกัน แต่ทับทิมอาจจะสะดวกในการทำต้นแบบความคิดสำหรับการส่ง

C ++

  • ต้องการ C ++ 11
  • สนับสนุนทางเลือกแบบมัลติเธรด
  • โดยไกลตัวควบคุมที่เร็วที่สุดในพวง

C #

  • ใช้ LINQ ดังนั้นจึงต้องใช้. NET 3.5
  • ค่อนข้างช้า

ชวา

  • ไม่ช้าโดยเฉพาะอย่างยิ่ง ไม่เร็วมาก

ลีดเดอร์บอร์ดเบื้องต้น

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

  Score   | # Games | User               | Language   | Bot           
===================================================================================
2914.13   |   2000  | kuroi neko         | C++        | Hard Believers
1817.05097|   1000  | TheBestOne         | Java       | Running Star
1009.72   |   2000  | kuroi neko         | C++        | Blind faith
 782.18   |   2000  | MT0                | C++        | Cautious Specimens
 428.38   |         | user2487951        | Python     | NeighborsOfNeighbors
 145.35   |   2000  | Wouter ibens       | C++        | Triple Score
 133.2    |         | Anton              | C++        | StarPlayer
 122.92   |         | Dominik Müller     | Python     | SkyWalker
  89.90   |         | aschmack           | C++        | LookAheadPlayer
  74.7    |         | bitpwner           | C++        | ColorFarSeeker
  70.98   |   2000  | Ceribia            | C++        | WallGuesser
  50.35   |         | feersum            | C++        | Run-Bonus Player
  35.85   |         | Zgarb              | C++        | Pathfinder
 (34.45)  |   5000  | Martin Büttner     | <all>      | ColorScorePlayer
   9.77   |         | DenDenDo           | C++        | SlowAndSteady
   3.7    |         | flawr              | Java       | IAmARobotPlayer
   1.9    |         | trichoplax         | Python     | Bishop
   1.04   |   2000  | fluffy             | C++        | Gray-Color Lookahead

เครดิต

ความท้าทายนี้เป็นความร่วมมืออย่างมาก:

  • Nathan Merril:เขียนตัวควบคุม Python และ Java เปลี่ยนแนวคิดการท้าทายจาก King-of-the-Hill เป็น Rat Race
  • trichoplax: การทดสอบ ทำงานบนคอนโทรลเลอร์ Python
  • feersum:เขียนตัวควบคุม C ++
  • VisualMelon:เขียนคอนโทรลเลอร์ C #
  • Martin Büttner:แนวคิด เขียนตัวควบคุม Ruby playtesting ทำงานบนคอนโทรลเลอร์ Python
  • T Abraham: การทดสอบ ทดสอบ Python และสอบทาน C # และ C ++ คอนโทรลเลอร์

ผู้ใช้ทั้งหมดข้างต้น (และอาจจะลืมไปมากกว่านี้อีกสองสามอย่าง) มีส่วนทำให้การออกแบบโดยรวมของความท้าทาย

อัพเดตคอนโทรลเลอร์ C ++

หากคุณใช้ C ++ กับ Visual Studio และ multithreading คุณควรได้รับการอัพเดทล่าสุดเนื่องจากบั๊กที่มีการสร้างตัวสร้างหมายเลขสุ่มซึ่งทำให้สามารถสร้างบอร์ดที่ซ้ำกันได้


3
บางคนไม่สามารถสร้างอัลกอริทึมพันธุกรรมทางพันธุกรรมเพื่อค้นหาอัลกอริทึมพันธุกรรมที่เหมาะสมที่สุดสำหรับปัญหานี้ได้หรือไม่?
mbomb007

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

1
@matovitch ดูส่วนที่ 5 ของส่วนคำสั่งซื้อของรายละเอียดเต็มไปด้วยเลือด (สเป็คเต็มรูปแบบ):'In particular, a new specimen which spawns on a lethal cell will not die immediately, but has a chance to move off the dangerous cell first.'
trichoplax

1
ฉันปรับแต่งรหัส C ++ เพื่อแสดงค่าเฉลี่ยตัวอย่าง stddev, stderr และ 99% conf-interval (ก่อนหน้าบันทึก / exp "เรขาคณิต" ของคุณ) และทำการค้นพบที่น่าตกใจ คำตอบที่ "ตาบอดศรัทธา" มี "ค่าเฉลี่ยตัวอย่างของ 116529 + - 2.78337e + 010 (99%) stddev = 7.77951e + 010" หลังจากการวิ่ง 50 ครั้ง "การลดช่วงความเชื่อมั่นลงเหลือ 50% ไม่ได้ทำให้เรื่องดีขึ้นเลย ค่าเฉลี่ยของรูปทรงเรขาคณิตนั้นมีแนวโน้มว่า: "ค่าเฉลี่ยของ 159.458 + - 117262 (99%) stddev = 32.6237" (ก่อนอัปเดต 800 คะแนนของเขา)
Mooing Duck

1
ฉันทำการทดลองด้วยอัตราการกลายพันธุ์และฉันคิดว่าความท้าทายจะน่าสนใจมากขึ้น (และผู้ควบคุมจะทำงานเร็วกว่ามาก) ถ้าความน่าจะเป็นเพิ่มขึ้นจาก. 01 ถึง. 0227 ซึ่งให้โอกาส DNA เพียง 10% ในการผ่าน การกลายพันธุ์ไม่เปลี่ยนแปลงแทน 37% ด้วยค่าปัจจุบัน วิธีนี้จะหลีกเลี่ยงการระเบิดของประชากรที่ไร้สาระ (ซึ่งจะช่วยประหยัดเวลาในการคำนวณได้มาก) และป้องกันความล้มเหลวมากมายเนื่องจากความหลากหลายไม่เพียงพอ คะแนนส่วนบุคคลต่ำกว่า แต่เนื่องจากมีผู้ชนะมากขึ้นค่าเฉลี่ยทั่วโลกจึงสูงขึ้น

คำตอบ:


37

ตาบอดศรัทธา - C ++ - ดูเหมือนว่าจะมีคะแนนสูงกว่า 800 (!) มากกว่า 2,000 ครั้ง

จีโนมการเข้ารหัสสีพร้อมเสียงตอบรับอย่างลึกลับและเครื่องยับยั้งการกระแทกผนังที่มีประสิทธิภาพ

#include "./gamelogic.cpp"

#define NUM_COLORS 16

// color meanings for our rats
typedef enum { good, bad, trap } colorType_t;
struct colorInfo_t {
    colorType_t type;
    coord_t offset; // trap relative location
    colorInfo_t() : type(good) {} // our rats are born optimists
};

// all 8 possible neighbours, carefully ordered
coord_t moves_up  [] = { { 1, 0 }, { 1,  1 }, { 1, -1 }, { 0,  1 }, { 0, -1 }, { -1, 0 }, { -1,  1 }, { -1, -1 } };  // toward the goal, going up   first
coord_t moves_down[] = { { 1, 0 }, { 1, -1 }, { 1,  1 }, { 0, -1 }, { 0,  1 }, { -1, 0 }, { -1, -1 }, { -1,  1 } };  // toward the goal, going down first

// map of the surroundings
struct map_t {
    static const size_t size = 5;
    static const int max = size / 2;
    static const int min = -max;
    colorType_t map[size*size];
    colorType_t & operator() (int x, int y) { return map[(x + max)*size + y + max]; }
    colorType_t & operator() (coord_t pos) { return operator()(pos.x, pos.y); }
    bool is_inside(int x, int y) { return abs(x) <= max && abs(y) <= max; }
    bool is_inside(coord_t pos) { return is_inside(pos.x,pos.y); }
};

// trap mapping info
struct trap_t {
    coord_t detector;
    colorInfo_t color;
    trap_t(int x, int y, colorInfo_t & color) : color(color) { detector.x = x; detector.y = y; }
    trap_t() {}
};

coord_t blindFaith(dna_t d, view_t v)
{
    colorInfo_t color[NUM_COLORS]; // color informations

    // decode colors
    for (size_t c = 0; c != 16; c++)
    {
        size_t base = c * 4;
        if (d[base])
        {
            color[c].type = d[base+1] ? good : bad;
        }
        else // decode trap location
        {
            color[c].type = trap;
            int offset = d[base+1] + 2 * d[base+2] + 4 * d[base+3];
            color[c].offset = moves_up[offset]; // the order is irrelevant as long as all 8 neighbours are listed
        }
    }

    // build a map of the surrounding cells
    map_t map;
    unsigned signature = 0;
    int i = 0;
    for (int x = map.min; x <= map.max; x++)
    for (int y = map.min; y <= map.max; y++)
    {
        int c = v(x, y);
        map(x, y) = (c == -1) ? bad : color[c].type;
        if (c != -1) signature ^= v(x, y) << ((i++) % 28);
    }

    // map traps
    for (int x = map.min; x <= map.max; x++)
    for (int y = map.min; y <= map.max; y++)
    {
        if (map(x, y) != trap) continue;
        const colorInfo_t & trap = color[v(x, y)];
        int bad_x = x + trap.offset.x;
        int bad_y = y + trap.offset.y;
        if (!map.is_inside(bad_x, bad_y)) continue;
        map(bad_x, bad_y) = bad;
        map(x, y) = good;
    }

    // pick a vertical direction according to surroundings signature
    int go_up = d[64 + signature % (DNA_BITS - 64)];

    // try to move to a good cell nearer the goal
    for (const coord_t &move : go_up ? moves_up : moves_down) if (map(move.x, move.y) == good) return move;

    // try not to increase fitness of this intellectually impaired specimen
    return{ -1, 0 };
}

int main() {
    time_t start = time(NULL);
    double score = runsimulation(blindFaith);
    slog << "Geometric mean score: " << score << " in " << time(NULL) - start << " seconds";
}

ตัวอย่างผลลัพธ์:

Scores: 15 4113306 190703 1 1 44629 118172 43594 63023 2 4 1 1 205027 1 455951 4194047 1 5 279 1 3863570 616483 17797 42584 1 37442 1 37 1 432545 5 94335 1 1 187036 1 4233379 1561445 1 1 1 1 35246 1 150154 1 1 1 1 90141 6 1 1 1 26849 1 161903 4 123972 1 55 988 7042063 694 4711342 90514 3726251 2 1 383389 1 593029 12088 1 149779 69144 21218 290963 17829 1072904 368771 84 872958 30456 133784 4843896 1 2 37 381780 14 540066 3046713 12 5 1 92181 5174 1 156292 13 1 1 29940 66678 125975 52714 1 5 3 1 101267 69003 1 1 10231 143110 282328 4 71750 324545 25 1 22 102414 1 3884626 4 28202 64057 1 1 1 1 70707 4078970 1623071 5047 1 1 549040 1 1 66 3520283 1 6035495 1 79773 1 1 1 218408 1 1 15 33 589875 310455 112274 1 1 4 1 3716220 14 180123 1 2 12785 113116 12 2 1 59286 822912 2244520 1840950 147151 1255115 1 49 2 182262 109717 2 9 1049697 59297 1 11 64568 1 57093 52588 63990 331081 54110 1 1 1537 3 38043 1514692 360087 1 260395 19557 3583536 1 4 152302 2636569 12 1 105991 374793 14 3934727 1 2 182614 1 1675472 121949 11 5 283271 207686 175468 1 1 173240 1 138778 1 1 59964 3290382 1 4 1757946 1 23520 1 2 94 1 124577 497071 1749760 39238 1 301144 3 1 2871836 1 1 10486 1 11 8 1 111421 11 1807900 1 587479 1 42725 116006 3 1 6 5441895 1 1 22 52465 952 1 18 1 1 46878 2 1 1 1994 4 593858 123513 4692516 820868 4247357 1 1 2 1 2 8770 2 1 95371 4897243 2 22741 1 1 1 1 325142 6 33650 4 51 102993 1 182664 1 4040608 18153 2045673 462339 1 1 617575 2 2551800 3 7760 1 108012 76167 143362 1148457 1 53460 1 71503 1 1 1 1 81482 3208 62286 69 139 1 3503941 1 253624 101903 3081954 80123 84701 9 16 1 1070688 71604 613064 2076 15009 9 1 1 1 199731 1 2 1 63132 1 1843855 27808 1 3569689 273144 1 460524 2703719 22443 10876 51242 1 6972678 4591939 1 140506 43981 45076 2 1 91301 5 1 1874615 1758284 608 13 1 96545 75161 1 618144 4 2056133 1 1 2 57401 1394307 6 188116 83545 1 41883 1 1 467189 371722 1 1122993 1 17912 159499 1 5 3355398 33 1 2 246304 1 2 168349 1 50292 12 141492 2723076 3 1 6 3060433 223360 171472 106409 1 2 1 102729 8814 1 285154 1 11 1 65 930 2 689644 3271116 1 5 4 60 77447 1 1 1477538 256023 100403 2480335 1 39888 1 1 70052 66090 1 250 1 2 8 115371 1523106 1424 168148 1 1 1 42938 17 1 364285 185080 1 1 36 4903764 13 51987 1106 276212 67460 1 251257 2 6867732 1 1 1890073 1 1 8 5 2118932 210 0 3792346 5209168 1 1 1 1 51 1 4621148 1 37 337073 3506096 1 1 1 1 458964 2 16 52930 1 15375 267685 1 1 1259646 14930 3248678 527105 1 103 24 1 3252685 6009 1 1 176340 3971529 121 1722808 1 31483 194232 2314706 95952 3625407 3 216755 56 1 8 1 1 1 1 885 229 9056 172027 31516 2526805 1 76076 1589061 1 1 8 90812 1 21 72036 1681271 2 212431 1581814 85993 79967 4 7 514708 1070070 1 71698 1 23478 15882 94453 1 27382 495493 277308 12127 91928 248593 1 1 1 26540 1709344 2119856 1 1 48867 107017 251374 64041 15924 15 87474 8 1 23 9 48 1 1 1 51793 2 61029 84803 15 689851 1 1 873503 10 140084 420034 87087 82223 1 163273 12 1 5 570463 19 26665 1 170311 1 39983 1 475306 1 2 36417 746105 11 141345 1 3 1 30 3 1 1 1 1 1312289 408117 1 42210 273871 561592 1 1 1 1 4448568 48448 7 378508 1 351858 278331 1 79515 1169309 3670107 14711 4686395 1156554 33 2528441 24537 76 335390 63545 122108 76675 21929 34 1 861361 83000 417781 1 90487 1 1 85116 7 2 1 60129 647991 79 1 2755780 726845 244217 50007 187212 1 3674051 286071 44068 3 307427 26973 1 26059 1957457 230783 58102 545318 1 4 172542 168365 1 89402 1 4 1 1 1 1 2 3 16 62935 5643183 117961 109942 85762 5 117376 118883 1 61 23893 122536 70185 1 64252 208409 179269 55381 1579240 3434491 1 4964284 3356245 3 21 2197119 346542 44340 59976 772220 5590844 199721 90858 63785 125989 57219 129737 81836 1 3671 16810 1 4151040 1 15 40108 1 443679 3224921 2 27498 2 3 146529 169409 19 1 1 1 1 41627 1 3 2722438 1 2013730 1 1649406 1 1 6943 125772 58652 1 1 1 2413522 1 2 48 36067 253807 2 146464 1 248 07 3359223 139896 395985 65241 43988 594638 69033 275085 1 17973 1 1 1 594835 1 1 4468341 3496274 222854 94769 55 161056 36185 8793 277592 3 1 6746 1 138151 66 37365 1 2729315 1 3 57091 22408 249875 246514 85058 1 20 5463152 1 3 1 45293 1 70488 2792458 461 441 951926 2236205 2 171980 1 1 48 3893009 1 458077 1 268203 1 70005 7 19299 1 278978 1 45286 26 2 1883506 274393 342679 1 1 913722 911600 12688 1 1 115020 1249307 1529878 53426 1 226862 3721440 23537 86033 397433 1 1 1 161423 96343 94496 1 1 1 2 1 111576 1 4039782 1 1 1 5742393 3569 46072 1 1 2 1 1 85335 219988 1 78871 115876 43405 1 300835 1 166684 53134 1 3 111487 6 3 3 77 1 115971 3 205782 10 1932578 356857 43258 47998 1 27648 127096 573939 32650 523906 45193 1 2 128992 1 10144 1 257941 1 19841 5077836 14670 5 3 6 1 1 21 14651 2906084 37942 45032 9 304192 3035905 6214026 2 177952 1 51338 1 65594 46426 553875 2676479 245774 95881 3 216364 3064811 1198509 223982 3 6 1 533254 1 590363 264940 68346 127284 1 7 1 1 4617874 5 45400 1 1 3097950 360274 1 3 1 8421 14 469681 418563 3 1 6 1 1 575766 405239 11 2631108 152667 1 1 1 467383 1 1 775499 1 157998 2 1 143351 92021 1 1 1173046 3636579 1 70635 162303 1 1534876 834682 2 1 1 11981 346908 245124 607794 17 1570641 126995 13 57050 1 2 33731 29739 1 1 35460 1 33716 168190 214704 1 443156 701674 2636870 108081 1604895 1 1 11 115901 23 571891 360680 1 1 35 1 2036975 1 1 2555536 4742615 5 360553 287044 1 1814255 7 59632 1 216 41546 1 540920 353424 2625301 223744 1 1 1 15717 3 429871 1 4 2329632 18 11 1 2 4 1 3905 5 1 1 1 2 5431442 1 859628 1 3 338378 15236 13764 1 3384362 1 15 65293 24 619599 152620 2 189921 35854 16647 7 2 404790 360096 1 2 189459 1097768 191610 1 1 470254 1 12 2 330299 364219 2365542 312023 2273374 2 10527 1 115453 1 2 3845592 52388 913449 1 14695 1 44 37352 90302 1 1 1 233577 51639 3474983 44010 1650727 31 2 2 1 8 7 1 3 5 25603 17799 45630 758457 1 4571839 37 4 3 2 1 1 1351271 196673 12 2880765 263886 2926173 1 2 1 241502 5 6 1 278576 9 7 290722 42749 143391 82753 21771 57887 1 1 60400 1766903 1 296392 1 5 2861787 125560 1 9 199218 1 1 308226 517598 2246753 12 1168981 3 98447 1 488613 9 842865 202108 10 1 238493 1 1523706 5383982 29435 1 1 207071 1 8 4 125742 70531 253135 72207 124291 23364 184376 2 40034 9569353 194109 102854 2 3247153 58313 85995 1 598 63 1 2676692 10 3573233 1 36651 118016 2486962 65456 46760 1 5813 723 178120 2 153305 1 1 2 1 2354413 3 1 17126 132953 437123 299778 3070490 1 6490 403704 2261 511439 1 39 33410 173045 1 1 120970 641346 132042 1 44906 1 33940 132124 467702 45472 9 44 1 1 1 107008 1 46635 1 121431 130760 1 7 3 1 56251 1299306 3 1 1 1 15 2147678 215169 1374943 1 332995 231089 269310 1 7816944 1 1 1 46 134426 1 1 1 2 76112 1 1 30438 299927 25 139373 76048 278757 71 3474997 1 294046 1 3126554 2518019 2 1 6 1 3054393 1 1 1 2 525 96 419528 1 1 154718 233 207879 26 1 6 57436 3 5944942 1 1 318198 147536 1 22 420557 1 1 120938 1 1 167412 4082969 73299 1 11 3557361 1 4 330028 269051 1 2569546 2 1 1 4 1 1 377412 1 1 1 213800 58131 1422177 54 109617 117751 12432 3830664 419046 3 6821 741 919 1 22335 1 1 15069 80694 488809 2389 2308679 145548 51411 115786 110984 107713 1 12 6 1 5 8365 1 2001874 210250 4674015 14 1 1204101 314354 89066 1 1 2438200 68350 1 1575329 5593838 2743787 151670 57 16 5948210 597158 128060 189160 23628 1 1 15 4171774 1 8206 4157492 1 2 315607 1618680 24736 18520 4787225 33842 134431 1 1 1 1 1 1115809 17759 1 33016 123117 1 77322 169633 219091 1 321593 57231 135536 175401 4 1 435702 1 253132 100707 114547 1 119324 6382967 1472898 3 72567 1707408 177958 26 208719 1 27083 74 12 576410 19375 177069 4 3 1 31 507048 2 1 1 2 1 2 1 40 7 99892 95202 60649 241396 232370 1 136579 70649 1 2877 280695 13603 102860 404583 29717 112769 1 54089 1 97579 40819 2 868629 64848 2 63432 5 1 1888426 99623 2 1 7911 53646 3047637 1 2 3 152910 1 3244662 105187 1 1 1 1 8966 200347 1 1 22 302654 6 17 1 10 328150 55259 1016 117291 2 1 224524 23846 74645 1 1 1 1 1 3117394 10847 33976 144613 4 201584 1 1 26959 3 4410588 27019 6 66749 55935 23 4126812 4089989 99959 1 1 1 1 55490 1 4275599 13652 33967 2 8126062 337093 320653 128015 4 1 7729132 1 10594 116651 20990 3046630 1 353731 132989 2066431 4 80 15575 147430 1 621461 3100943 2306122 5 33439 407945 25634 1 2911806 32511 2174235 298281 15159 54125 1 2 3063577 2205013 1 407984 1 319713 1 22171 1 2763843 1 2607606 1 100015 3096036 1 55905 1 1 635265 2890760 1 1 1 1 35854 1 352022 2652014 1 2 274366 1 4 1 602980 4 83828 602270 2816 2 59116 25340 1 11 1 5162051 34 8 218372 1186732 142966 1 1 170557 503302 1 84924 5 1 1350329 1 1 1 130273 78055 902762 1 8581 5 1 3635882 1 1 1 224255 44044 61250 2 438453 8 1 2729357 28 1 17658 82640 1 31809 10 1 33 1 1 45495 5798 5000217 40018 588787 67269 1 12 83512 2798339 1 609271 1 3 1 7 67912 189808 3388775 60961 81311 1167 24939 433791 405306 85934 1 1170651 2 1 66 552579 122985 515363 2188340 1 1 1 3807012 1502582 4 13 149593 1 1 2108196 3 34279 24613 1282047 27 1 2 1 1 584435 27487 1 1 5 33278 1 1 1202843 1 1 1 6 3649820 3100 2 266150 13 164117 10 53163 3295075 1 1 1 1 77890 1 286220 90823 18866 3139039 481826 1 3994676 23 116901 132290 6 3927 84948 1 1 1 1 256310 1 11 8 1 102002 8392 887732 98483 444991 1 1 49408 409967 1158979 1 1 1 81469 189764 3960930 296231 64258 1 1 176030 4 1 2 1 486856 1 1135146 31 2 13112 227077 31
Geometric mean score: 831.185 in 14820 seconds

จากการทดสอบระยะยาวโดยไม่สมัครใจของ feersum ฉันคิดว่าการวิ่ง 2000 นั้นเพียงพอที่จะให้ผลลัพธ์ที่มีเสถียรภาพ
เนื่องจากคอนโทรลเลอร์ที่ถูกดัดแปลงของฉันแสดงค่าเฉลี่ยทางเรขาคณิตปัจจุบันหลังจากการวิ่งแต่ละครั้งฉันยืนยันด้วยสายตาว่ารูปแบบที่เปลี่ยนแปลงในการวิ่ง 50 ครั้งล่าสุดนั้นค่อนข้างเล็ก (+ - 10 คะแนน)

อะไรที่ทำให้ critters เห็บ

แทนที่จะให้ความสำคัญเท่ากันกับแต่ละสีฉันจะพิจารณาค่าที่เป็นไปได้เหล่านี้:

  1. ดี -> หนูคิดว่าสามารถไปที่นั่นได้อย่างปลอดภัย
  2. ไม่ดี -> หนูจะไม่ไปที่นั่น
  3. กับดัก -> หนูจะพิจารณาตำแหน่งของกับดักที่ไม่ดีและเซลล์ที่ระบุกับดักที่ดี
    แม้ว่าฉันจะขี้เกียจเกินไปที่จะเปลี่ยนชื่อ แต่นี่เป็น "เครื่องตรวจจับอันตราย" ซึ่งระบุตำแหน่งที่ควรจะเป็นกับดักจริงผนัง teleporter ที่รอส่งคนจรจัดที่น่าสงสัยไปยังสถานที่ที่ไม่พึงประสงค์หรือแม้แต่ทางเข้าของคนตาย -End ในระยะสั้นสถานที่ที่หนูฉลาดไม่อยากไป

ยีนที่ดีหรือไม่ดีใช้เวลาเพียง 2 บิตในการจัดเก็บ (เช่น11และ10) แต่กับดักต้อง 4 บิต ( 0tttซึ่งtttเป็นหนึ่งในความเป็นไปได้ 8 สถานที่ตั้งที่ "อันตราย")

เพื่อให้แต่ละยีนที่สอดคล้องกัน (เช่นการรักษาความหมายของมันหลังจากที่ได้รับการผสมลงในจีโนมที่แตกต่างกันอย่างสิ้นเชิงซึ่งจะต้องมียีนแต่ละรหัสสีที่จะเป็นที่ตั้งคงที่) ค่าทั้งหมดจะเขียนในวันที่ 4 บิต (ดังนั้นที่ดีเป็นรหัสที่เป็น11xxและไม่ดีเป็น10xx) รวมเป็น 16 * 4 = 64 บิต

ส่วนที่เหลืออีก 36 บิตจะใช้เป็น "anti-bangers" (เพิ่มเติมในภายหลัง) 25 สีโดยรอบถูกแฮชเข้าไปในดัชนีของ 36 บิตเหล่านี้ แต่ละบิตระบุทิศทางแนวตั้งที่ต้องการ (ขึ้นหรือลง) ซึ่งจะใช้เมื่อมีตัวเลือกที่เป็นไปได้ระหว่างสองเซลล์

กลยุทธ์มีดังนี้:

  • ถอดรหัสแต่ละสีตามจีโนม (หรือรายงานตัวควบคุมโดยตรงสำหรับเซลล์ที่ "ไม่ดี" แบบ off-track)
  • สร้างแผนที่ของสภาพแวดล้อมใกล้เคียง (เซลล์ 3x3, 8 เพื่อนบ้านที่เป็นไปได้)
  • คำนวณลายเซ็นของสภาพแวดล้อม (แฮชของ 25 สียกเว้นเซลล์นอกลู่)
  • เลือกทิศทางแนวตั้งที่ต้องการจากลายเซ็น (ระหว่าง 36 ถังแฮ)
  • พยายามย้ายไปยังเพื่อนบ้านบอกเป็นนัยว่า "ดี" โดยเริ่มจากเป้าหมายที่ใกล้ที่สุดและไปในทิศทางแนวตั้งที่ต้องการก่อน
  • หากไม่พบเพื่อนบ้านที่“ ดี” ให้พยายามย้ายเซลล์หนึ่งกลับคืนมา (อาจเป็นเหยื่อของอุบัติเหตุที่โชคร้ายและหลีกเลี่ยงการเพิ่มความแข็งแรงในอัตราใด ๆ )

พวกสัตว์ฟันแทะจงดูศัตรูของพวกเจ้า

กำแพงที่หวั่น ห่วงเทเลพอร์ต

สิ่งที่แย่ที่สุดที่สามารถเกิดขึ้นกับประชากรที่จะได้มีการผลิตยังไม่มีผู้ชนะ แต่มากของหนูติดอย่างใดอย่างหนึ่งกับผนังหรือภายในวง teleporting อนันต์ใกล้พอที่จะเป้าหมายที่จะมีโอกาสที่โดดเด่นของการถูกเลือกสำหรับการเพาะพันธุ์
ตรงกันข้ามกับหนูที่ถูกแบนเข้ากับดักหรือถูกเทเลกำแพงเข้ามาหนูเหล่านี้จะถูกฆ่าเมื่ออายุมากขึ้นเท่านั้น
พวกเขาไม่มีความได้เปรียบในการแข่งขันกับลูกพี่ลูกน้องของพวกเขาที่ติดอยู่ 3 เซลล์จากจุดเริ่มต้น แต่พวกเขาจะมีเวลาเหลือเฟือที่จะผสมพันธุ์รุ่นหลังจาก cretins จนกระทั่งจีโนมของพวกเขากลายเป็นที่โดดเด่นจึงทำร้ายความหลากหลายทางพันธุกรรม

เพื่อลดปรากฏการณ์นี้ความคิดคือการทำให้ลูกหลานของหนูที่ไม่ดีและไม่ดีเหล่านี้มีแนวโน้มที่จะหลีกเลี่ยงการทำตามขั้นตอนของบรรพบุรุษของพวกเขา
การบ่งชี้ทิศทางแนวตั้งนั้นมีความยาวเพียง 1 บิต (โดยทั่วไปจะพูดว่า "ลองขึ้นหรือลงก่อนในสภาพแวดล้อมเหล่านี้") และมีไม่กี่บิตที่น่าจะมีผลกระทบกับเส้นทางที่ตามมาดังนั้นการกลายพันธุ์และ / หรือครอสโอเวอร์ ผลกระทบสำคัญ.
ลูกหลานจำนวนมากจะมีพฤติกรรมที่แตกต่างกันและจะไม่จบลงด้วยการกระแทกหัวของพวกเขาบนผนังเดียวกัน (ท่ามกลางซากศพของบรรพบุรุษที่อดอยาก)
สิ่งแปลกปลอมในที่นี้คือสิ่งบ่งชี้นี้ไม่ใช่ปัจจัยหลักในพฤติกรรมของหนู การตีความสีจะยังคงเหนือกว่าในกรณีส่วนใหญ่ (ตัวเลือกขึ้น / ลงจะมีความสำคัญหากมีสอง "ดี" อย่างแน่นอนและสิ่งที่หนูเห็นว่าเป็นสีที่ไม่เป็นอันตรายนั้นไม่ใช่เครื่องเคลื่อนย้ายมวลสารที่รอที่จะเหวี่ยงมันเข้าไปในกำแพง)

ทำไม (ดูเหมือน) ทำงาน

ฉันยังไม่รู้สาเหตุแน่ชัด

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

เมื่อใช้การเข้ารหัสจีโนมแบบสุ่มจะสร้างตัวระบุสี 25% "ดี", 25% "ไม่ดี" และ 50% "กับดัก"
ตัวระบุ "กับดัก" จะสร้างการประเมิน "ดี" และ "ไม่ดี" ซึ่งสัมพันธ์กับสภาพแวดล้อม 5x5
เป็นผลให้หนูในสถานที่ที่กำหนดจะ "เห็น" โลกเป็นส่วนผสมของสีที่มีเสถียรภาพและบริบท "go / no go"

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

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

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

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

เหตุใดการผสมผสานนี้จึงมีคุณสมบัติในการทำให้จีโนมมาบรรจบกันอย่างประสบความสำเร็จเป็นวิธีที่เกินกว่าคณิตศาสตร์ของฉัน

ฉันรู้สึกสะดวกสบายมากขึ้นกับเครื่องยับยั้งการกระแทกที่ผนัง สิ่งนี้ใช้งานได้ตามแผนที่วางไว้ แต่เหนือความคาดหมายของฉัน (คะแนนนั้นคูณด้วยสี่)

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

Turns:2499 best rat B  B  B  G  B  G  T3 G  T4 B  G  B  B  B  G  G  ^vv^^vv^v^v^^^vvv^v^^^v^^^v^vv^^v^^^ Max fitness: 790 Specimens: 1217 Score: 2800
Turns:4999 best rat B  B  B  G  B  G  T3 G  T4 B  G  B  B  B  G  G  ^vv^^vv^v^v^^^vvv^v^^^v^^^v^vv^^v^^^ Max fitness: 5217 Specimens: 15857 Score: 685986
Turns:7499 best rat B  B  B  G  B  G  T3 G  T4 B  G  B  B  B  G  G  ^vv^^vv^v^v^^^vvv^v^^^vvvvv^^v^v^^^^ Max fitness: 9785 Specimens: 31053 Score: 2695045
Turns:9999 best rat B  B  B  G  B  G  T3 G  T4 B  G  B  B  B  G  G  ^vv^^vv^v^v^^^vvv^v^^^vvvvv^^v^v^^^^ Max fitness: 14377 Specimens: 46384 Score: 6033904
Scored 6035495 in game 146 current mean 466.875

ที่นี่สายพันธุ์ซุปเปอร์หนูปรากฏตัวเร็ว (แทร็กอาจได้รับอนุญาตให้วิ่งเป็นเส้นตรงและหนูโชคดีในรุ่นแรก ๆ มี DNA ที่เหมาะสมในการใช้ประโยชน์จากมัน) จำนวนตัวอย่างในตอนท้ายประมาณครึ่งหนึ่งของค่าสูงสุดทางทฤษฎีของหนู 100,000 ตัวซึ่งหมายความว่าเกือบครึ่งหนึ่งของสัตว์เลื้อยคลานที่ได้รับความสามารถในการอยู่รอดเส้นทางนี้โดยเฉพาะ (!)
แน่นอนว่าคะแนนที่ได้นั้นเป็นสิ่งที่ลามกอนาจารเช่นเดียวกับเวลาในการคำนวณ

Turns:2499 best rat B  T0 G  B  T7 B  G  B  T6 T0 T3 B  G  G  G  T4 ^v^^^^^v^^v^v^^^^^^^^v^v^v^^vvv^v^^^ Max fitness: 18 Specimens: 772 Score: 1
Turns:4999 best rat T7 G  G  G  G  T7 G  B  T6 T0 T3 T5 G  G  B  T4 ^vvvvvvv^^^vvv^^v^v^^^^^^^^^^^^^v^^^ Max fitness: 26 Specimens: 856 Score: 1
Turns:7499 best rat G  T0 G  T3 G  T0 G  B  T6 T0 T2 B  T4 G  B  T4 ^^v^vvv^^^vv^^v^vvv^v^^vvvv^^^^^^^^^ Max fitness: 55 Specimens: 836 Score: 5
Turns:9999 best rat T6 T0 G  T5 B  T1 G  B  T6 T0 T3 B  T4 G  B  T4 ^^vv^^^^vv^^v^v^^v^^vvv^vv^vvv^^v^^v Max fitness: 590 Specimens: 1223 Score: 10478
Scored 10486 in game 258 current mean 628.564

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

ดูเหมือนว่ายีนสีมีคุณสมบัติที่มีประโยชน์บางประการ:

  • พวกเขามีความหมายในตัวเอง
    (สีที่เฉพาะเจาะจงจะต้องมีการจัดการในวิธีที่เฉพาะเจาะจง)
    การเข้ารหัสแต่ละสีสามารถถูกโยนลงในจีโนมที่แตกต่างกันอย่างสมบูรณ์โดยไม่ต้องเปลี่ยนพฤติกรรมอย่างมาก - ยกเว้นว่าสีเกิดขึ้นจริง กำแพงหรือเครื่องเคลื่อนย้ายมวลสารที่นำไปสู่การวนซ้ำไม่สิ้นสุด)
    นี่เป็นกรณีน้อยที่มีการเข้ารหัสระดับความสำคัญพื้นฐานเนื่องจากสีที่มีความสำคัญที่สุดคือข้อมูลที่ใช้ในการตัดสินใจว่าจะย้ายที่ใด ที่นี่ทุกสี "ดี" มีค่าเท่ากันดังนั้นสีที่กำหนดในรายการ "ดี" จะมีผลกระทบน้อยลง
  • พวกมันค่อนข้างยืดหยุ่นต่อการกลายพันธุ์
    การเข้ารหัสที่ดี / ไม่ดีมีเพียง 2 บิตที่สำคัญจาก 4 และตำแหน่งของกับดักอาจเปลี่ยนไปเกือบตลอดเวลาโดยไม่มีการเปลี่ยนแปลงพฤติกรรมหนูอย่างมีนัยสำคัญ
  • มันมีขนาดเล็ก (4 บิต) ดังนั้นความน่าจะเป็นที่จะถูกทำลายโดยครอสโอเวอร์จึงต่ำมาก
  • การกลายพันธุ์ทำให้เกิดการเปลี่ยนแปลงที่ไม่มีความหมายอย่างใดอย่างหนึ่งการกลายพันธุ์ของ
    ยีนที่ "ดี" จะมีผลเพียงเล็กน้อย (ถ้ามันสอดคล้องกับเซลล์ที่ว่างเปล่ามันอาจอนุญาตให้หาเส้นทางใหม่ที่สั้นกว่านี้ได้ กับดัก) หรืออันน่าทึ่ง (ถ้าสีแสดงถึงกำแพงหนูใหม่น่าจะติดอยู่ที่ใดที่หนึ่ง)
    ยีนที่พลิกไปที่ "กับดัก" จะกีดกันหนูจากสีที่จำเป็นหรือไม่มีผลที่เห็นได้ชัดเจน
    การกลายพันธุ์ของที่ตั้งดักจะมีความสำคัญถ้าหากมีกับดัก (หรืออะไรที่เป็นอันตราย) ข้างหน้าซึ่งมีความน่าจะเป็นที่ค่อนข้างเล็ก

สุดท้ายฉันเดาว่า 36 บิตสุดท้ายนั้นมีส่วนช่วยไม่ให้หนูติดค้าง แต่ยังแพร่กระจายหนูมากกว่าบนแทร็กอย่างสม่ำเสมอดังนั้นการรักษาความหลากหลายทางพันธุกรรมจนกระทั่งจีโนมที่ชนะปรากฏขึ้นและกลายเป็นส่วนสำคัญผ่านการเข้ารหัสสี

ทำงานต่อไป

ฉันต้องบอกว่าฉันพบว่าสัตว์เลื้อยคลานตัวเล็ก ๆ เหล่านี้น่าหลงใหล
ขอขอบคุณผู้มีส่วนร่วมทั้งหมดอีกครั้งสำหรับความท้าทายที่ยอดเยี่ยมนี้

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

ฉันอยากเห็นหนูเหล่านี้ทำงานเป็นอย่างมาก แต่ภาษา C ++ b ** ch นี้ทำให้เกิดการสร้าง - ทำให้ภาพเคลื่อนไหวได้อย่างอิสระ - ภาพ (เหนือสิ่งอื่นใด) เป็นงานที่ยุ่งเหยิง

ในท้ายที่สุดฉันต้องการผลิตระบบดักอย่างน้อยและอาจปรับปรุงได้

แฮ็คควบคุม

หากใครสนใจฉันสามารถเผยแพร่การดัดแปลงที่ฉันทำไว้กับคอนโทรลเลอร์
พวกเขาสกปรกและราคาถูก แต่พวกเขาทำงาน

ฉันไม่เข้าใจ GitHub ดังนั้นจะต้องผ่านการโพสต์เท่านั้น


16
ได้คะแนน 208.14 จาก 10,000 เกม ฉันพยายามทดสอบ 1,000 ครั้ง แต่ฉันไม่เคยรู้เลยว่าฉันพิมพ์ 0 พิเศษดังนั้นจึงใช้เวลามากกว่า 7 ชั่วโมง
feersum

ขอบคุณมากเหมือนกันทั้งหมด เมื่อเปรียบเทียบกับการวิ่ง 1,000 ครั้งของฉันดูเหมือนว่าการวิ่ง 2,000 ครั้งอาจให้ผลลัพธ์ที่มีเสถียรภาพ

คุณ^^v^vvv^^^vv^^v^vvv^v^^vvvv^^^^^^^^^มีความหมายว่าอย่างไร? ที่เหลือฉันสามารถเดาได้ แต่ฉันมีปัญหากับบิตนั้น?
Mooing Duck

ฉันใคร่ครวญการสร้างตัวควบคุม "debug" แยกต่างหากซึ่งทำงานครั้งละหนึ่งหนูและทุกครั้งที่หนูตัวใหม่ถูกสร้างขึ้นมันจะแสดง DNA ของทั้งพ่อแม่และลูก นั่นจะทำให้ง่ายขึ้นในการตรวจสอบว่าหนูทำงานอย่างไร
Mooing Duck

2
นั่นหมายถึงบิตตัวบ่งชี้ที่ 36 "ขึ้น / ลง" แต่ในตัวอย่างเหล่านี้ DNA ที่ชนะนั้นมีความโดดเด่นอยู่แล้วดังนั้นจึงไม่แตกต่างกันมากนัก

18

ผู้เชื่อที่ยาก - C ++ - (ผู้เคลื่อนย้ายมวลสารที่ปรับปรุงแล้ว): 10.000+ สำหรับการวิ่ง 2000 ครั้ง

(นี่คือวิวัฒนาการของความเชื่อแบบตาบอดดังนั้นคุณอาจต้องการปีนกำแพงข้อความก่อนหน้านี้)

#ifndef NDEBUG
#define NDEBUG
#include "./gamelogic.cpp"
#endif // NDEBUG
#include <cassert>

#define NUM_COLORS 16
#define BITS_OFFSET  3
#define BITS_TYPE    2
#define BITS_SUBTYPE 2
#define BITS_COLOR (BITS_TYPE+BITS_OFFSET)

// how our rats see the world
typedef unsigned char enumSupport_t;
typedef unsigned char trapOffset_t;
typedef enum : enumSupport_t {
    danger,   // code      trap detector
    beam,     // code      safe teleporter
    empty,    // code      empty
    block,    // code      wall, pit or teleporter
    trap,     // computed  detected trap
    pit,      // read      off-board cell
} colorType_t;

// color type encoding (4 first bits of a color gene)
// the order is critical. A single block/empty inversion can cost 2000 points or more
const colorType_t type_decoder[16] = {
    /*00xx-*/
    danger,
    empty,
    beam,
    block,
    /*01xx-*/
    beam,
    danger,
    empty,
    block,
    /*10xx-*/
    empty,
    beam,
    block,
    danger,
    /*11xx-*/
    block,
    empty,
    danger,
    beam,
};

// all 8 possible neighbours, carefully ordered
typedef coord_t neighborhood_t[8];
neighborhood_t moves_up =   { { 1, 0 }, { 1,  1 }, { 1, -1 }, { 0,  1 }, { 0, -1 }, { -1, 0 }, { -1,  1 }, { -1, -1 } };  // toward the goal, going up   first
neighborhood_t moves_down = { { 1, 0 }, { 1, -1 }, { 1,  1 }, { 0, -1 }, { 0,  1 }, { -1, 0 }, { -1, -1 }, { -1,  1 } };  // toward the goal, going down first

// using C++ as a macro-assembler to speedup DNA reading
/*
Would work like a charm *if* a well-paid scatterbrain at Microsoft had not defined
std::bitset::operator[] as

bool operator[](size_t _Pos) const
{   // subscript nonmutable sequence
return (test(_Pos));
}

Bounds checking on operator[] violates the spec and defeats the optimization.
Not only does it an unwanted check; it also prevents inlining and thus generates
two levels of function calls where none are necessary.
The fix is trivial, but how long will it take for Microsoft to implement it, if
the bug ever makes it through their thick layer of tech support bullshit artists?
Just one of the many reasons why STL appears not to live up to the dreams of
Mr Stroustrup & friends...
*/
template<size_t BITS> int DNA_read(dna_t dna, size_t base)
{
    const size_t offset = BITS - 1;
    return (dna[base + offset] << offset) | DNA_read<offset>(dna, base);
}
template<> int DNA_read<0>(dna_t, size_t) { return 0; }

// color gene
struct colorGene_t {
    colorType_t  type;
    trapOffset_t offset;  // trap relative location
    colorGene_t() : type(empty) {} // our rats are born optimists
};

// decoded DNA
class dnaInfo_t {
private:
    const dna_t & dna;
    static const size_t
        direction_start = NUM_COLORS*(BITS_TYPE + BITS_OFFSET),
        direction_size = DNA_BITS - direction_start;

public:
    colorGene_t color[NUM_COLORS];
    int         up_down; // anti-wall-banger

    // decode constant informations during construction
    dnaInfo_t(const dna_t & d) : dna(d)
    {
        for (size_t c = 0; c != NUM_COLORS; c++)
        {
            unsigned raw = DNA_read<BITS_COLOR>(d, c * BITS_COLOR);
            color[c].type = type_decoder[raw >> 1];
            if      (color[c].type == danger) color[c].offset = raw & 7;
            else if (color[c].type == beam  ) color[c].offset = raw & 3;
        }
    }

    // update with surroundings signatures
    void update(size_t signature)
    {
        // anti-blocker
        up_down = (direction_size > 0) ? dna[direction_start + signature % direction_size] : 0;
    }
};

// map of the surroundings
class map_t {
    struct cell_t {
        coord_t pos;
        int     color;
    };

    static const size_t size = 5;
    static const int max = size / 2;
    static const int min = -max;

    size_t local_signature[size*size]; // 8 neighbours signatures for teleporters
    cell_t track_cell[size*size]; // on-track cells
    size_t cell_num;
    colorType_t map[size*size];
    size_t raw_index(int x, int y) { size_t res = x * size + y + max + max * size; assert(res < size*size); return res; }
    size_t raw_index(coord_t pos) { return raw_index(pos.x, pos.y); }

    bool is_inside(int x, int y) { return abs(x) <= max && abs(y) <= max; }

public:
    size_t compute_signatures(view_t v, dnaInfo_t genome)
    {
        cell_num = 0;
        size_t signature = 0;
        memset (local_signature, 0, sizeof(local_signature));
        int i = 0;
        for (int x = min; x <= max; x++)
        for (int y = min; y <= max; y++)
        {
            int c = v(x, y);
            if (c == -1)
            {
                (*this)(x, y) = pit; continue;
            }
            track_cell[cell_num++] = { { x, y }, c };
            signature ^= c << (4 * (i++ & 1));

            if (genome.color[c].type == beam)
            {
                int in = 0;
                for (coord_t n : moves_up)
                {
                    coord_t pn = {x+n.x,y+n.y};
                    if (!is_inside(pn)) continue;
                    int cn = v(pn.x, pn.y);
//                    if (cn == -1) continue;
                    local_signature[raw_index(pn.x,pn.y)] ^= cn << (4 * (in++ & 1));
                }
            }
        }
        return signature;
    }

    void build(dnaInfo_t genome)
    {
        coord_t traps[size*size];
        size_t t_num = 0;

        // plot color meanings
        for (size_t c = 0; c != cell_num; c++)
        {
            const cell_t& cell = track_cell[c];
            const colorGene_t& color = genome.color[cell.color];
            (*this)(cell.pos) = (color.type == beam && (local_signature[raw_index(cell.pos.x,cell.pos.y)] % 4) == color.offset)
                    ? block
                    : color.type;

            // build a list of trap locations
            if (color.type == danger)
            {
                coord_t location = cell.pos + moves_up[color.offset];
                if (is_inside(location)) traps[t_num++] = location;
            }
        }

        // plot trap locations
        while (t_num) (*this)(traps[--t_num]) = trap;
    }

    // quick & dirty pathing
    struct candidate_t {
        coord_t pos;
        candidate_t * parent;
        candidate_t() {} // default constructor does not waste time in initializations
        candidate_t(int) : parent(nullptr) { pos.x = pos.y = 0; } // ...this is ugly...
        candidate_t(coord_t pos, candidate_t * parent) : pos(pos), parent(parent) {} // ...but so much fun...
    };

    coord_t path(const neighborhood_t & moves)
    {
        candidate_t pool[size*size]; // private allocation for express garbage collection...
        size_t alloc;

        candidate_t * border[size*size]; // fixed-size FIFO 
        size_t head, tail;

        std::bitset<size*size>closed;

        // breadth first search. A* would be a huge overkill for 25 cells, and BFS is already slow enough.
        alloc = head = tail = 0;
        closed = 0;
        closed[raw_index(candidate_t(0).pos)] = 1;
        border[tail++] = new (&pool[alloc++]) candidate_t(0);
        while (tail > head)
        {
            candidate_t & candidate = *(border[head++]); // FIFO pop
            for (const coord_t move : moves)
            {
                coord_t new_pos = candidate.pos + move;
                if (is_inside(new_pos))
                {
                    size_t signature = raw_index(new_pos);
                    if (closed[signature]) continue;
                    closed[signature] = 1;
                    if ((*this)(new_pos) > empty) continue;
                    if (new_pos.x == 2) goto found_exit; // a path to some location 2 cells forward
                    assert(alloc < size*size);
                    assert(tail < size*size);
                    border[tail++] = new(&pool[alloc++]) candidate_t(new_pos, &candidate); // allocation & FIFO push
                    continue;
                }
                // a path out of the 5x5 grid, though not 2 cells forward
            found_exit:
                if (candidate.parent == nullptr) return move;
                candidate_t * origin;
                for (origin = &candidate; origin->parent->parent != nullptr; origin = origin->parent) {}
                return origin->pos;
            }
        }

        // no escape
        return moves[1]; // one cell forward, either up or down
    }

    colorType_t & operator() (int x, int y) { return map[raw_index(x, y)]; }
    colorType_t & operator() (coord_t pos) { return operator()(pos.x, pos.y); }
    bool is_inside(coord_t pos) { return is_inside(pos.x, pos.y); }
};

std::string trace_DNA(const dna_t d, bool graphics = false)
{
    std::ostringstream res;
    dnaInfo_t genome(d);
    for (size_t c = 0; c != NUM_COLORS; c++)
    {
        if (graphics)
        {
            res << "tbew--"[genome.color[c].type];
            if (genome.color[c].type == danger) res << ' ' << moves_up[genome.color[c].offset].x << ' ' << moves_up[genome.color[c].offset].y;
            if (genome.color[c].type == beam) res << ' ' << genome.color[c].offset << " 0";
            if (c != NUM_COLORS - 1) res << ',';
        }
        else switch (genome.color[c].type)
        {
        case danger: res << "01234567"[genome.color[c].offset]; break;
        case beam  : res <<     "ABCD"[genome.color[c].offset]; break;
        default: res << "!*-#X@"[genome.color[c].type]; break;
        }
    }
    return res.str();
}

coord_t hardBelievers(dna_t d, view_t v)
{
    dnaInfo_t genome(d); // decoded DNA
    map_t     map;       // the surroundings seen by this particular rodent

    // update genome with local context
    genome.update(map.compute_signatures(v, genome));

    // build a map of the surrounding cells
    map.build(genome);

    // move as far to the right as possible, in the contextually preffered direction
    return map.path(genome.up_down ? moves_up : moves_down);
}

int main() {
    time_t start = time(NULL);
    double score = runsimulation(hardBelievers, trace_DNA);
    slog << "Geometric mean score: " << score << " in " << time(NULL) - start << " seconds";
}

Episode IV: เตรียมตลับลูกปืนของเราไว้บนตะแกรง

ผล

Scores: 309371 997080 1488635 1 19 45832 9 94637 2893543 210750 742386 1677242 206614 111809 1 1738598 1 1 342984 2868939 190484 3354458 568267 280796 1 1 1 679704 2858998 1 409584 3823 200724 1 973317 849609 3141119 1 1987305 1 1 57105 245412 1223244 2 1603915 2784761 9 12 1 1839136 1 298951 2 14 138989 501726 1365264 308185 707440 22 772719 17342 63461 3142044 19899 3 409837 48074 3549774 138770 32833 1 1 1184121 67473 310905 1996452 4201 1701954 2799895 2041559 218816 174 433010 51036 1731159 1871641 1 23 2877765 1 127305 27875 626814 142177 2101427 167548 2328741 4 8433 2674119 2990146 466684 1 2 8 83193 388542 2350563 1 1140807 100543 1313548 31949 73117 73300 121364 1899620 1280524 1 10726 12852 7 2165 1 3 44728 2 122725 41 2 1902290 3 1 8581 70598 1148129 429767 1 112335 1931563 521942 3513722 1 2400069 1 3331469 141319 220942 205616 57033 63515 34 6 1419147 1983123 1057929 1 599948 2730727 2438494 5586 268312 1728955 1183258 95241 1537803 11 13 1157309 1750630 1 1 2690947 101211 3463501 1 258589 101615 212924 137664 19624 251591 509429 510302 1878788 1 4045925 1 21598 459159 118663 7 3606309 3 13016 17765 640403 1 72841 695439 1 135297 2380810 1 43 31516 14 1442940 1001957 95903 194951 1 238773 773431 1 1 975692 2 4990979 52016 3261784 2 413095 12 3 420624 7905 60087 760051 2702333 2572405 1 1717432 1 12 3040935 1 1 31787 60114 513777 1 3270813 9639 581868 127091 270 164228 274393 1275008 261419 597715 138913 28923 13059 1848733 2895136 7754 14 1 107592 1 3557771 2067538 147790 112677 119004 1 13791082842974 249727 838699 4067558 6 470799 695141 1 3 1 1276069 23691 831013 5 165142 1236901 1 187522 2599203 1 67179 81345 44111 2909946 94752 7 406018 991024 4 1 3 573689 6 748463 2166290 33865 670769 322844 5657 1131171 1990155 5 4536811 1785704 3226501 2030929 25987 3055355 192547 1761201 433330 27235 2 312244 13203 756723 81459 12 1 1 54142 307858 2 25657 30507 1920292 3945574 1 191775 3748702 3348794 4188197 366019 1540980 3638591 1 1840852 1 26151 2888481 112861 8 11 2 1 27231 1 74 106853 3 173389 2390495 25 1 83116 3238625 75443 1 1 2125260 1 49626 1 6 312084 159735 358268 54351 367201 2868856 5779 172554 119016 141728 3 1 6 9 1 1504011 1 168968 1868493 1 5 1 244563 2 2887999 3144375 1598674 1 1578910 45313 176469 30969 8 127652 1911075 9 1300092 224328 168752 8 1619669 292559 9090 2040459 705819 1852774 10 139217 16 1221670 355060 339599 3 2184244 2546028 1 1 11 70958 242187 1 80737 1 190246 3 1 1 577711 150064 1 1047154 3851461 92399 224270 612237 1 3 3330053 1 1 1192533 615756 267923 144724 2 1 150018 4621881 1 6 299247 115996 2 10 6 185495 76351 465554 178786 1802565 257101 56 2491615 1 24547 1 1203267 32 5741149 541203 11393 1 368082 540534 16167 113481 2004136 13045 17 1 12 333803 14 1955075 1 4 38034 1286203 2382725 26777 1 180312 1 87161 4773392 1244024 1146401 3 80598 2983715 1 63741 1 1 2561436 16 1 1 1807854 1239680 200398 2 46153 1400933 11 5058787 8787 1 98841 89162 1106459 112566 1 4138891 2858906 101835 81375 539485 6587808 1 5359988 1 1 869106 443452 120748 436156 2 2 3944932 1 1875599 2 3081185 733911 447824 1 1 23187 3082414 33 3 1 1 2053904 410824 104571 885952 1946162 2 294773 364169 1 101310 2166548 1177524 2192461 12 4 3457016 90975 2356374 573234 53746 187527 7837 1441335 458407 52139 3387239 2030900 38 1648216 215105 212589 8278 1201586 244282 1 1 1897515 3957343 46 1 134481 1 1 2041785 3 1 37593 163173 1565457 3 1026885 1 34530 4655639 2 18 1940645 1550444 593209 1 2270700 706918 1 1 610113 9 1287883 3 1472134 1998685 1916822 1 296017 2 1 1737607 4155665 1510560 553342 56130 14436 13240604 4025888 1 4253261 174177 2043316 504151 2370989 420666 155232 1 219327 3752236 130062 571247 24 1 29015 31392 1020196 3 1117502 460873 7 1 228 8 133656 1 147008 1 93471 1 1 1 513410 4834094 1 14 1875636 182714 1504903 95263 4418053 1 357853 1135536 3698641 3 239316 4237884 131730 3878724 2158931 55650 1906785 1 26372 32 99217 1645677 379838 1 450352 7329657 112909 1 897980 2114198 308917 126215 1 53839 539997 238036 2 2270000 5 2388928 1668820 519153 58227 347528 1 1 2339954 10 5 2031341 54 2341529 2189774 112731 1 21918 748662 2068921 2 2232504 2923457 97740 3858 16604 398940 388755 1875003 667810 53633 315866 839868 1 7 1 14238 185 4 14 1 2 178947 1965719 398323 120849 48 1397222 961772 34124 2 160652 1 252629 246554 14529 1 299866 135255 490837 2863773 8 10 2 1906405 57 9782 118940 870003 255097 6 4187677 50965 3354376 17611 1804789 183601 158748 1539773 116107 77684 34738 2862836 1 2081903 727739 50328 2740070 17 923524 18 3089706 3144082 1 20 205247 347420 2076952 3725220 39270 2 15 49329 422629 5 1693818 2570558 2146654 1 5 129085 653766 47438 102243 389910 59715 21769 1246783 361571 4 120502 255235 1314165 3 3 5 2902624 76351 3117137 174413 2546645 14534 166054 1013583 1 1 2 9 3027288 3173742 338261 94929 1071263 4659804 1 506576 42798 4 984508 1 4 4 1 18541 7 1 269761 188905 2 1 92011 147031 677955 27484 1291675 2420682 99970 57943 1 4081062 1 250953 704904 4 349180 4273479 30528 2092508 2352781 3700946 1 77799 328993 3684623 3930179 1250080 1975798 54981 1621677 91664 1355832 1084049 721612 56950 197563 246868 5031 1 924076 1328694 58562 1 457662 2445958 1345169 957845 1056809 2485300 1687907 199029 3 9474 86928 1 2419980 3585265 570673 1 1514184 437383 1596697 29709 199606 126031 2 1541777 1 3 2090249 2402438 15 19 1423959 28 37852 4 1652596 1 405512 52 3 1948029 1 2 376 1155902 3 631665 3741991 57673 284026 424787 1 11569 5 1200313 1 20 2360854 1 119994 3889143 673424 797763 1 1 144306 1007659 1231874 75607 1 15 66187 8763 21366 146277 2684501 4458542 162223 3 1 5 94232 3036009 401312 19775 510737 3305062 58905 125783 274094 3089988 118483 1 106213 1 1289180 127905 30 528859 2 1215596 1955900 30 2236528 218643 1 2396631 1598175 1148688 452064 1 1840394 198540 1 1307187 107463 341396 2684981 9602 536871 1 148107 4068 4918434 1 2430254 2066144 88915 3585780 6464 259394 3098337 49601 42 79205 925658 1 2513666 26817 2738302 1 28 345735 5086930 361294 505662 386194 1103890 2653001 412247 4074274 2217918 1 519433 1338570 4289317 140138 18 2519983 168656 4546204 8 1 76545 511580 979214 9318 210013 50508 40 152908 17969 922507 1 7 32 1 388579 1 49886 13319 1066048 4663 27883 38419 1418098 2538216 1 778734 3556791 490764 666880 22746 5666164 4 20 1806284 21142 1 527906 2 12417 182224 49536 105029 206917 2427623 294247 1405136 321480 354137 84225 50 128073 1391176 352835 26074 91159 34229 237942 1 1519676 1 2428669 272681 148689 528951 560736 1 3548197 3833513 1438699 286613 1 1290904 47145 3456135 249648 277045 1012397 271073 1 6 149276 94843 11 177134 32336 2772732 7 22 37065 1 105299 76735 44 2211334 511942 30639 522056 5162 1899842 74 1 1448039 1 88817 21 1027532 555416 1 364383 1335609 167332 283252 49564 220972 1006800 3108886 801258 265596 61651 1 2413276 252747 416606 960925 54 311956 267135 3871698 22581 8978 2 10 1966155 3123429 28 46409 1 18433963725323 1769396 114766 49071 1 1 4228762 3483932 1139490 602592 2700468 770273 3 1 1 212087 281247 27093 156094 286299 1204001 18374 1 330780 1 1 25384 906728 99334 1250819 2161201 34 1027892 1 33449 2 129787 52246 94872 1536841 23470 1 1700323 1 1 3785351 1 95315 1014155 56570 22586 66842 7 156840 48752 1 3143722 1 1168309 2 4 101423 385892 42868 2893851 7 1783109 217499 24 460497 2003214 180135 3503010 131137 2 5240 1621601 2754811 11198 1 1 1105643 1 1671021 3 139611 18268 107229 44582 2211034 1 2880152747163 231008 262504 1 257760 1 1 52992 804418 2 2 4811272 1772250 3 1796530 1918647 1 1934549 1 100550 3448657 1681262 3 604526 320865 1901079 556908 2794800 2472000 637735 123663 1 3213187 118199 2553610 1 1750628 2563806 1 1670872 1 999609 50200 654831 1 164612 2865759 1841739 9 3744159 1331395 3202501 1 7 1 1 239868 1 1 581984 112413 401 1 29656 359367 74532 27226 51752 2583 1 645443 1559731 1 114195 1 85473 229474 111353 1 1521653 1 2568733 444398 2593568 18546 1 158085 1211147 1020006 23407 42514941388799 158442 1 1660358 5 34874 1594789 1551270 386464 502417 32280 170606 1954278 72486 3406066 11 52896 345631 4010742 33307 1951926 1441325 1886066 1 3 402778 3089364 351 28028 4301364 1 431569 5 3054030 375986 404966 1 449317 1230292 1 7 763949 1 2 3197443 1537806 335317 2 1 161263 1 1959902 1664530 139136 447570 1 1 50 158825 222939 1842131 11252 1680094 1017889 71 144808 1 53679 1 41278 1226724 1 1 2 10 2 1 112451 42133 1406662 1 112593 2 2832116 1544488 3579017 3029492 2752014 6 255091 731329 540861 1 426725 440330 212602 202358 173553 4 1189793 11031 84073 2084554 3963 1473295 1 642570 1 1423688 34509 75056 163273 490193 3200250 451777 157797 4156542 2386299 2794795 2735308 1332758 1193296 1131014 1001570 414257 4415511 4 3 1 3499595 536583 16731 93839 92382 1 45890 1 17695 8 867246 18 1607123 3197052 5 40009 1 329895 3497309 2416600 2316390 11 118179 2166659 2 136426 76762 2 14 2 3632525 214889 6 3900942 270409 230143 120414 417489 16706 1563597 31418 2 73 468763 88585 428274 3537347 2 1 491461 2806485 1 7 2950804 115684 4 1 429002 85771 2480 285541 186486 1 1 2430862 6 9 4 1833423 17143 353689 2568741 408890 2929237 208679 2198380 1 2501053 1933666 180843 1 1 2569886 1 17035 3449472 71357 246257 217898 1 47601 589824 401679 362878 13178 34464 1076419 1 554417 1 21248 2136449 1068 23029 8 766649 4 302879 274751 19 1 390259 1899931 233910 1392272 184492 2 2752059 55813 1 6 64674 205205 595508 1714309 582492 4821971 63973 1708726 189200 4548446 479425 2866037 1 1 1 2139319 1 1 3 1572621 2086152 2341038 1 619612 1 78942 772466 18932 1404368 936790 2263929 230200 3009227 251065 835010 88225 642856 824193 5559048 1 36348 2338046 481447 108132 2728223 3539009 1 197164 181408 171634 2172263 2317332 1598340 1318829 1746303 7 59657 1 1415452 122924 915828 1063890 40339 430186 4 2165185 2250922 704568 85138 4417453 255 326360 33541 3 49759 72127 912537 599665 1 29169 168741 349838 996835 1548193 2 28449 803521 4 2 2 3359043 3243259 1 491574 1675000 186105 3203018 11 39127 959876 334480 873131 70262 137080 1076591 1 2155613 74804 893022 2473922 1 1 269835 5 2407308 3 55200 905207 1 1 1245609 65934 7 1372126 530582 1383562 1 1 2718341 1 3947638 4 76837 412551 11 1 1 1208080 3024670 277 46485 1 9 562183 46 2985858 3379885 67816 1896527 1 105478 2035453 3026415 1 189256 2992616 2098002 1099666 775250 5913 13 406948 166773 1 322250 41919 480047 64950 17435 2147428 2336270 3330243 352709 86029 1398723 106236 312951 1 408211 252689 847088 2 17 34088 13128 187366 2 1559482 2349010 1651122 2371088 401005 1715445 1 29483921 1464444 50228 2365851 1651636 768715 226704 23677 83501 1 252623 444628 34 3640316 3602127 45369 1 1 1978261 1 3019189 1 25411 2177552 192839 191146 293712 3840622 182598 4069200 175757 1 2250458 4 1 7 2740824 2753005 1 2836428 1 12 19 2 1788326 3302198122211 3386546 1176663 20847 28 1194294 794665 2630378 13624 722012 2273872 1549353 1 3 1735700 1668388 416 970581 258382 295427 1 121571 3193610 3764806 1 368985 20436 89411 3 16130 2 241879 1 2996216 136958 2382095 510146 1762872 1372194 4215387 346915 4423 1 904153 2004500 248495 836598 3529163 27 2547535 1424181 1885308 1 1056747 289743 176929 2299073 170473 1 1 839941 12382 51457 608526 1684239 4843522 34550 929855 2767014 2979286 1 340808 184830 131077 57298 63854 381689 201998 1715328 118687 69190 123466 1 2 69392 159797 382756 1513430 2506318 457 1
Geometric mean score: 10983.8 in 31214 seconds

ฉันเปลี่ยนเป็น g ++ / MinGW และ 3 เธรด
รหัสที่สร้างโดย GNU นั้นเร็วกว่าสองเท่าของ Microsoft
ไม่น่าแปลกใจอะไรกับการใช้ STL ที่น่าตกใจ

เคลื่อนย้ายมวลสาร

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

นี่เป็นแบบจำลองที่หยาบเกินไป
เครื่องเคลื่อนย้ายมวลสารที่กำหนดสามารถขับเคลื่อนหนูไปข้างหน้าจนกว่าเซลล์บางเซลล์จากเป้าหมาย แต่เมื่อมีเครื่องเคลื่อนย้ายมวลสารเดียวกันสามารถเหวี่ยงหนูออกจากกระดาน
เครื่องเคลื่อนย้ายมวลสารดังกล่าวมีแนวโน้มที่จะได้รับการยอมรับว่าผ่านได้ (เนื่องจากจะเพิ่มความแข็งแรงเร็วกว่าเมื่อ "เดิน" ไปยังตำแหน่ง x เดียวกัน) กลายเป็นส่วนหนึ่งของจีโนมที่โดดเด่นและฆ่าหนูเกือบทุกตัวที่เชื่อมั่นว่า
เนื่องจากหนูไม่ทราบตำแหน่ง X ของพวกมันทางออกเดียวในการตรวจสอบเครื่องเคลื่อนย้ายมวลที่ทรยศเหล่านี้คือการตัดสินใจว่าจะเหยียบพวกเขาโดยพิจารณาจากข้อมูลเชิงบริบทเพียงอย่างเดียวเช่นตารางสี 5x5

ในการทำเช่นนั้นฉันได้กำหนดยีนสี 4 ประเภท:

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

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

8 สีเพื่อนบ้านสามารถรวมกันเพื่อสร้างลายเซ็นท้องถิ่นซึ่งไม่เปลี่ยนแปลงตามตำแหน่งในเขาวงกต น่าเสียดายที่เพื่อนบ้าน 8 แห่งนั้นมองเห็นได้เฉพาะเซลล์ที่อยู่ภายในช่องมองเห็น 3x3 ดังนั้นการเซ็นชื่อจะไม่ถูกต้องบนขอบสนามของการมองเห็น
อย่างไรก็ตามสิ่งนี้จะทำให้เรามีข้อมูลเชิงบริบทที่คงที่ในบริเวณใกล้เคียงซึ่งเพียงพอที่จะเพิ่มความน่าจะเป็นในการนำทางเครื่องเคลื่อนย้ายมวลสารได้สำเร็จ

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

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

สิ่งนี้ทำได้โดยการอัพเดตลายเซ็นโลคัลเท่านั้น เกณฑ์ปัจจุบันสำหรับการอัพเดตลายเซ็นในเครื่องจะอยู่ในระยะห่างของสีที่ระบุว่าเป็นเครื่องเคลื่อนย้ายมวลสารที่มีศักยภาพ

การเข้ารหัสใช้ 5 บิตต่อยีนสีและประเภทกลุ่มเพื่อเพิ่มจำนวนบิตที่มีนัยสำคัญน้อยกว่า 3 บิตเพื่อเข้ารหัสค่า 0..7:

  • 4 อันตราย
  • 4 ว่าง
  • 4 บล็อก
  • 4 ลำแสง

แต่ละลำแสงยีนมีโอกาส 1/4 ที่จะถูกพิจารณาว่าเป็นบล็อกและ 3/4 โอกาสที่จะถูกพิจารณาว่าว่างเปล่าดังนั้น 4 ลำจึงเป็นตัวแทนโดยเฉลี่ย 1 บล็อกและ 3 ว่าง

สัดส่วนเฉลี่ยแสดงโดยการแพร่กระจายแบบสุ่มจาก 16 สีจึง:

  • 4 อันตราย
  • 7 ว่าง
  • 5 บล็อก

การผสมผสานนี้ดูเหมือนจะให้ผลลัพธ์ที่ดีที่สุดจนถึงตอนนี้ แต่ฉันไม่ได้ทำการปรับแต่ง

ความไม่แน่นอนของยีน

สิ่งหนึ่งที่แน่นอนคือ: ค่ารหัสที่เลือกเพื่อแสดงประเภทของยีนนั้นมีความสำคัญ การแปลงค่าสองค่าเป็นค่าใช้จ่าย 2,000 คะแนนขึ้นไป

นี่คือเหตุผลว่าทำไมเกินกว่าคณิตศาสตร์ของฉันอีกครั้ง

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

เส้นทางสู่การช่วยเหลือ

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

อย่างไรก็ตามสิ่งนี้ไม่ได้ช่วยแก้ไขแผนที่ที่จีโนมไม่สามารถสร้างเส้นทางที่เหมาะสมได้

จะทำอย่างไรกับปัญญาอ่อน?

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

ลู่ก่อน

สำหรับฉันอัตราการกลายพันธุ์นั้นค่อนข้างต่ำเกินไป (สำหรับหนูของฉันอย่างน้อย)

การตั้งค่าปัจจุบัน 0.01 ให้โอกาส 37% ที่จะเอาชีวิตรอดจากกระบวนการกลายพันธุ์เหมือนเดิม การเปลี่ยนพารามิเตอร์เป็น 0.0227 ช่วยลดความน่าจะเป็นนี้ลงได้ประมาณ 10%

สูตรลึกลับคือการกลายพันธุ์ P 1 บิต = จีโนมทั้ง 1-P ครบถ้วน1/100และ 100 เป็นความยาวบิตจีโนม

ตัวอย่างเช่นสำหรับความน่าจะเป็น 10% การกลายพันธุ์ของ P 1 บิต = 1 - 0.1 1/100 = 0.0277
สำหรับความน่าจะเป็น 5%, P = 1 - 0.05 1/100 = 0.0295 การแทรก
สูตรเราพบว่า 0.01 ให้โอกาส 37% ในการเป็น ไม่เปลี่ยนแปลงโดยการกลายพันธุ์

ฉันทำการทดสอบเดียวกันซ้ำอีกครั้ง (โดยใช้ลำดับการสุ่มของเมล็ด) ด้วยความน่าจะเป็น 10%
บนแผนที่จำนวนมากความล้มเหลวก่อนหน้านี้กลายเป็นความสำเร็จ (จำกัด ) ในทางกลับกันการระเบิดของประชากรจำนวนมากมีน้อยกว่า (ซึ่งมีผลข้างเคียงที่น่าสนใจในการเร่งการคำนวณอย่างมาก)
แม้ว่าคะแนนที่สูงมาก (หนึ่งล้าน +) นั้นน้อยกว่าทั่วไป แต่จำนวนการวิ่งที่ประสบความสำเร็จมากกว่านั้นก็เพียงพอที่จะชดเชย
ในท้ายที่สุดค่าเฉลี่ยเพิ่มขึ้นจาก 1,400+ เป็นประมาณ 2000

ในทางกลับกันการตั้งค่า P ถึง 5% นั้นมีค่าเฉลี่ยประมาณ 600
ผมคิดว่าอัตราการกลายพันธุ์นั้นสูงมากจนจีโนมของหนูที่ชนะนั้นตกอยู่ในสายพันธุ์ที่มีประสิทธิภาพน้อยกว่า

วิธีนี้ใช้งานได้

ด้วยเครื่องตรวจจับ teleporter ที่เพิ่มจำนวนของเกมที่ล้มเหลว (คะแนน <10) ลดลงอย่างมีนัยสำคัญ
ในการทดลองใช้ 2,000 ครั้งมีเพียง 1/3 ของความล้มเหลว
ค่าเฉลี่ยเรขาคณิตเพิ่มขึ้นจาก 2,900 เป็น 3300 เท่านั้น แต่ตัวเลขนี้ไม่สามารถสะท้อนการปรับปรุงได้

สีที่ว่างเปล่ามักถูกเดาว่าเป็นลำแสงและอันตราย (โดยปกติคือ 2 ถึง 5) จีโนม "ใช้" สีเหล่านี้เพื่อปิดกั้นเส้นทางที่จะทำให้หนูมีปัญหา

จีโนมนั้นค่อนข้างดีในการคาดเดากับดัก (เช่นเมื่อหนูสามารถไปถึงเป้าหมายได้สีที่เป็นตัวแทนของเครื่องตรวจจับกับดักจริงจะเดาได้ประมาณ 90% ของเวลา)
นอกจากนี้ยังใช้รหัสลำแสงใหม่สำหรับเครื่องเคลื่อนย้ายมวลสารแม้จะไม่ค่อยบ่อยนัก (อาจเป็นเพราะเครื่องเคลื่อนย้ายมวลสารที่ "ทรยศ" นั้นพบได้น้อยกว่ากับกับดักและสีลำแสง / อันตรายอื่น ๆ พัฒนาขึ้นเพื่อขัดขวางเส้นทางไปยัง

ตัดสินจากจำนวนของเกมที่จีโนมที่ชนะปรากฏหลังจาก 5,000 รอบขึ้นไปฉันคิดว่าสายพันธุ์ใหม่นี้จะได้รับประโยชน์อย่างมากจากอัตราการกลายพันธุ์ที่เพิ่มขึ้น


เนื่องจากมีกับดักจำนวนมากว่างเปล่ากำแพงและเทเลพอร์ทคุณจึงต้องใช้ 3 บิตในการจัดเก็บสัดส่วนอย่างแม่นยำ (แม้ว่าคุณจะพิจารณากับดัก == กำแพง) นอกจากนี้คุณยังได้พิจารณา / ยกเลิกความคิดในการใช้บิตออฟเซ็ต Trap ที่ไม่ได้ใช้ในการต่อต้านกำแพง เนื่องจากเป้าหมายที่จะไม่สืบทอดมาจากพ่อแม่คุณจึงสามารถใช้บิตทั้งหมดในการต่อต้านกำแพง ไม่มีเหตุผลสำหรับพวกเขาที่จะไม่เหมือนใครฉันจะไม่คิด
Mooing Duck

1
@MooingDuck ฉันทดสอบความคิดของคุณเกี่ยวกับการนำบิตออฟเซ็ตกลับมาใช้ใหม่ แต่มันล้มเหลว อย่างที่ฉันกลัวการใช้ข้อมูลซ้ำเพื่อวัตถุประสงค์ที่แตกต่างกันสองอย่างดูเหมือนจะไม่ทำงาน สมมติว่าจำเป็นต้องใช้บิตออฟเซ็ตของสีที่กำหนดสำหรับจีโนมเพื่อเลือกทิศทางแนวตั้งที่เหมาะสมในเส้นทางที่กำหนดสีนี้ไม่สามารถแสดงกับดักที่มีความหมายได้อีกต่อไปโดยไม่ทำลายเส้นทางที่ขึ้นอยู่กับข้อมูลเดียวกัน ฉันยังพยายามใช้ 6 บิต แต่ด้วยความกลัวฉันยังมีกำแพงป้องกันที่เหลืออีก 4 ตัวที่เหลือน้อยเกินไป

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

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

16

ColorScorePlayer คะแนนขั้นต้น≈ 22

นี่คือบอทที่คุณเห็นในที่ทำงานใน GIF ในการท้าทาย

นี่คือบอททดสอบของเราตลอดช่วงการพัฒนา มันใช้จีโนมเพื่อจัดเก็บคะแนนคุณภาพสำหรับแต่ละ 16 สี จากนั้นก็จะทำให้การย้ายไปข้างหน้าที่จะย้ายมันลงบนสีที่มีคะแนนดีที่สุด (และไม่เคยย้ายไปยัง-1) ในกรณีที่มีการเสมอกันจะมีการสุ่มย้ายระหว่างเซลล์ที่ถูกผูก

เราได้ย้ายเครื่องเล่นนี้เป็นภาษาคอนโทรลเลอร์ทั้งหมดดังนั้นจึงทำหน้าที่เป็นตัวอย่างสำหรับวิธีใช้:

หลาม

class ColorScorePlayer(Player):
    def __init__(self):
        Player.__init__(self)
        self.coords = [Coordinate( 1, 0),
                       Coordinate( 1,-1),
                       Coordinate( 1, 1)]
        self.n_moves = len(self.coords)

    def turn(self):
        max_score = max([self.bit_chunk(6*self.vision_at(c.x, c.y), 6) for c in self.coords if self.vision_at(c.x, c.y)>=0])
        restricted_coords = [c for c in self.coords if self.vision_at(c.x, c.y)>=0 and self.bit_chunk(6*self.vision_at(c.x,c.y), 6) == max_score]

        return random.choice(restricted_coords)

ทับทิม

class ColorScorePlayer < Player
    def initialize(rng)
        super(rng)
        @coords = [Vector2D.new( 1,-1),
                   Vector2D.new( 1, 0),
                   Vector2D.new( 1, 1)]
    end

    def vision_at(vec2d)
        @vision[vec2d.x+2][vec2d.y+2]
    end

    def turn
        max_score = @coords.map { |c|
            color = vision_at(c)
            color < 0 ? -1 : bit_chunk(6*color, 6)
        }.max

        restricted_coords = @coords.select { |c|
            color = vision_at(c)
            color >= 0 && bit_chunk(6*color, 6) == max_score
        }

        restricted_coords.sample(random: @rng)
    end
end

C ++

coord_t colorScorePlayer(dna_t d, view_t v) {
    const int chunklen = DNA_BITS / N_COLORS;
    int ymax[3], nmax, smax = -1;
    for(int y = -1; y <= 1; y++) {
        if(v(1, y) == OUT_OF_BOUNDS) continue;
        int score = dnarange(d, v(1, y)*chunklen, chunklen);
        if(score > smax) {
            smax = score;
            nmax = 0;
        }
        if(score == smax) ymax[nmax++] = y;
    }
    return {1, ymax[v.rng.rint(nmax)]};
}

C #

public static void ColorScorePlayer(GameLogic.IView v, GameLogic.IGenome g, Random rnd, out int ox, out int oy)
{
    ox = 0;
    oy = 0;

    var max_score = cspcoords.Where(c => v[c.x, c.y] > -1).Select(c => g.cutOutInt(6 * v[c.x, c.y], 6)).Max();
    var restrictedCoords = cspcoords.Where(c => v[c.x, c.y] > -1 && g.cutOutInt(6 * v[c.x, c.y], 6) == max_score).ToArray();

    Coord res = restrictedCoords[rnd.Next(restrictedCoords.Length)];

    ox = res.x;
    oy = res.y; 
}

ชวา

package game.players;

import java.awt.*;
import java.util.Map;

public class ColorScorePlayer extends Player{
    private static final Point[] possibleMoves = {new Point(1, 0), new Point(1, -1), new Point(1, 1)};

    @Override
    public Point takeTurn(String genome, Map<Point, Integer> vision) {
        int chunkLength = genome.length()/16;
        int maxSum = -1;
        Point maxSumMove = possibleMoves[0];
        for (Point move: possibleMoves){
            if (vision.get(move) == -1){
                continue;
            }
            int initialPoint = chunkLength*vision.get(move);
            int sum = 0;
            for (int i = initialPoint; i < initialPoint + chunkLength; i++){
                sum = (sum<<1)+Integer.parseInt(genome.charAt(i)+"");
            }
            if (sum > maxSum){
                maxSum = sum;
                maxSumMove = move;
            }
        }
        return maxSumMove;
    }
}

ผู้เล่นให้คะแนนค่อนข้างไม่สอดคล้องกัน นี่คือ 50 การสุ่มวิ่ง:

Scores: 1 1 1132581 3 43542 1 15 67 57 1 11 8 623162 1 1 1 134347 93198 6 1 2 1 1 245 3 1 1 27 1 31495 65897 9 5 1 2 20 2 117715 1 1 1 20 64616 5 38 1 2 1 2 12

12

ColorFarSeeker, C ++ ≈ 74.7

ความท้าทายนี้ค่อนข้างสนุกและเรียบง่ายถ้าคุณลอง

อย่าย่อตัวด้วยคำอธิบายที่ยาว
เพียงไปที่ GitHub และตรวจสอบสิ่งต่าง ๆ ... ทุกอย่างจะชัดเจนมากขึ้น! :)

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

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

พยายามที่จะก้าวไปข้างหน้า แต่ถ้าไม่เห็นการเคลื่อนไหวที่ปลอดภัย ... จากนั้นลองไปด้านข้าง ... และหากสิ่งอื่นล้มเหลวให้เลื่อนถอยหลังแบบสุ่ม

coord_t colorFarSeeker(dna_t d, view_t v) {
#define s(w,x,y) (v(x,y)>-1?((b+dnarange(d,l+m+n*v(x,y),n))*w):0)
#define max2(a,b) (((a)>(b))?(a):(b))
#define max3(a,b,c) (max2(a,max2(b,c)))
#define push(vec,maxScore,score,x,y) if(score==maxScore&&v(x,y)>-1)vec.push_back({x,y});
#define tryReturn() if(vec.size()){return vec[v.rng.rint((int)vec.size())];}vec.clear();

    // Some constants to tweak
    int k = 4;
    int l = 3;
    int m = dnarange(d, 0, l);
    int n = 4;
    int b = dnarange(d, l, k) + 10;

    std::vector<coord_t> vec;

    // Looks forward for good moves...
    int upRightScore = s(1,0,-2) + s(1,1,-2) + s(1,2,-2) + s(5,1,-1);
    int forwardScore = s(1,2,-1) + s(1,2,0) + s(1,2,1) + s(5,1,0);
    int downRightScore = s(1,0,2) + s(1,1,2) + s(1,2,2) + s(5,1,1);
    int maxForwardScore = max3(upRightScore,forwardScore,downRightScore);
    push(vec,maxForwardScore,upRightScore,1,-1);
    push(vec,maxForwardScore,forwardScore,1,0);
    push(vec,maxForwardScore,downRightScore,1,1);
    tryReturn();

    // Looks sideways for good moves...
    int upScore = s(1,-1,-2) + s(1,0,-2) + s(1,1,-2) + s(5,0,-1);
    int downScore = s(1,-1,2) + s(1,0,2) + s(1,1,2) + s(5,0,1);
    int maxSideScore = max2(upScore,downScore);
    push(vec,maxSideScore,upScore,0,-1);
    push(vec,maxSideScore,downScore,0,1);
    tryReturn();

    // If all else fails, move backwards randomly.
    // I have tried considering the scores of backmoves,
    // but it seems worse than just randomly moving backwards. 
    vec.push_back({-1,-1});
    vec.push_back({-1,0});
    vec.push_back({-1,1});
    return vec[v.rng.rint((int)vec.size())];

}

คะแนน:

มีค่อนข้าง 1 ของ ... ซึ่งอาจเป็นเรื่องน่าเศร้าเมื่อคุณเห็นคอนโซลพ่น 1 ซึ่งกันและกัน เหมือนดาวเคราะห์ที่มีความจำเป็นต่อชีวิต แต่ไม่มีสัญญาณของอารยธรรมหนูขั้นสูง ...
แล้วเข็มเป็นครั้งคราว :)

อืม ... เห็นได้ชัดว่าฉันโชคดีสำหรับการวิ่งรุ่นที่ 1 ของฉันซึ่งมีรูปเรขาคณิตมากกว่า 300+ คะแนนมีความผันผวนค่อนข้างมาก แต่อย่างไรก็ตามด้วยการใช้งานเครื่องจำลองจำนวนมากขึ้นมันอาจจะใกล้ถึง≈ 74 (ขอบคุณสำหรับการช่วยฉันจำลองและโปรแกรมที่รวดเร็วของเขา)

คะแนนจากการวิ่งของฉัน: 6 6 53 1 5 101223 89684 17 2 303418 4 85730 24752 1 1 1 3482515 39752 1 59259 47530 13 554321 1 563794 1 1770329 1 57386 1 123870 4 1 1 79092 69931 594057 1 69664 2 1 51704 1 254006 4 24749 1 117987 49591 220151 26 4292194 23 57616 72 67 1 4 308039 1 1 103 89258 1 286032 1 5 3 1 5 114851 46 143712 5 15 9 80 7425 1 1 7 1 108379 70122 97238 1 23 104794 1 10476 59245 1 204 1 1 12 1 29641 1 314894 18785 13 1 3 1 1 1 2 2 526001 1 1 1 27559 29285 3 3 128708 70386 30 2 2 1 208531 331 1 2 1 61 114993 1 15 1 99119 1 1 31 4 3 1 161422 207 1 64 1 1 1 68594 145434 87763 150187 169 185518 1 1 1 1 24208 2570 1 1 537 1 1 462284 1 2 55 1 1 214365 1 40147 2 213952 1 29 3 1 2144435 5 4502444 72111 1 1 1 1 1 774547


1
ฉันได้ค่าเฉลี่ยทางเรขาคณิตของ 74.7 กับ 1,000 เกมเป็นงานที่ดี
feersum

8

บิชอป - งูใหญ่คะแนนเบื้องต้น 1.901

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

บอทนี้เรียนรู้อย่างรวดเร็วในตอนแรก แต่จากนั้นมักจะกระทบเพดานก่อนถึงเส้นชัยซึ่งสันนิษฐานว่าหนึ่งในสองปัญหาต่อไปนี้เกิดขึ้น:

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

รหัส

class BishopPlayer(Player):
    def __init__(self):
        Player.__init__(self)
        self.coords = [Coordinate(1,-1),
                       Coordinate(1, 1),
                       ]
        self.inputs = [(x,y) for x in (0,1,2) for y in (-1,0,1)]

    def turn(self):
        # Move away from out of bounds areas
        if self.vision_at(0,-1) == -1:
            return self.coords[1]
        if self.vision_at(0,1) == -1:
            return self.coords[0]

        # Move right, and either up or down based on one bit of the genome
        bit_to_use = sum(self.vision_at(self.inputs[i][0],
                                        self.inputs[i][1]
                                        ) * (16 ** i) for i in range(9)
                         ) % 100
        return self.coords[self.bit_at(bit_to_use)]

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

(มีเครื่องเคลื่อนย้ายมวลสารที่จับคู่สองประเภทและแต่ละชนิดมีความน่าจะเป็นที่ 0.5 ของการชดเชยที่เคลื่อนย้ายชิ้นงานไปอีกครึ่งหนึ่งของสี่เหลี่ยมสีดำและสีขาวดังนั้นความน่าจะเป็นของกระดานที่มีเครื่องเคลื่อนย้ายมวลสารเพียงอย่างเดียว ครึ่งหนึ่งของบอร์ดต่อรอบเพียง 0.25)

คะแนนแสดงให้เห็นว่าชัยชนะเป็นครั้งคราวสลับกับระยะเวลานานของการล้มลงของการจบ:

คะแนน: 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 11 1 2 1 1 1 1 1 6 1 8 1 10 15 1 1 12544 1 2 1 1 1 1 3 7554 1 1 1 1 1


8

ผู้เล่นที่ทำโบนัสได้: เรขาคณิตหมายถึง 50.35 (ทดสอบ 5000 เกม)

บอทนี้ให้คะแนนกำลังสองตามสีของแต่ละบุคคลโดยใช้ส่วน 6 บิตของ DNA เช่นโปรแกรมเล่นคะแนนสี แต่ใช้ระบบตัวเลขที่แตกต่างกัน บอทนี้ได้แรงบันดาลใจจากความคิดที่ว่าโดยพลการว่าหนึ่งในบิตเปลี่ยนค่าของคะแนน 32 ในขณะที่อีกอันทำเช่นนั้นเพียง 1 เท่านั้นมันกำหนดค่า n (n + 1) / 2 ให้ทำงาน n บิตติดต่อกัน 1 บิต นอกจากนี้ยังเพิ่มกลไกการสุ่มในความพยายามที่จะหลีกเลี่ยงการติดขัด มันจะทำการเคลื่อนที่ไปข้างหน้าแบบสุ่มโดยมีโอกาส 1 ใน 30

สำหรับการเปรียบเทียบผู้เล่นที่ทำคะแนนสีได้คะแนน 30 ถึง 35 ในการทดสอบ 1,000 เกมสองสามครั้ง ที่น่าสนใจคะแนนสูงสุดของผู้เล่นเกมทำคะแนนสีอยู่ในช่วง 3-5 ล้านในขณะที่คะแนนโบนัสสูงสุดของการรันคือเพียง 200,000 ผลประโยชน์จากโบนัสวิ่งจากระบบการให้คะแนนแบบลอการิทึมโดยได้รับคะแนนที่ไม่ใช่ศูนย์อย่างสม่ำเสมอ

การรัน 5,000 เกมใช้เวลาประมาณ 20 นาทีโดยมี 6 เธรดในตัวควบคุม C ++

coord_t runbonus(dna_t d, view_t v) {
    int ymax[3], nmax, smax = -1;
    if(!v.rng.rint(30)) {
        int y;
        while(!~v(1, y = v.rng.rint(-1, 1)));
        return {1, y};
    }
    for(int y = -1; y <= 1; y++) {
        if(v(1, y) == OUT_OF_BOUNDS) continue;
        int score = 0;
        int streak = 0;
        for(int i = 0; i < 6; i++) {
            if(d[6*v(1,y) + i])
                score += ++streak;
            else
                streak = 0;
        }
        if(score > smax) {
            smax = score;
            nmax = 0;
        }
        if(score == smax) ymax[nmax++] = y;
    }
    return {1, ymax[v.rng.rint(nmax)]};
}

เพิ่งออกมาจากความอยากรู้การทดสอบ 5,000 เพลงใช้เวลานานเท่าไหร่? หนูของฉันต้องใช้เวลามากกว่าหนึ่งชั่วโมงจึงจะเสร็จสมบูรณ์ 1,000 แทร็กดังนั้นฉันจะต้องให้คอมพิวเตอร์ทำงานตลอดทั้งคืนเพื่อทำซ้ำกรณีทดสอบของคุณ

@kuroineko คำตอบสำหรับคำถามของคุณอยู่ในคำตอบของฉันแล้ว
feersum

ขอโทษค่ะ ฉันจะลองโค้ดของคุณบนพีซีของฉันเพื่อดูว่าฮาร์ดแวร์เล่นส่วนใดในความเร็วที่ต่างกัน และอาจลองใช้ gcc แทน MSVC ฉันสังเกตเห็นการเพิ่มประสิทธิภาพ 30% เหนือ MSVC ในอีกสองสามบิตของการคำนวณรหัสหนัก ๆ

รหัสของคุณทำงานในบิตมากกว่า 20 นาทีสำหรับ 1,000 แทร็กใน i3-2100@3.1GHz ของฉันพร้อม 4 เธรด คะแนนอยู่ที่ประมาณ56 56ดูเหมือนว่าพีซีของฉันจะช้ากว่าของคุณ 5 เท่าและรหัสของฉันก็จะช้าลงประมาณ 6 เท่าในเครื่องที่ให้มา (แต่การมีคะแนนที่ดีกว่านั้นหมายถึงเวลาในการคำนวณที่นานขึ้น) เนื่องจากฉันยากจนเกินกว่าที่จะซื้อพีซีเครื่องใหม่มันถึงเวลาแล้วที่จะต้องปรับให้เหมาะสม ...

8

StarPlayer | C ++ | คะแนน: 162 (ขึ้นอยู่กับ 500 เกม)

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

#include <utility>

#define IDX(a,b) a[VIEW_DIST + b.x][VIEW_DIST + b.y]

std::pair<coord_t,int> planAhead(int weights[N_COLORS], view_t &v, coord_t target) {
    bool open[VIEW_DIST*2+1][VIEW_DIST*2+1] = {false};
    bool closed[VIEW_DIST*2+1][VIEW_DIST*2+1] = {false};
    int f_score[VIEW_DIST*2+1][VIEW_DIST*2+1] = {0};
    int g_score[VIEW_DIST*2+1][VIEW_DIST*2+1] = {0};
    coord_t came_from[VIEW_DIST*2+1][VIEW_DIST*2+1] = {{0,0}};
    open[VIEW_DIST][VIEW_DIST] = true;
    g_score[VIEW_DIST][VIEW_DIST] = v.rng.rint(5);
    f_score[VIEW_DIST][VIEW_DIST] = (abs(target.x) + abs(target.y)) * 10;
    for (;;) {
        coord_t current{VIEW_DIST+1,0};
        for (int x = 0; x < (VIEW_DIST*2+1); x++)
            for (int y = 0; y < (VIEW_DIST*2+1); y++)
                if (open[x][y] && (current.x > VIEW_DIST || f_score[x][y] < IDX(f_score,current)))
                    current = {x - VIEW_DIST, y - VIEW_DIST};
        if (current.x > VIEW_DIST)
            return {{1,0}, 1000000};
        if (current.x == target.x && current.y == target.y)
            break;
        IDX(open,current) = false;
        IDX(closed,current) = true;
        for (int dx = -1; dx <= 1; dx++) for (int dy = -1; dy <= 1; dy++) {
            if (dx == 0 && dy == 0)
                continue;
            coord_t tentative{current.x + dx, current.y + dy};
            if (abs(tentative.x) > VIEW_DIST || abs(tentative.y) > VIEW_DIST)
                continue;
            if (IDX(closed,tentative))
                continue;
            auto color = v(tentative.x, tentative.y);
            if (color == OUT_OF_BOUNDS)
                continue;
            auto tentative_g = IDX(g_score,current) + weights[color];
            if (!IDX(open,tentative) || tentative_g < IDX(g_score,tentative)) {
                IDX(came_from,tentative) = current;
                auto distance = abs(tentative.x - target.x) + abs(tentative.y - target.y);
                IDX(f_score,tentative) = tentative_g + distance * 10;
                IDX(g_score,tentative) = tentative_g;
                IDX(open,tentative) = true;
            }
        }
    }
    auto prev = target, current = target;
    while (current.x != 0 || current.y != 0)
        prev = current, current = IDX(came_from,current);
    return {prev, IDX(g_score,target)};
}

coord_t starPlayer(dna_t d, view_t v) {
    const int chunklen = DNA_BITS / N_COLORS;
    int weights[N_COLORS];
    for (int i = 0; i < N_COLORS; i++)
        weights[i] = dnarange(d, i*chunklen, chunklen);
    std::pair<coord_t,int> choice{{1,0}, 1000000};
    for (int y = -VIEW_DIST; y <= VIEW_DIST; y++) {
        auto plan = planAhead(weights, v, {VIEW_DIST, y});
        if (plan.second < choice.second)
            choice = plan;
    }
    return choice.first;
}

คะแนนตัวอย่าง:

4 92078 1 10 1 1 3 2 2862314 5 24925 1 3 2 126502 1 24 1097182 39 1 1 1 47728 227625 137944 15 1 30061 1 1 1 3171790 19646 10 345866 1 1 829756 425 6699 22 8 1


1
ในเกม 1,000 เกมฉันได้คะแนน 133.2 เป็นสิ่งที่ดี
feersum

7

WallGuesser - ทำคะแนน 113.266 ในการทดสอบ 1,000 เกม

การเข้ารหัส

ฉันทำการเข้ารหัส 6 บิต / สีที่เรียบง่ายจริงๆ เพื่อถอดรหัสสี [n]

  • รวมทุก ๆ นิดหน่อยในจีโนมถึง 96
  • หากคะแนนรวมคือ> = 4 ให้บอกว่าจัตุรัสนี้ถูกบล็อก
  • หากคะแนนรวมคือ <= 4 ดังนั้นคะแนนสุดท้ายคือ 2 ^ ของคะแนนรวม

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

การเคลื่อนไหว

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

การลดจำนวนหนูที่ไม่เหมาะสม

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

ทำ

ขณะนี้ไม่มีพฤติกรรมแบบสุ่มดังนั้นจึงเป็นเรื่องง่ายสำหรับหนูที่จะติดอยู่

#include "./gamelogic.cpp"

#include <algorithm>
#include <set>
#include <map>
#include <climits>

bool operator< (const coord_t &a, const coord_t &b){
    if(a.x != b.x){ return a.x < b.x; }
    else if (a.y != b.y){ return a.y < b.y; }
    else{ return false; }
}

bool operator== (const coord_t &a, const coord_t &b){
    return (a.x == b.x) && (a.y == b.y);
}

int coordDistance(const coord_t &a, const coord_t &b){
    int xDif = abs(a.x - b.x);
    int yDif = abs(a.y - b.y);
    return xDif > yDif ? xDif : yDif;
}

int coordMinSetDistance(const coord_t &a, const std::set<coord_t> &ends){
    int min = INT_MAX;
    for (auto i : ends){
        int cur = coordDistance(a, i);
        if (cur < min){
            min = cur;
        }
    }
    return min;
}


class ColorMap{
public:
    view_t *v;
    int colors[16] = {};
    const int Blocked = -1;

    ColorMap(dna_t &d, view_t *v){
        this->v = v;

        //Decode the genome
        for (int i = 0; i <= (16*6); i++){
            if (d.at(i) == true){
                colors[i % 16]++;
            }
        }

        //Encode the result
        bool guessedWalls = false;
        for (int i = 0; i < 16; i++){
            if (colors[i] >= 4){
                colors[i] = Blocked;
                guessedWalls = true;
            }
            else{
                colors[i] = pow(2, colors[i]);
            }
        }

        if (guessedWalls == false){
            for (auto i : colors){
                i = Blocked;
            }
        }
    }

    int operator() (coord_t pos){
        if (abs(pos.x) > VIEW_DIST || abs(pos.y) > VIEW_DIST){
            return Blocked;
        }

        int value = (*v)(pos.x, pos.y);
        if (value == OUT_OF_BOUNDS){
            return Blocked;
        }
        else{
            return colors[value];
        }
    }

    void print(){
        int lower = -1 * VIEW_DIST;
        int upper = VIEW_DIST;
        for (int y = lower; y <= upper; y++){
            for (int x = lower; x <= upper; x++){
                std::cout << std::setw(3) << this->operator()({ x, y });
            }
            std::cout << std::endl;
        }
    }
};

class node{
public:
    coord_t pos;
    coord_t cameFrom;
    int gScore;
    int minDistance;

    node(coord_t pos, coord_t cameFrom, int gScore, int minDistance){
        this->pos = pos;
        this->cameFrom = cameFrom;
        this->gScore = gScore;
        this->minDistance = minDistance;
    }

    int fScore() const{ return gScore + minDistance; };

    bool operator< (const node &rhs) const{ return fScore() < rhs.fScore(); }
};

class EditablePriorityQueue{
private:
    //This is reversed so smallest are on top
    struct lesser{
        bool operator()(node *a, node *b) const{
            return (*b) < (*a);
        }
    };

    std::vector<node*> queue; // Use heap functions to maintain the priority queue ourself
    std::map<coord_t, node*> members;

public:
    EditablePriorityQueue(){};

    ~EditablePriorityQueue(){
        for (auto &m : members){
            delete m.second;
        }
    }

    bool empty(){ return members.empty(); }

    node *top(){
        auto top = this->queue.front();
        std::pop_heap(queue.begin(), queue.end(), lesser());
        queue.pop_back();
        members.erase(top->pos);
        return top;
    }

    void set(coord_t target, coord_t cameFrom, int gScore, int minDistance){
        auto targetLocation = members.find(target);

        //If the target isn't a member add it
        if (targetLocation == members.end()){
            auto *newNode = new node(target, cameFrom, gScore, minDistance);
            queue.push_back(newNode);
            std::push_heap(queue.begin(), queue.end(), lesser());
            members[target] = newNode;
        }
        //The target must be updated
        else{
            auto currentNode = targetLocation->second;
            if (currentNode->gScore > gScore){
                currentNode->gScore = gScore;
                currentNode->cameFrom = cameFrom;
                std::make_heap(queue.begin(), queue.end()); //More efficient way to do this?
            }
        }
    }
};

std::pair<coord_t, int> pathCost(ColorMap &m, coord_t start, const std::set<coord_t> &ends){
    EditablePriorityQueue openSet;
    std::set<coord_t> closedSet;
    std::map<coord_t, coord_t> cameFrom;

    openSet.set(start, start, 0, coordMinSetDistance(start, ends));
    while (openSet.empty() == false){
        auto current = openSet.top();
        closedSet.insert(current->pos);
        cameFrom[current->pos] = current->cameFrom;

        //Check if we're done
        if (ends.count(current->pos) != 0){
            //Recover the path
            coord_t path = current->pos;
            int finalScore = current->gScore;
            delete current;
            while (!(cameFrom[path] == start)){
                path = cameFrom[path];
            }

            return{ path, finalScore };
        }               

        //Examine current's neighbours
        for (int x = -1; x <= 1; x++) for (int y = -1; y <= 1; y++){
            coord_t neighbour = { current->pos.x + x, current->pos.y + y };

            if (x == 0 && y == 0){ continue; }

            closedSet.count(neighbour);
            if (closedSet.count(neighbour) != 0){ continue; }

            int neighbourScore = m(neighbour);
            if (neighbourScore == m.Blocked){ continue; }

            int tentativeScore = current->gScore + neighbourScore;
            openSet.set(neighbour, current->pos, tentativeScore, coordMinSetDistance(neighbour, ends));

        }
        delete current;
    }

    return{ { -1, 0 }, INT_MAX }; //Try to end it
}

coord_t myPlayer(dna_t d, view_t v) {
    auto ourMap = ColorMap(d, &v);

    std::set<coord_t> edges;
    for (coord_t edge = { VIEW_DIST, -1 * VIEW_DIST }; edge.y <= VIEW_DIST; edge.y++){
        edges.insert(edge);
    }

    //Move to the neighbor closest to a square on the right
    auto result = pathCost(ourMap, { 0, 0 }, edges);
    auto minMove = result.first;

    return minMove;
}

int main() {
    slog << "Geometric mean score: " << runsimulation(myPlayer) << std::endl;
}

g++ -std=c++11 .\wallguesser.cpp -O2 -o .\wallguesser.exeหืมนี้ไม่ได้รวบรวมสำหรับผมด้วย ฉันได้รับข้อผิดพลาดมากมาย แต่ข้อแรกคือ.\wallguesser.cpp:47:19: error: 'dna_t' has no member named 'at' if (d.at(i) == true){
Martin Ender

ไม่มีปัญหาเพียงแค่เปลี่ยนatเพื่อ[]แก้ไข
feersum

7

The FITTEST - คะแนนเฉลี่ยเรขาคณิต: ~ 922 (วิ่ง 2K)

แนวทางของฉันคือ:

  1. ค้นหาสิ่งที่ฆ่าเผ่าพันธุ์และกำหนดพฤติกรรมที่ต้องการ (หน้าที่)
  2. ใช้พฤติกรรมที่ต้องการในรหัส (ทางเทคนิค)
  3. ให้ความสำคัญกับมัน มันสำคัญกว่าหรือสำคัญกว่าพฤติกรรมอื่น ๆ ที่ต้องการ
  4. เพิ่มประสิทธิภาพคะแนนเฉลี่ยเรขาคณิตโดยการปรับแต่งพารามิเตอร์ของการแก้ปัญหา

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

พฤติกรรมที่ต้องการ:

  1. สายพันธุ์ควรเรียนรู้ว่าสีใดปลอดภัยและไม่ดี
  2. สปีชีส์ควรมุ่งเน้นไปที่การตัดสินใจว่าจะย้ายไปอยู่ที่ใดโดยขึ้นอยู่กับเซลล์ 3 เซลล์ข้างหน้า แต่ถ้าไม่มีการเคลื่อนไหวที่ดีมีการเคลื่อนไหวแนวตั้งหรือย้อนหลังควรพิจารณาการ
  3. สายพันธุ์ควรดูสิ่งที่อยู่นอกเหนือ 8 เซลล์รอบ ๆ ตัวเขาและใช้ข้อมูลนั้นในการตัดสินใจ
  4. สายพันธุ์ที่ควรเรียนรู้ที่จะแจ้งกับดัก
  5. บางสปีชีส์ไม่ถูกต้องสมมติว่ากำแพงนั้นดีและพยายามเคลื่อนที่ไปหาพวกมันตลอดเวลาและติดอยู่ที่ด้านหน้ากำแพง หากพวกเขาเป็นสายพันธุ์ที่มีคะแนน fittest สูงสุดในขณะนั้นดีเอ็นเอของพวกเขากับสมมติฐานที่ผิดเกี่ยวกับผนังซ้ำหลายครั้งเข้าไปในทารกแรกเกิด หลังจากนั้นครู่หนึ่งทุกเผ่าพันธุ์จะติดอยู่หน้ากำแพงและไม่มีใครไปถึงเป้าหมายคะแนนคะแนน วิธีหยุดปัญญาอ่อน?

วิธีการเก็บข้อมูล:

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

ฉันพบคะแนนเฉลี่ยเรขาคณิตมีความไวต่อวิธีการจัดเก็บข้อมูล สมมติว่าเราอ่าน 4 บิตแรกของ 100 บิตของ DNA และต้องการเก็บไว้ในตัวแปรจำนวนเต็ม เราสามารถทำได้หลายวิธี:

  1. การจัดเก็บข้อมูลทศนิยม:โดยใช้dnarangeฟังก์ชัน'ในตัว' ตัวอย่าง: 4bits 1011จะกลายเป็น `1x2 ^ 3 + 0x2 ^ 2 + 1x2 ^ 1 + 1x2 ^ 0 = 15 ค่าที่เป็นไปได้ (สำหรับ 4 บิต): [0, 1 , 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
  2. การจัดเก็บข้อมูลลายเส้น:โดยใช้dnaStreakRangeฟังก์ชั่น (ที่กำหนดไว้ด้านล่าง) ตัวอย่างเช่น: 4bits 1011 1x1 + 0x1 + 1x1+ 1x2 = 4จะกลายเป็น ค่าที่เป็นไปได้ (สำหรับ 4 บิต): [0, 1, 2, 3, 6, 10]
int dnaStreakRange(dna_t &d, int start, int chunklen) {
    int score = 0;
    int streak = 0;
    for(int i = 0; i < chunklen; i++) {
        if(d[start + i])
            score += ++streak;
        else
            streak = 0;
    };  
    return score;
}
  1. การจัดเก็บข้อมูล Bitsum:โดยใช้dnaCountRangeฟังก์ชั่น (ที่กำหนดไว้ด้านล่าง) ตัวอย่างเช่น: 4bits 1011 1x1 + 0x1 + 1x1 + 1x1 = 3จะกลายเป็น ค่าที่เป็นไปได้ (สำหรับ 4 บิต): [0, 1, 2, 3, 4]
int dnaCountRange(dna_t &d, int start, int chunklen) {
    int score = 0;
    for(int i = 0; i < chunklen; i++) {
        if(d[start + i])
            score ++;
    };  
    return score;
}

ความแตกต่างระหว่างวิธีการจัดเก็บคือ:

  • วิธีการจัดเก็บทศนิยมนั้นมีความเสี่ยงต่อการเปลี่ยนแปลง DNA เพียงเล็กน้อย เมื่อค่า bitsum เปลี่ยนจาก 1011 เป็น 0011 ค่าจะเปลี่ยนจาก 3 เป็น 2 ซึ่งเป็นการเปลี่ยนแปลงเล็กน้อย
  • วิธีการจัดเก็บข้อมูลทศนิยมเป็นเนื้อเดียวกัน ค่าที่เป็นไปได้แต่ละค่ามีการเปลี่ยนแปลงเหมือนกัน โอกาสที่คุณอ่านค่า 15 จากบล็อกหน่วยความจำหน่วยความจำ 4 บิตคือ 1/16 = 6% วิธีการเก็บรักษาแชมป์ไม่ได้เป็นเนื้อเดียวกัน โอกาสที่ค่า streak 4 บิตน้อยกว่าหรือเท่ากับ 6 คือ (15-3) / 16 = 81% (ทั้ง 16 ชุดยกเว้น 0111,1110,111) ด้านล่างเป็นภาพที่แสดงรูปร่างของการกระจาย อย่างที่คุณเห็นที่ลูกศรสีน้ำเงินโอกาสที่จะมีจำนวน 4 บิตน้อยกว่าหรือเท่ากับ 6 คือ 81%: การสร้างภาพของการกระจายตัวของประเภทการจัดเก็บทศนิยมริ้วและบิตการจัดเก็บสำหรับเลขฐานสองยาว 4,5 และ 6 บิต

จัดลำดับความสำคัญการแก้ปัญหา

เมื่อ ColorScorePlayer ได้ระบุการเคลื่อนที่ไปข้างหน้าสองครั้งที่มีคะแนนเท่ากันจะมีตัวเลือกตามใจชอบ IMHO, คุณไม่ควรใช้ฟังก์ชันสุ่มv.rng.rint()ฟังก์ชั่น แต่คุณควรใช้โอกาสนี้ในการได้คะแนนเท่ากันในฐานะที่เป็นตะขอในการประเมินวิธีแก้ปัญหาสำหรับผลกระทบลำดับที่สอง

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

การใช้พฤติกรรมที่ต้องการ

เรียนรู้ว่าสีใดปลอดภัย:

  • 33% ของ 16 สีไม่ดีและดังนั้นเมื่อคะแนนของการเคลื่อนไหวต่ำกว่า 63/3 การย้ายจะไม่ได้รับอนุญาต ดังนั้นthreshold = 63/3=21ที่ 63 คือคะแนนสูงสุดสำหรับ 6 บิตและ 33% = 1/3 (สามารถค้นหาในกราฟด้านบน)

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

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

ดูสิ่งที่เกินกว่า:

  • เมื่อ 2 หรือ 3 การเคลื่อนไหวมีคะแนนเท่ากันกล่อง 3x3 รอบการเคลื่อนไหวเหล่านั้นจะเป็นตัวกำหนด (ผ่านx2และy2ลูป) ตัวเลือกที่ดีที่สุดคืออะไร (ผ่านmainSubScoreตัวแปร) คอลัมน์ที่ถูกต้องที่สุดในกล่อง 3x3 นั้นเป็นผู้นำ
coord_t adjustedColorPlayer(dna_t d, view_t v) {
    const int chunklen = 6,threshold = 63/3;
    int xBestScore=0, yBestScore=0;
    long bestScore=-1, weightMove, weightMove2, mainScore;
    for(int x = -1; x <= 1; x++) {
        if (x < 0) weightMove = 1000; // moving backward
        if (x== 0) weightMove = 10000; //moving vertical
        if (x > 0) weightMove = 100000; //moving forward
        for(int y = -1; y <= 1; y++) {
            if(v(x, y) == OUT_OF_BOUNDS || (x==0&&y==0) ) continue;
            mainScore = dnarange(d,v(x,y)*chunklen,chunklen);
            if (mainScore<threshold+1) {
                mainScore =  0; //not a suitable move because too low score
            }else{
                mainScore*= weightMove;
                // when equal score, use sub score by examining 5x5 box to rank moves
                for(int x2 = x-1; x2 <= x+1; x2++){     
                    if (x2 < x) weightMove2 = 1; // moving backward
                    if (x2== x) weightMove2 = 10; //moving vertical
                    if (x2 > x) weightMove2 = 100; //moving forward
                    for(int y2 = x-1; y2 <= y+1; y2++){     
                        if(v(x2, y2) != OUT_OF_BOUNDS){
                            long mainSubScore = dnarange(d,v(x2,y2)*chunklen,chunklen);
                            if (mainSubScore>=threshold+1) mainScore+=mainSubScore*weightMove2;
                        }
                    }
                 }
            }
            if(mainScore > bestScore) {
                bestScore = mainScore;              
                xBestScore = x;
                yBestScore = y;
            }
        }
    }
    return{xBestScore,yBestScore};
}

คะแนน: 123 (2K วิ่ง)

50 คะแนนแรก (18 เกมทำคะแนนเพียง 1 คะแนน):

1 10 1 79947 3 1 11 125 7333287 23701 310869 53744 1 2 2 2 2 1 1 57556 2 688438 60 1 2 2636261 26306 1 125369 1 1 1 61895 27 1 36 1 91100 87636 1 2 47497 53 16 1 11 222384 1 1

ระบุกับดัก:

ฉันตรวจสอบ DNA ของเผ่าพันธุ์ด้วยคะแนนสูงสุดเมื่อเกมจบลงโดยใช้พื้นที่จัดเก็บ bitum4 (ดังนั้นคะแนนสีจึงมีช่วง [0,4]):

  • คะแนน 0: เทเลพอร์ตไปข้างหลังทั้งสองข้างผนัง 1x ปลอดภัย
  • คะแนน 1: กับดักไว้ข้างหลัง (ไม่เป็นอันตราย), เทเลพอร์ตไปข้างหลัง, 1x ปลอดภัย
  • คะแนน 2: กับดักไปข้างหน้า (อันตรายมาก), 1x ปลอดภัย
  • คะแนน 3: เทเลพอร์ตไปข้างหน้า 5x เซฟ
  • คะแนน 4: เทเลพอร์ตไปข้างหน้า 1x ปลอดภัย

จากนี้จึงสามารถสรุปได้ว่ากำแพงและเทเลพอร์ตนั้นได้คะแนนที่ถูกต้อง กับดักไม่ได้ระบุเนื่องจากขึ้นอยู่กับทิศทางและสีของแหล่งกำเนิดในขณะที่การให้คะแนนจะทำในสีของปลายทาง ดังนั้นจึงมีความจำเป็นที่จะต้องจัดเก็บข้อมูลเกี่ยวกับสีของต้นกำเนิดด้วยv(0,0)ด้วย ในโลกอุดมคติเราต้องการเก็บข้อมูลสำหรับ 16 สี x 8 ทิศทาง x 3 บิต = 384 บิต

น่าเสียดายที่มีเพียง 100 บิตเท่านั้นและเราไม่สามารถใช้งานได้ทั้งหมดเนื่องจากเราต้องการหน่วยความจำบางส่วนสำหรับวิธีการแก้ปัญหาที่อธิบายไว้ข้างต้น ดังนั้นเราจะสร้างถังขยะ 4 สี:

  • 0: color 0 - color 3,
  • 1: สี 4 - สี 7
  • 2: color 8 - color 11,
  • 3: color 12 - color 16

และถังขยะ 4 ทิศทาง

  • 0: เลื่อนแนวตั้งหรือย้อนกลับ
  • 1: เลื่อนไปข้างหน้า
  • 2: ก้าวไปข้างหน้า
  • 3: เลื่อนไปข้างหน้าลง

เมื่อคะแนนทศนิยมคือ 4 หรือสูงกว่า (100,101,110,111) จะถือว่าการดักมีความสัมพันธ์กับเซลล์นี้เนื่องจากการย้ายนี้จะไม่ถูกเลือกเมื่อคะแนนเท่ากันเกิดขึ้น ดังนั้นการระบุตัวดักจึงเป็นเอฟเฟกต์ลำดับที่สองและ 'ดูว่ามีอะไรเกินกว่า' จะเป็นวิธีแก้ปัญหาลำดับที่สาม

int dnaLookup2(dna_t &d, int start, int chunklen, int storageMethod) {
    // Definition of storageMethod: 0=decimal, 1=streak, 2=bitsum
    int score = 0, streak = 0;
    for(int i = start; i < start+chunklen; i++) {
        int value = d[i];
        if (storageMethod==0) {
            score = (score << 1) |value;
        }else{
            if (storageMethod==1){
                if(value) score += ++streak; else streak = 0;
            }else{
                if(value) score ++;         
            }
        }
    };  
    return score;
}

coord_t theTrapFighter(dna_t d, view_t v) {
    // Definition of storageMethod: 0=decimal, 1=streak, 2=bitsum
    const int colorMemStorageMethod = 1, colorMemBlockSize = 3;
    const int trapMemStorageMethod = 0, trapMemBlockSize = 3;
    const int trapMemTopThreshold = 4, nDirBins = 4, nColorBins = 4;

    int xBestScore=0, yBestScore=0;
    long bestScore=-1, weightMove, weightMove2, mainScore;
  for(int x = -1; x <= 1; x++) {
        if (x < 0) weightMove = 1000; // moving backward
        if (x== 0) weightMove = 10000; //moving vertical
        if (x > 0) weightMove = 100000; //moving forward
        for(int y = -1; y <= 1; y++) {          
            int color = v(x, y);
            if(color == OUT_OF_BOUNDS || (x==0&&y==0) ) continue;
            mainScore = dnaLookup2(d,color*colorMemBlockSize,
             colorMemBlockSize,colorMemStorageMethod);
            if (mainScore==0) {
                //not a suitable move because too low score
            }else{
                mainScore*= weightMove;
                //lookup trap likelihood
                int directionBin = 0;
                if (nDirBins==3) directionBin = x>0?y+1:-1;
                if (nDirBins==4) directionBin = x>0?y+2:0;
                // put 16 colors in nColorBins bins
                int colorBin = v(0,0)*nColorBins/N_COLORS; 
                colorBin = colorBin>(nColorBins-1)?(nColorBins-1):colorBin;
                if (directionBin >= 0 &&
                 dnaLookup2(
                   d,
                   colorMemBlockSize*16
                    +trapMemBlockSize*(nColorBins*directionBin+colorBin),
                   trapMemBlockSize,
                   trapMemStorageMethod
                 ) >=trapMemTopThreshold){
                  //suspect a trap therefore no sub score is added                  
                 }else{
                    // when equal score, use sub score by examining 5x5 box to rank moves
                    for(int x2 = x-1; x2 <= x+1; x2++){     
                        if (x2 < x) weightMove2 = 1; // moving backward
                        if (x2== x) weightMove2 = 10; //moving vertical
                        if (x2 > x) weightMove2 = 100; //moving forward
                        for(int y2 = x-1; y2 <= y+1; y2++){     
                            int color2 = v(x2, y2);
                            if(color2 != OUT_OF_BOUNDS){
                                mainScore+=weightMove2 * dnaLookup2(d,color2*colorMemBlockSize,
                                 colorMemBlockSize,colorMemStorageMethod);
                            }
                        }
                    }               
                 }
            }
            if(mainScore > bestScore) {
                bestScore = mainScore;              
                xBestScore = x;
                yBestScore = y;
            }
        }
    }
    return{xBestScore,yBestScore};
}

คะแนน: 580 (2K วิ่ง)

50 คะแนนแรก (13 เกมได้คะแนนเพียง 1 คะแนน):

28.044 14.189 1 2.265.670 2.275.942 3 122.769 109.183 401.366 61.643 205.949 47.563 138.680 1 107.199 85.666 31 2 29 1 89.519 22 100.908 14.794 1 3.198.300 21.601 14 3.405.278 1 1 1 2 74.167 1 71.242 97.331 201.080 1 1 102 94.444 2.734 82.948 1 4 19.906 1 1 255.159

สมมติฐานที่ผิดเกี่ยวกับกำแพงนั้นซ้ำซ้อนกับปัญญาอ่อนหลายครั้ง:

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

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

การต่อสู้ Morons: โซลูชันที่ 1: การกลับสี

ทางออกแรกที่ฉันลองใช้คือความพยายามที่จะใช้ส่วนหนึ่งของหน่วยความจำที่ไม่ได้ใช้ซึ่งยังคงมีความหลากหลายมาก สมมติว่าคุณจัดสรร 84 บิตให้กับหน่วยความจำสีและกับดักเพื่อค้นหาหน่วยความจำ 16 บิตที่เหลือจะมีความหลากหลายมาก เราสามารถเติมตัวแปรทศนิยม 8 ตัว 2 ตัวที่มีค่าในช่วง [0,255] และพวกมันเหมือนกันซึ่งหมายความว่าแต่ละค่ามีโอกาส 1/256 ตัวแปรจะถูกเรียกและinInverseinReverse

ถ้าinInverseเท่ากับ 255 (โอกาส 1/256) แล้วเราจะผกผันแปลความหมายของคะแนนสี ดังนั้นกำแพงที่คนปัญญาอ่อนคิดว่าปลอดภัยเพราะมันเป็นคะแนนสูงจะได้คะแนนต่ำและดังนั้นจะกลายเป็นก้าวที่ไม่ดี ข้อเสียคือสิ่งนี้จะส่งผลต่อยีน 'สิทธิ' ดังนั้นเราจะมีคะแนนที่น้อยมาก นอกจากนี้inInverseสายพันธุ์นี้จะต้องทำซ้ำตัวเองและลูกหลานของมันจะได้รับบางส่วนของดีเอ็นเอที่โดดเด่น ส่วนที่สำคัญที่สุดคือการนำความหลากหลายกลับมา

ถ้าinReverseเท่ากับ 255 (โอกาส 1/256) แล้วเราจะกลับคำสั่งของตำแหน่งที่จัดเก็บข้อมูลของคะแนนสี ดังนั้นก่อนที่สี 0 จะถูกเก็บไว้ในบิต 0-3 ตอนนี้สี 15 จะถูกเก็บไว้ในตำแหน่งนั้น ความแตกต่างกับinInverseวิธีการคือความinReverseตั้งใจที่จะยกเลิกงานที่ทำไปแล้ว เรากลับมาที่จตุรัสหนึ่ง เราได้สร้างสปีชีส์ที่มียีนที่คล้ายคลึงกันเหมือนกับตอนที่เกมเริ่มต้น (ยกเว้นกับดักเพื่อค้นหาหน่วยความจำ)

ผ่านการปรับให้เหมาะสมจะถูกทดสอบว่าควรใช้inInverseและinReverseในเวลาเดียวกันหรือไม่ หลังจากการปรับให้เหมาะสมก็สรุปได้ว่าคะแนนไม่เพิ่มขึ้น ปัญหาคือเรามีประชากรที่หลากหลายมากขึ้น แต่สิ่งนี้ก็ส่งผลต่อ 'DNA ที่ถูกต้อง' เช่นกัน เราต้องการทางออกอื่น

การต่อสู้ Morons: โซลูชันที่ 2: รหัสแฮช

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

แฮชโค้ดควรมีจุดประสงค์ในการระบุเอกลักษณ์และป้ายตำแหน่งปัจจุบันบนกระดาน จุดประสงค์ไม่ใช่เพื่อค้นหาว่าตำแหน่ง (x, y) คืออะไร แต่เพื่อตอบคำถามที่บรรพบุรุษของฉันเคยมีมาก่อนในตำแหน่งนี้

สมมติว่าคุณจะมีบอร์ดที่สมบูรณ์ต่อหน้าคุณและคุณจะสร้าง jpg ของช่องสี่เหลี่ยมขนาด 5 ถึง 5 เซลล์ที่เป็นไปได้ คุณจะพบกับ (53-5) x (15-5) = 380 ภาพ ให้ตัวเลขภาพเหล่านี้จาก 1 ถึง 380 hashcodeของเรา ควรถูกมองว่าเป็น ID ซึ่งแตกต่างจากที่มันไม่ได้ทำงานตั้งแต่ 1 ถึง 330 แต่มี IDS ที่หายไปเช่น 563, 3424, 9424, 21245 เป็นต้น

unsigned long hashCode=17;
for(int x = -2; x <= 2; x++) {
    for(int y = -2; y <= 2; y++) {
        int color = v(x, y)+2;
        hashCode = hashCode*31+color;
    }
}       

ตัวเลขที่สำคัญ17และ31อยู่ในนั้นเพื่อป้องกันข้อมูลที่เพิ่มเข้ามาในจุดเริ่มต้นในลูปจะหายไป เพิ่มเติมภายหลังเกี่ยวกับวิธีรวมแฮชโค้ดของเราเข้ากับส่วนที่เหลือของโปรแกรม

ให้แทนที่ "ดูว่ามีอะไรเกินกว่า" กลไกการให้คะแนนแบบย่อยด้วยกลไกการให้คะแนนแบบย่อยอื่น เมื่อสองหรือสามเซลล์มีคะแนนหลักเท่ากันจะมีโอกาส 50% หนึ่งอันดับแรกจะถูกเลือกโอกาส 50% ที่จะเลือกเซลล์ด้านล่างและโอกาส 0% ที่จะเลือกกลาง โอกาสจะไม่ถูกกำหนดโดยตัวสร้างแบบสุ่ม แต่โดยบิตจากหน่วยความจำเนื่องจากด้วยวิธีนี้เราจึงมั่นใจได้ว่าในสถานการณ์เดียวกันจะมีตัวเลือกเดียวกัน

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

เมื่อลูกหลานเดินทางคณะกรรมการเดียวกันกับ DNA ที่มีการเปลี่ยนแปลงเล็กน้อยเขาจะเป็นผู้ตัดสินใจ (> 99%) ในการตัดสินใจเดียวกัน แต่ยิ่งเขายิ่งมีโอกาสมากขึ้นโอกาสที่เส้นทางของเขาจะแตกต่างจากบรรพบุรุษของเขา โอกาสที่เขาจะติดอยู่บนกำแพงอันไกลโพ้นนี้จึงมีขนาดเล็ก ในขณะที่ติดอยู่บนกำแพงใกล้เคียงกับบรรพบุรุษของเขามีขนาดค่อนข้างใหญ่ แต่สิ่งนี้ก็ไม่เลวเพราะเขาจะไม่ให้กำเนิดลูกมากนัก หากไม่มีวิธีการแฮชโค้ดโอกาสของการติดขัดบนผนังใกล้เคียงและห่างไกลก็เกือบจะเหมือนกัน

การเพิ่มประสิทธิภาพ

หลังจากการปรับให้เหมาะสมจึงสรุปได้ว่าตารางการระบุกับดักไม่จำเป็นและ 2 บิตต่อสีก็เพียงพอแล้ว ส่วนที่เหลือของหน่วยความจำ 100-2x16 = 68 บิตใช้เพื่อจัดเก็บรหัสแฮช ดูเหมือนว่ากลไกรหัสแฮชสามารถหลีกเลี่ยงกับดักได้

ฉันปรับให้เหมาะสำหรับพารามิเตอร์ 15 ตัว รหัสนี้รวมชุด tweaked พารามิเตอร์ที่ดีที่สุด (จนถึง):

int dnaLookup(dna_t &d, int start, int chunklen, int storageMethod,int inInverse) {
    // Definition of storageMethod: 0=decimal, 1=streak, 2=bitsum
    int score = 0;
    int streak = 0;
    for(int i = start; i < start+chunklen; i++) {
        int value = d[i];
        if (inInverse) value = (1-d[i]);            
        if (storageMethod==0) {
            score = (score << 1) |value;
        }else{
            if (storageMethod==1){
                if(value) score += ++streak; else streak = 0;
            }else{
                if(value) score ++;         
            }
        }
    };  
    return score;
}

coord_t theFittest(dna_t d, view_t v) {
    // Definition of storageMethod: 0=decimal, 1=streak, 2=bitsum
    const int colorMemStorageMethod = 2, colorMemBlockSize = 2, colorMemZeroThreshold = 0;
    const int useTrapMem = 0, trapMemStorageMethod = -1, trapMemBlockSize = -1;
    const int trapMemTopThreshold = -1, nDirBins = -1, nColorBins = -1;
    const int reorderMemStorageMethod = -1, reorderMemReverseThreshold = -1;
    const int reorderMemInverseThreshold = -1;
    // Definition of hashPrority: -1: no hash, 0:hash when 'look beyond' scores equal,
    // 1: hash replaces 'look beyond', 2: hash replaces 'trap finder' and 'look beyond'
    // 3: hash replaces everything ('color finder', 'trap finder' and 'look beyond')
    const int hashPrority = 2;
    int inReverse = reorderMemReverseThreshold != -1 && 
     (dnaLookup(d,92,8,reorderMemStorageMethod,0) >= reorderMemReverseThreshold);
    int inInverse = reorderMemInverseThreshold != -1 && 
     (dnaLookup(d,84,8,reorderMemStorageMethod,0) >= reorderMemInverseThreshold);
    int trapMemStart=N_COLORS*colorMemBlockSize;
    unsigned long hashCode=17;
    int moveUp=0;
    if (hashPrority>0){
        for(int x = -2; x <= 2; x++) {
            for(int y = -2; y <= 2; y++) {
                int color = v(x, y)+2;
                hashCode = hashCode*31+color;
            }
        }       
        unsigned long hashMemStart=N_COLORS*colorMemBlockSize;
        if (useTrapMem==1 && hashPrority<=1) hashMemStart+=nDirBins*nColorBins*trapMemBlockSize;
        if (hashPrority==3) hashMemStart=0;
        int hashMemPos = hashCode % (DNA_BITS-hashMemStart);
        moveUp = dnaLookup(d,hashMemStart+hashMemPos,1,0,inInverse);
    }

    int xBestScore=0, yBestScore=0;
    long bestScore=-1, weightMove, weightMove2, mainScore;
    for(int x = -1; x <= 1; x++) {
        if (x < 0) weightMove = 1000; // moving backward
        if (x== 0) weightMove = 10000; //moving vertical
        if (x > 0) weightMove = 100000; //moving forward
        for(int y = -1; y <= 1; y++) {          
            int color = v(x, y);
            if (inReverse) color = 15-v(x, y);
            if(color == OUT_OF_BOUNDS || (x==0&&y==0) ) continue;
            //when MoveUp=1 -> give move with highest y most points (hashScore=highest)
            //when MoveUp=0 -> give move with lowest y most points (hashScore=lowest)
            int hashScore = (y+2)*(2*moveUp-1)+4; 
            mainScore = dnaLookup(
              d,
              color*colorMemBlockSize,
              colorMemBlockSize,
              colorMemStorageMethod,
              inInverse
             );
            if (mainScore<colorMemZeroThreshold+1) {
                mainScore =  0; //not a suitable move because too low score
            }else{
                mainScore*= weightMove;
                //lookup trap likelihood
                int directionBin = 0;
                if (nDirBins==3) directionBin = x>0?y+1:-1;
                if (nDirBins==4) directionBin = x>0?y+2:0;
                // put 16 colors in nColorBins bins
                int colorBin = v(0,0)*nColorBins/N_COLORS; 
                if (inReverse) colorBin = (15-v(0,0))*nColorBins/N_COLORS; 
                colorBin = colorBin>(nColorBins-1)?(nColorBins-1):colorBin;
                if (useTrapMem && directionBin >= 0 &&
                 dnaLookup(
                   d,
                   trapMemStart+trapMemBlockSize*(nColorBins*directionBin+colorBin),
                   trapMemBlockSize,
                   trapMemStorageMethod,
                   0
                 )>=trapMemTopThreshold){
                  //suspect a trap therefore no sub score is added                  
                 }else{
                    if (hashPrority>=1){
                        mainScore+=hashScore;
                    } else{
                        // when equal score, use sub score by examining 5x5 box to rank moves
                        for(int x2 = x-1; x2 <= x+1; x2++){     
                            if (x2 < x) weightMove2 = 1; // moving backward
                            if (x2== x) weightMove2 = 10; //moving vertical
                            if (x2 > x) weightMove2 = 100; //moving forward
                            for(int y2 = x-1; y2 <= y+1; y2++){     
                                int color2 = v(x2, y2);
                                if (inReverse) color2 = 15-v(x2, y2);
                                if(color2 != OUT_OF_BOUNDS){
                                    long mainSubScore = dnaLookup(
                                      d,
                                      color2*colorMemBlockSize,
                                      colorMemBlockSize,
                                      colorMemStorageMethod,
                                      inInverse
                                    );
                                    if (mainSubScore>=colorMemZeroThreshold+1){
                                        mainScore+=mainSubScore*weightMove2;
                                    }
                                }
                            }
                        }
                    }               
                 }
            }
            if (hashPrority==2 || (useTrapMem<=0 && hashPrority>=1)) mainScore+=hashScore*10;
            if (hashPrority==3) mainScore=hashScore*weightMove;         

            if(mainScore > bestScore) {
                bestScore = mainScore;              
                xBestScore = x;
                yBestScore = y;
            }
        }
    }
    return{xBestScore,yBestScore};
}   

คะแนน: 922 (2K วิ่ง)

50 คะแนนแรก (9 เกมทำคะแนนได้เพียง 1 คะแนน):

112,747 3 1 1,876,965 8 57 214,921 218,707 2,512,937 114,389 336,9,46,9,8,9,8,9,8,9,8,986,3,9,8,8,9,8,86,,,,,,,,,,,,,,,,,,,,,,3,3,986,804,986,986,316,3,9,986,316,986,316,986,347,987,986,986,987 3 4 5 6 7 8 9 10 1 1 2 6 7

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

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


ฉันคิดว่าการวิเคราะห์กับดักของคุณน่าสนใจทีเดียว

คุณลองฟังก์ชั่นแฮชอื่น ๆ เช่นยกตัวอย่างค่า x 25 ค่าสีที่เห็นเป็น 12.5 16 บิตและใช้โมดูโล ฉันไม่มั่นใจว่าค่าความสอดคล้องของจำนวนเฉพาะจะให้ความสม่ำเสมอที่ดีกว่า แต่ฉันไม่ใช่นักคณิตศาสตร์ตัวยง

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

คุโรอิขอบคุณสำหรับความคิดเห็นของคุณ ฉันไม่ได้ลอง xoring เนื่องจากฉันไม่ค่อยคุ้นเคยกับการทำงานแบบไบนารีใน c ++ ฉันถือว่าคุณหมายถึง 12.5 8 บิตคำ? คุณใช้ xoring หรือไม่
Ruut

คุณสามารถดูรหัส "ผู้เชื่อยาก" ของฉันเพื่อดูฟังก์ชันแฮชที่ฉันใช้ โดยทั่วไปฉันจะข้ามเซลล์ออฟ - แทร็กและพิจารณาสีออนแทร็คเป็นส่วนสูงและต่ำของส่วนของคำ 16 บิต คำเหล่านี้ทั้งหมดจะถูกสะสมด้วย XORs ในรีจิสเตอร์ที่จะถูกหารด้วยขนาดตารางแฮช ตราบใดที่ค่าแฮ็กสูงสุด (65535) สูงกว่าขนาดโต๊ะ (<100) โมดูโล่จะมีพลังการแพร่กระจายที่ดี ฉันทดสอบบนกริดที่สร้างขึ้นแบบสุ่มและดูเหมือนว่าจะมีความสม่ำเสมอที่ดี

6

Pathfinder, C ++, คะแนนเบื้องต้น 35.8504 (50 รอบ)

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


int dnarange(dna_t &d, int start, int len) {
    int res = 0;
    for(int i = start; i < start+len; i++) {
        res = (res << 1) | d[i];
    }
    return res;
}

int dnasum(dna_t &d, int start, int len) {
    int res = 0;
    for(int i = start; i < start+len; i++) {
        res += d[i];
    }
    return res;
}

int dnaweight(dna_t &d, int start) {
    return d[start] + d[start+1] + 2*d[start+2] + 2*d[start+3] + 3*d[start+4];
}

int trap_d [16] = {1,0,1,1,0,1,-1,1,-1,0,-1,-1,0,-1,1,-1}; //immutable
int nhood [10] = {1,0,1,1,1,-1,0,1,0,-1}; //immutable

coord_t pathfinder(dna_t d, view_t v) {
  int is_trap[16] = {0};
  int pos_or_weight[16] = {0};
  int u_weight = dnaweight(d, 80);
  for (int i = 0; i < 16; i++) {
    int status = dnarange(d, 5*i, 2);
    if (status == 1) {
      is_trap[i] = 1;
      pos_or_weight[i] = dnarange(d, 5*i + 2, 3);
    } else {
      pos_or_weight[i] = dnaweight(d, 5*i);
    }
  }
  int w_area[7][4] = {0};
  for (int j = 0; j < 7; j++) {
    w_area[j][3] = u_weight;
  }
  for (int i = 0; i < 3; i++) {
    w_area[0][i] = u_weight;
    w_area[6][i] = u_weight;
  }
  int d_coeff = dnaweight(d, 85);
  for (int i = 0; i < 3; i++) {
    for (int j = 1; j < 6; j++) {
      int p_or_w, color = v(i, j-3);
      if (color != OUT_OF_BOUNDS) {
    p_or_w = pos_or_weight[color];
      } else {
    p_or_w = 1000;
      }
      if (color != OUT_OF_BOUNDS && is_trap[color] && i+trap_d[2*p_or_w] >= 0) {
    w_area[j + trap_d[2*p_or_w + 1]][i + trap_d[2*p_or_w]] += d_coeff;
      } else {
    w_area[j][i] += p_or_w;
      }
    }
  }
  for (int i = 3; i >= 0; i--) {
    for (int j = 0; j < 7; j++) {
      int min_w = 1000;
      for (int k = std::max(0, j-1); k <= std::min(6, j+1); k++) {
    min_w = std::min(min_w, w_area[k][i + 1]);
      }
      w_area[j][i] += min_w;
    }
  }
  int speed = dnasum(d, 90, 5);
  w_area[2][0] += 2 + speed;
  w_area[4][0] += 2 + speed;
  int goal = dnaweight(d, 95);
  int min_w = 10000;
  int sec_w = 10000;
  int min_x, min_y, sec_x, sec_y, w;
  for (int i = 0; i < 5; i++) {
    w = w_area[nhood[2*i + 1] + 3][nhood[2*i]];
    if (w < min_w) {
      sec_w = min_w;
      sec_x = min_x;
      sec_y = min_y;
      min_w = w;
      min_x = nhood[2*i];
      min_y = nhood[2*i + 1];
    } else if (w < sec_w) {
      sec_w = w;
      sec_x = nhood[2*i];
      sec_y = nhood[2*i + 1];
    }
  }
  if (min_w > goal) {
    int r = v.rng.rint(5);
    return {nhood[2*r], nhood[2*r+1]};
  } else if (sec_w <= goal && v.rng.rint(100) < 2*speed) {
    return {sec_x, sec_y};
  }
  return {min_x, min_y};
}

คำอธิบาย

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

ใน 80 บิตแรกของจีโนมแต่ละสีจะจัดใช้ 5 abcdeบิต ถ้าab = 01สีเป็นกับดักและcdeเข้ารหัสทิศทางของมัน (ความเป็นไปได้แปดอย่าง) ถ้าสีไม่ได้เป็นกับดักและน้ำหนักของมันคือab ≠ 01a + b + 2*(c + d + e)

ต่อไปเราจะเริ่มต้นตาราง 3x7 ซึ่งแสดงเขตข้อมูลการมองเห็นของหนูทางด้านขวาของมันเต็มไปด้วยสี "ไม่ทราบ" บิต 80-84 เข้ารหัสน้ำหนักของเซลล์ที่ไม่รู้จักเช่นเดียวกับสีที่ไม่ใช่กับดักและบิต 85-89 เข้ารหัสน้ำหนักทั่วไปสำหรับกับดัก เราเติมกริดด้วยน้ำหนักคำนวณเส้นทางที่สั้นที่สุดและเพิ่มน้ำหนักพิเศษบางส่วน (เข้ารหัสในบิต 90-95) ไปยังเซลล์ด้านบนและด้านล่างของหนูเพื่อกีดกันการหลบเลี่ยง บิต 95-99 เข้ารหัสน้ำหนักเป้าหมาย. หากน้ำหนักขั้นต่ำของเส้นทางอยู่ต่ำกว่าหนูอาจติดอยู่ที่ใดที่หนึ่งและดำเนินการย้ายแบบสุ่ม (แต่ไม่เคยย้อนรอย) มิฉะนั้นจะเป็นไปตามเส้นทางน้ำหนักขั้นต่ำ ด้วยความน่าจะเป็นเล็ก ๆ น้อย ๆ ขึ้นอยู่กับน้ำหนักการป้องกันการเลี่ยงก้าวเท้าหนูเลือกเส้นทางน้ำหนักตัวที่สองถึงขั้นต่ำแทน นี่คือเพื่อป้องกันการติดกับผนัง (แต่ตอนนี้ดูเหมือนจะไม่ทำงานได้ดีมาก)


ใช้งานของคุณบนคอมพิวเตอร์ของฉัน ใช้เวลาสองสามชั่วโมง ได้รับคะแนนเฉลี่ย 7.848433940863856 คะแนน pastebin.com/d50GcwnK
Jakube

@ Jakube ขอบคุณมาก! นั่นแย่กว่าที่ฉันคาดไว้มาก แต่ตอนนี้ฉันดูรหัสอีกครั้งฉันเห็นข้อบกพร่องหลายอย่างและสิ่งแปลกประหลาดอื่น ๆ ฉันจะลองพอร์ตนี้กับ C ++ ในภายหลังเพื่อให้ฉันสามารถวิเคราะห์ได้ด้วยตนเอง
Zgarb

5

LookAheadPlayer C ++ ≈ 89.904

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

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

ดังนั้นเช่น ColorScorePlayer ฉันตัด DNA เป็น 16 ชิ้นและใช้คะแนนเหล่านั้นเป็นคะแนนที่กำหนด อย่างไรก็ตามคะแนนถูกสไทรพ์เพื่อให้แต่ละบิตของแต่ละคะแนนไม่อยู่ติดกัน จากนั้นฉันก็รวมคะแนนของการเคลื่อนไหวที่เป็นไปได้ในปัจจุบันและการเคลื่อนไหวที่มีศักยภาพถัดไปและเลือกการเคลื่อนไหวที่ดีที่สุดที่จะทำ

หมายเหตุ: นี่คือรหัส / ทดสอบใน MinGW มันจะไม่รวบรวมกับการเพิ่มประสิทธิภาพหรือ multithreading ฉันไม่มีการติดตั้ง Linux จริงหรือ Visual Studio มีประโยชน์ในการใช้คอมไพเลอร์ซึ่งจะใช้งานได้ พรุ่งนี้ฉันจะทำการทดสอบอย่างรวดเร็ว แต่โปรดแจ้งให้เราทราบหากคุณพบปัญหาใด ๆ

// get striped color score, 6 bits per color. should be
// resistant to getting erased by a crossover
void mapColorsBitwise(dna_t &d, int* color_array) {
    for (int i=0; i<N_COLORS; i++) {
        int score = 0;
        for (int j=0; j<6; j++) {
            score = (score<<1) | d[ j*N_COLORS + i ];
        }
        color_array[i] = score;
    }
}

// label for the lookup tables
enum direction_lut {
    UP_RIGHT=0, RIGHT, DOWN_RIGHT
};

// movement coord_t's to correspond to a direction
static const coord_t direction_lut[3] = {
    { 1, -1 }, { 1, 0 }, { 1, 1 }
};

// indexes into the arrays to denote what should be summed
// for each direction.
static const int sum_lut[3][6] = {
    { 3, 4, 8, 8, 9, 14 }, { 9, 13, 13, 14, 14, 19 },
    { 14, 18, 18, 19, 23, 24 }
};

coord_t lookAheadPlayer(dna_t d, view_t v) {
    int scoreArray[25] = { 0 };
    int colorScores[N_COLORS] = { };

    // Get color mapping for this iteration
    mapColorsBitwise(d, colorScores);

    for (int y=-2; y<=2; y++) {
        for (int x=0; x<=2; x++) {
            // Get the scores for our whole field of view
            color_t color = v(x,y);
            if (color != OUT_OF_BOUNDS)
                scoreArray[ (x+2)+((y+2)*5) ] += colorScores[color];
        }
    }

    // get the best move by summing all of the array indices for a particular
    // direction
    int best = RIGHT;
    int bestScore = 0;
    for (int dir=UP_RIGHT; dir<=DOWN_RIGHT; dir++) {
        if (v(direction_lut[dir].x, direction_lut[dir].y) == OUT_OF_BOUNDS)
            continue;

        int score = 0;
        for (int i=0; i<6; i++) {
            score += scoreArray[ sum_lut[dir][i] ];
        }

        if (score > bestScore) {
            bestScore = score;
            best = dir;
        }
    }

    return direction_lut[best];
}

5

SlowAndSteady C ++ (คะแนน 9.7)

เราไม่สามารถพึ่งพาการแปลความหมายของจีโนมเป็นตัวเลขได้เนื่องจากการพลิกบิตเพียงครั้งเดียวอาจมีผลกระทบที่แตกต่างกันอย่างรุนแรงขึ้นอยู่กับตำแหน่งของมัน Thats ทำไมฉันเพียงแค่ใช้ 16 กลุ่ม 6 บิตและทำคะแนนให้พวกเขาอยู่กับจำนวนของ1s เริ่มแรก111111ดีและ000000ไม่ดีและในขณะที่มันไม่สำคัญในระยะยาว (เมื่อจีโนมได้รับการพัฒนาอย่างเต็มที่) ในการกำหนดค่าเริ่มต้นของ DNA ส่วนใหญ่ของกลุ่มมี 2-4 คนดังนั้นฉันเปลี่ยนไปใช้9 - (#1 - 3)^2สำหรับการให้คะแนนนี้ ช่วยให้อิสระในการเคลื่อนไหวมากขึ้นในรอบแรกและวิวัฒนาการที่เร็วขึ้น

ตอนนี้ฉันดูที่เพื่อนบ้านที่ใกล้ที่สุด 7 คนเท่านั้นเพิ่มอคติทิศทางไปยังคะแนนสีและเคลื่อนที่ในทิศทางสูงสุดแบบสุ่ม

แม้ว่าคะแนนตัวเองจะไม่สูงมากนัก critters ของฉันถึงเส้นชัยและคะแนน> 1 ใน 3/4 ของกรณี

coord_t SlowAndSteadyPlayer(dna_t d, view_t v) {
    const int chunklen = 6;
    int color_scores[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
    for(int i=0; i<16; i++){ //count ones
        for(int j=0; j<chunklen; j++){
            color_scores[i] += d[i*chunklen + j];
        }
    }

    int moves[7][2] = {
        {-1,1}, {0,1}, {1,1},
                       {1,0},
        {-1,-1},{1,-1},{-1,-1}
    };
    int movescores[7];
    int smax = -1;
    int nmax = 0;
    int best_moves[7];
    for(int m=0; m<7; m++){ //compute the score for each move
        int temp_color = v(moves[m][0], moves[m][1]);
        if(temp_color == OUT_OF_BOUNDS){
            movescores[m] = 0;
            continue;
        }
        int dir_bias[3] = {1,3,6};
        int temp_score = 9-(color_scores[temp_color]-3)*(color_scores[temp_color]-3) + dir_bias[moves[m][0]+1];
        movescores[m] = temp_score;

        if(temp_score > smax) {
            smax = temp_score;
            nmax = 0;
        }
        if(temp_score == smax) best_moves[nmax++] = m;
    }

    int best_chosen = v.rng.rint(nmax);
    return {moves[best_moves[best_chosen]][0], moves[best_moves[best_chosen]][1]};
}

และตัวอย่างคะแนนบนกระดาน 100

Scores: 5 4 13028 1 1 101 2 24 1 21 1 4 2 44 1 1 24 8 2 5 1 13 10 71 2 19528 6 1 69 74587 1 1 3 138 8 4 1 1 17 23 1 2 2 50 7 7 710 6 231 1 4 3 263 4 1 6 7 20 24 11 1 25 1 63 14 1 2 2 1 27 9 7 1 7 31 20 2 17 8 176 3 1 10 13 3 142 1 9 768 64 6837 49 1 9 3 15 32 10 42 8

คะแนนเฉลี่ยเรขาคณิต: 9.76557


คะแนนที่คุณพูดถึงสำหรับหนึ่งกระดานใช้อัตราการกลายพันธุ์มาตรฐานหรือค่าที่ปรับของคุณหรือไม่
trichoplax

"critters ของฉันถึงเส้นชัยและคะแนน> 1 ใน 3/4 ของกรณี" ฉันหวังว่าคะแนนการให้คะแนนนี้ได้รับรางวัล
Sparr

5

WeightChooser | C # | คะแนน: 220.8262 ใน 1520 เกม

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

using ppcggacscontroller;
using System.Linq;
using System;

public class WeightChooser
{
    public static ppcggacscontroller.Program.Coord[] cspcoords = new[] {
            new Program.Coord(1, -1),
            new Program.Coord(1, 0),
            new Program.Coord(1, 1),
        };

    const int dnaBits = 4;

    public static void move(GameLogic.IView v, GameLogic.IGenome g, Random rnd, out int ox, out int oy)
    {
        var gcrds = cspcoords.Where(c => viewVal(v, c) > -1)
            .OrderByDescending(p => getBitsSet(g, viewVal(v, p)))
            .ThenByDescending(gt => weight(v, g, gt));

        Program.Coord nextMove = gcrds.First();
        ox = nextMove.x;
        oy = nextMove.y;
    }

    private static uint getBitsSet(GameLogic.IGenome g, int vVal)
    {
        uint i = g.cutOutInt(dnaBits * vVal, dnaBits);
        i = i - ((i >> 1) & 0x55555555);
        i = (i & 0x33333333) + ((i >> 2) & 0x33333333);
        return (((i + (i >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24;
    }

    private static int viewVal(GameLogic.IView v, Program.Coord c)
    {
        return v[c.x, c.y];
    }

    private static double weight(GameLogic.IView v, GameLogic.IGenome g, Program.Coord toGo)
    {
        double w = 0;

        int y = (toGo.y + v.yd) - 1;
        int i = 0;
        for (; i <= 2; i++)
        {
            int field = v[toGo.x + 1, (y + i) - v.yd];
            if (field > -1)
                w += getBitsSet(g, field);
        }

        return w / i;
    }
}

Scores: 32, 56103, 1361, 3351446, 33027, 23618, 22481, 1172713, 1, 3, 1, 1, 1, 2 88584, 106357, 1, 1232, 1, 1651280, 16690, 1, 1, 23732, 207554, 53, 69424, 1, 1,  79361, 1, 1, 51813, 229624, 25099, 2, 1, 234239, 362531, 1, 1, 19, 7295, 1, 7, 2, 196672, 1654208, 73453, 1, 23082, 1, 8, 5, 1685018, 4, 20, 1, 1, 1, 1, 1, 144 671, 122309, 10, 94752, 100895, 1, 54787, 54315, 252911, 79277, 1159, 241927, 94 347, 1, 318372, 37793, 1, 1, 1345310, 18934, 169700, 1, 1, 3, 186740, 83018, 121 758, 1, 358, 1935741, 88, 1, 1, 1, 1, 7, 21, 51144, 2, 1, 267638, 1, 1, 3, 1, 1,  1, 1, 674080, 47211, 8879, 7, 222766, 67214, 2, 89, 21038, 178463, 92846, 3, 14 0836, 1, 1, 111927, 1, 92165, 1, 192394, 1, 1, 2563722, 1, 42648, 1, 16, 1, 1, 2 85665, 1, 212653, 1, 4, 20513, 3, 135118, 13161, 2, 57, 78355, 3, 3, 44674, 8, 1 , 226472, 1, 1, 31588, 19619, 1, 2931870, 60814, 1, 1, 33867, 60740, 20558, 1, 1 5, 3, 5, 1, 1, 1, 60737, 450636, 468362, 1, 1, 347193, 91248, 551642, 1, 427215,  1, 57859, 17, 15, 66577, 24192, 1, 63560, 6568, 40279, 68216, 23098, 180732, 1,  1, 3041253, 1, 253488, 60535, 1, 1, 150838, 7361, 72855, 290699, 104644, 1, 763 01, 378, 1, 89220, 1, 262257, 2, 2, 1, 117, 105478, 33, 1, 65210, 1, 117588, 1, 1, 24320, 12, 3714568, 81152, 1, 1, 10125, 2, 1, 22, 1, 45201, 1, 1, 10518, 1, 1 , 1, 1, 34, 210021, 1, 1, 1, 65641, 6, 72, 1, 7, 2, 161578, 1, 1, 38378, 1, 4113 741, 1, 34450, 244212, 127660, 1, 256885, 46, 2, 1, 1, 103532, 1, 503965, 114774 , 52450, 124165, 73476, 50250, 1, 3, 3755352, 24928, 1, 1, 51, 11, 1, 210580, 1,  62375, 1, 1, 92745, 341232, 167675, 86, 242, 293710, 454841, 1, 49840, 4456758,  121378, 145323, 74904, 5048, 25459, 1, 57, 116999, 1, 1, 76074, 111447, 95706, 1, 1, 52631, 166756, 2159474, 161216, 1, 2, 3, 11904, 1, 22050, 6, 1, 1, 1, 41, 48908, 6, 80878, 28125, 28, 160516, 1, 4, 1, 8, 1, 1, 7, 362724, 1, 397193, 1, 2 5, 1, 59926, 3, 74548, 2320284, 470189, 1, 108, 1, 1, 16, 1, 496013, 1, 1, 1, 1,  107758, 1, 284144, 146728, 1, 70769, 94215, 1, 1, 9961, 97300, 7, 1, 76263, 1, 27, 294046, 40, 8, 2, 1, 57796, 2, 79800, 1043488, 470547, 1, 1, 1, 6, 69666, 8,  1, 1, 344011, 205325, 3963186, 1141527, 61598, 446029, 1, 1, 1, 1, 625247, 1877 92, 136391, 1, 72519, 1, 141168, 412, 98491, 103995, 297052, 1, 1, 1, 1, 3, 17, 9, 62899, 5, 47810, 254, 26789, 2, 1, 1, 3, 10361, 19615, 40430, 17288, 3, 71831 , 41374, 1, 91317, 409526, 1, 184305, 1, 192552, 3, 3587674, 39, 13, 134500, 41,  42, 672, 559835, 9, 39004, 51452, 1, 1, 12293, 11544, 265766, 8590, 1, 8632, 1,  1, 61849, 35155, 1, 74798, 72773, 1, 89, 37, 4, 4405882, 1, 99, 44397, 5, 4, 6,  1, 1, 1, 515818, 78383, 20, 127829, 1824801, 157, 1, 1, 268561, 19, 2, 230922, 1, 103, 98146, 5029789, 304324, 1, 5, 60516, 1, 139, 28982, 7, 20755, 187083, 1,  1, 143811, 37697, 1, 1, 269819, 83, 1, 202860, 13793, 16438, 113432, 1, 1, 2, 5 134384, 29, 84135, 39035, 2, 125, 1, 30, 129771, 41982, 13548, 61, 1, 2, 1, 82, 102, 2, 105581, 210399, 291204, 3012324, 1, 84763, 1, 1, 442067, 2, 1, 1, 1, 116 , 1, 3, 3, 56, 208807, 1, 2, 1, 14, 29, 31286, 1, 1, 162358, 28856, 46898, 1, 16 2698, 1, 1, 1, 65, 1, 1, 234566, 6, 1, 1, 128, 124, 2167692, 181946, 29, 1, 1, 1 , 1, 17, 162550, 179588, 4, 226480, 28, 1, 158512, 35084, 1, 26160, 17566, 1, 81 826, 2, 33, 1, 1, 11, 1, 230113, 1, 1, 1, 24405, 17, 1, 2, 1, 162365, 2, 1, 1, 8 5225, 1, 15016, 51509, 1, 5, 1, 93, 13, 59, 24548, 1, 3, 2, 2, 1, 64424, 1, 1, 4 , 1, 1, 1, 2, 267115, 139478, 52653, 96225, 1, 1, 35768, 3, 1, 1, 3280017, 8, 80 014, 43095, 112102, 1, 1, 1, 79594, 5, 1, 1, 4, 455714, 19, 15, 1, 233760, 55850 5, 2, 2, 1, 63672, 1, 3732951, 1, 135858, 134256, 452456, 151573, 79057, 638215,  88820, 1, 1, 76517, 13, 314006, 5, 1, 17704, 1, 79589, 1, 18371, 530793, 59020,  1, 1, 1, 4, 1, 1, 1, 71735, 1, 1, 1, 1, 1, 37894, 1, 2, 24054, 1, 8, 26471, 34,  1, 48033, 5, 3, 1, 25, 101, 1, 1, 5, 1, 1, 1, 97521, 1, 682817, 286486, 5, 1472 4, 1, 7805226, 6, 1, 1, 1, 7, 2, 1, 1, 1, 25, 233330, 1, 20899, 3417337, 92793, 23, 80821, 1, 1, 115948, 264191, 3, 79809, 1, 2, 59531, 2, 1, 1, 28684, 97, 1, 2 69433, 98769, 1, 76608, 138124, 1, 1, 325554, 122567, 1, 1, 3, 689604, 4, 85823,  66911, 138091, 169416, 21430, 1, 2, 486654, 108446, 93072, 1, 67907, 4, 1, 1, 5 2260, 67867, 210496, 25157, 1, 1, 1, 5477, 2, 2, 11907, 106, 48404, 1, 1, 1, 787 11, 190304, 112025, 1, 9313, 143055, 40189, 315537, 157581, 70714, 6, 180600, 38 594, 103658, 59444, 7, 31575, 1, 1, 581388, 370430, 1, 114446, 1, 1, 2, 3968, 1,  1, 1, 1, 1, 4523411, 1, 1, 270442, 1, 59, 235631, 3, 110196, 9, 1, 93724, 1, 22 917, 1, 6, 1, 2350266, 1, 1, 20, 4686858, 31, 1, 240180, 10, 470592, 3, 61051, 1 45372, 2831, 64052, 10, 120652, 255971, 479239, 1, 387659, 1, 1, 1, 378379, 7, 3 3218, 55914, 1, 1, 1667456, 6, 2, 74428, 3, 2, 1, 121582, 121274, 19651, 59899, 1, 11, 406670, 137835, 100269, 2, 164361, 98762, 44311, 25817, 178053, 31576, 1,  8, 2539307, 121430, 1, 41001, 1, 4, 1, 116258, 91101, 1, 126857, 1, 8, 49503, 1 , 489979, 12, 500332, 1, 52, 4, 8786, 4, 4878652, 12354, 27480, 89115, 87560, 11 793, 5, 1, 4702325, 301188, 1, 1, 1, 1, 1, 416520, 49357, 230103, 24497, 1, 3, 2 , 57366, 183021, 1, 1, 1, 1, 1, 2, 2, 2546229, 1, 2, 38665, 1, 6903, 1, 89519, 9 5119, 64879, 1, 1, 160380, 474336, 3107, 1, 7, 29099, 28667, 3, 196933, 35979, 1 2924, 7, 1, 99885, 6, 1, 1, 1, 7, 1, 1, 1, 1, 65727, 1, 1, 1, 1, 2108110, 3, 107 811, 23818, 701905, 1, 156034, 32, 1, 29, 143548, 1, 67665, 4612762, 1, 3, 20, 1 , 1, 9, 28543, 1, 1, 1, 30978, 9, 1, 19504, 79412, 15375, 763265, 1, 352373, 193 045, 1, 4570217, 9, 1, 6, 29180, 90030, 1, 1, 1, 1, 1, 93, 1, 100889, 1, 1, 37, 15, 17, 1, 81184, 1, 2, 272831, 1, 137, 1, 9, 42874, 679183, 1, 350027, 12, 1, 2 , 1, 26408, 1, 11182, 1, 30, 139590, 7, 3, 1, 1, 34729, 1, 2, 1, 1, 50343, 66873 , 3891, 1, 148952, 1, 1, 22322, 104176, 1, 3, 20549, 140266, 37827, 30504, 17, 6 8588, 120195, 1, 123353, 2, 64301, 11, 1, 109867, 4, 1, 1, 1, 28671, 1, 50963, 5 4584, 1, 1, 1, 33, 1, 381918, 1, 265823, 4771840, 155179, 314, 134086, 1, 1, 30,  1, 2, 1102665, 18, 132243, 3861, 1, 1, 208906, 60112, 1, 1, 1, 31273, 551, 3490 0, 2, 43606, 1, 1, 1, 1, 5, 2, 88342, 2, 1, 19, 3, 1, 1, 1, 1, 28507, 1, 491467,  1, 1, 22, 1, 1, 1, 1, 9345, 9, 18, 84343, 1, 2, 1, 18, 36816, 1, 1, 513028, 287 88, 5037383, 721932, 170292, 108942, 539115, 1, 575676, 20, 1, 31698, 99797, 205 21, 380986, 1, 1, 14, 2, 1, 201100, 30, 1, 119484, 1, 1, 1, 1, 2214252, 3, 4, 18 179, 9, 4, 542150, 1, 6, 157, 3182099, 4, 1, 1, 6140, 3339847, 498283, 52523, 1,  1, 1, 1, 1, 202054, 263324, 1, 6, 2, 1, 2, 72357, 12, 5, 66, 4, 7368, 1, 30706,  61936, 3945270, 138991, 1, 68247, 1, 1, 30482, 35326, 1, 1, 9, 1, 148, 1, 46985 , 1, 4325093, 1, 1, 2880384, 65173, 1, 56581, 179178, 372369, 56187, 3, 12, 8, 4 00743, 3, 28658, 1, 1, 9, 1, 4, 2, 34357, 1, 42596, 68840, 2, 62638, 158027, 617 34, 71263, 1, 1, 9, 1, 6830309, 3, 1, 1, 157253, 129837, 9, 5008187, 48499, 5981 3, 1, 40320, 233893, 5, 1383, 7732178, 16, 1, 13, 5686145, 84554, 1, 79442, 1, 1 , 256812, 127818, 31, 226113, 1, 4, 1, 1, 4506163, 1, 4, 1, 40176, 19107, 205, 2 7, 1, 448999, 1, 1, 2750, 62723, 1, 12, 1, 1, 79881, 1, 48, 13, 4, 1, 28765, 1, 33, 291330, 30817, 2, 1, 1, 1, 4170949, 16, 1, 1, 118781, 10473, 520797, 1, 8, 1 , 80215, 1, 21759, 5143209, 79141, 40229, 1, 17403, 71680, 1115694, 1, 1, 1, 10,  1, 77149, 382712, 1, 11, 84891, 47633, 1, 2, 39037, 1, 213148, 1607280, 127674,  1, 333207, 1, 78901, 1, 16203, 87580, 1, 1565571, 537902, 53000, 15, 1, 2, 1, 2 13127, 1, 338634, 2469990, 469479, 9519, 51083, 1, 42082, 33179, 1, 1, 32444, 3,  1, 201642, 99724, 377, 1, 2, 1, 36919, 1, 322707, 2, 164765, 82516, 1, 5274643,  1, 36421, 1, 8, 1, 117856, 1, 1, 493342, 1, 36289, 7, 1, 62, 2, 1, 38533, 1, 68 , 45754, 9, 102015, 312941, 1, 99 
Final score is 220.826222910756

5

RATS IN ACTION (ไม่ใช่คำตอบ แต่เป็นเครื่องมือกราฟิกสำหรับบอท C ++)

ตั้งแต่เริ่มต้นการท้าทายนี้ฉันมีปัญหาในการค้นหาว่าหนูกำลังเผชิญหน้ากับอะไรในการติดตาม
ในที่สุดฉันก็แฮ็คคอนโทรลเลอร์และเขียนเครื่องมือด้านข้างเพื่อรับภาพกราฟิกของแทร็ก
ในที่สุดฉันก็ทำการแฮ็กและเพิ่มการมองเห็นเส้นทางที่เป็นไปได้ของ DNA ของหนูที่ได้รับ

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

นี่คือตัวอย่าง:

ติดตามตัวอย่าง

คุณอาจต้องซูมเข้าเพื่อดูอะไรเลยดังนั้นนี่เป็นครึ่งแรก:

ครึ่งทาง (ไม่ต้องการเล่นสำนวน)

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

เส้นทางจะถูกแสดงด้วยลูกศรตรงขนาดใหญ่ สีอธิบายผลลัพธ์:

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

ในตัวอย่างเรามีตำแหน่งเริ่มต้นที่ชนะ 12 ตำแหน่งอันหนึ่งนำไปสู่วงที่ไม่มีที่สิ้นสุดและอีกสองถึงความตายที่โหดเหี้ยม

เส้นทางที่ไม่ต่อเนื่องเกิดจากการเคลื่อนย้ายทางไกลซึ่งคุณสามารถตามด้วยลูกศรโค้งที่สอดคล้องกันได้

ตอนนี้สำหรับสัญลักษณ์สี พวกเขาแสดงถึงความหมายของ 16 สี (สีเทาแสดงถึงสิ่งที่หนูเห็น)

  • ผนัง: สี่เหลี่ยมจัตุรัส
  • teleporter: 4 กิ่งแยก
  • เครื่องตรวจจับกับดัก: octogon ขนาดเล็ก

สีที่ว่างเปล่าคือ ... ดี ... ว่างเปล่า

ผู้ส่งโทรเลขมีลูกศรชี้ไปที่ปลายทาง

เครื่องตรวจจับกับดักยังมีลูกศรที่บอกกับดักซึ่งคิดว่าเป็นวงกลมสีแดง
ในกรณีหนึ่งจาก 9 กับดักอยู่ในเซลล์เดียวกับเครื่องตรวจจับซึ่งในกรณีนี้คุณจะเห็น octogon ขนาดเล็กด้านบนของวงกลมสีแดง

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

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

สุดท้ายสัญลักษณ์สีเทาแสดงถึงสิ่งที่หนูเห็น (เช่นความหมายของคุณลักษณะจีโนมของสี)

  • ผนัง: สี่เหลี่ยมจัตุรัส
  • เครื่องตรวจจับกับดัก: octogon
  • กับดัก: X

โดยพื้นฐานแล้วเซลล์ทั้งหมดนั่งอยู่บนสี่เหลี่ยมสีเทาถือเป็นผนังของหนู
Big X's เป็นตัวแทนของเซลล์ที่พิจารณาว่าเป็นกับดักโดยมีอ็อกโตกอนที่สอดคล้องกันซึ่งระบุเครื่องตรวจจับที่รายงานพวกมัน

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

จากเครื่องเคลื่อนย้ายมวลสาร 4 เครื่องนั้น 2 ถือว่าเป็นผนัง (สีฟ้าครามและผิวสีแทน) และ 2 เป็นเซลล์ว่าง (แดงและเหลือง)

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

รหัส

มันเป็นระเบียบ แต่ก็ใช้งานได้ดี

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

ฉันแฮ็คคอนโทรลเลอร์เพื่อสร้างสตริงตัวละครขนาดใหญ่ที่เรียงรายละเอียดแทร็กและสีด้วย "ระยะแห้ง" ของ DNA ของหนูจากสถานที่ที่เป็นไปได้ทั้งหมด

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

สุดท้ายร่องรอยเหล่านี้ทั้งหมดจะถูกใส่ลงในไฟล์ข้อความขนาดใหญ่ที่ถูกอ่านในภายหลังโดยยูทิลิตี้ PHP ที่สร้างผลลัพธ์กราฟิก

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

หากใครสนใจฉันสามารถเผยแพร่รหัสได้

เห็นได้ชัดว่าใช้งานได้เฉพาะกับ C ++ บอทและคุณจะต้องเขียนฟังก์ชันติดตามและอาจแก้ไขโค้ด PHP หากคุณต้องการแสดงข้อมูลจีโนมบางตัว (ตัวเลขสีเทาในกรณีของฉัน)
แม้จะไม่มีข้อมูลเฉพาะ DNA คุณสามารถดูเส้นทางตามด้วย DNA ของคุณบนแผนที่ที่กำหนดได้โดยใช้ความพยายามเพียงเล็กน้อย

ทำไมสัญญาณออกกลาง?

ก่อนอื่น C ++ ไม่มีไลบรารี่กราฟิกแบบพกพาที่เหมาะที่จะพูดโดยเฉพาะเมื่อใช้ MSVC แม้ว่า Win32 builds มักจะพร้อมใช้งานพวกเขามักจะมาภายหลังและจำนวนไลบรารีภายนอกแพ็กเกจและสิ่งที่คล้ายยูนิกซ์อื่น ๆ ที่ต้องการทำให้การเขียนแอปพลิเคชันกราฟิกที่รวดเร็วและง่ายดายเป็นอาการปวดสาหัสในส่วนหนึ่งของร่างกาย ฉันจากการตั้งชื่อ

ฉันพิจารณาการใช้ Qt (เกี่ยวกับสภาพแวดล้อมเดียวที่ทำให้การพัฒนา GUI / กราฟิคแบบพกพาใน C ++ เป็นงานที่ง่ายและน่าพอใจ IMHO - อาจเป็นเพราะมันเพิ่มระบบการส่งข้อความà Objective C ที่ C ++ ไม่เพียงพอและทำหน้าที่ จำกัด หน่วยความจำ การจัดการให้น้อยที่สุด) แต่ดูเหมือนว่า overkill สำหรับงานในมือ (และทุกคนที่ต้องการใช้รหัสจะต้องติดตั้ง SDK ที่ใหญ่มาก - แทบจะไม่คุ้มค่ากับความพยายามเท่าไรนัก)

แม้สมมติว่าเป็นไลบรารีแบบพกพาก็ไม่มีความต้องการความเร็วในการพูดถึง (หนึ่งวินาทีหรือมากกว่านั้นในการสร้างภาพส่วนใหญ่ก็เพียงพอแล้ว) และด้วยความแข็งแกร่งที่เป็นเลิศและความยุ่งเหยิงโดยธรรมชาติ C ++ ไม่ใช่เครื่องมือที่ดีที่สุดสำหรับงานนี้

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

ทำไมต้อง PHP

ฉันพบว่าภาษานั้นง่ายและปรับตัวได้อย่างสะดวกมากสำหรับการทำต้นแบบ ฉันทำให้มันเป็นภาษาสัตว์เลี้ยงของฉันสำหรับความท้าทายด้านรหัสที่ไม่ต้องการการแสดงที่สุดยอด
มันเป็นภาษาที่แย่มากสำหรับการเล่นกอล์ฟ แต่กอล์ฟก็ไม่เคยเป็นชาของฉันเลย

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

แม้ว่าคุณจะไม่รู้ภาษา แต่ก็ไม่ควรที่จะปรับเปลี่ยนรหัสให้เหมาะกับความต้องการของคุณ อย่าลืมค่า$ก่อนตัวแปรเช่นเดียวกับวันพื้นฐานเก่า ๆ ที่ดี :)


1
คุณจะช่วยแบ่งปันเครื่องมือของคุณ? ฉันไม่เห็นรหัสหรือลิงก์ในคำตอบของคุณ
Franky

5

SkyWalker - Python - ทำคะแนนน้อยกว่า 231 ใน 50 เกม

ดังนั้นให้เขียนรหัสก่อนแล้วจึงอธิบายบางอย่าง ฉันหวังว่าไม่มีอะไรพังขณะคัดลอก

class SkyWalker(Player):
    def __init__(self):
        Player.__init__(self)
        self.coords = [#Coordinate(-1,-1),
                       #Coordinate( 0,-1),
                       Coordinate( 1, 0),
                       Coordinate( 1,-1),
                       #Coordinate(-1, 0),
                       #Coordinate( 0, 0),
                       #Coordinate(-1, 1),
                       #Coordinate( 0, 1),
                       Coordinate( 1, 1)]

        self.n_moves = len(self.coords)

    def visionToMove(self, x, y):
        x = x - 2
        y = y - 2

        return (x, y)

    def trapToMove(self, x, y, offx, offy):
        x = x - 2 + (offx % 3) - 1
        y = y - 2 + (offy % 3) - 1
        return (x, y)

    def isNeighbour(self, x1, y1, x2, y2):
        if (x1 == x2) or (x1+1 == x2) or (x2+1 == x1):
            if (y1 == y2) or (y1+1 == y2) or (y2+1 == y1):
                return True
        return False

    def calcMove(self, donots, never, up):
        forwards = {(1, 0): 0, (1, 1): 0, (1, -1): 0, (0, 1): 10, (0, -1): 10}

        for key in forwards:
            if key in never:
                forwards[key] = 100
            for x in donots:
                if (key[0] == x[0]) and (key[1] == x[1]):
                    forwards[key] = 20

        min_value = min(forwards.itervalues())
        min_keys = [k for k in forwards if forwards[k] == min_value]

        return random.choice(min_keys)

    def turn(self):
        trap1 = self.bit_chunk(0, 4)
        trap1_offsetx = self.bit_chunk(4, 2)
        trap1_offsety = self.bit_chunk(6, 2)
        trap2 = self.bit_chunk(8, 4)
        trap2_offsetx = self.bit_chunk(12, 2)
        trap2_offsety = self.bit_chunk(14, 2)
        wall1 = self.bit_chunk(16, 4)
        wall2 = self.bit_chunk(20, 4)
        tel1 = self.bit_chunk(24, 4)
        tel1_good = self.bit_chunk(28, 3)
        tel2 = self.bit_chunk(31, 4)
        tel2_good = self.bit_chunk(35, 3)
        tel3 = self.bit_chunk(38, 4)
        tel3_good = self.bit_chunk(42, 3)
        tel4 = self.bit_chunk(45, 4)
        tel4_good = self.bit_chunk(49, 3)
        up = self.bit_at(100)

        donots = []
        never = []

        for y in range(0, 5):
            for x in range(0, 5):
                c = self.vision[y][x]
                if (c == -1):
                    never += self.visionToMove(x, y),
                elif (c == trap1):
                    donots += self.trapToMove(x, y, trap1_offsetx, trap1_offsety),
                elif (c == trap2):
                    donots += self.trapToMove(x, y, trap2_offsetx, trap2_offsety),
                elif (c == wall1):
                    donots += self.visionToMove(x, y),
                elif (c == wall2):
                    donots += self.visionToMove(x, y),
                elif (c == tel1):
                    if (tel1_good > 3):
                        donots += self.visionToMove(x, y),
                elif (c == tel2):
                    if (tel2_good > 3):
                        donots += self.visionToMove(x, y),
                elif (c == tel3):
                    if (tel3_good > 3):
                        donots += self.visionToMove(x, y),
                elif (c == tel4):
                    if (tel4_good > 3):
                        donots += self.visionToMove(x, y),

        coord = self.calcMove(donots, never, up)

        return Coordinate(coord[0], coord[1])

คำอธิบายบางอย่าง

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

  • 2 x 8 บิตสำหรับกับดัก 4 บิตแรกคือหมายเลขสีส่วนอีก 4 บิตเป็นออฟเซ็ต
  • 2 x 4 บิตสำหรับผนังเพียงสี
  • 4 x 7 บิตสำหรับเครื่องเคลื่อนย้ายมวลสารอีก 4 บิตสำหรับสี 3 เพื่อตัดสินว่าดีหรือไม่ดี

สิ่งนี้ทำให้รวมเป็น 52 บิตที่ใช้ อย่างไรก็ตามฉันใช้ตัวส่งสัญญาณเคลื่อนย้าย 3 บิตแรกเท่านั้น (ฉันตรวจสอบว่าตัวเลขมากกว่า 3) ดังนั้นอีก 2 สามารถลบทิ้งฉันที่ 44 บิตใช้

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

ขึ้นอยู่กับรายการของเขตข้อมูลที่ไม่ดีเหล่านั้นย้ายถัดไปจะถูกคำนวณ ลำดับของฟิลด์ที่ต้องการคือ:

  1. ข้างหน้า
  2. ขึ้นหรือลง
  3. ถอยหลังขึ้นหรือลง
  4. ย้อนกลับ

หากมีสองฟิลด์ของหมวดหมู่ที่เกี่ยวข้องจะมีการเลือกแบบสุ่ม

ผล

Individual scores: [192, 53116, 5, 1649, 49, 2737, 35, 5836, 3, 10173, 4604, 22456, 21331, 445, 419, 2, 1, 90, 25842, 2, 712, 4, 1, 14, 35159, 13, 5938, 670, 78, 455, 45, 18, 6, 20095, 1784, 2, 11, 307853, 58171, 348, 2, 4, 190, 7, 29392, 15, 1158, 24549, 7409, 1]
On average, your bot got 231.34522696 points

ความคิด

  • ฉันไม่มีความคิดถ้าฉันโชคดีกับการวิ่ง 50 ครั้งหรือว่ามีปัญญาอยู่บ้างในกลยุทธ์ของฉัน

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

  • แบบสุ่มเล็ก ๆ บางอย่างนั้นดีที่จะไม่ติดกับกับดักบางที่ใกล้ถึงจุดสิ้นสุดของการแข่งขัน

  • ฉันคิดว่าสีที่ไม่พิเศษนั้นไม่เลวเลย อย่างไรก็ตามอินสแตนซ์ของพวกเขาอาจไม่ดีเมื่อพวกเขาอยู่ในออฟเซ็ตของกับดัก ดังนั้นการติดฉลากสีที่ไม่ดีถ้ามันไม่ใช่กับดักผนังหรือเครื่องเคลื่อนย้ายมวลสารที่ไม่ดีก็ไม่สมเหตุสมผล

  • กำแพงเป็นศัตรูที่ยิ่งใหญ่ที่สุด

ปรับปรุง

อย่างแรกแม้ว่าฉันจะพลาดการเห็นสี่เหลี่ยมสีดำขยับเข้ามาใกล้เป้าหมายยิ่งขึ้นก็ตามพอร์ต C ++ นั้นจำเป็นต่อการทดสอบมากขึ้นและได้ผลลัพธ์ที่มีความหมายมากขึ้น

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

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

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

ฉันควรใช้จีโนมช่วงครึ่งหลังของฉัน


ฉันพยายามเก็บสี แต่ในท้ายที่สุดสรุปว่ามันไม่ทำงานเพราะคุณจะได้รับสองเท่า ตัวอย่างเช่นหากself.bit_chunk(16, 4)และself.bit_chunk(20, 4)มีทั้งค่าที่0010คุณมีเพียงแค่จัดเก็บข้อมูลเกี่ยวกับหนึ่งในสองกับดักที่มีประสิทธิภาพ
Ruut

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

สำหรับคนอื่นที่ประสงค์จะทำงานนี้: มันทำงานในหลาม 2 และสามารถทำงานในหลาม 3 โดยการเปลี่ยนที่เกิดขึ้นเพียงครั้งเดียวของการitervalues values
trichoplax

ฉันได้ผลลัพธ์ดังนี้: [6155, 133, 21, 12194, 8824, 3, 3171, 112, 111425, 3026, 1303, 9130, 2680, 212, 28, 753, 2923, 1, 1, 4140, 107, 1256 , 90, 11, 104, 1538, 63, 917, 8, 1, 709, 11, 304, 212, 2, 43, 5, 4, 206, 8259, 75, 28, 7, 1, 11, 5, 1 , 1244, 1398, 13] ค่าเฉลี่ยทางเรขาคณิต 122.9220309940335
trichoplax

ดูเหมือนว่าเราต้องการเรียกใช้มากกว่า 50 เกมเพื่อให้ได้คะแนนที่เชื่อถือได้
trichoplax

3

Python, NeighborOfNeighbors, คะแนน = 259.84395 มากกว่า 100 เกม

นี่คือรูปแบบที่แตกต่างกันของ ColorScorePlayer ทุก ๆ 6 บิตจะเก็บคะแนนคุณภาพของรูปสี่เหลี่ยม เมื่อบอตกำลังเคลื่อนที่มันจะทำคะแนนสแควร์ไปข้างหน้า 3 อัน ได้แก่ เส้นทแยงมุมขึ้นไปข้างหน้าและทแยงมุมลง คะแนนคือคุณภาพของสแควร์บวกครึ่งหนึ่งของคุณภาพเฉลี่ยของ 3 สแควร์ถัดไป สิ่งนี้ทำให้บอทมองไปข้างหน้าโดยไม่ทำให้คุณภาพของสแควร์แรกท่วมท้น อัลกอริทึมคล้ายกับ LookAheadPlayer ซึ่งฉันไม่ได้เห็นก่อนที่จะเขียนวิธีการแก้ปัญหานี้

class NeighborsOfNeighbors(Player):
  def __init__(self):
    Player.__init__(self)
    self.coords = [ Coordinate( 1, 0),
                    Coordinate( 1,-1),
                    Coordinate( 1, 1)
                    ]

  def turn(self):
    scores=[self.score(c.x,c.y)+0.5*self.adjacentScore(c.x,c.y) if self.vision_at(c.x,c.y)>-1 else None for c in self.coords ]
    max_score = max(scores)
    return random.choice( [c for s,c in zip(scores,self.coords) if s==max_score] )

  def adjacentScore(self,x,y):
    adjacent = [(x+1,y)]
    if self.vision_at(x,y+1)>-1:
      adjacent+=[(x+1,y+1)]
    if self.vision_at(x,y-1)>-1:
      adjacent+=[(x+1,y-1)]
    adjscores=[self.score(a,b) for a,b in adjacent]
    return sum(adjscores)/float(len(adjscores))

  def score(self,x,y):
    return -1 if self.vision_at(x,y) == -1 else self.bit_chunk(6*self.vision_at(x,y),6)

มีการเยื้องในบรรทัดเดียวหายไป ฉันเดาว่ามันจะหายไปเมื่อทำการวางเข้าไปฉันได้เพิ่มเข้าไปแล้ว
trichoplax

ทำงานในหลาม 3 มันบ่นเกี่ยวกับการเปรียบเทียบไม่มีเมื่อคำนวณ max (คะแนน) ดังนั้นผมจึงเปลี่ยนelse Noneไปelse 0ในบรรทัดก่อนหน้านี้ในการคำนวณคะแนนของคุณ หวังว่าจะทำให้ตรรกะของคุณไม่เปลี่ยนแปลง (ฉันไม่ได้ทำการเปลี่ยนแปลงโค้ดของคุณที่นี่ใน SE นอกเหนือจากการเพิ่มการเยื้องที่หายไป)
trichoplax

ทำงานในหลาม 3 ฉันได้คะแนนต่อไปนี้สำหรับคำตอบนี้: [1, 13085, 360102, 1, 73713, 1, 189, 1, 1, 193613, 34, 195718, 199, 8, 1, 60006, 66453, 2, 2, 53, 425206, 1, 4, 1, 1, 16, 153556, 1, 18134, 35655, 1, 4211684, 2, 1, 26451, 8, 1, 724635, 69242, 38469, 7135555 1, 25, 40017, 76064, 66478, 209365, 3925393]
trichoplax

ค่าเฉลี่ยเรขาคณิตของ 428.3750848244933
trichoplax

2

ROUS (ขนาดที่ผิดปกติของหนู), Java, คะแนน = 0

สิ่งนี้จะซ่อนสภาพแวดล้อมเพื่อตัดสินใจว่าจะไปที่ไหน เนื่องจากคอนโทรลเลอร์ Java ไม่ทำงานฉันไม่มีคะแนนสำหรับสิ่งนี้ สิ่งนี้จะได้ไกลมากหากพบผู้เคลื่อนย้ายมวลสารเพียงไม่กี่คนที่จะช่วยเหลือสิ่งนี้มีแนวโน้มที่จะสูญพันธุ์และทำให้คอนโทรลเลอร์ล้มเหลวเป็นครั้งคราว นี่อาจเป็นเพราะความจริงที่ว่าสภาพแวดล้อมทางธรรมชาตินั้นเป็น Fire Swamp

import java.awt.*;
import java.util.Map;

public class ROUS extends Player{

    private static final int NUMBER_OF_GENES = 33;
    private static final int GENE_SIZE = 3;
    private static final Point[] coords = new Point[]{
        new Point(-1, -1),
        new Point(-1, 0),
        new Point(-1, 1),
        new Point(0, -1),
        new Point(0, 1),
        new Point(1, -1),
        new Point(1, 0),
        new Point(1, 1)
    };

    public Point takeTurn(String dna, Map<Point, Integer> vision){
        Point[] table = decode(dna);
        int hash = hash(vision);
        return table[hash];
    }

    private int hash(Map<Point, Integer> surroundings) {
        return Math.abs(surroundings.hashCode()) % NUMBER_OF_GENES;
    }

    private Point[] decode(String dna) {
        Point[] result = new Point[NUMBER_OF_GENES];

        for (int i = 0; i < NUMBER_OF_GENES; i++){
            int p = Integer.parseInt(dna.substring(i * GENE_SIZE, (i + 1) * GENE_SIZE), 2);
            int x;
            int y;

            result[i] = coords[p];
        }
        return result;
    }
}

1
ตัวควบคุม Java ทำงานในขณะนี้
Martin Ender

3
ตอนแรกฉันคิดว่าคุณกำลังแสดงความเคารพต่อรัสเซียโบราณ แต่อย่างที่ปรากฎแก่ Rob Reiner

คะแนนต่ำสุดที่เป็นไปได้คือ 1
trichoplax

@trichoplax ... ขัดข้องคอนโทรลเลอร์ ...
TheNumberOne

โอ้ฉันเห็นแล้วนั่นเกิดขึ้นบ่อยครั้งพอที่คุณจะวิ่งไม่ไหว
trichoplax

2

Lookahead สีเทา (C ++, ~ 1.35)

อันนี้ทำได้ไม่ดีนักโดยเฉลี่ย แต่ในบางครั้งมันก็ทำได้ดีมาก น่าเสียดายที่เราได้รับคะแนนเฉลี่ยทางเรขาคณิต (1.35) และไม่ได้คะแนนสูงสุด (20077)

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

มันไม่ทำอะไรเลยอย่างแน่นอนที่จะพยายามจัดการกับดักพิเศษและฉันสงสัยว่าอาจเป็นความหายนะ (แม้ว่าฉันจะไม่ได้เพิ่มเครื่องมือใด ๆ ลงในคอนโทรลเลอร์เพื่อทดสอบทฤษฎีนี้)

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

coord_t colorTileRanker(dna_t d, view_t v) {
    const int COLOR_OFFSET = 0; // scores for each color (4 bits each)
    const int SELF_MUL_OFFSET = 96; // 2 bits for self-color multiplier
    const int MOVE_MUL_OFFSET = 98; // 2 bits for move-forward multiplier

    static const int gray2[4] = {0, 1, 3, 2};
    static const int gray3[8] = {0, 1, 3, 2, 7, 6, 4, 5};

    // bias factor table
    const int factorTable[4] = {0, 1, 2, 1};

    const int selfMul = factorTable[gray2[dnaRange(d, SELF_MUL_OFFSET, 2)]]*2 + 9;
    const int moveMul = factorTable[gray2[dnaRange(d, MOVE_MUL_OFFSET, 2)]] + 1;

    // scoring table for the color scores
    static const int scoreValue[8] = {0, 1, 2, 3, 4, 3, 2, 1};

    std::vector<coord_t> bestMoves;
    int bestScore = 0;

    for (int x = -1; x <= 1; x++) {
        for (int y = -1; y <= -1; y++) {
            const int color = v(x, y);
            if ((x || y) && (color >= 0)) {
                int score = 0;

                // score for the square itself
                score += selfMul*(scoreValue[gray3[dnaRange(d, COLOR_OFFSET + color*3, 3)]] - 2);

                // score for making forward progress;
                score += moveMul*(x + 1);

                // score for the resulting square's surrounding tiles
                for (int a = -1; a <= 1; a++) {
                    for (int b = -1; b <= 1; b++) {
                        const int color2 = v(x + a, y + b);
                        if (color2 >= 0) {
                            score += scoreValue[gray3[dnaRange(d, COLOR_OFFSET + color2*3, 3)]] - 2;
                        }
                    }
                }

                if (score > bestScore) {
                    bestMoves.clear();
                    bestScore = score;
                }
                if (score >= bestScore) {
                    bestMoves.push_back({x, y});
                }
            }
        }
    }

    if (bestMoves.empty()) {
        return {v.rng.rint(2), v.rng.rint(3) - 1};
    }
    return bestMoves[v.rng.rint(bestMoves.size())];
}

ในการวิ่งครั้งล่าสุดของฉันฉันได้รับคะแนน: 1 1 1 1 1 1 1 1 46 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 20077 1 1 1 2 2 1 1 1 1 1

ฉันหวังว่าฉันจะได้รับมากกว่าปี 20077 และน้อยกว่า 1s :)


1
การใช้รหัสสีเทาเป็นแนวคิดสีเทา! ;)
matovitch

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

2

C ++, TripleScore, คะแนน: 100 ~ 400

ก่อนอื่นคะแนนของฉันแตกต่างอย่างมากจากการวิ่งหลายครั้ง (ส่วนใหญ่เป็นเพราะจำนวน 1)

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

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

การให้คะแนนทิศทาง: TripleScore คำนวณคะแนนการเคลื่อนที่โดยใช้คะแนนย่อย 3 คะแนน:

  • คะแนนของสีของปลายทาง (ขึ้นอยู่กับ dna เช่นเดียวกับ colorScorePlayer)
  • คะแนนของการก้าวไปข้างหน้า (ขึ้นอยู่กับ DNA)
  • คะแนนสูงสุดของการย้ายไปข้างหน้าจากปลายทาง (คูณด้วยปัจจัยที่เก็บไว้ในดีเอ็นเอ)

เช่นเดียวกับคำตอบอื่น ๆ คะแนนขึ้นอยู่กับจำนวน 1 คะแนนที่ส่งคืนมาก

#define CHUNKSIZE 5 //We have 20 values so 5 bits/value
#define MAXVALUE 32 //2^CHUNKSIZE
#define AVGVALUE MAXVALUE/2

#define DNASEGMENT(dna, i) dnarange(dna, i*CHUNKSIZE, CHUNKSIZE)
#define DNA_COLOR 0
#define DNA_FORWARD 16
#define DNA_LOOKAHEAD 17

//Get the score for a specific move
int calcscore(dna_t dna, view_t view, int x, int y, bool final){
  if (view(x,y) == OUT_OF_BOUNDS){
    //We cant go there
    return -MAXVALUE;
  }
  //The score of the color
  int s = DNASEGMENT(dna, DNA_COLOR+view(x,y))-AVGVALUE;
  //The score of going forward
  s += x*DNASEGMENT(dna, DNA_FORWARD);

  //Get the children or not
  if (!final){
    int max=-MAXVALUE;
    int v;
    //Get the maximum score of the children
    for (int i=-1; i<2; ++i){
        v = calcscore(dna, view, x+1, y+i, true);
        if (v>max){
            max=v;
        }
    }
    //Apply dna factor to the childs score
    s += (max * DNASEGMENT(dna, DNA_LOOKAHEAD))/AVGVALUE;
  }
  return s;
}

coord_t TripleScore(dna_t dna, view_t view) {
  int maxscore = -100;
  int score;
  coord_t choices[5]; //Maximum 5 possible movements
  int maxchoices = 0;
  int zeroscore = calcscore(dna, view, 0, 0, false);

  //Go over all possible moves and keep a list of the highest scores
  for (int x=0; x<2; ++x){
    for (int y=-1; y<2; ++y){
        if (x | y){
            score = calcscore(dna, view, x, y, false);
            if (score > maxscore){
                maxscore = score;
                choices[0] = {x, y};
                maxchoices = 1;
            }else if (score == maxscore){
                choices[maxchoices++] = {x, y};
            }
        }
    }
    if (!x && maxscore <= zeroscore){
        //I will NOT bounce!
        maxscore = -100;
    }
  }

  return choices[view.rng.rint(maxchoices)];
}

2

Ruby - ProbabilisticScorePlayer

class ProbabilisticScorePlayer < Player
    Here = Vector2D.new( 0, 0)
    Forward = Vector2D.new( 1, 0)
    Right = Vector2D.new( 0, 1)
    Left = Vector2D.new( 0,-1)

    def vision_at(vec2d)
        v = @vision[vec2d.x+2][vec2d.y+2]
        v==-1?nil:v
    end

    def turn
        coords = [Forward]
        [Here,Forward].each{|x|
            [Here,Right,Left].each{|y|
                c = x+y
                if x!=y && vision_at c > -1
                  coords.push c if bit_at(vision_at c)==1
                  coords.push c if bit_at(vision_at(c+Forward)+16)==1
                  coords.push c if bit_at(vision_at(c+Right)+32)==1
                  coords.push c if bit_at(vision_at(c+Left)+48)==1
                  coords.push c if bit_at(vision_at(c+Forward+Right)+64)==1
                  coords.push c if bit_at(vision_at(c+Forward+Left)+80)==1
                end
            }
        }
        coords.sample(random: @rng)
    end
end

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

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


+1 สำหรับความคิดริเริ่ม คุณทำคะแนนแบบไหน

ยังไม่เคยทดสอบจริง ๆ ...
MegaTom

คุณลืมที่จะให้cค่าเริ่มต้นหรือไม่? ifมันดูเหมือนจะไม่ได้มีการกำหนดไว้เมื่อคุณใช้มันในครั้งแรก
Martin Ender

@ MartinBüttnerใช่ฉันลืมไปแล้ว ฉันจะแก้ไขทันที
MegaTom

ฉันไม่รู้ว่า Ruby เป็นอย่างดี แต่โค้ดของคุณไม่ทำงานภายใต้ Ruby2.1.5 coordsไม่ใช่รายการคุณใช้&&แทนandและลืมวงเล็บและแม้ว่าหลังจากแก้ไขทั้งหมดนี้แล้วคุณก็ไม่ได้ จำกัด ค่า RNG เพื่อให้คุณได้รับทิศทางที่ว่างเปล่า นี่เป็นโค้ดหลอกหรือมีบางอย่างที่ควรใช้กับภาษาถิ่น Ruby บางประเภทหรือไม่?

2

Java, RunningStar, คะแนน = 1817.050970291959 มากกว่า 1,000 เกม

บอทนี้ใช้การเข้ารหัสสีของRun-Bonusด้วยเทคนิคของStarPlayer

ปรับปรุง: แก้ไขจาวาคอนโทรลเลอร์

Scores: 6, 81533, 1648026, 14, 5, 38841, 1, 76023, 115162, 3355130, 65759, 59, 4, 235023, 1, 1, 1, 3, 2, 1, 1, 14, 50, 1, 306429, 68, 3, 35140, 2, 1, 196719, 162703, 1, 1, 50, 78233, 5, 5, 5209, 1, 2, 60237, 1, 14, 19710, 1528620, 79680, 33441, 58, 1, 4, 45, 105227, 11, 4, 40797, 2, 22594, 9, 2192458, 1954, 294950, 2793185, 4, 1, 1, 112900, 30864, 23839, 19330, 134178, 107920, 5, 122894, 1, 1, 2721770, 8, 175694, 25235, 1, 3109568, 4, 11529, 1, 8766, 319753, 5949, 1, 1856027, 19752, 3, 99071, 67, 198153, 18, 332175, 8, 1524511, 1, 159124, 1, 1917181, 2, 1, 10, 276248, 1, 15, 1, 52, 1159005, 43251, 1, 536150, 75864, 509655, 1126347, 250730, 1548383, 17, 194687, 27301, 2, 1, 207930, 621863, 6065, 443547, 1, 6, 1, 1, 1, 1, 556555, 436634, 25394, 2, 61335, 98076, 1, 190958, 2, 18, 67981, 3, 8, 119447, 1, 1, 1, 19, 28803, 23, 33, 60281, 613151, 1, 65, 20341, 799766, 476273, 105018, 357868, 3, 92325, 2062793, 18, 72097, 30229, 1, 1, 3, 610392, 1, 202149, 887122, 56571, 1, 77788, 61580, 4, 72535, 381846, 148682, 26676, 1, 210, 3556343, 212550, 650316, 33491, 180366, 1, 295685, 46255, 43295, 1006367, 63606, 1, 1, 1, 1, 3094617, 21, 10, 3, 1, 1, 14730, 1585801, 102, 2, 410353, 1570, 1, 17423, 1, 1849366, 5, 1, 357670, 1, 1, 1, 1, 89936, 349048, 15, 7, 6, 2, 121654, 1852897, 19, 1, 103275, 1, 1, 771797, 23, 19, 6700, 1, 135844, 2966847, 3, 2356708, 101515, 1, 17, 1, 996641, 22, 16, 657783, 171744, 9604, 1, 1335166, 1739537, 2365309, 1, 3378711, 11332, 3980, 182951, 609339, 8, 10, 1746504, 61895, 386319, 24216, 331130, 12193, 1, 284, 1, 2, 50369, 38, 8, 1, 1238898, 177435, 124552, 22370, 1418184, 20132, 6, 2, 730842, 1, 1341094, 141638, 534983, 1551260, 31508, 96196, 434312, 3012, 715155, 1, 276172, 214255, 1, 208948, 4, 1631942, 512293, 37, 64474, 1342713, 1, 132634, 13, 2, 61876, 1081704, 160301, 2, 488156, 2414109, 1809831, 5, 74904, 6, 11, 5, 1, 79856, 96, 35421, 229858, 238507, 3838897, 18, 44, 1, 1659126, 9, 33708, 12, 1, 758381, 162742, 256046, 3, 15, 142673, 70953, 58559, 6, 2, 1, 984066, 290404, 1072226, 66415, 4465, 924279, 48133, 319765, 519401, 1, 1, 1201037, 418362, 17022, 68, 213072, 37, 1039025, 1, 2, 6, 4, 45769, 1, 5, 1061838, 54614, 21436, 7149, 1, 1, 1, 35950, 2199045, 1, 379742, 3, 2008330, 238692, 181, 7, 140483, 92278, 214409, 5179081, 1, 1, 334436, 2, 107481, 1142028, 1, 31146, 225284, 1, 14533, 4, 3963305, 173084, 102, 1, 4732, 14, 1, 25, 11032, 224336, 2, 131110, 175764, 81, 5630317, 1, 42, 1, 89532, 621825, 2291593, 210421, 8, 44281, 4, 303126, 2895661, 2672876, 3, 436915, 21025, 1, 4, 49227, 1, 39, 3, 1, 103531, 256423, 2, 1600922, 15, 1, 2, 58933, 1114987, 1, 4, 3, 1, 1544880, 285673, 240, 2, 128, 214387, 3, 1327822, 558121, 5, 2718, 4, 1258135, 7, 37418, 2729691, 1, 346813, 385282, 2, 35674, 513070, 13, 1930635, 117343, 1929415, 52822, 203219, 1, 52407, 1, 1, 1, 3, 2, 37121, 175148, 136893, 2510439, 2140016, 437281, 53089, 40647, 37663, 2579170, 83294, 1597164, 206059, 1, 9, 75843, 773677, 50188, 12, 1, 1067679, 105216, 2452993, 1813467, 3279553, 280025, 121774, 62, 5, 113, 182135, 1, 16, 71853, 4, 557139, 37803, 228249, 6, 32420, 8, 410034, 73889, 1, 2, 96706, 48515, 1, 3, 1314561, 137, 966719, 692314, 80040, 85147, 75291, 1, 1, 30, 38119, 182723, 42267, 3836110, 22, 986685, 2, 37, 1, 3, 26, 43389, 2679689, 1, 1, 57365, 1, 2662599, 2, 72055, 1, 141247, 1, 1, 1122312, 1, 1080672, 4, 266211, 1, 34163, 1490610, 256341, 1, 627753, 32110, 1, 42468, 1, 10746, 1, 9, 1, 46, 1714133, 5, 117, 1, 104340, 218338, 151958, 122407, 211637, 223307, 57018, 74768, 582232, 2, 621279, 4, 1, 11, 196094, 1839877, 167117, 8, 42991, 2199269, 124676, 1, 1, 1, 5, 1, 1, 698083, 1, 76361, 1564154, 67345, 1398411, 9, 11, 105726, 1197879, 1, 2, 62740, 39, 2, 397236, 17057, 267647, 13, 57509, 22954, 1, 12, 747361, 4325650, 21425, 2160603, 144738, 1, 204054, 3113425, 6, 3019210, 30, 3359, 1, 89117, 489245, 1, 218068, 1, 1, 14718, 222722, 1, 1, 216041, 72252, 279874, 183, 89224, 170218, 1549362, 2, 1, 953626, 32, 130355, 30460, 121028, 20, 159273, 5, 2, 30, 1, 76215, 1654742, 2326439, 1, 53836, 1, 6, 4, 72327, 9, 285883, 1, 908254, 698872, 47779, 3, 2293485, 265788, 3766, 1, 1, 83151, 36431, 307577, 256891, 29, 1, 1, 1093544, 145213, 5, 2, 581319, 2911699, 1, 213061, 1359700, 2, 1, 343110, 1, 157592, 1708730, 1, 22703, 32075, 1, 1, 87720, 159221, 2313143, 10, 2266815, 2106917, 1345560, 3146014, 4, 551632, 1066905, 550313, 4069794, 1, 1406178, 38981, 1, 3, 1, 3039372, 241545, 35, 63325, 85804, 1365794, 2, 2143204, 48, 1, 99, 3225633, 7, 4074564, 1023899, 3209940, 2054326, 70880, 2, 1, 284192, 1944519, 84682, 2, 867681, 90022, 378115, 1, 15, 602743, 1337444, 131, 1, 229, 161445, 3, 2, 5591616, 195977, 92415, 637936, 142928, 1, 2310569, 923, 1, 230288, 1300519, 398529, 2233, 100261, 4323269, 81362, 37300, 1, 233775, 32277, 434139, 323797, 19214, 782633, 2881473, 1, 1, 9, 337016, 1, 515612, 44637, 17, 1, 25, 67758, 1737819, 16454, 30613, 692963, 62216, 222062, 344596, 3, 33782, 19, 180441, 23552, 20462, 70740, 10298, 109691, 1, 1729427, 33714, 1770930, 1, 1, 1, 1, 290766, 136688, 688231, 3250223, 30703, 1985963, 527128, 3, 226340, 195576, 30, 1, 3, 1, 793085, 5527, 5, 1, 2188429, 1327399, 5, 6192537, 1445186, 2478313, 2, 16892, 3, 1, 1, 15, 12, 1361157, 4, 1241684, 1, 45008, 1, 505095, 4037314, 14, 8, 1, 16740, 69906, 45, 1, 240949, 3975533, 212705, 2617552, 278884, 1, 24966, 958059, 231886, 22929, 4052071, 51259, 67791, 78739, 1, 165787, 67, 518191, 86923, 437, 1271004, 135941, 244766, 1, 1, 1, 1152745, 1, 3, 406365, 3847357, 476636, 135097, 304368, 8, 1578276, 1, 1, 375, 1, 1, 1298206, 1860743, 2, 35311, 834516, 421428, 2, 66629, 1, 309845, 398756, 33, 907277, 384475, 2267460, 1, 269300, 124525, 34399, 93584, 362186, 811260, 426109, 1, 1009323, 109986, 122181, 1, 1, 3626487, 11452, 1092410, 57233, 6, 2009226, 1, 83333, 4, 1338631, 79114, 2140249, 51813, 1118986, 43514, 1529365, 1, 101, 1, 1,
package game.players;

import java.awt.Point;
import java.util.*;

public class RunningStar extends Player{

    @Override
    public Point takeTurn(String genome, Map<Point, Integer> vision) {
        Map<Integer, Integer> squareCosts = decode(genome);
        Path path = astar(vision, squareCosts);
        return path.get(1);
    }

    private Path astar(Map<Point, Integer> vision, Map<Integer, Integer> squareCosts) {
        Set<Path> closed = new HashSet<>();
        PriorityQueue<Path> open = new PriorityQueue<>();
        open.add(new Path(new Point(0, 0), 0));
        while (!open.isEmpty()){
            Path best = open.remove();
            if (best.head().x == 2 || (best.head().x > 0 && (best.head().y == 2 || best.head().y == -2))){
                return best;
            }
            for (Path path : pathsAround(best, vision, squareCosts)){
                if (!closed.contains(path) && !open.contains(path)){
                    open.add(path);
                }
            }
            closed.add(best);
        }

        Path p = new Path(new Point(0,0), 0);
        return p.add(new Point((int)(random.nextDouble() * 3 - 1), (int)(random.nextDouble() * 3 - 1)), 0);
    }

    private List<Path> pathsAround(Path path, Map<Point, Integer> vision, Map<Integer, Integer> costs) {
        Point head = path.head();
        List<Path> results = new ArrayList<>();
        for (int i = -1; i <= 1; i++){
            for (int j = -1; j <= 1; j++){
                if (i == 0 && j == 0){
                    continue;
                }
                Point p = new Point(head.x + i, head.y + j);
                if (!vision.containsKey(p) || vision.get(p) == -1){
                    continue;
                }
                results.add(path.add(p, costs.get(vision.get(p))));
            }
        }
        return results;
    }

    private Map<Integer, Integer> decode(String genome) {
        int chunkLength = genome.length()/16;
        Map<Integer, Integer> costs = new HashMap<>();
        for (int i = 0; i < 16; i++){
            int runSize = 0;
            int cost = 0;
            for (int j = i * chunkLength; j < (i + 1) * chunkLength; j++){
                switch (genome.charAt(j)){
                    case '0':
                        runSize = 0;
                        break;
                    case '1':
                        cost += ++runSize;
                }
            }
            costs.put(i, cost);
        }
        return costs;
    }

    private class Path implements Comparable<Path>{

        Point head;
        Path parent;
        int length;
        int totalCost;

        private Path(){}

        public Path(Point point, int cost) {
            length = 1;
            totalCost = cost;
            head = point;
            parent = null;
        }

        public Point get(int index) {
            if (index >= length || index < 0){
                throw new IllegalArgumentException(index + "");
            }
            if (index == length - 1){
                return head;
            }
            return parent.get(index);
        }

        public Point head() {
            return head;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;

            Path path = (Path) o;

            if (!head.equals(path.head)) return false;

            return true;
        }

        @Override
        public int hashCode() {
            return head.hashCode();
        }

        @Override
        public int compareTo(Path o) {
            return totalCost - o.totalCost;

        }

        public Path add(Point point, int cost) {
            Path p = new Path();
            p.head = point;
            p.totalCost = totalCost + cost;
            p.length = length + 1;
            p.parent = this;
            return p;
        }
    }
}

2

LeapForward, Python 2

ไม่ได้เป็นเพียงแค่การทำลาย แต่มันเป็นความพยายามเพียงอย่างเดียวของฉันที่แสดง ok-ish

class LeapForward(Player):
  def __init__(self):
    Player.__init__(self)
    self.coords = [Coordinate( 1, 0),
                   Coordinate( 1,-1),
                   Coordinate( 1, 1)]
    self.n_moves = len(self.coords)

  def turn(self):
    notOKColors = [self.bit_chunk(4*n,4) for n in range(4,8)]
    notOKMap = [Coordinate(x-2,y-2) for x in range(0,5) for y in range(0,5) if self.vision[y][x] not in notOKColors]
    goTo = [c for c in self.coords if c in notOKMap]
    if not goTo:
      goTo = [Coordinate(1,0)]
    return random.choice(goTo)

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


อาจจะมีการเรียกมันว่า "RedQueen" :)
plannapus

1

Java - IAmARobotPlayer - คะแนน 3.7

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

package game.players;
import java.awt.*;
import java.util.Map;
public class IAmARobotPlayer extends Player{
    private static final Point[] possibleMoves = {new Point(1,-1), new Point(1,0), new Point(1,1), new Point(0,-1), new Point(0,1), new Point(1,-1), new Point(1,0), new Point(1,1)};
    private int isGood(int pos,Map<Point,Integer> vision, char[] genomeChar){
        int value = vision.get(new Point(1,pos));
        if(value ==-1){
            return 0;
        } else {
            return genomeChar[84+value]-'0';
        }
    }

    @Override
    public Point takeTurn(String genome, Map<Point, Integer> vision) {

        char[] genomeChar = genome.toCharArray();
        int situation = 4*isGood(1,vision,genomeChar)+2*isGood(0,vision,genomeChar)+1*isGood(-1,vision,genomeChar);
        int reaction = 4*(genomeChar[3*situation+0]-'0')+2*(genomeChar[3*situation+1]-'0')+1*(genomeChar[3*situation+2]-'0');
        return possibleMoves[reaction];

    }
}

ผลลัพธ์:

Individual scores: 1, 1, 332, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 47560, 15457, 1, 
Your final score is 3.7100115087136234

1

Cautious Specimens - C ++ - ให้คะแนนประมาณ 2030 กว่า 200 ตัว

สิ่งนี้ใช้ส่วนสี (16x4 บิต) ของการเข้ารหัส DNA จากBlind Faithแต่ทิ้งส่วนที่เหลือ (36 บิต) ของ DNA ที่ไม่ได้ใช้ทั้งหมด

การเข้ารหัสสำหรับสีคือ:

  • 10XX - สำหรับสี่เหลี่ยมที่ปลอดภัย;
  • 11XX - สำหรับกำลังสองที่ร้ายแรง และ
  • 0000 ถึง 0111 - สำหรับสี่เหลี่ยมกับดัก 8 ชนิด

โดยที่ X หมายถึงบิตที่ไม่ได้ใช้ ระบุว่ามีเพียง 2-of-16 สีเป็นกับดักที่จะใช้ทั้ง 4 บิต (และเฉพาะในกรณีที่กับดักถูกชดเชยซึ่งจะเป็น 8-of-9 ครั้ง) จากนั้นโดยทั่วไปจะมี 64 บิตที่ไม่ได้ใช้ - ทฤษฎีคือการกลายพันธุ์ที่ส่งผลกระทบต่อบิตใด ๆ ที่ไม่ได้ใช้เหล่านี้จะไม่ทำให้เกิดความเสียหายต่อจีโนมและความเสถียรนั้นดีกว่าโซลูชันแฟนซีใด ๆ ที่สามารถใช้บิตที่เหลือเหล่านั้นได้

ตัวอย่างจากนั้นใช้สิ่งนี้เพื่อวางแผนเส้นทางที่ปลอดภัยภายในตาราง 7x7 ที่มีศูนย์กลางอยู่ที่ตัวเอง (5x5 การมองเห็นของพวกเขาช่วยให้บวก 1 ตารางในแต่ละด้านเพื่อให้กับดักออฟเซ็ต) จัดลำดับความสำคัญการเคลื่อนย้ายระยะทางมากที่สุด

ในขั้นต้นฉันเริ่มสร้างในการตรวจสอบบางอย่างเพื่อให้แน่ใจว่าสีที่ชิ้นงานกำลังยืนอยู่นั้นไม่ตรงกับจีโนมและทำเครื่องหมายสีผิดพลาดใด ๆ ในรูปสี่เหลี่ยมของความปลอดภัย UNSURE (และสี่เหลี่ยมที่อยู่ติดกัน) - อย่างไรก็ตามมันเพิ่มนัยสำคัญ ภาวะแทรกซ้อนจากการได้กำไรเพียงเล็กน้อยถึงไม่มีเลยเมื่อเทียบกับการทำเครื่องหมายสี่เหลี่ยมเหล่านั้นว่าปลอดภัยและฆ่าตัวอย่างเพิ่มเติมบางส่วน ฉันจะกลับมาที่นี่ถ้าฉันมีเวลา

#include <initializer_list>
#include <vector>

enum class D { SAFE, LETHAL,TRAP_N, TRAP_NE, TRAP_E, TRAP_SE, TRAP_S, TRAP_SW, TRAP_W, TRAP_NW, UNSURE };
enum class X { SAFE, LETHAL, UNSURE };

inline void checkLocation( color_t color, D (&dna)[16], D check )
{
    if ( color != OUT_OF_BOUNDS && dna[color] == check )
        dna[color] = D::UNSURE;
}

inline void updateMapLocation( X (&map)[7][7], unsigned int x, unsigned int y, const X& safety ){
    if (        ( safety == X::LETHAL && map[x][y] != X::LETHAL )
            || ( safety == X::UNSURE && map[x][y] == X::SAFE ) )
        map[x][y] = safety;
}

inline unsigned int isSafePath( X (&map)[7][7], coord_t p )
{
    return map[p.x][p.y] == X::SAFE ? 1 : 0;
}
inline unsigned int isSafePath(X (&map)[7][7],coord_t p,coord_t q,coord_t r){
    if ( isSafePath( map,p ) )
        if ( isSafePath( map, q ) )
            return isSafePath( map, r );
    return 0;
}

inline unsigned int isSafeEast( X (&map)[7][7], coord_t p )
{
    if ( !isSafePath( map, p ) )
        return 0;
    if ( p.x == 6 )
        return 1;
    return isSafeEast(map,{p.x+1,p.y-1})
            +isSafeEast(map,{p.x+1,p.y+0})
            +isSafeEast(map,{p.x+1,p.y+1});
}

template<typename T> inline T max(T a,T b){return a>=b?a:b;}
template<typename T, typename... A> inline T max(T a,T b,A... c){return max(max(a,b),c...); }

coord_t cautiousSpecimins( dna_t d, view_t v ) {
    X map[7][7] = { { X::SAFE } };
    D dna[16] = { D::UNSURE };
    for ( color_t i = 0; i < 16; i++ )
    {
        if ( d[4*i] == 1 )
        {
            dna[i] = d[4*i + 1] == 1 ? D::LETHAL : D::SAFE;
        }
        else
        {
            switch ( dnarange( d, 4*i + 1, 3 ) )
            {
                case 0: dna[i] = D::TRAP_N; break;
                case 1: dna[i] = D::TRAP_NE; break;
                case 2: dna[i] = D::TRAP_E; break;
                case 3: dna[i] = D::TRAP_SE; break;
                case 4: dna[i] = D::TRAP_S; break;
                case 5: dna[i] = D::TRAP_SW; break;
                case 6: dna[i] = D::TRAP_W; break;
                case 7: dna[i] = D::TRAP_NW; break;
                default: dna[i] = D::UNSURE; break;
            }
        }
    }
    if ( v(-1, 0) != OUT_OF_BOUNDS )
        checkLocation( v( 0, 0), dna, D::LETHAL );

    if ( v(-1, 0) != OUT_OF_BOUNDS )
        for ( unsigned int y = 0; y < 7; ++ y )
            map[2][y] = X::LETHAL;

    if ( v(-2, 0) != OUT_OF_BOUNDS )
        for ( unsigned int x = 0; x < 2; ++x )
            for ( unsigned int y = 0; y < 7; ++ y )
                map[x][y] = X::LETHAL;

    if ( v( 0, 1) == OUT_OF_BOUNDS )
        for ( unsigned int x = 0; x < 7; ++x )
                map[x][4] = X::LETHAL;

    if ( v( 0, 2) == OUT_OF_BOUNDS )
        for ( unsigned int x = 0; x < 7; ++x )
            for ( unsigned int y = 5; y < 7; ++ y )
                map[x][y] = X::LETHAL;

    if ( v( 0,-1) == OUT_OF_BOUNDS )
        for ( unsigned int x = 0; x < 7; ++x )
                map[x][2] = X::LETHAL;

    if ( v( 0,-2) == OUT_OF_BOUNDS )
        for ( unsigned int x = 0; x < 7; ++x )
            for ( unsigned int y = 0; y < 2; ++ y )
                map[x][y] = X::LETHAL;

    checkLocation( v( 1, 1), dna, D::TRAP_SW );
    checkLocation( v( 1, 0), dna, D::TRAP_W  );
    checkLocation( v( 1,-1), dna, D::TRAP_NW );
    checkLocation( v( 0,-1), dna, D::TRAP_N  );
    checkLocation( v(-1,-1), dna, D::TRAP_NE );
    checkLocation( v(-1, 0), dna, D::TRAP_E  );
    checkLocation( v(-1, 1), dna, D::TRAP_SE );
    checkLocation( v( 0, 1), dna, D::TRAP_S  );

    for ( int x = 1; x <= 5; ++x )
    {
        for ( int y = 1; y <= 5; ++y )
        {
            switch( dna[v(x-3,y-3)] )
            {
                case D::LETHAL : updateMapLocation( map, x+0, y+0, X::LETHAL ); break;
                case D::TRAP_N : updateMapLocation( map, x+0, y+1, X::LETHAL ); break;
                case D::TRAP_NE: updateMapLocation( map, x+1, y+1, X::LETHAL ); break;
                case D::TRAP_E : updateMapLocation( map, x+1, y+0, X::LETHAL ); break;
                case D::TRAP_SE: updateMapLocation( map, x+1, y-1, X::LETHAL ); break;
                case D::TRAP_S : updateMapLocation( map, x+0, y-1, X::LETHAL ); break;
                case D::TRAP_SW: updateMapLocation( map, x-1, y-1, X::LETHAL ); break;
                case D::TRAP_W : updateMapLocation( map, x-1, y+0, X::LETHAL ); break;
                case D::TRAP_NW: updateMapLocation( map, x-1, y+1, X::LETHAL ); break;
//              case D::UNSURE : updateMapLocation( map, x+0, y+0, X::SAFE );
//                               updateMapLocation( map, x+0, y+1, X::UNSURE );
//                               updateMapLocation( map, x+1, y+1, X::UNSURE );
//                               updateMapLocation( map, x+1, y+0, X::UNSURE );
//                               updateMapLocation( map, x+1, y-1, X::UNSURE );
//                               updateMapLocation( map, x+0, y-1, X::UNSURE );
//                               updateMapLocation( map, x-1, y-1, X::UNSURE );
//                               updateMapLocation( map, x-1, y+0, X::UNSURE );
//                               updateMapLocation( map, x-1, y+1, X::UNSURE );
//                               break;
                default        : break;
            }           
        }
    }

    unsigned int north = isSafeEast(map,{4,4});
    unsigned int east  = isSafeEast(map,{4,3});
    unsigned int south = isSafeEast(map,{4,2});
    unsigned int mx    = max( north, east, south );
    unsigned int sz;
    std::vector<coord_t> dir;
    if ( mx > 0 )
    {
        if ( north == mx ) dir.push_back( {+1,+1} );
        if ( east  == mx ) dir.push_back( {+1,+0} );
        if ( south == mx ) dir.push_back( {+1,-1} );

        return dir[v.rng.rint(dir.size())];
    }


    north = isSafePath(map,{4,4},{5,5},{5,6})
            + isSafePath(map,{4,4},{4,5},{5,6});
    south = isSafePath(map,{4,2},{5,1},{5,0})
            + isSafePath(map,{4,2},{4,1},{5,0});
    mx = max( north, south );
    if ( mx > 0 )
    {
        if ( north == mx ) dir.push_back( {+1,+1} );
        if ( south == mx ) dir.push_back( {+1,-1} );

        return dir[v.rng.rint(dir.size())];
    }

    north = isSafePath(map,{3,4},{4,5},{5,6});
    south = isSafePath(map,{3,2},{4,1},{5,0});
    mx = max( north, south );
    if ( mx > 0 )
    {
        if ( north == mx ) dir.push_back( {+0,+1} );
        if ( south == mx ) dir.push_back( {+0,-1} );

        return dir[v.rng.rint(dir.size())];
    }

    north = 2*isSafePath(map,{4,4},{4,5},{4,6})
            + 1*isSafePath(map,{4,4},{3,5},{4,6});
    south = 2*isSafePath(map,{4,2},{4,1},{4,0})
            + 1*isSafePath(map,{4,2},{3,1},{4,0});
    mx = max( north, south );
    if ( mx > 0 )
    {
        if ( north == mx ) dir.push_back( {+1,+1} );
        if ( south == mx ) dir.push_back( {+1,-1} );

        return dir[v.rng.rint(dir.size())];
    }

    north = isSafePath(map,{3,4},{4,5},{4,6})
            + isSafePath(map,{3,4},{3,5},{4,6});
    south = isSafePath(map,{3,2},{4,1},{4,0})
            + isSafePath(map,{3,2},{3,1},{4,0});
    mx = max( north, south );
    if ( mx > 0 )
    {
        if ( north == mx ) dir.push_back( {+0,+1} );
        if ( south == mx ) dir.push_back( {+0,-1} );

        return dir[v.rng.rint(dir.size())];
    }

    north = isSafePath(map,{2,4},{3,5},{4,6});
    south = isSafePath(map,{2,2},{3,1},{4,0});
    mx = max( north, south );
    if ( mx > 0 )
    {
        if ( north == mx ) dir.push_back( {-1,+1} );
        if ( south == mx ) dir.push_back( {-1,-1} );

        return dir[v.rng.rint(dir.size())];
    }

    north = isSafePath(map,{3,4},{3,5},{3,6})
            + isSafePath(map,{3,4},{2,5},{3,6});
    south = isSafePath(map,{3,2},{3,1},{3,0})
            + isSafePath(map,{3,2},{2,1},{3,0});
    mx = max( north, south );
    if ( mx > 0 )
    {
        if ( north == mx ) dir.push_back( {+0,+1} );
        if ( south == mx ) dir.push_back( {+0,-1} );

        return dir[v.rng.rint(dir.size())];
    }

    north = isSafePath(map,{2,4},{3,5},{4,6});
    south = isSafePath(map,{2,2},{3,1},{4,0});
    mx = max( north, south );
    if ( mx > 0 )
    {
        if ( north == mx ) dir.push_back( {-1,+1} );
        if ( south == mx ) dir.push_back( {-1,-1} );

        return dir[v.rng.rint(dir.size())];
    }

    return {-1,-1};
}

คะแนนตัวอย่าง:

Scores: 421155 2 129418 71891 90635 1 211 1111987 29745 7 2200750 41793 50500 45 2012072 2 485698 1 110061 1554720 210308 249336 2 1 262110 17 3 19 1719139 23859 45118 3182784 318 2 1 15572 14 2822954 18 11 2 3 15954 1331392 2296280 135015 1 360826 1 692367 4 244775 4814645 3749144 3 1 660000 1 11 3688002 3920202 3428464 123053 1 243520 86 9 6 289576 195966 549120 220918 9 1 43 71046 5213 118177 150678 54639 3 200839 1 3 6 1978584 1514393 119502 1 1 137695 184889 337956 1 1 441405 133902 991 1 4137428 1 1427115 3340977 1 2 1 55559 11 1 94886 30270 1 6 3 69394 264780 6877 47758 128568 1 116672 130539 163747 96253 1 2654354 1 141 58212 1613661 27 9504 1 2474022 843890 1 59 3110814 2353731 150296 313748 2590241 6 5970407 1434171 2 334715 141277 1 56810 2964306 51544 61973 715590 1 106 900384 50948 2 34652 108096 391006 1 2969764 47625 1 24 30481 44 8 1 18 2094036 106461 3080432 75 620651 16 71730 282145 275031 17 1 8 15 121731 18 2 1 1 495868 3252390 6 1 63712 7 3733149 13380 1 1
Geometric mean score: 2030.17

คะแนนสูงสุดระหว่างการทดสอบ: 8,150,817 ชิ้นงานที่บันทึกไว้


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

ฉันกำลังทำ 2,000 วิ่งสำหรับเรื่องนี้ ... หลังจาก 900 ครั้งแรกค่าเฉลี่ยดูเหมือนว่าจะอยู่ที่ประมาณ 600 ซึ่งค่อนข้างไกลจากปี 2000 คุณคิดว่าจะอ่านมันอีกหรือเปล่าเพื่อดูว่าในปี 2000 แค่บังเอิญ
Martin Ender
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.