Lab Rat Race: một bài tập về thuật toán di truyền


113

Đây là Thử thách nửa đêm # 3. Chủ đề: Thuật toán di truyền

Thử thách này là một chút thử nghiệm. Chúng tôi muốn xem những gì chúng tôi có thể làm, thách thức khôn ngoan, với các thuật toán di truyền. Không phải mọi thứ có thể là tối ưu, nhưng chúng tôi đã cố gắng hết sức để làm cho nó có thể truy cập được. Nếu điều này diễn ra, ai biết những gì chúng ta có thể thấy trong tương lai. Có lẽ một vị vua di truyền của Hill?

Thông số kỹ thuật khá dài! Chúng tôi đã cố gắng tách thông số kỹ thuật thành Cơ bản - mức tối thiểu bạn cần biết để bắt đầu chơi với khung và gửi câu trả lời - và Chi tiết Gory - thông số đầy đủ, với tất cả chi tiết về bộ điều khiển, dựa trên đó bạn có thể viết của riêng bạn.
Nếu bạn có bất kỳ câu hỏi nào, hãy tham gia trò chuyện với chúng tôi!

Bạn là một nhà nghiên cứu trong tâm lý học hành vi. Đó là tối thứ sáu và bạn và đồng nghiệp của bạn quyết định vui chơi và sử dụng chuột trong phòng thí nghiệm của bạn cho một cuộc đua chuột nhỏ. Trên thực tế, trước khi chúng ta quá gắn bó với chúng, hãy gọi chúng là mẫu vật .

Bạn đã thiết lập một đường đua nhỏ cho các mẫu vật và để làm cho nó thú vị hơn, bạn đã đặt một vài bức tường và bẫy và dịch chuyển tức thời trên đường đua. Bây giờ, mẫu vật của bạn vẫn là chuột ... họ không biết bẫy hay dịch chuyển tức thời là gì. Tất cả những gì họ nhìn thấy là một số thứ trong các màu sắc khác nhau. Họ cũng không có bất kỳ loại bộ nhớ nào - tất cả những gì họ có thể làm là đưa ra quyết định dựa trên môi trường hiện tại. Tôi đoán chọn lọc tự nhiên sẽ chọn ra những mẫu vật biết cách tránh bẫy từ những loài không (cuộc đua này sẽ mất một lúc ...). Hãy để cuộc chơi bắt đầu!

Hình ảnh ví dụ của bảng đang sử dụng

† 84.465 mẫu vật đã bị tổn hại khi thực hiện thử thách này.

Những thứ cơ bản

Đây là một trò chơi một người chơi (bạn và đồng nghiệp của bạn không muốn trộn lẫn các quần thể để mỗi người xây dựng đường đua của riêng mình). Đường đua là một lưới hình chữ nhật, cao 15 ô và rộng 50 ô. Bạn bắt đầu với 15 mẫu trên các ô ngẫu nhiên (không nhất thiết phải khác biệt) ở cạnh trái (trong đó x = 0 ). Mẫu vật của bạn nên cố gắng đạt được mục tiêu là bất kỳ ô nào tại x ≥ 490 y ≤ 14 (mẫu vật có thể vượt quá đường đua sang phải). Mỗi lần điều này xảy ra, bạn sẽ nhận được một điểm. Bạn cũng bắt đầu trò chơi với 1 điểm. Bạn nên cố gắng tối đa hóa điểm của mình sau 10.000 lượt.

Nhiều mẫu vật có thể chiếm cùng một tế bào và sẽ không tương tác.

Ở mỗi lượt, mỗi mẫu vật nhìn thấy một lưới 5x5 của môi trường xung quanh (với chính nó ở giữa). Mỗi tế bào của lưới sẽ chứa một màu -1để 15. -1đại diện cho các tế bào nằm ngoài giới hạn. Mẫu vật của bạn chết nếu nó di chuyển ra khỏi giới hạn. Đối với các màu khác, chúng đại diện cho các ô trống, bẫy, tường và dịch chuyển tức thời. Nhưng mẫu vật của bạn không biết màu nào đại diện cho cái gì và bạn cũng không. Có một số hạn chế mặc dù:

  • 8 màu sẽ đại diện cho các ô trống.
  • 4 màu sẽ đại diện cho một dịch chuyển tức thời. Một dịch chuyển tức thời sẽ gửi mẫu đến một ô nhất định trong vùng lân cận 9x9 của nó. Phần bù này sẽ giống nhau cho tất cả các dịch chuyển tức thời cùng màu.
  • 2 màu sẽ đại diện cho các bức tường. Di chuyển vào một bức tường cũng giống như đứng yên.
  • 2 màu sẽ đại diện cho một cái bẫy. Một cái bẫy chỉ ra rằng một trong 9 ô trong vùng lân cận của nó là gây chết người (không nhất thiết phải là tế bào bẫy). Phần bù này sẽ giống nhau cho tất cả các bẫy cùng màu.

Bây giờ, về lựa chọn tự nhiên đó ... mỗi mẫu vật có một bộ gen, đó là một số có 100 bit. Mẫu vật mới sẽ được tạo ra bằng cách lai chéo hai mẫu vật hiện có, và sau đó làm biến đổi bộ gen một chút. Mẫu vật càng thành công, cơ hội sinh sản càng lớn.

Vì vậy, đây là nhiệm vụ của bạn: Bạn sẽ viết một hàm duy nhất, nhận đầu vào là lưới 5x5 màu mà mẫu vật nhìn thấy, cũng như bộ gen của nó. Hàm của bạn sẽ trả về một di chuyển (Δx, y) cho mẫu vật, trong đó x và Δy sẽ là một trong số đó {-1, 0, 1}. Bạn không được lưu lại bất kỳ dữ liệu nào giữa các lệnh gọi hàm. Điều này bao gồm sử dụng các trình tạo số ngẫu nhiên của riêng bạn. Chức năng của bạn sẽ được cung cấp RNG hạt giống mà bạn có thể sử dụng miễn phí theo ý muốn.

Điểm của bài nộp của bạn sẽ là giá trị trung bình hình học của số điểm trên 50 bài hát ngẫu nhiên. Chúng tôi đã phát hiện ra rằng điểm số này có thể có một chút sai lệch. Do đó, những điểm số này sẽ là sơ bộ . Một khi thách thức này kết thúc, thời hạn sẽ được công bố. Khi hết thời hạn, 100 bảng sẽ được chọn ngẫu nhiên và tất cả các bài nộp sẽ được giải cứu trên 100 bảng này. Vui lòng đặt một số điểm ước tính trong câu trả lời của bạn, nhưng chúng tôi sẽ tự chấm điểm mỗi lần gửi để đảm bảo không có ai gian lận.

Chúng tôi đã cung cấp các chương trình điều khiển trong một số ít ngôn ngữ. Hiện tại, bạn có thể viết bài gửi của mình bằng Python (2 hoặc 3), Ruby , C ++ , C # hoặc Java . Bộ điều khiển tạo ra các bảng, chạy trò chơi và cung cấp một khung cho thuật toán di truyền. Tất cả bạn phải làm là cung cấp chức năng di chuyển.

Đợi đã, vậy chính xác thì tôi làm gì với bộ gen?

Thách thức là tìm ra điều đó!

Vì các mẫu vật không có bộ nhớ, tất cả những gì bạn có trong một lượt cho trước là một lưới màu 5x5 không có ý nghĩa gì với bạn. Vì vậy, bạn sẽ phải sử dụng bộ gen để đạt được mục tiêu. Ý tưởng chung là bạn sử dụng các phần của bộ gen để lưu trữ thông tin về màu sắc hoặc bố cục lưới và bot của bạn dựa trên quyết định của nó về thông tin bổ sung được lưu trữ trong bộ gen.

Bây giờ, tất nhiên bạn không thể thực sự lưu trữ bất cứ thứ gì ở đó bằng tay. Vì vậy, thông tin thực tế được lưu trữ ở đó ban đầu sẽ hoàn toàn ngẫu nhiên. Nhưng thuật toán di truyền sẽ sớm chọn ra những mẫu vật có bộ gen chứa thông tin đúng trong khi tiêu diệt những mẫu có thông tin sai. Mục tiêu của bạn là tìm một ánh xạ từ các bit genome và trường nhìn của bạn để di chuyển, cho phép bạn nhanh chóng tìm thấy đường dẫn đến mục tiêu và luôn phát triển thành chiến lược chiến thắng.

Điều này cần đủ thông tin để giúp bạn bắt đầu. Nếu bạn muốn, bạn có thể bỏ qua phần tiếp theo và chọn bộ điều khiển bạn chọn từ danh sách các bộ điều khiển ở phía dưới (cũng chứa thông tin về cách sử dụng bộ điều khiển cụ thể đó).

Đọc tiếp nếu bạn muốn tất cả ...

Chi tiết Gory

Thông số kỹ thuật này đã hoàn tất. Tất cả các bộ điều khiển phải thực hiện các quy tắc này.

Tất cả sự ngẫu nhiên sử dụng một phân phối thống nhất, trừ khi có quy định khác.

Theo dõi thế hệ:

  • Đường đua là một lưới hình chữ nhật, rộng X = 53 ô và cao Y = 15 ô. Các ô có x ≥ 49các ô mục tiêu (trong đó x là không dựa trên).
  • Mỗi ô có một màu duy nhất và có thể hoặc không gây chết - các ô không gây chết trừ khi được chỉ định bởi một trong các loại ô bên dưới.
  • 16 màu ô khác nhau, được dán nhãn từ 0đến 15, ý nghĩa của chúng sẽ thay đổi từ trò chơi này sang trò chơi khác. Ngoài ra, -1đại diện cho các tế bào nằm ngoài giới hạn - đây là những tế bào gây chết người .
  • Chọn 8 màu ngẫu nhiên . Đây sẽ là các ô trống (không có tác dụng).
  • Chọn thêm 4 màu ngẫu nhiên . Đây là những người dịch chuyển tức thời. Đối với hai trong số các màu này, chọn độ lệch khác không trong vùng lân cận 9x9 (từ (-4, -4) đến (4,4) ngoại trừ (0,0)). Đối với hai màu còn lại, đảo ngược các độ lệch đó. Nếu một mẫu vật bước trên thiết bị dịch chuyển tức thời, nó sẽ được di chuyển ngay lập tức bởi phần bù đó.
  • Chọn thêm 2 màu ngẫu nhiên . Đây là những cái bẫy. Đối với mỗi màu này, chọn một phần bù trong vùng lân cận 3x3 (từ (-1, -1) đến (1,1)). Một cái bẫy chỉ ra rằng tế bào ở phần bù đó gây chết người . Lưu ý: Bản thân tế bào bẫy không nhất thiết gây chết người.
  • Các 2 màu còn lại là bức tường, mà cản trở phong trào. Cố gắng di chuyển lên một tế bào trên tường sẽ biến việc di chuyển thành đứng yên. Các tế bào tường tự gây chết người .
  • Đối với mỗi ô không có mục tiêu của lưới, chọn một màu ngẫu nhiên. Đối với mỗi tế bào mục tiêu chọn ngẫu nhiên trống màu.
  • Đối với mỗi ô ở cạnh trái của bản nhạc, hãy xác định liệu mục tiêu có thể đạt được trong vòng 100 lượt hay không (theo quy tắc thứ tự lần lượt bên dưới). Nếu vậy, ô này là một ô bắt đầu được chấp nhận . Nếu có ít hơn 10 ô bắt đầu, hãy loại bỏ bản nhạc và tạo một ô mới.
  • Tạo 15 mẫu vật, mỗi mẫu có bộ gen ngẫu nhiên và 0 tuổi . Đặt từng mẫu trên một ô bắt đầu ngẫu nhiên.

Đặt hàng lần lượt:

  1. Các bước sau đây sẽ được thực hiện, theo thứ tự, cho từng mẫu. Các mẫu vật không tương tác hoặc nhìn thấy nhau, và có thể chiếm cùng một tế bào.
    1. Nếu tuổi của mẫu vật là 100 , nó sẽ chết. Nếu không, tăng tuổi của nó lên 1.
    2. Mẫu vật được đưa ra trường nhìn của nó - một lưới màu 5x5, tập trung vào mẫu vật - và trả về một bước di chuyển trong vùng lân cận 3x3 của nó. Di chuyển ngoài phạm vi này sẽ khiến bộ điều khiển chấm dứt.
    3. Nếu ô mục tiêu là một bức tường, thì di chuyển được thay đổi thành (0,0).
    4. Nếu ô mục tiêu là một dịch chuyển tức thời, mẫu vật được di chuyển bằng phần bù của dịch chuyển tức thời. Lưu ý: Bước này được thực hiện một lần , không lặp lại.
    5. Nếu tế bào hiện đang bị chiếm giữ bởi mẫu vật (có khả năng sau khi sử dụng một dịch chuyển tức thời) sẽ gây chết mẫu. Đây là mẫu vật duy nhất có thời gian chết (ngoài bước 1.1. Ở trên). Cụ thể, một mẫu vật mới sinh ra trên một tế bào gây chết người sẽ không chết ngay lập tức, nhưng có cơ hội di chuyển khỏi tế bào nguy hiểm trước tiên.
    6. Nếu mẫu vật chiếm một ô mục tiêu, ghi điểm, di chuyển mẫu đến một ô bắt đầu ngẫu nhiên và đặt lại tuổi của nó về 0.
  2. Nếu có ít hơn hai mẫu vật còn lại trên bảng, trò chơi kết thúc.
  3. Tạo 10 mẫu vật mới với tuổi 0 . Mỗi bộ gen được xác định (cá nhân) theo các quy tắc nhân giống dưới đây. Đặt từng mẫu trên một ô bắt đầu ngẫu nhiên.

Chăn nuôi:

  • Khi một mẫu vật mới được tạo ra, chọn ngẫu nhiên hai cha mẹ khác nhau , với sự thiên vị đối với mẫu vật đã tiến xa hơn về phía bên phải. Xác suất của mẫu vật được chọn tỷ lệ thuận với điểm thể lực hiện tại của nó . Điểm thể lực của mẫu vật là

    1 + x + 50 * số lần đạt được mục tiêu

    Trong đó x là chỉ số ngang dựa trên 0. Mẫu vật được tạo ra trong cùng một lượt không thể được chọn làm cha mẹ.

  • Trong hai cha mẹ, chọn một ngẫu nhiên để lấy bit gen đầu tiên từ đó.

  • Bây giờ khi bạn đi dọc theo bộ gen, chuyển đổi cha mẹ với xác suất 0,05 và tiếp tục lấy bit từ cha mẹ kết quả.
  • Đột biến bộ gen được lắp ráp hoàn chỉnh: với mỗi bit, lật nó với xác suất 0,01 .

Ghi điểm:

  • Một trò chơi kéo dài 10.000 lượt.
  • Người chơi bắt đầu trò chơi với 1 điểm (để cho phép sử dụng giá trị trung bình hình học).
  • Mỗi khi mẫu vật đạt được mục tiêu, người chơi sẽ ghi được một điểm.
  • Hiện tại, mỗi lần gửi của người chơi sẽ được chạy trong 50 trò chơi, mỗi trò chơi có một bản nhạc ngẫu nhiên khác nhau.
  • Cách tiếp cận trên dẫn đến nhiều phương sai hơn mong muốn. Một khi thách thức này kết thúc, thời hạn sẽ được công bố. Khi hết thời hạn, 100 bảng sẽ được chọn ngẫu nhiên và tất cả các bài nộp sẽ được giải cứu trên 100 bảng này.
  • Điểm tổng thể của người chơi là giá trị trung bình hình học của điểm số của các trò chơi cá nhân này.

Bộ điều khiển

Bạn có thể chọn bất kỳ bộ điều khiển nào sau đây (vì chúng tương đương về chức năng). Chúng tôi đã kiểm tra tất cả trong số chúng, nhưng nếu bạn phát hiện ra lỗi, muốn cải thiện mã hoặc hiệu suất hoặc thêm một tính năng như đầu ra đồ họa, vui lòng gửi vấn đề hoặc gửi yêu cầu kéo trên GitHub! Bạn cũng được hoan nghênh thêm bộ điều khiển mới bằng ngôn ngữ khác!

Nhấp vào tên ngôn ngữ cho mỗi bộ điều khiển để đến đúng thư mục trên GitHub, trong đó có một README.mdhướng dẫn sử dụng chính xác.

Nếu bạn không quen thuộc với git và / hoặc GitHub, bạn có thể tải xuống toàn bộ kho lưu trữ dưới dạng ZIP từ trang trước (xem nút trong thanh bên).

Con trăn

  • Được kiểm tra kỹ lưỡng nhất. Đây là thực hiện tham khảo của chúng tôi.
  • Hoạt động với cả Python 2.6+ và Python 3.2+!
  • Nó rất chậm. Chúng tôi khuyên bạn nên chạy nó với PyPy để tăng tốc đáng kể.
  • Hỗ trợ đầu ra đồ họa bằng cách sử dụng pygamehoặc tkinter.

Hồng ngọc

  • Đã thử nghiệm với Ruby 2.0.0. Nên làm việc với các phiên bản mới hơn.
  • Nó cũng khá chậm, nhưng Ruby có thể thuận tiện cho việc tạo ra một ý tưởng cho bài nộp.

C ++

  • Yêu cầu C ++ 11.
  • Tùy chọn hỗ trợ đa luồng.
  • Cho đến nay bộ điều khiển nhanh nhất trong bó.

C #

  • Sử dụng LINQ, vì vậy nó yêu cầu .NET 3.5.
  • Khá chậm.

Java

  • Không đặc biệt chậm. Không đặc biệt nhanh.

Bảng xếp hạng sơ bộ

Tất cả các điểm số là sơ bộ. Tuy nhiên, nếu một cái gì đó là sai hoặc lỗi thời, xin vui lòng cho tôi biết. Trình ví dụ của chúng tôi được liệt kê để so sánh, nhưng không tranh cãi.

  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

Tín dụng

Thử thách này là một nỗ lực hợp tác lớn:

  • Nathan Merril: Đã viết trình điều khiển Python và Java. Biến khái niệm thử thách từ Vua đồi thành Cuộc đua chuột.
  • trichoplax: Chơi. Làm việc trên bộ điều khiển Python.
  • frageum: Đã viết trình điều khiển C ++.
  • VisualMelon: Đã viết trình điều khiển C #.
  • Martin Büttner: Khái niệm. Đã viết trình điều khiển Ruby. Chơi đùa Làm việc trên bộ điều khiển Python.
  • T Áp-ra-ham: Chơi đùa. Đã kiểm tra Python và xem xét bộ điều khiển C # và C ++.

Tất cả những người dùng ở trên (và có lẽ một vài người nữa tôi đã quên) đã góp phần vào thiết kế tổng thể của thử thách.

Cập nhật bộ điều khiển C ++

Nếu bạn đang sử dụng C ++ với Visual Studio và đa luồng, bạn sẽ nhận được bản cập nhật mới nhất do lỗi với trình tạo số ngẫu nhiên của chúng cho phép tạo bảng trùng lặp.


3
Không ai có thể tạo ra một thuật toán di truyền để tìm ra thuật toán di truyền tối ưu cho vấn đề này?
mbomb007

1
@ anon3202 Vâng, điều đó tất nhiên sẽ cung cấp cho bạn thêm thông tin về bố cục theo dõi vì bạn có thể đánh giá được bạn đang ở đâu. Về cơ bản, chúng tôi muốn giữ giao diện cho bot đơn giản và biến nó thành vấn đề hoàn toàn cục bộ, nơi bạn sẽ cần bộ gen để tìm hiểu giải pháp địa phương nào có lợi nhất cho tiến trình toàn cầu của bạn.
Martin Ender

1
@matovitch Xem phần 5 của phần Đặt hàng lần lượt của Chi tiết Gory (thông số đầy đủ):'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
Tôi đã điều chỉnh mã C ++ để hiển thị trung bình mẫu, stddev, stderr và 99% conf-distance, (trước log / exp "hình học" của bạn) và thực hiện một khám phá đáng kinh ngạc. Câu trả lời "Niềm tin mù quáng" có "Giá trị trung bình mẫu là 116529 + - 2,78337e + 010 (99%) stddev = 7,77951e + 010" sau 50 lần chạy. "Giảm khoảng tin cậy xuống 50% hoàn toàn không cải thiện vấn đề. Trung bình hình học là stabler mặc dù: "Trung bình của 159.458 + - 117262 (99%) stddev = 32.6237" (Trước khi cập nhật 800 điểm của anh ấy)
Vịt Mooing

1
Tôi đã thực hiện một số thử nghiệm với tốc độ đột biến và tôi nghĩ rằng thử thách sẽ thú vị hơn (và các bộ điều khiển sẽ chạy nhanh hơn rất nhiều) nếu xác suất được nâng từ 0,01 lên 0,27, cho phép DNA chỉ có 10% cơ hội đi qua đột biến không thay đổi thay vì 37% với giá trị hiện tại. Điều này tránh các vụ nổ dân số vô lý (do đó tiết kiệm rất nhiều thời gian tính toán) và ngăn ngừa rất nhiều thất bại do không đủ sự đa dạng. Điểm số cá nhân thấp hơn, nhưng vì nhiều lượt chạy tạo ra người chiến thắng, trung bình toàn cầu có xu hướng tăng.

Câu trả lời:


37

Niềm tin mù quáng - C ++ - dường như đạt số điểm trên 800 (!) Trên 2000 lượt chạy

Bộ gen mã hóa màu sắc với phản hồi theo dõi bí ẩn và răn đe đập tường hiệu quả

#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";
}

Kết quả mẫu:

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

Dựa trên bài kiểm tra dài vô tình của frageum, tôi cho rằng 2000 lần chạy là đủ để tạo ra kết quả ổn định chấp nhận được.
Vì bộ điều khiển đã sửa đổi của tôi hiển thị giá trị trung bình hình học hiện tại sau mỗi lần chạy, tôi đã xác nhận một cách trực quan rằng biến thể trong 50 lần chạy gần nhất là tương đối nhỏ (+ - 10 điểm).

Điều gì làm cho những sinh vật này đánh dấu

Thay vì đưa ra các ưu tiên như nhau cho mỗi màu, tôi xem xét các giá trị có thể sau:

  1. tốt -> con chuột nghĩ rằng nó có thể đi đến đó an toàn
  2. xấu -> con chuột sẽ không đến đó
  3. bẫy -> chuột sẽ xem xét vị trí của bẫy xấu và tế bào chỉ ra bẫy tốt .
    Mặc dù tôi quá lười để đổi tên nó, nhưng đây là một "máy dò nguy hiểm" chỉ ra vị trí (được cho là) ​​của một cái bẫy thực sự, một bức tường, một người dịch chuyển đang chờ để đưa kẻ lang thang không nghi ngờ đến một nơi khó chịu hoặc thậm chí là lối vào của một người chết -kết thúc. Nói tóm lại, một nơi mà một con chuột khôn ngoan thà không đi.

gen tốt hay xấu chỉ mất 2 bit để lưu trữ (ví dụ 1110), nhưng bẫy yêu cầu 4 bit ( 0ttttrong đó tttđại diện cho một trong 8 vị trí "nguy hiểm" có thể).

Để giữ cho mỗi gen nhất quán (nghĩa là giữ nguyên ý nghĩa của nó sau khi được trộn vào một bộ gen hoàn toàn khác nhau, đòi hỏi mỗi gen mã hóa màu phải ở một vị trí cố định), tất cả các giá trị được mã hóa trên 4 bit (vì vậy, mã hóa tốt11xxxấu10xx), với tổng số 16 * 4 = 64 bit.

36 bit còn lại được sử dụng làm "chống đập tường" (nhiều hơn về sau). 25 màu xung quanh được băm vào một chỉ mục của 36 bit này. Mỗi bit chỉ ra một hướng dọc ưa thích (lên hoặc xuống), được sử dụng khi có sự lựa chọn khả dĩ giữa hai ô.

Chiến lược như sau:

  • giải mã từng màu theo bộ gen (hoặc báo cáo bộ điều khiển trực tiếp cho các ô "xấu" không theo dõi)
  • xây dựng bản đồ môi trường xung quanh ngay lập tức (3x3 ô, 8 lân cận có thể)
  • tính toán chữ ký của môi trường xung quanh (hàm băm gồm 25 màu trừ các ô không theo dõi)
  • chọn hướng dọc ưa thích từ chữ ký (trong số 36 thùng băm)
  • cố gắng di chuyển đến một người hàng xóm được gợi ý là "tốt", bắt đầu với những mục tiêu gần nhất và đi theo hướng dọc ưa thích trước
  • nếu không tìm thấy hàng xóm "tốt", hãy cố gắng di chuyển một tế bào trở lại (do đó có thể là nạn nhân của một tai nạn đáng tiếc, và tránh tăng thể lực ở mức nào)

Các loài gặm nhấm, coi kẻ thù của bạn

bức tường kinh hoàng vòng dịch chuyển

Điều tồi tệ nhất có thể xảy ra với dân số là chưa tạo ra được người chiến thắng, nhưng rất nhiều chuột bị mắc kẹt vào tường hoặc bên trong một vòng dịch chuyển vô hạn đủ gần với mục tiêu để có cơ hội được chọn để nhân giống .
Trái ngược với những con chuột bị nhốt trong bẫy hoặc dịch chuyển vào tường, những loài gặm nhấm này sẽ chỉ bị giết bởi tuổi già.
Chúng không có lợi thế cạnh tranh so với anh em họ đã mắc kẹt 3 tế bào ngay từ đầu, nhưng chúng sẽ có nhiều thời gian để sinh sản sau khi tạo ra cretin cho đến khi bộ gen của chúng trở nên chiếm ưu thế, do đó không có lý do chính đáng.

Để giảm thiểu hiện tượng này, ý tưởng là làm cho sự bù đắp của những con chuột xấu, xấu này có nhiều khả năng tránh làm theo các bước của tổ tiên chúng.
Chỉ báo hướng dọc chỉ dài 1 bit (về cơ bản là "thử đi lên hoặc xuống trước trong những môi trường xung quanh này") và khá nhiều bit có thể có ảnh hưởng đến đường dẫn theo sau, do đó, các đột biến và / hoặc chéo phải có tác động đáng kể.
Rất nhiều sự bù đắp sẽ có một hành vi khác nhau và cuối cùng sẽ không đập đầu vào cùng một bức tường (trong số các xác chết của tổ tiên bị bỏ đói của họ).
Subtelty ở đây là dấu hiệu này không phải là yếu tố chi phối trong hành vi của chuột. Giải thích màu sắc vẫn sẽ chiếm ưu thế trong hầu hết các trường hợp (lựa chọn tăng / giảm sẽ chỉ quan trọng nếu thực sự có hai "tốt" những gì con chuột thấy là một màu vô hại không phải là một dịch chuyển tức thời đang chờ để ném nó vào tường).

Tại sao nó (dường như) hoạt động?

Tôi vẫn không biết chính xác tại sao.

Đột quỵ tuyệt đối của may mắn vẫn còn là một bí ẩn chưa được giải quyết là logic lập bản đồ bẫy. Không nghi ngờ gì là nền tảng của sự thành công, nhưng nó hoạt động theo những cách bí ẩn của riêng nó.

Với mã hóa được sử dụng, một bộ gen ngẫu nhiên sẽ tạo ra 25% nhận dạng màu "tốt", 25% "xấu" và 50% "bẫy".
các định danh "bẫy" sẽ lần lượt tạo ra các ước tính "tốt" và "xấu" tương quan với môi trường xung quanh 5x5.
Do đó, một con chuột tại một địa điểm nhất định sẽ "nhìn" thế giới như một sự pha trộn của màu sắc "đi / không đi" ổn định và theo ngữ cảnh.

Vì cơ chế chống đập khá thành công dường như chỉ ra, loại yếu tố tồi tệ nhất trên đường đua là bức tường đáng sợ (và người anh em họ của nó là vòng dịch chuyển tức thời, nhưng tôi đoán chúng ít phổ biến hơn).

Kết luận là, một chương trình thành công trên hết phải quản lý để tiến hóa chuột có thể phát hiện các vị trí sẽ dẫn đến tình trạng đói chậm mà không đạt được mục tiêu.

Ngay cả khi không "đoán" hai màu đại diện cho các bức tường, màu "bẫy" dường như góp phần tránh tường bằng cách cho phép một con chuột vượt qua một vài chướng ngại vật không phải vì nó "nhìn thấy" các bức tường, mà bởi vì ước tính "bẫy" đã loại trừ những các tế bào tường đặc biệt trong những môi trường xung quanh cụ thể.

Mặc dù con chuột cố gắng di chuyển về phía mục tiêu (có thể dẫn đến việc nghĩ rằng các chỉ số bẫy "hữu ích" nhất là những chỉ báo nguy hiểm ở phía trước), tôi nghĩ rằng tất cả các hướng bẫy đều có ảnh hưởng gần như nhau: một cái bẫy chỉ ra "nguy hiểm phía sau "Nằm 2 ô phía trước một con chuột có ảnh hưởng tương tự như một ô biểu thị" nguy hiểm phía trước "khi con chuột đứng ngay trên nó.

Tại sao sự pha trộn này có đặc tính để làm cho bộ gen hội tụ thành công như vậy là vượt quá toán học của tôi, thật không may.

Tôi cảm thấy dễ thương hơn với sự răn đe đập tường. Điều này chỉ hoạt động theo kế hoạch, mặc dù vượt quá mong đợi của tôi (điểm số về cơ bản được nhân với bốn).

Tôi đã hack bộ điều khiển rất nhiều để hiển thị một số dữ liệu. Dưới đây là một vài bước chạy:

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

Ở đây một giống siêu chuột xuất hiện sớm (đường đua có thể được phép chạy theo đường thẳng và một số chuột may mắn trong thế hệ đầu tiên có DNA phù hợp để tận dụng lợi thế của nó). Số lượng mẫu vật cuối cùng là khoảng một nửa số lượng tối đa lý thuyết của khoảng 100.000 con chuột, có nghĩa là gần một nửa số sinh vật có được khả năng sống sót theo dõi đặc biệt này vô thời hạn (!).
Tất nhiên, điểm số kết quả chỉ đơn giản là tục tĩu - như là thời gian tính toán.

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

Ở đây chúng ta có thể thấy sự tinh chỉnh bộ gen trong công việc. Dòng dõi giữa hai bộ gen cuối cùng xuất hiện rõ ràng. Các đánh giá tốtxấu là quan trọng nhất. Các dấu hiệu bẫy dường như dao động cho đến khi chúng ổn định thành bẫy "hữu ích" hoặc biến thành tốt hoặc xấu .

Có vẻ như các gen màu có một vài đặc điểm hữu ích:

  • chúng có một ý nghĩa khép kín
    (một màu cụ thể phải được xử lý theo một cách cụ thể)
    Mỗi mã màu có thể được ném vào một bộ gen hoàn toàn khác nhau mà không thay đổi hành vi một cách đáng kể - trừ khi thực tế màu sắc là một màu quyết định (thông thường một bức tường hoặc một dịch chuyển tức thời dẫn đến một vòng lặp vô hạn).
    Đây là trường hợp ít hơn với mã hóa ưu tiên cơ bản, vì màu ưu tiên nhất là thông tin duy nhất được sử dụng để quyết định nơi di chuyển. Ở đây tất cả các màu "tốt" đều bằng nhau, do đó, một màu nhất định được thêm vào danh sách "tốt" sẽ có ít tác động hơn.
  • chúng tương đối linh hoạt với các đột biến
    , mã hóa tốt / xấu chỉ có 2 bit đáng kể trong số 4 và vị trí bẫy có thể được thay đổi hầu hết thời gian mà không làm thay đổi đáng kể hành vi của chuột.
  • chúng nhỏ (4 bit) nên xác suất bị phá hủy bởi sự giao nhau là rất thấp.
  • đột biến tạo ra vô hại những thay đổi có ý nghĩa
    Một gen đột biến thành "tốt" sẽ có ít tác dụng (ví dụ, nếu nó tương ứng với một tế bào trống, nó có thể cho phép tìm ra một con đường mới, ngắn hơn, nhưng điều đó cũng có thể dẫn con chuột đi thẳng vào một cái bẫy), hoặc một cái kịch tính (nếu màu sắc đại diện cho một bức tường, con chuột mới rất có thể bị mắc kẹt ở đâu đó).
    Một gen chuyển sang "bẫy" sẽ làm mất con chuột từ một màu thiết yếu hoặc không có tác dụng đáng chú ý.
    Một đột biến của một vị trí bẫy sẽ chỉ quan trọng nếu thực sự có một cái bẫy (hoặc bất cứ thứ gì có hại) phía trước, có xác suất tương đối nhỏ (tôi sẽ nói một cái gì đó như 1/3).

Cuối cùng, tôi đoán 36 bit cuối cùng không chỉ góp phần tránh bị chuột bị mắc kẹt mà còn lan truyền chuột đồng đều hơn trên đường đua, do đó bảo tồn sự đa dạng di truyền cho đến khi bộ gen chiến thắng xuất hiện và chiếm ưu thế thông qua phần mã hóa màu.

Công việc tiếp theo

Tôi phải nói rằng tôi tìm thấy những sinh vật nhỏ hấp dẫn.
Cảm ơn một lần nữa cho tất cả những người đóng góp cho thử thách tuyệt vời này.

Tôi đang nghĩ đến việc tàn sát bộ điều khiển hơn nữa để hiển thị dữ liệu quan trọng hơn, như tổ tiên của một con chuột thành công.

Tôi cũng rất muốn thấy những con chuột này hoạt động, nhưng ngôn ngữ C ++ này khiến việc tạo ra - chứ đừng nói đến hoạt hình - hình ảnh (trong số nhiều thứ khác) là một việc vặt.

Cuối cùng, tôi muốn đưa ra ít nhất một lời giải thích về hệ thống bẫy và có thể cải thiện nó.

Hack điều khiển

Nếu ai đó quan tâm, tôi có thể xuất bản các sửa đổi tôi đã thực hiện cho bộ điều khiển.
Họ bẩn và rẻ tiền, nhưng họ làm công việc.

Tôi không hiểu biết về GitHub, vì vậy sẽ phải trải qua một bài viết đơn thuần.


16
Có số điểm là 208,14 với 10.000 trò chơi. Tôi đã thử kiểm tra nó trong 1000, nhưng tôi không bao giờ nhận ra mình đã gõ thêm 0, vì vậy phải mất hơn 7 giờ.
frageum

LOL cảm ơn tất cả như nhau. So sánh với hai 1000 lần chạy của tôi, có vẻ như khoảng 2000 lần chạy có thể tạo ra kết quả ổn định sau đó.

Ý ^^v^vvv^^^vv^^v^vvv^v^^vvvv^^^^^^^^^nghĩa của bạn là gì? Phần còn lại tôi có thể đoán, nhưng tôi gặp rắc rối với bit đó?
Vịt Mooing

Tôi đang suy nghĩ về việc tạo ra một bộ điều khiển "gỡ lỗi" riêng biệt, mỗi lần chạy một con chuột và mỗi lần tạo ra một con chuột mới, nó sẽ hiển thị DNA của cả cha mẹ và đứa trẻ (thông qua một số chức năng tùy chỉnh). Điều đó sẽ giúp việc kiểm tra chuột hoạt động dễ dàng hơn nhiều.
Vịt Mooing

2
đại diện cho các bit chỉ thị 36 "lên / xuống", nhưng trong các ví dụ này, DNA chiến thắng đã trở nên chiếm ưu thế nên chúng không thay đổi nhiều.

18

Những tín đồ khó tính - C ++ - (dịch chuyển tức thời được cải thiện): 10.000+ cho 2000 lần chạy

(đây là một sự phát triển của đức tin mù quáng , vì vậy bạn có thể muốn trèo lên một bức tường văn bản khác trước cái này)

#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";
}

Tập IV: đưa vòng bi của chúng tôi lên lưới

Các kết quả

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

Tôi chuyển sang g ++ / MinGW và 3 chủ đề.
Mã do GNU tạo ra nhanh hơn gấp đôi so với Microsoft.
Không có gì ngạc nhiên, những gì với việc thực hiện STL kinh khủng của họ.

Dịch chuyển tức thời

Hiệu ứng dịch chuyển là phụ thuộc nhiều vào vị trí. Cho đến bây giờ tôi rất vui khi xem xét một dịch chuyển tức thời là luôn luôn tốt (được xem là một khoảng trống) hoặc luôn luôn xấu (được xem như một bức tường để không loài gặm nhấm nào có thể lấy nó).

Đây là một mô hình quá thô.
Một người dịch chuyển tức thời có thể đẩy một con chuột về phía trước cho đến khi một vài tế bào từ mục tiêu, nhưng một khi có cùng một người dịch chuyển tức thời có thể ném con chuột ra khỏi bảng.
Một dịch chuyển tức thời như vậy rất có thể sẽ được công nhận là có thể qua được (vì nó tăng thể lực nhanh hơn so với khi "đi bộ" đến cùng một vị trí x), trở thành một phần của bộ gen thống trị và tiêu diệt gần như tất cả những con chuột tin rằng nó "luôn an toàn".
Vì chuột không có phương tiện để biết vị trí X của chúng, nên giải pháp duy nhất để phát hiện các dịch chuyển tức thời nguy hiểm này là quyết định có nên bước lên chúng dựa trên dữ liệu theo ngữ cảnh duy nhất có sẵn, tức là lưới màu 5x5.

Để làm như vậy, tôi đã xác định 4 loại gen màu:

  • máy dò bẫy nguy hiểm
  • trống có thể vượt qua bất cứ nơi nào trên đường đua
  • chặn bất cứ nơi nào trên đường đua
  • chùm được xem là trống hoặc khối tùy thuộc vào môi trường xung quanh

Ý tưởng là cố gắng phân biệt một người dịch chuyển tức thời bằng cách nhìn vào 8 người hàng xóm ngay lập tức của nó. Vì xác suất có 8 hàng xóm giống hệt nhau tại một địa điểm nhất định là rất thấp, điều đó sẽ cho phép xác định một thể hiện duy nhất của mỗi dịch chuyển tức thời.

8 màu lân cận có thể được kết hợp để tạo thành một chữ ký cục bộ, bất biến tương ứng với vị trí trong mê cung. Thật không may, 8 hàng xóm chỉ hiển thị cho các ô nằm trong trường 3x3 của hình vuông bên trong tầm nhìn, vì vậy chữ ký sẽ không chính xác trên vành của trường nhìn.
Tuy nhiên, điều này sẽ cung cấp cho chúng tôi một thông tin theo ngữ cảnh liên tục trong vùng lân cận, điều này đủ để tăng khả năng điều hướng dịch chuyển tức thời thành công.

gen chùm có trường biến 2 bit.
Đối với một chữ ký địa phương dịch chuyển tức thời, có một cơ hội trong bốn rằng tế bào chùm tia sẽ được coi là không thể vượt qua. Mỗi giá trị của trường chọn một trong bốn khả năng này.
Kết quả là, một đột biến gen chùm trên 2 bit này sẽ chuyển qua 4 ý nghĩa ngữ cảnh có thể có của màu sắc.

Bên cạnh đó, màu sắc quan trọng nhất để đoán vẫn là tường và bẫy. Điều này có nghĩa là chúng ta chỉ nên cho phép phát hiện dịch chuyển tức thời sau khi chuột biết được tường và bẫy ở đâu.

Điều này được thực hiện bằng cách cập nhật chữ ký địa phương chỉ một cách tiết kiệm. Tiêu chí hiện tại để cập nhật chữ ký địa phương là phải có màu sắc được xác định là dịch chuyển tức thời tiềm năng.

Việc mã hóa sử dụng 5 bit cho mỗi gen màu và các loại nhóm để giải phóng 3 bit ít quan trọng hơn để mã hóa giá trị 0..7:

  • 4 nguy hiểm
  • 4 trống
  • 4 khối
  • 4 chùm

Mỗi gen chùm có 1/4 cơ hội được coi là một khối và 3/4 cơ hội được coi là trống, vì vậy 4 chùm đại diện cho trung bình 1 khối và 3 khối trống.

Do đó, tỷ lệ trung bình được biểu thị bằng một dải màu ngẫu nhiên gồm 16 màu:

  • 4 nguy hiểm
  • 7 trống
  • 5 khối

Sự pha trộn này dường như cho kết quả tốt nhất cho đến nay, nhưng tôi không hoàn thành việc điều chỉnh nó.

Tính đột biến gen

Một điều chắc chắn là: các giá trị mã được chọn để đại diện cho các loại gen là rất quan trọng. Đảo ngược hai giá trị có thể tốn 2000 điểm trở lên.

Ở đây một lần nữa lý do tại sao là ngoài toán học của tôi.

Tôi đoán là xác suất đột biến từ loại này sang loại khác phải được cân bằng, hoặc nếu không, như trong ma trận Markow, xác suất tích lũy có xu hướng hạn chế các giá trị trong tập hợp con có xác suất chuyển tiếp đến cao nhất.

Đường đến giải cứu

Đường dẫn sẽ làm giảm đáng kể số lượng ô được truy cập, cho phép chỉ kiểm tra khả năng dẫn đến mục tiêu nhất. Do đó, không chỉ một số ngõ cụt thường xuyên được tránh, mà mã màu sai cũng có nhiều khả năng được phát hiện sớm hơn.
Do đó, thời gian hội tụ giảm mạnh.

Tuy nhiên, điều này không giúp giải quyết các bản đồ nơi bộ gen không thể tạo ra một đại diện phù hợp của bản nhạc.

Làm gì với morons?

Sau khi nhìn trực quan vào đường đua, tôi hiểu tại sao một chiến lược mặc định cố gắng tiến về phía trước ngay cả khi dường như không có gì ngoài những bức tường phía trước thực sự tốt hơn là giữ lại.
"Những bức tường" có thể là trong các dịch chuyển tức thời thực tế tạo ra rất nhiều kết quả đáng tiếc đến mức bộ gen coi chúng là chướng ngại vật không bao giờ bị giẫm đạp, nhưng trong những trường hợp hiếm hoi, một ví dụ cụ thể của dịch chuyển tức thời nghịch ngợm này có thể có tác động tích cực (hoặc ít nhất là không gây chết người) , vì vậy, lấy nó thay vì di chuyển trở lại làm tăng cơ hội tìm thấy con đường dẫn đến chiến thắng.

Hội tụ sớm

Dường như với tôi tỷ lệ đột biến là một chút quá thấp (ít nhất là đối với loài gặm nhấm của tôi).

Cài đặt 0,01 hiện tại cung cấp cho DNA 37% cơ hội sống sót trong quá trình đột biến nguyên vẹn. Thay đổi tham số thành 0,0227 làm giảm xác suất này xuống còn khoảng 10%

Công thức bí ẩn là đột biến P 1 bit = 1-P toàn bộ bộ gen nguyên vẹn 1/100 , 100 là chiều dài bit của bộ gen.

Ví dụ: xác suất 10%, đột biến P 1 bit = 1 - 0,1 1/100 = 0,0277
Với xác suất 5%, P = 1 - 0,05 1/100 = 0,0295
Đảo ngược công thức, chúng tôi thấy rằng 0,01 cho 37% cơ hội tồn tại không thay đổi do đột biến.

Tôi chạy lại thử nghiệm chính xác tương tự (sử dụng chuỗi hạt ngẫu nhiên cố định) với xác suất 10%.
Trên rất nhiều bản đồ, những thất bại trước đó đã biến thành (giới hạn) thành công. Mặt khác, các vụ nổ dân số khổng lồ ít hơn (có tác dụng phụ thú vị là tăng tốc tính toán rất nhiều).
Mặc dù điểm số rất cao (một triệu +) ít phổ biến hơn, số lần chạy thành công hơn là quá đủ để bù lại.
Cuối cùng, giá trị trung bình tăng từ 1400+ lên khoảng 2000.

Ngược lại, đặt P thành 5%, tạo ra giá trị trung bình khoảng 600.
Tôi cho rằng tỷ lệ đột biến quá cao đến mức bộ gen của những con chuột chiến thắng đã phân chia quá thường xuyên thành các biến thể kém hiệu quả hơn.

Cái này hoạt động thế nào

Với các máy dò dịch chuyển tức thời được thêm vào, số lượng trò chơi thất bại (điểm <10) giảm đáng kể.
Trong một thử nghiệm năm 2000, chỉ có 1/3 thất bại.
Giá trị trung bình hình học chỉ tăng từ 2900 đến 3300, nhưng con số này không phản ánh sự cải thiện.

Màu trống thường được đoán là chùm và nguy hiểm (thường là 2 đến 5). Bộ gen "sử dụng" những màu sắc này để chặn những con đường khiến chuột gặp rắc rối.

Bộ gen khá giỏi trong việc đoán bẫy (tức là một khi chuột có thể đạt được mục tiêu, màu sắc đại diện cho các máy dò bẫy thực tế được đoán khoảng 90% thời gian).
Nó cũng sử dụng mã chùm mới cho dịch chuyển tức thời, mặc dù hiếm hơn (có lẽ vì dịch chuyển tức thời "nguy hiểm" ít phổ biến hơn bẫy và các màu chùm / nguy hiểm khác phát triển để chặn đường đến những trường hợp cuối cùng của những kẻ phản bội này).

Đánh giá về số lượng trò chơi mà bộ gen chiến thắng xuất hiện sau 5000 lượt trở lên, tôi cho rằng giống chó mới này sẽ được hưởng lợi rất nhiều từ tỷ lệ đột biến gia tăng.


Vì có số lượng bẫy chẵn, trống, tường và dịch chuyển tức thời, bạn chỉ cần 3 bit để lưu trữ tỷ lệ chính xác (ngay cả khi bạn xem xét bẫy == tường). Ngoài ra, bạn đã xem xét / loại bỏ ý tưởng sử dụng các bit bù bẫy không sử dụng trong việc chống wallbanging chưa? Vì mục tiêu là không được thừa kế từ cha mẹ, nên bạn thực sự có thể sử dụng tất cả các bit trong việc chống wallbanging. Không có lý do gì để chúng là duy nhất tôi sẽ không nghĩ.
Vịt Mooing

1
@MooingDuck Tôi đã thử nghiệm ý tưởng của bạn về việc sử dụng lại các bit bù, nhưng nó đã thất bại. Như tôi sợ, việc sử dụng lại một thông tin cho hai mục đích khác nhau dường như không hiệu quả. Ví dụ, giả sử các bit bù của một màu nhất định là cần thiết cho bộ gen để chọn hướng dọc phù hợp trong một đường dẫn nhất định, màu này không thể biểu thị một bẫy có ý nghĩa nữa mà không phá hủy đường dẫn phụ thuộc vào cùng một dữ liệu. Tôi cũng đã cố gắng sử dụng 6 bit, nhưng vì tôi sợ rằng 4 tiếng nổ chống tường còn lại cũng bị thiếu.

1
Rất tốt để biết, nhưng tôi đã gợi ý hai ý tưởng ở đó, một là sử dụng tất cả các bit (sử dụng lại một số) và hai là sử dụng các bit bù bẫy không sử dụng cho các bức tường / trống. Bạn đã thử cả hai? (Tôi hoàn toàn hiểu nếu bạn không muốn thử, bạn hầu như không cần phải thử nếu bạn không muốn)
Vịt Mooing

1
Tôi đã thử cả hai, và cả hai đều thất bại. Bẫy bẫy rất quan trọng ngay cả khi một gen không sử dụng chúng, bởi vì gen này vẫn có thể biến đổi trở lại thành màu bẫy, trong trường hợp đó, bẫy bù có thể sẽ bị biến đổi thành bất kỳ bit bối cảnh nào có lợi nhất và mất đi ý nghĩa của nó như là một bù . Bây giờ nó sẽ biến đổi trở lại giá trị bù có lợi nhuận và phá hủy các đường dẫn của những con chuột phụ thuộc vào nó như các chỉ số theo ngữ cảnh. Tôi nghĩ rằng tôi đã thấy trường hợp dao động như vậy với công cụ đồ họa của tôi, nhưng không dễ để thể hiện một ví dụ rõ ràng về vấn đề này.

16

ColorScorePlayer, điểm sơ bộ 22

Đây là bot bạn thấy trong công việc trong GIF trong thử thách.

Đây là bot thử nghiệm của chúng tôi trong suốt giai đoạn phát triển. Nó sử dụng bộ gen để lưu trữ điểm chất lượng cho mỗi trong số 16 màu. Sau đó, nó làm cho chuyển động về phía trước di chuyển nó lên màu sắc với điểm số tốt nhất (và không bao giờ di chuyển lên -1). Trong trường hợp hòa, một di chuyển ngẫu nhiên giữa các ô buộc được chọn.

Chúng tôi đã chuyển trình phát này sang tất cả các ngôn ngữ của bộ điều khiển, vì vậy nó hoạt động như một ví dụ cho cách sử dụng chúng:

Con trăn

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)

Hồng ngọc

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; 
}

Java

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;
    }
}

Người chơi ghi điểm khá không nhất quán. Dưới đây là 50 lần chạy ngẫu nhiên:

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

Thử thách này thực sự khá thú vị và đơn giản nếu bạn thử.

Đừng để bị trì hoãn bởi các mô tả dài.
Chỉ cần truy cập GitHub và kiểm tra mọi thứ ... mọi thứ sẽ rõ ràng hơn nhiều! :)

Trình giả lập C ++ rất được khuyến khích cho tốc độ của nó. Ngay cả sau khi tôi đã dịch xong chương trình python của mình sang C ++, mô phỏng python vẫn chưa dừng lại.

Đây là một biến thể cải tiến của ColorScorePlayer. Để sử dụng tốt chế độ xem 5x5 của nó, nó xem xét di chuyển 2 bước từ nó bằng cách sử dụng chức năng có trọng số. Di chuyển 1 bước trước nó sẽ có trọng lượng cao hơn, vì chúng có tác dụng ngay lập tức hơn đối với sự sống còn. Di chuyển 2 bước về phía trước được cho trọng lượng thấp hơn.

Cố gắng di chuyển về phía trước, nhưng nếu không thấy di chuyển an toàn ... sau đó cố gắng đi ngang ... và nếu tất cả các cách khác đều thất bại, hãy di chuyển lùi một cách ngẫu nhiên.

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())];

}

Ghi bàn:

Có khá nhiều 1 ... đó có thể là một chút buồn khi bạn thấy giao diện điều khiển phun ra 1 cái khác. Giống như một hành tinh với tất cả các nhu cầu thiết yếu cho cuộc sống, nhưng không có dấu hiệu của nền văn minh chuột tiên tiến ...
Rồi thỉnh thoảng tăng đột biến. :)

Hmm ... rõ ràng tôi đã may mắn cho đợt chạy đầu tiên của mình, có được hình học hơn 300. Điểm số thực sự dao động khá nhiều. Nhưng dù sao, với nhiều lần chạy giả lập hơn, có lẽ nó gần với ≈ 74. (Thx frageum đã giúp tôi mô phỏng và chương trình nhanh chóng của anh ấy)

Điểm từ các lần chạy của tôi: 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 57376 1 123870 4 1 1 79092 69931 59 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 701 1 23 104794 1 10476 59245 1 204 1 1 12 1 29641 1 314894 18785 13 1 3 1 1 1 2 526001 1 1 1 27559 29285 3 3 128708 70386 30 2 2 1 208531 331 1 2 1 61 114993 1 15 51997 1 2 1 14619 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 1 214365 1 40147 2 213952 1 29 3 1 2144435 5 4502444 1 1 1 1 774547


1
Tôi có một ý nghĩa hình học của 74,7 với 1000 trò chơi, công việc tốt.
frageum

8

Giám mục - Python, điểm sơ bộ 1.901

Giám mục luôn di chuyển theo đường chéo nên một nửa bảng không thể truy cập được trên một trek nhất định trên bảng, nhưng điều này có nghĩa là ít di chuyển tiềm năng hơn để mã hóa, do đó, mỗi bit của bộ gen có thể đại diện cho một di chuyển (Giám mục không bao giờ rút lui). Bit nào để tham khảo được quyết định dựa trên khối hình vuông 3x3 phía trước (bên phải) của mẫu thử. Động thái tốt nhất cho một tình huống nhất định chỉ là một đột biến đơn lẻ.

Bot này học rất nhanh lúc đầu, nhưng sau đó thường chạm trần trước khi về đích, có lẽ là một trong hai vấn đề sau xảy ra:

  • Hai hoặc nhiều phần của bản đồ bảng đến cùng một bit nhưng yêu cầu di chuyển khác nhau.
  • Một số bảng không thể vượt qua chỉ sử dụng di chuyển chéo.

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)]

Mặc dù có những hạn chế này, trong những dịp hiếm hoi, Giám mục làm tốt, với các mẫu riêng lẻ hoàn thành một vài vòng của bảng. Tôi đã nghĩ rằng trên một vòng đua nhất định, một mẫu vật chỉ có thể di chuyển trên một nửa bàn cờ (tương đương với chỉ các ô vuông màu đen hoặc chỉ các ô vuông trắng trên bàn cờ vua). Tuy nhiên, như Martin Büttner đã chỉ ra, một người dịch chuyển tức thời có thể di chuyển một mẫu vật từ hình vuông màu đen sang hình vuông màu trắng hoặc ngược lại vì vậy trên hầu hết các bảng họ sẽ không bị hạn chế.

(Có hai cặp loại dịch chuyển tức thời phù hợp và mỗi loại có xác suất 0,5 có độ lệch di chuyển mẫu vật vào nửa kia của hình vuông đen và trắng. Vì vậy, xác suất của một bảng chỉ có dịch chuyển tức thời hạn chế mẫu vật thành một một nửa bảng trên mỗi vòng chỉ 0,25.)

Điểm số cho thấy những chiến thắng không thường xuyên được xen kẽ với những khoảng thời gian dài không đạt được kết thúc:

Điểm: 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

Run-Bonus player: Hình học trung bình 50,35 (thử nghiệm 5000 trò chơi)

Bot này chấm điểm bình phương bằng các màu riêng biệt dựa trên phần DNA 6 bit như trình phát điểm màu, nhưng với hệ thống số khác nhau. Bot này được thúc đẩy bởi ý nghĩ rằng nó khá độc đoán khi một trong số các bit thay đổi giá trị của điểm số bằng 32, trong khi một bit khác làm như vậy chỉ bằng 1. Nó gán giá trị n (n + 1) / 2 cho một lần chạy n liên tiếp 1 bit. Ngoài ra, nó thêm một cơ chế ngẫu nhiên trong một nỗ lực để tránh bị mắc kẹt. Nó sẽ thực hiện một bước tiến ngẫu nhiên với cơ hội 1 trong 30.

Để so sánh, người chơi điểm màu ghi được 30 đến 35 trong một vài thử nghiệm 1000 trò chơi. Điều thú vị là, điểm số trò chơi tối đa của người chơi có màu nằm trong khoảng 3-5 triệu, trong khi tối đa phần thưởng chạy chỉ là 200 nghìn. Run-phần thưởng lợi ích từ hệ thống tính điểm trung bình logarit bằng cách có được điểm số khác không nhất quán hơn.

Chạy 5000 trò chơi mất khoảng 20 phút với 6 luồng trên bộ điều khiển 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)]};
}

Vì tò mò, bài kiểm tra 5000 bài đã mất bao lâu? Chuột của tôi cần hơn một giờ để hoàn thành 1000 bản nhạc, vì vậy tôi sẽ phải để máy tính chạy suốt đêm để tái tạo trường hợp thử nghiệm của bạn.

@kuroineko Câu trả lời cho câu hỏi của bạn đã có trong câu trả lời của tôi.
frageum

ối xin lỗi. Tôi sẽ thử mã của bạn trên PC sau đó, để xem phần cứng đóng vai trò gì trong sự khác biệt về tốc độ. Và có thể thử sử dụng gcc thay vì MSVC. Tôi nhận thấy hiệu suất tăng 30% so với MSVC trên một vài đoạn mã nặng tính toán khác.

Mã của bạn đã chạy trong hơn 20 phút cho 1000 bản nhạc trên i3-2100@3.1GHz của tôi với 4 luồng. Điểm số khoảng 56 . Điều đó có nghĩa là PC của tôi chậm hơn 5 lần so với máy của bạn và mã của tôi sẽ chậm hơn khoảng 6 lần trên một máy nhất định (nhưng có điểm số tốt hơn về mặt cơ học ngụ ý thời gian tính toán lâu hơn). Vì tôi quá muốn mua một PC mới, nên đã đến lúc tối ưu hóa một chút ...

8

StarPlayer | C ++ | Điểm: 162 (dựa trên 500 lần chạy trò chơi)

Người chơi này cố gắng sử dụng A * để tìm cách tốt nhất về phía trước. Nó gán trọng số giống như ColorScorePlayer và cố gắng tìm đường đến cạnh phải của khung nhìn. Việc thực hiện không phải là đẹp nhất tôi từng làm nhưng ít nhất nó không quá chậm.

#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;
}

Điểm mẫu:

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 1 829756 425 6699 22 8 1 1 6 6 104889


1
Trong 1000 trò chơi tôi đã đạt được số điểm 133,2, rất tuyệt.
frageum

7

WallGuesser - Đã ghi 113.266 trong 1000 thử nghiệm trò chơi

Mã hóa

Tôi đã thực hiện mã hóa 6 bit / màu thực sự đơn giản. Để giải mã màu [n]

  • Tính tổng mỗi bit thứ n trong bộ gen lên tới 96
  • Nếu tổng điểm là> = 4 thì nói ô vuông này bị chặn
  • Nếu tổng điểm là <= 4 thì điểm cuối cùng của nó là 2 ^ tổng điểm của nó

Bằng cách trải đều các bit cho một màu trong toàn bộ bộ gen, tôi sẽ tăng khả năng các bit từ cả hai cha mẹ sẽ được sử dụng cho mỗi màu.

Phong trào

Tôi sử dụng một tìm kiếm dựa trên (tôi chắc chắn không hiệu quả) A * để tìm đường dẫn chi phí thấp nhất đến bất kỳ hình vuông cạnh phải nào. Nếu một màu ánh xạ tới, "bị chặn", thì nó sẽ không bao giờ được nhập bởi tìm kiếm. Nếu tìm kiếm không thể tìm thấy một con đường, nó cho rằng con chuột này không phù hợp để sinh sản và cố gắng kết thúc nó bằng cách di chuyển sang bên trái.

Giảm số lượng chuột không phù hợp

Vì bộ gen của tôi đang đoán một cách hiệu quả về những hình vuông là tường hoặc dịch chuyển tức thời, những con chuột không có dự đoán (không có màu nào ánh xạ tới bị chặn) không phù hợp lắm. Để thử và loại bỏ những con chuột này nếu không có màu nào được đánh dấu là bị chặn thì MỌI màu được đánh dấu là bị chặn và chuột sẽ luôn di chuyển một bên sang trái.

LÀM

Hiện tại không có sự ngẫu nhiên trong hành vi nên chuột dễ bị mắc kẹt.

#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;
}

Hừm, cái này không được biên dịch cho tôi g++ -std=c++11 .\wallguesser.cpp -O2 -o .\wallguesser.exe. Tôi nhận được rất nhiều lỗi nhưng lỗi đầu tiên là.\wallguesser.cpp:47:19: error: 'dna_t' has no member named 'at' if (d.at(i) == true){
Martin Ender

Không có vấn đề, chỉ cần thay đổi atđể []sửa chữa nó.
frageum 2/2/2015

7

FITTEST - Điểm trung bình hình học: ~ 922 (chạy 2K)

Cách tiếp cận của tôi là:

  1. Tìm hiểu những gì giết chết các loài và xác định hành vi mong muốn (chức năng)
  2. Thực hiện hành vi mong muốn trong mã (kỹ thuật)
  3. Cho nó một ưu tiên . Là nó quan trọng hơn hoặc ít quan trọng hơn các hành vi mong muốn khác.
  4. Tối ưu hóa điểm trung bình hình học bằng cách điều chỉnh các tham số của các giải pháp.

Tôi đã thử nghiệm hơn 2000 bộ thông số với cùng 50 hạt giống. Các bộ hứa hẹn nhất đã được chọn và được ghi bằng 250 hạt giống nhau và những hạt có thứ hạng cao nhất là đầu vào cho vòng thử nghiệm tiếp theo. Vì vậy, tôi đã quản lý để tạo ra một thuật toán di truyền để tìm ra thuật toán di truyền tối ưu cho vấn đề này theo đề xuất của người dùng mbomb007 .

Hành vi mong muốn:

  1. Các loài nên học màu nào an toànmàu nào xấu.
  2. Các loài chủ yếu nên tập trung quyết định di chuyển đến đâu dựa trên 3 ô ngay trước mặt, nhưng nếu không có động thái tốt, nên xem xét di chuyển dọc hoặc lùi
  3. Các loài cũng nên nhìn những gì nằm ngoài 8 tế bào xung quanh mình và sử dụng thông tin đó trong việc ra quyết định
  4. Các loài nên học cách xác định bẫy .
  5. Một số loài cho rằng các bức tường là tốt và cố gắng di chuyển đến chúng mọi lúc và do đó bị mắc kẹt trước các bức tường. Nếu chúng là loài có điểm số cao nhất tại thời điểm đó DNA của chúng với giả định sai về bức tường được nhân đôi nhiều lần vào trẻ sơ sinh . Sau một thời gian, tất cả các loài bị mắc kẹt trước các bức tường và không ai trong số chúng đạt được mục tiêu để ghi điểm. Làm thế nào để ngăn chặn các morons?

Phương pháp lưu trữ dữ liệu:

Chúng tôi muốn các loài học hỏi mọi thứ, thích nghi với môi trường của nó, trở thành kẻ mạnh nhất. Chắc chắn điều này chỉ hoạt động, nếu việc học có thể được lưu trữ bằng cách nào đó. Việc học sẽ được 'lưu trữ' trong 100 bit DNA. Đó là một cách lưu trữ kỳ lạ, bởi vì chúng tôi không thể thay đổi giá trị DNA của chúng tôi. Vì vậy, chúng tôi giả định rằng DNA đã lưu trữ thông tin về các động thái xấu và tốt. Nếu đối với một loài nhất định, thông tin chính xác được lưu trữ trong DNA của nó, anh ta sẽ tiến nhanh về phía trước và tạo ra nhiều loài mới bằng DNA của nó.

Tôi phát hiện ra điểm trung bình hình học rất nhạy cảm với cách thông tin được lưu trữ. Giả sử chúng ta đọc 4 bit đầu tiên trong số 100 bit DNA và muốn lưu trữ số này trong một biến số nguyên. Chúng tôi có thể làm điều này theo nhiều cách:

  1. lưu trữ dữ liệu thập phân: bằng cách sử dụng hàm 'tích hợp' dnarange, ví dụ: 10114 bit sẽ trở thành `1x2 ^ 3 + 0x2 ^ 2 + 1x2 ^ 1 + 1x2 ^ 0 = 15. Giá trị có thể (cho 4 bit): [0, 1 , 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
  2. lưu trữ dữ liệu streaks: bằng cách sử dụng dnaStreakRangechức năng (được xác định bên dưới), ví dụ: 4bits 1011 sẽ trở thành 1x1 + 0x1 + 1x1+ 1x2 = 4. Các giá trị có thể (cho 4 bit): [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. lưu trữ dữ liệu bitum: bằng cách sử dụng dnaCountRangehàm (được xác định bên dưới), ví dụ: 4 bit 1011 sẽ trở thành 1x1 + 0x1 + 1x1 + 1x1 = 3. Các giá trị có thể (cho 4 bit): [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;
}

Sự khác biệt giữa các phương thức lưu trữ là:

  • Phương pháp lưu trữ thập phân dễ bị tổn thương đối với một thay đổi bit đơn đối với DNA. Khi giá trị bitum thay đổi từ 1011 đến 0011, giá trị của nó thay đổi từ 3 thành 2, đây là một thay đổi nhỏ.
  • Phương pháp lưu trữ thập phân là đồng nhất . Mỗi giá trị có thể có cùng một thay đổi xảy ra. Cơ hội bạn đọc giá trị 15 từ khối bộ nhớ lưu trữ 4 bit là 1/16 = 6%. Các phương pháp lưu trữ streak là không đồng nhất . Cơ hội mà một giá trị 4 bit có ít hơn hoặc bằng 6 là (15-3) / 16 = 81% (tất cả 16 kết hợp ngoại trừ 0111,1110.111). Dưới một hình ảnh cho thấy hình dạng của phân phối. Như bạn có thể thấy ở mũi tên màu xanh, khả năng chuỗi 4 bit nhỏ hơn hoặc bằng 6 là 81%: trực quan hóa việc phân phối các loại lưu trữ thập phân, sọc và bitum cho các số nhị phân dài 4,5 và 6 bit

Ưu tiên giải pháp.

Khi ColorScorePlayer đã xác định hai bước tiến với điểm số giống hệt nhau, một lựa chọn tùy ý được thực hiện. IMHO, bạn không bao giờ nên sử dụng chức năng ngẫu nhiên v.rng.rint()chức năng . Thay vào đó, bạn nên sử dụng cơ hội có điểm số bằng nhau này như một cái móc để đánh giá các giải pháp cho hiệu ứng thứ hai.

Hiệu ứng thứ tự đầu tiên được ưu tiên cao nhất. Nếu đạt được điểm bằng nhau, giải pháp có mức độ ưu tiên là 2 chiếm ưu thế. Bằng cách điều chỉnh các tham số của một giải pháp, bạn có thể ảnh hưởng đến cơ hội điểm số bằng nhau xảy ra và theo cách đó thay đổi trọng số của các giải pháp ưu tiên 1 và ưu tiên 2.

Thực hiện hành vi mong muốn

Tìm hiểu màu nào là an toàn:

  • 33% trong số 16 màu là xấu và do đó khi điểm di chuyển dưới 63/3 thì di chuyển sẽ không được phép. Do đó threshold = 63/3=21, trong đó 63 là điểm tối đa cho 6 bit và 33% = 1/3 (có thể được tra cứu trong biểu đồ trên).

Nếu không có di chuyển tốt có sẵn, di chuyển dọc hoặc lùi:

  • Khi không cho phép di chuyển về phía trước, di chuyển dọc sẽ được so sánh với nhau theo cùng một cách. Nếu cũng không cho phép di chuyển dọc, di chuyển lùi được xếp hạng. Điều này đạt được thông qua các weightMovebiến.

Hãy nhìn những gì vượt ra ngoài:

  • Khi 2 hoặc 3 lần di chuyển có điểm giống hệt nhau, hộp 3x3 xung quanh các lần di chuyển đó sẽ xác định (thông qua x2y2vòng lặp) đâu là lựa chọn tốt nhất (thông qua mainSubScorebiến). Cột bên phải nhất trong hộp 3x3 đó đang dẫn đầu.
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};
}

Điểm: 123 (2K lượt chạy)

50 điểm đầu tiên (18 trò chơi chỉ ghi được 1 điểm):

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 1

Xác định bẫy:

Tôi đã kiểm tra DNA của các loài có số điểm cao nhất khi một trò chơi tùy ý kết thúc bằng cách sử dụng bộ lưu trữ bitsum4 (vì vậy điểm màu có phạm vi [0,4]):

  • Điểm 0: Dịch chuyển về phía sau, cả hai bức tường, 1x an toàn
  • ghi 1: Bẫy lùi (vô hại), dịch chuyển ngược, 1x an toàn
  • Điểm 2: Bẫy về phía trước (rất nguy hiểm), 1x an toàn
  • đạt điểm 3: Dịch chuyển tức thời, an toàn 5x
  • đạt điểm 4: Dịch chuyển tức thời, 1x an toàn

Từ đó có thể kết luận rằng các bức tường và dịch chuyển tức thời có được một số điểm chính xác. Bẫy không được xác định vì chúng phụ thuộc vào hướng và màu sắc của nguồn gốc, trong khi việc ghi điểm được thực hiện theo màu của điểm đến. Do đó, cũng cần lưu trữ dữ liệu về màu sắc của nguồn gốc, vì vậy v(0,0). Trong một thế giới lý tưởng, chúng tôi muốn lưu trữ thông tin cho 16 màu x 8 hướng x 3 bit = 384 bit.

Thật không may, chỉ có 100 bit có sẵn và chúng tôi không thể sử dụng tất cả vì chúng tôi cũng cần một số bộ nhớ cho giải pháp được giải thích ở trên. Vì vậy, chúng tôi sẽ làm 4 thùng màu:

  • 0: màu 0 - màu 3,
  • 1: màu 4 - màu 7,
  • 2: màu 8 - màu 11,
  • 3: màu 12 - màu 16

và 4 thùng hướng di chuyển

  • 0: di chuyển dọc hoặc lùi,
  • 1: tiến lên phía trước,
  • 2: tiến về phía trước,
  • 3: di chuyển xuống dưới

Khi điểm thập phân là 4 hoặc cao hơn (100,101,110,1111), người ta cho rằng một cái bẫy được liên kết với ô này, do đó, di chuyển này sẽ không được chọn khi có điểm bằng nhau. Vì vậy, nhận dạng bẫy là hiệu ứng thứ hai và 'nhìn những gì vượt ra ngoài' sẽ là giải pháp ưu tiên thứ ba.

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};
}

Điểm: 580 (chạy 2K)

50 điểm đầu tiên (13 trận chỉ ghi được 1 điểm):

11,044 14

Giả định sai về bức tường được nhân đôi nhiều lần thành trẻ sơ sinh bởi morons:

Một số loài cho rằng các bức tường là tốt và cố gắng di chuyển đến chúng mọi lúc và do đó bị mắc kẹt trước các bức tường. Họ cũng có thể bị mắc kẹt trong các vòng lặp vô hạn của dịch chuyển tức thời. Hiệu quả là như nhau trong cả hai trường hợp.

Vấn đề chính là sau vài trăm lần lặp, một số gen trở nên rất chi phối . Nếu đây là các gen 'đúng', bạn có thể nhận được điểm số rất cao (> 1 triệu điểm). Nếu những điều này là sai, bạn sẽ bị mắc kẹt, vì bạn cần sự đa dạng để tìm ra gen 'đúng'.

Chiến đấu tinh thần: Giải pháp 1: đảo ngược màu sắc

Giải pháp đầu tiên tôi đã thử là một nỗ lực sử dụng một phần bộ nhớ chưa sử dụng vẫn còn rất đa dạng. Giả sử bạn đã phân bổ 84 bit cho bộ nhớ màu và bẫy tìm bộ nhớ. 16 bit còn lại sẽ rất đa dạng. Chúng ta có thể điền 2 biến thập phân8 có các giá trị trong khoảng [0,255] và chúng đồng nhất, có nghĩa là mỗi giá trị có cơ hội là 1/256. Các biến sẽ được gọi inInverseinReverse.

Nếu inInversebằng 255 (cơ hội 1/256), thì chúng ta sẽ đảo ngược việc giải thích điểm màu . Vì vậy, bức tường mà moron cho là an toàn vì nó có điểm cao, sẽ bị điểm thấp và do đó sẽ trở thành một nước cờ xấu. Nhược điểm là điều này cũng sẽ ảnh hưởng đến gen 'quyền', vì vậy chúng tôi sẽ có điểm số rất thấp. Hơn nữa, inInverseloài này sẽ phải tự sinh sản và con của nó cũng sẽ có được các phần của DNA trội. Phần quan trọng nhất là nó mang lại sự đa dạng.

Nếu inReversebằng 255 (cơ hội 1/256), thì chúng tôi sẽ đảo ngược thứ tự các vị trí lưu trữ của điểm màu . Vì vậy, trước khi màu 0 được lưu trữ trong các bit 0-3. Bây giờ màu 15 sẽ được lưu trữ ở vị trí đó. Sự khác biệt với inInversecách tiếp cận là ý inReversechí hoàn tác công việc đã hoàn thành cho đến nay. Chúng tôi trở lại tại một hình vuông. Chúng tôi đã tạo ra một loài có gen tương tự như khi trò chơi bắt đầu (ngoại trừ bẫy tìm bộ nhớ)

Thông qua tối ưu hóa, nó được kiểm tra nếu sử dụng đồng thời inInversevà khôn ngoan inReverse. Sau khi tối ưu hóa nó đã được kết luận, điểm số không tăng. Vấn đề là chúng ta có quần thể gen đa dạng hơn, nhưng điều này cũng ảnh hưởng đến 'DNA đúng'. Chúng ta cần một giải pháp khác.

Chiến đấu tinh thần: Giải pháp 2: mã băm

Loài này có 15 vị trí bắt đầu có thể và hiện tại có một cơ hội quá lớn anh ta sẽ đi theo chính xác cùng một con đường nếu anh ta bắt đầu ở cùng một vị trí bắt đầu. Nếu anh ta là một kẻ ngốc yêu những bức tường, anh ta sẽ bị mắc kẹt trên cùng một bức tường nhiều lần. Nếu anh ta may mắn tìm được một bức tường phía trước, anh ta sẽ bắt đầu thống trị nhóm DNA với những giả định sai lầm của mình. Điều chúng ta cần là con cháu của anh ta sẽ đi theo một con đường hơi khác (vì dù sao anh ta cũng đã quá muộn) và sẽ không bị mắc kẹt trên bức tường phía trước, mà là trên một bức tường gần hơn . Điều này có thể đạt được bằng cách giới thiệu một mã băm .

Một mã băm nên có mục đích để xác định duy nhất và gắn nhãn vị trí hiện tại trên bảng. Mục đích không phải là để tìm hiểu vị trí (x, y) là gì, mà là để trả lời các câu hỏi mà tổ tiên của tôi đã có trước đây trên vị trí này?

Giả sử bạn sẽ có một bảng hoàn chỉnh trước mặt và bạn sẽ tạo ra một jpg của mỗi ô vuông 5 x 5 có thể. Bạn sẽ kết thúc với (53-5) x (15-5) = 380 hình ảnh. Hãy đưa ra những hình ảnh số từ 1 đến 380. chúng tôi hashcode nên được xem như một ID như vậy, với điều đó khác nhau mà nó không chạy từ 1 đến 330, nhưng đã mất tích IDS, vì vậy ví dụ như 563, 3424, 9424, 21.245, vv

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;
    }
}       

Các số nguyên tố 1731nằm trong đó để ngăn thông tin được thêm vào đầu trong vòng lặp biến mất. Sau đó, về cách tích hợp mã băm của chúng tôi vào phần còn lại của chương trình.

Cho phép thay thế cơ chế thuê bao "nhìn những gì vượt ra ngoài" bằng một cơ chế thuê bao khác. Khi hai hoặc ba ô có điểm chính bằng nhau, sẽ có 50% cơ hội chọn ô trên cùng, 50% khả năng các ô phía dưới được chọn và 0% cơ hội sẽ chọn ô giữa. Cơ hội sẽ không được xác định bởi trình tạo ngẫu nhiên, mà bằng các bit từ bộ nhớ , vì theo cách đó chúng tôi đảm bảo rằng trong cùng một tình huống, cùng một lựa chọn được đưa ra.

Trong một thế giới lý tưởng (nơi chúng tôi có một số lượng vô hạn của bộ nhớ), chúng tôi sẽ tính toán một độc đáo hashcode cho tình hình hiện tại của chúng tôi, ví dụ như 25.881, và đi đến vị trí bộ nhớ 25.881 và đọc ở đó nếu chúng ta nên chọn ô trên cùng hoặc dưới cùng (khi có là một số điểm bằng nhau). Theo cách đó, chúng ta sẽ ở trong tình huống chính xác (khi chúng ta đi du lịch lần thứ hai và bắt đầu ở cùng một vị trí) đưa ra các quyết định tương tự. Vì chúng tôi không có bộ nhớ vô hạn, chúng tôi sẽ áp dụng một modulo có kích thước của bộ nhớ khả dụng cho mã băm . Mã băm hiện tại là tốt theo nghĩa phân phối sau hoạt động modulo là đồng nhất.

Khi con cái đi cùng một bảng với DNA thay đổi một chút, trong hầu hết các trường hợp (> 99%) sẽ đưa ra quyết định chính xác như nhau. Nhưng càng đi xa, cơ hội trở nên lớn hơn là con đường của anh ta khác với tổ tiên của anh ta. Vì vậy, cơ hội mà anh ta sẽ bị mắc kẹt trên bức tường phía trước này là rất nhỏ. Mặc dù bị mắc kẹt trên cùng một bức tường gần đó vì tổ tiên của anh ta tương đối lớn, nhưng điều này không quá tệ, vì anh ta sẽ không tạo ra nhiều đứa con. Nếu không có cách tiếp cận hashcode , cơ hội bị mắc kẹt trên bức tường gần đó và gần như là gần như nhau

Tối ưu hóa

Sau khi tối ưu hóa, kết luận rằng bảng nhận dạng bẫy là không cần thiết và 2 bit cho mỗi màu là đủ. Phần còn lại của bộ nhớ 100-2x16 = 68 bit được sử dụng để lưu trữ mã băm. Có vẻ như cơ chế mã băm có thể tránh bẫy.

Tôi đã tối ưu hóa cho 15 thông số. Mã này bao gồm tập hợp các tham số được điều chỉnh tốt nhất (cho đến nay):

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};
}   

Điểm: 922 (chạy 2K)

50 điểm đầu tiên (9 trận chỉ ghi được 1 điểm):

112.747 3 1

Đây là chương trình C ++ đầu tiên của tôi. Tôi có hầu hết các bạn bây giờ nền tảng trong phân tích gnome. Tôi muốn cảm ơn các nhà tổ chức, vì tôi thực sự thích làm việc này.

Nếu bạn có bất kỳ thông tin phản hồi, xin vui lòng để lại một bình luận dưới đây. Lời xin lỗi cho các văn bản dài.


Tôi thấy phân tích bẫy của bạn khá thú vị.

Bạn đã thử một hàm băm khác, chẳng hạn như xending 25 giá trị màu được xem là 12,5 16 bit từ và lấy một modulo? Tôi không tin rằng sự đồng dạng số nguyên tố mang lại sự đồng nhất tốt hơn, nhưng tôi không phải là nhà toán học lớn.

Ngoài ra, bạn đã xem xét thêm một thuật toán đường dẫn? Nó dường như là một yếu tố cải tiến rất lớn bất kể bộ gen, vì nó sẽ hạn chế việc di chuyển đến những người kiểm tra khả năng của bộ gen chỉ dọc theo những con đường có nhiều khả năng dẫn đến vị trí chiến thắng.

Kuroi, cảm ơn phản hồi của bạn. Tôi đã không thử xending, vì tôi không quá quen thuộc với các hoạt động nhị phân trong c ++. Tôi giả sử bạn có nghĩa là 12,5 8 bit từ? Bạn đang sử dụng xoring?
Ruut

Bạn có thể xem mã "tín đồ cứng" của tôi để xem loại hàm băm nào tôi sử dụng. Về cơ bản, tôi bỏ qua các ô không theo dõi và xem xét các màu trên đường đua là các phần có thứ tự cao và thấp của một từ 16 bit. Tất cả những từ này được tích lũy với XOR trong một thanh ghi sau đó được chia cho kích thước bảng băm. Miễn là giá trị băm tối đa (65535) cao hơn nhiều so với kích thước bảng (<100), modulo có khả năng lan truyền tốt. Tôi đã thử nghiệm nó trên một loạt các lưới được tạo ngẫu nhiên và nó dường như có tính đồng nhất tốt.

6

Pathfinder, C ++, điểm sơ bộ 35.8504 (50 vòng)

Một cuộc đại tu hoàn chỉnh! Tôi đã chuyển thuật toán của mình sang C ++ và điều chỉnh nó một chút, nhưng điểm số vẫn không cao lắm, có lẽ là do lũ chuột cứ đập đầu vào tường. Tôi mệt mỏi vì cố gắng cải thiện điều này, vì vậy tôi sẽ chỉ để nó bây giờ.


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};
}

Giải trình

Ý tưởng chung là phân loại từng màu là bẫy hay không, sau đó gán chỉ đường cho bẫy và trọng lượng cho các bẫy không và cố gắng đi theo đường dẫn có trọng lượng tối thiểu đến đường viền bên phải của lưới tầm nhìn.

Trong 80 bit đầu tiên của bộ gen, mỗi màu được phân loại bằng 5 bit abcde. Nếu ab = 01, màu sắc là một cái bẫy và cdemã hóa hướng của nó (tám khả năng). Nếu ab ≠ 01, màu sắc không phải là một cái bẫy, và trọng lượng của nó là a + b + 2*(c + d + e).

Tiếp theo, chúng tôi khởi tạo lưới 3x7, đại diện cho trường nhìn của chuột ở bên phải, được đệm bằng các màu "không xác định". Các bit 80-84 mã hóa trọng lượng của các ô chưa biết tương tự như các màu không bẫy và các bit 85-89 mã hóa trọng lượng chung cho các bẫy. Chúng tôi điền vào lưới với các trọng số, tính toán các đường đi ngắn nhất và thêm một số trọng lượng bổ sung (được mã hóa trong các bit 90-95) vào các ô ngay bên trên và bên dưới con chuột để ngăn chặn việc vượt qua. Các bit 95-99 mã hóa trọng lượng mục tiêu. Nếu trọng lượng tối thiểu của một con đường nằm dưới nó, con chuột có thể bị mắc kẹt ở đâu đó và tiến hành di chuyển ngẫu nhiên (nhưng không bao giờ quay lại). Mặt khác, nó đi theo con đường trọng lượng tối thiểu. Với một xác suất nhỏ tùy thuộc vào trọng lượng ngăn chặn sidestep, chuột chọn con đường trọng lượng thứ hai đến tối thiểu thay thế. Điều này là để tránh bị mắc kẹt vào tường (nhưng có vẻ như nó không hoạt động tốt ngay bây giờ).


Ran thực hiện của bạn trên máy tính của tôi. Mất vài giờ. Nó được điểm trung bình là 7.848433940863856 điểm. pastebin.com/d50GcwnK
Jakube

@Jakube Cảm ơn rất nhiều! Điều đó tồi tệ hơn nhiều so với những gì tôi mong đợi, nhưng bây giờ khi tôi nhìn lại mã, tôi thấy một số lỗi và những điều kỳ lạ khác. Tôi sẽ cố gắng chuyển cái này sang C ++ sau để tôi có thể tự phân tích nó.
Zgarb

5

LookAheadPlayer C ++ 89.904

Suy nghĩ ban đầu của tôi là tìm kiếm 4 bit phù hợp với màu mà tôi đang tìm kiếm và sử dụng một vài bit sau đây làm điểm số. Điều này hóa ra là một ý tưởng khủng khiếp, có thể là do đột biến.

Vì vậy, tôi đã nghĩ về các cách bảo vệ chống lại các đột biến và chéo, và nó nhắc nhở tôi về công việc mà tôi đã thực hiện khi giải mã mã QR. Trong mã QR, dữ liệu được chia thành các khối và sọc để tránh lỗi phá hủy quá nhiều phần dữ liệu nhất định.

Do đó, giống như ColorScorePlayer, tôi đã cắt DNA thành 16 đoạn và sử dụng chúng làm điểm số cho trước. Tuy nhiên, điểm số được sọc để các bit riêng lẻ của mỗi điểm không liền kề nhau. Sau đó, tôi tổng hợp điểm của cả hai nước đi hiện tại và các nước đi tiềm năng tiếp theo và chọn nước đi tốt nhất để thực hiện.

Lưu ý: điều này đã được mã hóa / thử nghiệm trên MinGW. Nó sẽ không biên dịch với tối ưu hóa, hoặc với đa luồng. Tôi không có cài đặt Linux thực tế hoặc Visual Studio tiện dụng để sử dụng trình biên dịch nơi những thứ này sẽ hoạt động. Tôi sẽ kiểm tra nhanh vào sáng mai, nhưng xin vui lòng cho tôi biết nếu bạn gặp phải bất kỳ vấn đề nào.

// 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 ++ (điểm 9.7)

Chúng ta không thể dựa vào việc diễn giải các đoạn của bộ gen dưới dạng số vì một lần lật bit có thể có các hiệu ứng hoàn toàn khác nhau phụ thuộc vào vị trí của nó. Đó là lý do tại sao tôi chỉ cần sử dụng 16 phân đoạn 6 bit và ghi điểm cho số 1s. Ban đầu 111111là tốt và 000000xấu, và về lâu dài không thành vấn đề (một khi bộ gen được phát triển đầy đủ) trong cấu hình ban đầu của DNA, hầu hết các phân đoạn đều có 2-4, vì vậy tôi đã chuyển sang sử dụng 9 - (#1 - 3)^2để ghi điểm, điều này cho phép tự do di chuyển hơn nhiều trong các vòng đầu tiên và tiến hóa nhanh hơn.

Ngay bây giờ tôi chỉ nhìn vào 7 hàng xóm gần nhất, thêm độ lệch hướng cho điểm màu và di chuyển theo một trong những hướng cao nhất một cách ngẫu nhiên.

Mặc dù bản thân điểm số không cao lắm, nhưng các sinh vật của tôi đạt đến đích và đạt điểm> 1 trong 3/4 trường hợp.

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]};
}

Và một điểm mẫu trên 100 bảng

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

Điểm trung bình hình học: 9.76557


Là số điểm bạn đề cập cho một bảng bằng cách sử dụng tỷ lệ đột biến tiêu chuẩn hoặc giá trị điều chỉnh của bạn?
trichoplax

"Những sinh vật của tôi đạt đến đích và đạt điểm> 1 trong 3/4 trường hợp" Tôi ước số liệu chấm điểm được thưởng này
Sparr

5

Lựa chọn trọng lượng | C # | Điểm: 220.8262 trong 1520 Trò chơi

Tính trọng lượng cho lần di chuyển tiếp theo có thể (màu xanh) dựa trên trọng lượng trung bình của các lần di chuyển tiếp theo có thể (màu vàng)

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 (không phải là câu trả lời, mà là một công cụ đồ họa cho bot C ++)

Kể từ khi bắt đầu thử thách này, tôi đã gặp khó khăn trong việc tìm ra những con chuột thực sự phải đối mặt trên đường đua.
Cuối cùng, tôi đã hack bộ điều khiển và viết một công cụ phụ để có được một số biểu diễn đồ họa của một bản nhạc.
Cuối cùng tôi đã thực hiện thêm một số hack và thêm một hình dung về các đường có thể có của DNA của một con chuột nhất định.

Bản đồ cực kỳ lộn xộn và đòi hỏi một chút làm quen, nhưng tôi thấy nó khá hữu ích để hiểu cách các bot của tôi hoạt động.

Đây là một ví dụ:

theo dõi mẫu

Có lẽ bạn sẽ cần phóng to để xem bất cứ điều gì, vì vậy đây chỉ là nửa đầu:

một nửa bài hát (không có ý định chơi chữ)

Đầu tiên, chúng ta hãy nhìn vào con đường của chuột. Có một đường dẫn cho mỗi vị trí bắt đầu có thể (thường là 15, đôi khi ít hơn một chút). Thông thường họ có xu hướng hợp nhất, lý tưởng dẫn đến một vị trí chiến thắng duy nhất.

Các đường dẫn được thể hiện bằng các mũi tên thẳng lớn. Màu sắc mô tả kết quả:

  • màu xanh lá cây: chiến thắng
  • màu vàng: vòng lặp vô hạn
  • nâu: đập tường
  • đỏ: tai nạn đáng tiếc

Trong ví dụ, chúng ta có 12 vị trí bắt đầu chiến thắng, một vị trí dẫn đến một vòng lặp vô hạn và hai đến cái chết mệt mỏi (bị dịch chuyển vào một cái bẫy, như nó xuất hiện).

Sự không liên tục của đường dẫn là do dịch chuyển tức thời, mà bạn có thể theo dõi với các mũi tên cong tương ứng.

Bây giờ cho các biểu tượng màu. Chúng đại diện cho ý nghĩa của 16 màu (những màu xám đại diện cho những gì một con chuột nhìn thấy).

  • tường: vuông
  • dịch chuyển tức thời: 4 sao phân nhánh
  • bẫy phát hiện: octogon nhỏ

màu sắc trống rỗng ... cũng ... trống rỗng.

Dịch chuyển tức thời có mũi tên đi ra chỉ đến đích của họ.

Máy dò bẫy cũng có mũi tên chỉ ra bẫy, được hình là một vòng tròn màu đỏ.
Trong một trường hợp trong số 9, bẫy được đặt trong cùng một ô với máy dò của nó, trong trường hợp đó bạn sẽ thấy octogon nhỏ trên đỉnh của vòng tròn màu đỏ.

Đây là trường hợp cho cái bẫy màu vàng nhạt trong ví dụ này.
Bạn cũng có thể thấy các máy dò bẫy màu hoa cà chỉ xuống bẫy được chỉ định của chúng.

Lưu ý rằng đôi khi vòng tròn màu đỏ của bẫy sẽ bị ẩn dưới một bức tường. Cả hai đều gây chết người nên kết quả là như nhau trong trường hợp dịch chuyển tức thời.
Cũng lưu ý rằng một cái bẫy có thể được đặt trên một thiết bị dịch chuyển tức thời, trong trường hợp đó, dịch chuyển tức thời được ưu tiên (tức là chuột bị dịch chuyển trước khi rơi vào bẫy, có hiệu lực vô hiệu hóa bẫy).

Cuối cùng, các biểu tượng màu xám đại diện cho những gì chuột của tôi nhìn thấy (nghĩa là các thuộc tính bộ gen của chúng với màu sắc).

  • tường: vuông
  • máy dò bẫy: octogon
  • bẫy: X

Về cơ bản, tất cả các tế bào ngồi trên một hình vuông màu xám được coi là bức tường của chuột.
Big X là đại diện cho các tế bào được coi là bẫy, với các octogon tương ứng chỉ ra máy dò báo cáo chúng.

Trong ví dụ này, cả hai bức tường được xác định là như vậy, như cái bẫy màu vàng nhạt (biểu thị thực sự là một tế bào chết người, vì vậy đại diện cho nó là một bức tường là chính xác).
Máy dò bẫy màu hoa cà đã được xác định như vậy (nó nằm trên một octogon màu xám), nhưng vị trí bẫy không chính xác (bạn có thể thấy rằng một số vòng tròn màu đỏ không có đường chéo dưới chúng).

Trong số 4 dịch chuyển tức thời, 2 được coi là các bức tường (màu ngọc lam và màu nâu) và 2 là các ô trống (màu đỏ và hơi vàng).

Một vài ô trống được coi là máy dò bẫy hoặc tường. Nhìn kỹ, bạn có thể thấy rằng các "máy dò lỗi" này thực sự đang cấm xâm nhập vào các tế bào sẽ khiến chuột gặp rắc rối, vì vậy mặc dù chúng không khớp với màu sắc thực, chúng có mục đích rõ ràng.

Mật mã

Vâng, đó là một mớ hỗn độn, nhưng nó hoạt động khá tốt.

Nhìn từ mã của người chơi, tôi chỉ thêm một giao diện: một hàm theo dõi được sử dụng để báo cáo ý nghĩa của một DNA đã cho. Trong trường hợp của tôi, tôi đã sử dụng 3 loại (tường, bẫy dò và trống) nhưng về cơ bản bạn có thể xuất ra bất cứ thứ gì liên quan đến màu sắc (hoặc không có gì cả nếu bạn không muốn có đồ họa liên quan đến bộ gen).

Tôi đã hack bộ điều khiển để tạo ra một chuỗi ký tự khổng lồ đối chiếu mô tả theo dõi và màu sắc với "chạy khô" DNA của chuột từ tất cả các vị trí có thể.

Nó có nghĩa là kết quả sẽ thực sự có ý nghĩa chỉ khi bot không sử dụng các giá trị ngẫu nhiên. Mặt khác, các đường dẫn được hiển thị sẽ chỉ đại diện cho một kết quả có thể.

Cuối cùng, tất cả các dấu vết này được đưa vào một tệp văn bản lớn mà sau đó được đọc bởi một tiện ích PHP tạo ra đầu ra đồ họa.

Trong phiên bản hiện tại, tôi chụp ảnh nhanh mỗi khi một con chuột chết sau khi đạt được thể lực tối đa mới (điều đó cho thấy khá rõ sự tinh chỉnh tiến bộ của bộ gen mà không yêu cầu quá nhiều ảnh chụp nhanh) và ảnh chụp nhanh cuối cùng vào cuối trò chơi (điều đó cho thấy DNA thành công nhất).

Nếu ai đó quan tâm tôi có thể xuất bản mã.

Rõ ràng điều này chỉ hoạt động với các bot C ++ và bạn sẽ cần phải viết một hàm theo dõi có thể sửa đổi mã PHP nếu bạn muốn hiển thị một số dữ liệu cụ thể về bộ gen (các số liệu màu xám trong trường hợp của tôi).
Ngay cả khi không có thông tin cụ thể về DNA, bạn có thể thấy các đường dẫn theo DNA của mình trên bản đồ nhất định với rất ít nỗ lực.

Tại sao một đầu ra trung gian?

Trước hết, C ++ không có thư viện đồ họa di động phong nha để nói đến, đặc biệt là khi sử dụng MSVC. Ngay cả khi các bản dựng Win32 thường có sẵn, chúng thường xuất hiện như một suy nghĩ và số lượng thư viện bên ngoài, các gói và các chi tiết giống như unix khác cần làm cho việc viết một ứng dụng đồ họa đơn giản và nhanh chóng trở thành nỗi đau khủng khiếp trong một phần của cơ thể tôi từ đặt tên.

Tôi đã cân nhắc việc sử dụng Qt (về môi trường duy nhất giúp phát triển GUI / đồ họa di động trong C ++ trở thành một nhiệm vụ đơn giản và thậm chí dễ chịu, IMHO - có lẽ vì nó bổ sung một hệ thống nhắn tin à la Objective C mà C ++ vô cùng thiếu và thực hiện một công việc đáng kinh ngạc là hạn chế bộ nhớ quản lý ở mức tối thiểu), nhưng điều này có vẻ như quá mức cho nhiệm vụ trong tay (và bất kỳ ai muốn sử dụng mã sẽ phải cài đặt SDK lớn - hầu như không đáng để bỏ công sức, tôi đoán vậy).

Ngay cả khi giả sử một thư viện di động, không có yêu cầu về tốc độ để nói (một giây hoặc lâu hơn để tạo ra một bức ảnh là đủ) và với độ cứng của câu tục ngữ và sự lộn xộn vốn có của nó, C ++ chắc chắn không phải là công cụ tốt nhất cho công việc.

Hơn nữa, có một đầu ra văn bản trung gian thêm rất nhiều tính linh hoạt. Khi dữ liệu đã ở đó, bạn có thể sử dụng chúng cho các mục đích khác (ví dụ: phân tích hiệu suất của các bot).

Tại sao lại là PHP?

Tôi thấy ngôn ngữ cực kỳ đơn giản và dễ thích nghi, rất thuận tiện cho việc tạo mẫu. Tôi đã biến nó thành ngôn ngữ thú cưng của mình cho các thử thách mã không đòi hỏi các màn trình diễn khắc nghiệt.
Mặc dù đó là một ngôn ngữ khủng khiếp để chơi golf, nhưng dù sao thì golf cũng chưa bao giờ là tách trà của tôi.

Tôi cho rằng python hoặc Ruby sẽ dễ chịu khi sử dụng cho cùng một mục đích, nhưng tôi chưa bao giờ có cơ hội thực hiện một số công việc nghiêm túc với chúng, và tôi đã làm việc trên các trang web gần đây, vì vậy PHP là như vậy.

Ngay cả khi bạn không biết ngôn ngữ, việc sửa đổi mã cho phù hợp với nhu cầu của bạn cũng không quá khó khăn. Chỉ cần đừng quên $s trước các biến, giống như những ngày cơ bản cũ :).


1
Bạn sẽ vui lòng chia sẻ công cụ của bạn? Tôi không thấy mã hay liên kết trong câu trả lời của bạn.
Franky

5

SkyWalker - Python - đạt ít hơn 231 trong 50 trò chơi

Vì vậy, mã đầu tiên và sau đó một số giải thích. Tôi hy vọng không có gì phá vỡ trong khi sao chép.

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])

Một số giải thích

Theo tôi, sự khác biệt chính là tôi không mã mỗi màu. Thay vào đó, tôi cố gắng lưu số lượng màu sắc quan trọng. Theo tôi những màu sắc đó là bẫy, tường và dịch chuyển tức thời. Mẫu vật không cần biết màu của một tế bào tốt. Do đó, bộ gen của tôi được cấu trúc theo cách sau.

  • 2 x 8 bit cho bẫy, 4 bit đầu tiên là số màu, 4 bit còn lại là phần bù
  • 2 x 4 bit cho tường, chỉ màu
  • 4 x 7 bit cho dịch chuyển tức thời, lại 4 bit cho màu, 3 để quyết định tốt hay xấu

Điều này làm cho tổng số 52 bit được sử dụng. Tuy nhiên, tôi chỉ sử dụng bit đầu tiên trong số 3 bộ giải mã dịch chuyển tức thời (tôi kiểm tra xem số này có lớn hơn 3 không). Do đó, 2 cái còn lại có thể bị xóa, để lại cho tôi 44 bit được sử dụng.

Trên mỗi lượt, tôi kiểm tra mọi trường trong tầm nhìn của tôi nếu đó là một màu xấu (+ ngoài bảng -1) và thêm nó vào danh sách các trường mà mẫu vật không muốn di chuyển đến. Trong trường hợp bẫy, tôi thêm trường nằm trên phần bù đã lưu cho màu bẫy đó.

Dựa trên danh sách các trường xấu đó, bước tiếp theo được tính toán. Thứ tự của các lĩnh vực ưa thích là:

  1. ở đằng trước
  2. lên hoặc xuống
  3. ngược lên hoặc xuống
  4. ngược

Nếu hai trường của một thể loại được áp dụng, một trường được chọn ngẫu nhiên.

Các kết quả

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

Suy nghĩ

  • Tôi không biết, nếu tôi gặp may mắn với 50 lần chạy hoặc nếu thực sự có một chút khôn ngoan trong chiến lược của tôi.

  • Những bước chạy của tôi dường như không bao giờ cất cánh và đạt điểm siêu cao nhưng họ cũng có xu hướng tìm thấy ít nhất một vài lần mục tiêu

  • Một số ngẫu nhiên nhỏ là tốt để không bị mắc kẹt trong một cái bẫy ở gần cuối cuộc đua

  • Tôi nghĩ màu sắc không đặc biệt không bao giờ là xấu. Tuy nhiên, các trường hợp của chúng có thể là xấu, khi chúng ở trên phần bù của một cái bẫy. Do đó, ghi nhãn màu xấu nếu nó không bẫy, tường hoặc dịch chuyển tức thời xấu không có ý nghĩa.

  • Tường là kẻ thù lớn nhất

Cải tiến

Đầu tiên, mặc dù tôi sẽ bỏ lỡ khi nhìn thấy các ô vuông màu đen di chuyển ngày càng gần mục tiêu hơn, một cổng C ++ là cần thiết để tiến hành nhiều thử nghiệm hơn và nhận được kết quả có ý nghĩa hơn.

Một trong những vấn đề chính là nếu có những tế bào xấu (hoặc những mẫu vật cho rằng xấu) trước con chuột, nó dễ dàng bắt đầu di chuyển lên xuống theo vòng tròn. Điều này có thể được dừng hoặc giảm bằng cách nhìn 2 bước về phía trước trong những trường hợp đó và ngăn không cho nó di chuyển đến một trường nơi nó sẽ di chuyển trở lại.

Thường thì sẽ mất khá nhiều thời gian cho đến khi một con chuột có gen tốt đạt được mục tiêu và bắt đầu truyền bá gen. Có lẽ tôi cần một số chiến lược để tăng sự đa dạng trong những trường hợp đó.

Vì dịch chuyển tức thời rất khó tính, có lẽ tôi nên chia dân số ở những người có rủi ro và luôn luôn có những người dịch chuyển tốt và những người quan tâm hơn và chỉ lấy họ nếu không có lựa chọn nào khác.

Tôi nên sử dụng nửa sau của bộ gen của mình bằng cách nào đó.


Tôi cũng cố gắng lưu trữ màu sắc nhưng cuối cùng kết luận nó không hoạt động vì bạn sẽ nhận được gấp đôi. Ví dụ: nếu self.bit_chunk(16, 4)self.bit_chunk(20, 4)có cả giá trị 0010bạn có chỉ lưu trữ thông tin về một trong hai bẫy một cách hiệu quả.
Ruut

Tôi cần thêm thụt vào một dòng để chạy cái này - tôi đoán nó bị mất trong khi sao chép và dán. Tôi đã thêm nó vào mã của bạn ở đây bây giờ quá.
trichoplax

Đối với bất kỳ ai khác muốn chạy cái này: Nó chạy trong python 2 và có thể chạy trong python 3 bằng cách thay đổi lần xuất hiện duy nhất itervaluesthành values.
trichoplax

Tôi nhận được các kết quả sau: [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] Trung bình hình học 122.9220309940335
trichoplax

Có vẻ như chúng tôi cần chạy hơn 50 trò chơi để có được số điểm đáng tin cậy.
trichoplax

3

Python, NeighborOfNeighbor, Điểm = 259.84395 trên 100 trò chơi

Đây là một biến thể trên ColorScorePlayer. Cứ 6 bit lưu một điểm chất lượng cho một hình vuông. Khi bot thực hiện một động tác, nó sẽ ghi điểm trong 3 ô vuông phía trước - chéo lên, tiến lên và chéo xuống. Điểm số là chất lượng của hình vuông cộng với một nửa chất lượng trung bình của 3 hình vuông tiếp theo. Điều này mang lại cho bot một số cái nhìn về phía trước, mà không áp đảo chất lượng của hình vuông đầu tiên. Thuật toán tương tự như LookAheadPlayer, điều mà tôi không thấy trước khi viết giải pháp này.

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)

Có vết lõm bị thiếu trên một dòng. Tôi đoán nó đã bị mất khi dán vào. Tôi đã thêm nó vào.
trichoplax

Chạy trong python 3 nó phàn nàn về việc so sánh Không khi tính max (điểm). Vì vậy, tôi đã thay đổi else Noneđể else 0trên dòng trước đó để tính toán điểm số của bạn. Hy vọng rằng logic của bạn không thay đổi (Tôi đã không thay đổi mã của bạn ở đây trên SE ngoài việc thêm vào phần thụt lề bị mất).
trichoplax

Chạy trong python 3 Tôi đã nhận được số điểm sau cho câu trả lời này: [1, 13085, 360102, 1, 73713, 1, 189, 1, 1, 193613, 34, 195718, 199, 8, 1, 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, 796553, 111340, 1, 25, 40017, 76064, 66478, 209365, 3925393]
trichoplax

Một giá trị trung bình hình học của 428.3750848244933
trichoplax

2

ROUS (Loài gặm nhấm có kích thước khác thường), Java, Điểm = 0

Điều này băm xung quanh để quyết định nơi để đi. Do bộ điều khiển Java không hoạt động, tôi không có điểm cho việc này. Điều này sẽ chỉ nhận được rất xa nếu nó tìm thấy một vài dịch chuyển tức thời để giúp nó.Điều này có xu hướng bị tuyệt chủng và sụp đổ bộ điều khiển một lần trong một thời gian. Điều này có lẽ là do thực tế rằng môi trường tự nhiên của nó là Đầm lầy lửa.

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
Bộ điều khiển Java đang hoạt động.
Martin Ender

3
Lúc đầu, tôi nghĩ rằng bạn đang tỏ lòng tôn kính đối với nước Nga cổ đại, nhưng khi nó xuất hiện thì đó là Rob Reiner.

Điểm tối thiểu có thể là 1
trichoplax

@trichoplax ... làm hỏng bộ điều khiển ...
TheNumberOne

Ồ tôi hiểu rồi - vậy điều đó có xảy ra thường xuyên đến mức bạn không thể đi đến cuối cuộc chạy không?
trichoplax

2

Nhìn màu xám (C ++, ~ 1,35)

Điều này không làm rất tốt trung bình, nhưng trong một dịp hiếm hoi, nó thực hiện tuyệt vời. Thật không may, chúng tôi đang được tính điểm trung bình hình học (1,35) và không đạt điểm tối đa (20077).

Thuật toán này hoạt động bằng cách chỉ sử dụng mã màu xám 4 bit để ánh xạ điểm của từng màu ở đâu đó từ -2 đến 2 (với độ lệch về phạm vi [-1..1]) và tính điểm của từng ô di chuyển và các bước di chuyển tiếp theo của nó . Nó cũng sử dụng mã màu xám 2 bit để xác định hệ số nhân cho chính ô cũng như hệ số sai lệch khi di chuyển sang phải. (Mã màu xám ít bị ảnh hưởng bởi các bước nhảy lớn do đột biến, mặc dù chúng không thực sự có bất kỳ ưu đãi nào cho sự giao nhau giữa tiền mã hóa ...)

Nó cũng hoàn toàn không có gì để cố gắng xử lý các bẫy đặc biệt và tôi nghi ngờ đó có thể là sự sụp đổ (mặc dù tôi chưa thêm bất kỳ thiết bị nào vào bộ điều khiển để kiểm tra lý thuyết này).

Đối với mỗi lần di chuyển có thể, nó sẽ xác định một điểm và trong số tất cả các lần di chuyển có điểm cao nhất, nó sẽ chọn ngẫu nhiên.

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())];
}

Trong lần chạy gần đây nhất, tôi đã đạt được điểm: 1 1 1 1 1 1 1 46 1 1 1 1 1 1 1 1 1 1 2 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 1 1 1 1 1

Tôi ước tôi có thể nhận được nhiều hơn những năm 20077 và ít hơn số 1. :)


1
Sử dụng mã màu xám là một ý tưởng Grayt! ;)
matovitch

1
+1 cho mã Gray. Tuy nhiên, một bộ gen hoàn toàn đột biến sẽ làm tổn thương sự đa dạng khá nhiều. Và Btw điểm 20.000 thậm chí không gần mức tối đa bạn có thể đạt được. Nếu một số con chuột phát triển khả năng chạy đường đua từ bất kỳ vị trí bắt đầu có thể nào, nó sẽ có hiệu lực bất tử và có được số điểm thể lực rất lớn. Bộ gen của nó nhanh chóng chiếm ưu thế, dẫn đến một quần thể lên tới gần 50 nghìn con chuột và số điểm vài triệu.

2

C ++, TripleScore, Điểm: 100 ~ 400

Trước hết, điểm của tôi thay đổi rất nhiều qua nhiều lần chạy (chủ yếu là do số lượng 1).

Cốt lõi tính toán điểm của 5 hướng: lên, xuống, tiến lên, tiến lên và xuống trước. Đầu tiên, điểm số lên và xuống được tính toán, so với kết quả được so sánh với giá trị của việc giữ nguyên vị trí. Nếu ở tại chỗ tốt hơn là di chuyển lên hoặc xuống, những hướng này sẽ không được chọn (vì vậy nó phải đi tiếp). Điều này là để ngăn chặn việc nảy (lên, xuống, lên, xuống, ...) giữa 2 điểm.

Bây giờ 3 hướng khác được ghi: tiến lên, thẳng tiến và xuống dưới. Từ tất cả các hướng điều tra, những người có số điểm cao nhất được giữ và 1 trong số họ được chọn ngẫu nhiên.

Ghi điểm theo hướng: TripleScore tính toán điểm của một phong trào bằng cách sử dụng 3 điểm con:

  • Điểm số của màu của điểm đến (tùy thuộc vào dna, như trong colorScorePlayer)
  • Điểm của đi tiếp (phụ thuộc vào dna)
  • Điểm tối đa của việc di chuyển về phía trước từ đích (nhân với một yếu tố được lưu trữ trong dna)

Cũng như các câu trả lời khác, điểm số phụ thuộc rất nhiều vào số điểm 1 được trả về.

#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 - Xác suấtScorePlayer

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

Con chuột không có tính quyết định cao này tính toán xác suất để đi vào một không gian bởi khu vực lân cận. 16 vị trí đầu tiên trong bộ gen đại diện cho 16 màu. 1 trong một khe có nghĩa là màu sắc tốt để bước lên, 0 có nghĩa là xấu. 16 người tiếp theo giữ tương tự cho khoảng trống phía trước mục tiêu của bạn, v.v.

Ưu điểm chính của phương pháp xác suất là gần như không thể bị mắc kẹt sau một bức tường lâu. Nhược điểm là bạn sẽ gần như không bao giờ có được một con chuột gần như hoàn hảo.


+1 cho tính nguyên bản. Những loại điểm bạn đã nhận được?

Chưa bao giờ thực sự thử nghiệm nó ...
MegaTom

Bạn đã quên đưa ra cmột giá trị ban đầu? Nó dường như không được xác định khi bạn sử dụng nó lần đầu tiên if.
Martin Ender

@ MartinBüttner vâng tôi đã quên. Tôi sẽ sửa nó ngay bây giờ.
MegaTom

Tôi không biết rõ về Ruby, nhưng mã của bạn không chạy trong Ruby2.1.5. coordskhông phải là một danh sách, bạn sử dụng &&thay vì andvà quên dấu ngoặc đơn và thậm chí sau khi sửa tất cả những điều này, bạn không bị ràng buộc các giá trị RNG để bạn nhận được một hướng trống. Đây có phải là mã giả, hoặc một cái gì đó có nghĩa là được chạy với một loại phương ngữ Ruby?

2

Java, Runningstar, Điểm = 1817.050970291959 trên 1000 trò chơi

Bot này sử dụng mã màu của Run-Bonus với kỹ thuật của StarPlayer .

Cập nhật: Đã sửa lỗi bộ điều khiển java.

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

Không đặc biệt đột phá nhưng đó là nỗ lực duy nhất của tôi thực hiện 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)

Về cơ bản, nó mã hóa bốn màu (mỗi 4 bit) để tránh, trong bộ gen. Sau đó, nó chuyển sang màu không có trong danh sách đó. Nếu tất cả các màu là xấu, nó vẫn nhảy về phía chưa biết.


Có lẽ nên gọi nó là "RedQueen" :)
plannapus

1

Java - IAmARobotPlayer - Điểm 3.7

Tôi chỉ tạo ra con chuột robot này để so sánh với một chương trình khác (không thú vị lắm) cho đến nay. Nó không đạt điểm cao về tổng thể nhưng nếu nó ghi được ở đâu đó, nó sẽ nhận được nhiều con chuột. Ý tưởng là nó sẽ chỉ nhìn vào ba ô phía trước nó, mỗi ô là tốt hay xấu. Điều này cho một số nhị phân. Sau đó, nó sẽ tìm kiếm số này trong bộ gen của nó, lấy ba bit liên tiếp, cũng hội tụ chúng thành một số và thực hiện hành động được lưu trữ dưới số này. Vì vậy, nó luôn luôn hành động giống nhau khi gặp tình huống tương tự.

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];

    }
}

Kết quả:

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

Mẫu vật thận trọng - C ++ - đạt khoảng 2030 trên 200 lượt chạy

Điều này sử dụng phần màu (16x4 bit) của mã hóa DNA từ Blind Faith nhưng phần còn lại ( 36 bit) của DNA hoàn toàn không được sử dụng.

Mã hóa cho một màu là:

  • 10XX - cho hình vuông an toàn;
  • 11XX - cho hình vuông gây chết người; và
  • 0000 đến 0111 - cho 8 loại hình vuông bẫy.

Trong đó X chỉ ra các bit không được sử dụng. Cho rằng chỉ có 2 trong số 16 màu là các bẫy sẽ sử dụng tất cả 4 bit của chúng (và chỉ khi bẫy được bù, đó sẽ là trường hợp 8 trong 9 lần), thông thường sẽ có 64 bit không được sử dụng - lý thuyết là các đột biến ảnh hưởng đến bất kỳ bit nào không được sử dụng này sẽ không phá hủy bộ gen và tính ổn định tốt hơn bất kỳ giải pháp ưa thích nào có thể sử dụng các bit còn lại.

Các mẫu vật sau đó sử dụng phương pháp này để lập kế hoạch tuyến an toàn trong lưới 7x7 tập trung vào chính chúng (5x5 tầm nhìn của chúng cho phép cộng 1 ô vuông mỗi bên để cho phép bẫy bù) ưu tiên di chuyển khoảng cách lớn nhất về phía trước sau 3 lần di chuyển.

Ban đầu tôi đã bắt đầu xây dựng trong một số kiểm tra để đảm bảo rằng thực tế rằng màu sắc của mẫu vật hiện đang tồn tại không gây chết người tương ứng với bộ gen và gắn cờ bất kỳ màu sắc sai lầm nào như hình vuông của sự an toàn của UNSURE (và hình vuông liền kề của chúng) - tuy nhiên nó đã thêm đáng kể sự phức tạp đối với ít hoặc không đạt được so với việc đánh dấu các ô vuông đó là AN TOÀN và giết chết một vài mẫu vật bổ sung. Tôi sẽ trở lại điều này nếu tôi có thời gian.

#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};
}

Điểm mẫu:

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

Điểm tối đa trong quá trình thử nghiệm: 8.150.817 Mẫu đã lưu.


Bây giờ bạn đã làm điều đó ... Tôi muốn lưu lại đường dẫn cho sau này, nhưng tôi không thể để các loài gặm nhấm thận trọng của bạn không bị cản trở :) Khi nó xuất hiện, đường dẫn hoạt động thậm chí còn tốt hơn với mã hóa hiệu quả hơn. Ý tưởng của bạn về việc mở rộng khu vực đường dẫn lên 7x7 dường như cũng đầy hứa hẹn. Tôi sẽ xem nếu tôi có thể sử dụng nó.

Tôi hiện đang thực hiện 2000 hoạt động này ... sau 900 đầu tiên, giá trị trung bình dường như ổn định khoảng 600, khá xa so với năm 2000. Bạn có phiền khi chạy lại nó không, để xem 2000 có phải không chỉ là một con sán?
Martin Ender
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.