Cuộc chiến Nano Core


21

Đây là một sự thích nghi của Core War , một chương trình KOTH lập trình có từ thế kỷ 20. Để cụ thể hơn, nó đang sử dụng một bộ hướng dẫn cực kỳ đơn giản chủ yếu dựa trên đề xuất ban đầu .

Lý lịch

Trong Core War, có hai chương trình chiến đấu để kiểm soát máy tính. Mục tiêu của mỗi chương trình là giành chiến thắng bằng cách định vị và chấm dứt chương trình đối nghịch.

Trận chiến diễn ra trong bộ nhớ chính của máy tính. Bộ nhớ này được gọi là Core và chứa 8192 địa chỉ. Khi trận chiến bắt đầu, mã cho mỗi đối thủ (được gọi là chiến binh) được đặt trong một đoạn bộ nhớ ngẫu nhiên. Thực hiện chương trình xen kẽ giữa các chiến binh, thực hiện một chỉ dẫn của mỗi chiến binh. Mỗi hướng dẫn có khả năng sửa đổi một phần của Lõi, dẫn đến khả năng tự sửa đổi chương trình.

Mục tiêu là chấm dứt chương trình đối lập. Một chương trình chấm dứt khi nó cố thực hiện một lệnh không hợp lệ, đó là bất kỳ DATlệnh nào .

Bộ hướng dẫn

Mỗi chương trình bao gồm một loạt các hướng dẫn cấp thấp, mỗi hướng dẫn có hai trường, được gọi là trường A và B.

Bộ hướng dẫn này rút ra rất nhiều từ thông số ban đầu. Những thay đổi chính là 1) làm rõ về việc thêm / bớt các lệnh và 2) thay đổi #chế độ địa chỉ để cho phép nó được sử dụng ở bất cứ đâu. Hầu hết các phiên bản đầy đủ của Core Wars có hơn 20 opcodes, 8 chế độ địa chỉ và một bộ "sửa đổi hướng dẫn".

Mã nguồn

Mỗi hướng dẫn phải có một trong bảy opcodes khác nhau.

  • DAT A B- (dữ liệu) - Điều này chỉ đơn giản là giữ các số AB. Điều quan trọng là, một quá trình sẽ chết khi nó cố thực hiện một lệnh DAT.
  • MOV A B- (di chuyển) - Thao tác này sẽ di chuyển nội dung của vị trí Abộ nhớ sang vị trí bộ nhớ B. Đây là một minh chứng trước và sau:

    MOV 2 1
    ADD @4 #5
    JMP #1 -1
    
    MOV 2 1
    JMP #1 -1
    JMP #1 -1
    
  • ADD A B- (thêm) - Điều này thêm nội dung của vị trí Abộ nhớ vào vị trí bộ nhớ B. Hai trường đầu tiên của cả hai được thêm vào và các trường thứ hai được thêm vào.

    ADD 2 1
    MOV @4 #5
    JMP #1 -1
    
    ADD 2 1
    MOV @5 #4
    JMP #1 -1
    
  • SUB A B- (trừ) - Điều này trừ nội dung của vị trí bộ nhớ Atừ (và lưu kết quả vào) vị trí bộ nhớ B.

    SUB 2 1
    MOV @4 #5
    JMP #1 -1
    
    SUB 2 1
    MOV @3 #6
    JMP #1 -1
    
  • JMP A B- (nhảy) - Nhảy đến vị trí A, sẽ được thực hiện chu kỳ tiếp theo. Bphải là một số nhưng không làm gì cả (bạn có thể sử dụng nó để lưu trữ thông tin).

    JMP 2 1337
    ADD 1 2
    ADD 2 3
    

    Nhảy có nghĩa là ADD 2 3sẽ được thực hiện chu kỳ tiếp theo.

  • JMZ A B- (nhảy nếu không) - Nếu cả hai trường của dòng Blà 0, thì chương trình sẽ nhảy đến vị trí A.

    JMZ 2 1
    SUB 0 @0
    DAT 23 45
    

    Vì hai trường của lệnh 1 là 0, nên lệnh DAT sẽ được thực thi lần lượt tiếp theo, dẫn đến cái chết sắp xảy ra.

  • CMP A B- (so sánh và bỏ qua nếu không bằng nhau) - Nếu các trường trong hướng dẫn ABkhông bằng nhau, hãy bỏ qua hướng dẫn tiếp theo.

    CMP #1 2
    ADD 2 #3
    SUB @2 3
    

    Vì hai trường của hướng dẫn 1 và 2 có giá trị bằng nhau, nên lệnh ADD không bị bỏ qua và được thực hiện lần lượt tiếp theo.

Khi hai hướng dẫn được thêm / bớt, hai trường (A và B) sẽ được thêm / trừ theo cặp. Chế độ địa chỉ và opcode không được thay đổi.

Chế độ địa chỉ

Có ba loại chế độ địa chỉ. Mỗi trong hai trường của một lệnh có một trong ba chế độ địa chỉ này.

  • Ngay lập tức#X - Xlà dòng được sử dụng trực tiếp trong tính toán. Ví dụ, #0là dòng đầu tiên của chương trình. Các dòng tiêu cực đề cập đến các dòng trong lõi trước khi bắt đầu chương trình.

    ... //just a space-filler
    ...
    ADD #3 #4
    DAT 0 1
    DAT 2 4
    

    Điều này sẽ thêm dòng đầu tiên trong hai dòng DAT vào dòng thứ hai, vì các dòng này nằm trong dòng 3 và 4, tương ứng. Tuy nhiên, bạn sẽ không muốn sử dụng mã này, bởi vì DAT sẽ giết bot của bạn trong chu kỳ tiếp theo.

  • Tương đốiX - Số Xđại diện cho vị trí của một địa chỉ bộ nhớ đích, liên quan đến địa chỉ hiện tại. Số tại vị trí này được sử dụng trong tính toán. Nếu dòng #35đang được thực thi và chứa -5, thì dòng #30được sử dụng.

    ... //just a space-filler
    ...
    ADD 2 1
    DAT 0 1
    DAT 2 4
    

    Điều này sẽ thêm dòng DAT thứ hai vào đầu tiên.

  • Gián tiếp@X - Số Xđại diện cho một địa chỉ tương đối. Các nội dung tại vị trí đó được tạm thời thêm vào số X để tạo thành một địa chỉ tương đối mới, từ đó số được lấy. Nếu dòng #35đang được thực thi, và trường thứ hai của nó là @4, và trường thứ hai của dòng #39chứa số -7, thì dòng #32được sử dụng.

    ... //just a space-filler
    ...
    ADD @1 @1
    DAT 0 1
    DAT 2 4
    

    Điều này sẽ thêm ĐẠT đầu tiên vào lần thứ hai, nhưng theo cách dễ hiểu hơn. Trường đầu tiên là @ 1, lấy dữ liệu từ địa chỉ tương đối đó, là trường đầu tiên của DAT đầu tiên, 0. Đây được hiểu là địa chỉ tương đối thứ hai từ vị trí đó, vì vậy 1 + 0 = 1 cho tổng số bù đắp từ hướng dẫn ban đầu. Đối với trường thứ hai, @ 1 nhận giá trị từ địa chỉ tương đối đó (số 1 trong trường thứ hai của ĐẠT thứ nhất) và thêm nó vào chính nó theo cùng một cách. Tổng bù là 1 + 1 = 2. Vì vậy, hướng dẫn này được thực hiện tương tự như ADD 1 2.

Mỗi chương trình có thể chứa tới 64 hướng dẫn.

Khi một vòng bắt đầu, hai chương trình được đặt ngẫu nhiên trong một ngân hàng bộ nhớ với 8192 vị trí. Con trỏ lệnh cho mỗi chương trình bắt đầu khi bắt đầu chương trình và được tăng lên sau mỗi chu kỳ thực hiện. Chương trình chết khi con trỏ lệnh của nó cố thực hiện một DATlệnh.

Các thông số của lõi

Kích thước lõi là 8192, với thời gian chờ là 8192 * 8 = 65536 tick. Cốt lõi là tuần hoàn, do đó, ghi vào địa chỉ 8195 cũng giống như viết vào địa chỉ 3. Tất cả các địa chỉ không sử dụng được khởi tạo DAT #0 #0.

Mỗi đối thủ cạnh tranh không được dài hơn 64 dòng. Số nguyên sẽ được lưu dưới dạng số nguyên có chữ ký 32 bit.

Phân tích cú pháp

Để giúp lập trình dễ dàng hơn cho các đối thủ cạnh tranh, tôi sẽ thêm một tính năng nhãn dòng vào trình phân tích cú pháp. Bất kỳ từ nào xuất hiện trên một dòng trước opcode sẽ được hiểu là nhãn dòng. Ví dụ, tree mov 4 6có nhãn dòng tree. Nếu, bất cứ nơi nào trong chương trình, có một trường có chứa tree #treehoặc @tree, một số sẽ được thay thế. Ngoài ra, viết hoa được bỏ qua.

Dưới đây là một ví dụ về cách nhãn dòng được thay thế:

labelA add labelB @labelC
labelB add #labelC labelC
labelC sub labelA @labelB

Ở đây, các nhãn A, B và C nằm trên các dòng 0, 1 và 2. Các trường hợp #labelsẽ được thay thế bằng số dòng của nhãn. Các trường hợp labelhoặc @labelđược thay thế bằng vị trí tương đối của nhãn. Chế độ địa chỉ được bảo tồn.

ADD 1 @2
ADD #2 1
SUB -2 @-1

Chấm điểm

Đối với mỗi cặp thí sinh, mọi trận chiến có thể được thực hiện. Vì kết quả của một trận chiến phụ thuộc vào độ lệch tương đối của hai chương trình, nên mọi sự bù đắp có thể (khoảng 8000 trong số chúng) đều được thử. Hơn nữa, mỗi chương trình có một cơ hội để di chuyển đầu tiên trong mỗi bù. Chương trình giành được phần lớn các khoản bù đắp này là người chiến thắng của cặp.

Đối với mỗi cặp mà một chiến binh chiến thắng, nó được thưởng 2 điểm. Đối với mỗi cà vạt, một chiến binh được thưởng 1 điểm.

Bạn được phép gửi nhiều hơn một chiến binh. Các quy tắc điển hình cho nhiều lần gửi được áp dụng, chẳng hạn như không gắn thẻ, không hợp tác, không làm vua, v.v ... Thực sự không có chỗ cho điều này trong dù sao trong Chiến tranh cốt lõi, vì vậy nó không phải là vấn đề lớn.

Bộ điều khiển

Mã cho bộ điều khiển, cùng với hai bot ví dụ dễ dàng, được đặt ở đây . Vì sự cạnh tranh này (khi chạy bằng cài đặt chính thức) là hoàn toàn quyết định, bảng xếp hạng bạn tạo sẽ giống hệt như bảng xếp hạng chính thức.

Bot ví dụ

Dưới đây là một ví dụ bot thể hiện một số tính năng của ngôn ngữ.

main mov bomb #-1
     add @main main
     jmp #main 0
bomb dat 0 -1

Bot này hoạt động bằng cách từ từ xóa tất cả bộ nhớ khác trong lõi bằng cách thay thế nó bằng một "quả bom". Vì bom là một DATchỉ dẫn, bất kỳ chương trình nào đạt được bom sẽ bị phá hủy.

Có hai nhãn dòng, "chính" và "bom" dùng để thay thế số. Sau khi tiền xử lý, chương trình trông như thế này:

MOV 3 #-1
ADD @-1 -1
JMP #0 0
DAT 0 -1

Dòng đầu tiên sao chép quả bom vào dòng ngay phía trên chương trình. Dòng tiếp theo thêm giá trị của bom ( 0 -1) vào lệnh di chuyển và nó cũng thể hiện việc sử dụng @chế độ địa chỉ. Sự bổ sung này làm cho lệnh di chuyển trỏ đến một mục tiêu mới. Lệnh tiếp theo vô điều kiện nhảy trở lại bắt đầu chương trình.


Bảng xếp hạng hiện tại

24 - Turbo
22 - DwarvenEngineer
20 - HanShotFirst
18 - Dwarf
14 - ScanBomber
10 - Paranoid
10 - FirstTimer
10 - Janitor
10
- Evolve
6 - EasterBunny 6 - CopyPasta
4 - Imp
2 - Slug

Kết quả theo cặp:

Dwarf > Imp
CopyPasta > Imp
Evolved > Imp
FirstTimer > Imp
Imp > Janitor
Imp > ScanBomber
Slug > Imp
DwarvenEngineer > Imp
HanShotFirst > Imp
Turbo > Imp
EasterBunny > Imp
Paranoid > Imp
Dwarf > CopyPasta
Dwarf > Evolved
Dwarf > FirstTimer
Dwarf > Janitor
Dwarf > ScanBomber
Dwarf > Slug
DwarvenEngineer > Dwarf
HanShotFirst > Dwarf
Turbo > Dwarf
Dwarf > EasterBunny
Dwarf > Paranoid
Evolved > CopyPasta
FirstTimer > CopyPasta
Janitor > CopyPasta
ScanBomber > CopyPasta
CopyPasta > Slug
DwarvenEngineer > CopyPasta
HanShotFirst > CopyPasta
Turbo > CopyPasta
CopyPasta > EasterBunny
Paranoid > CopyPasta
Evolved > FirstTimer
Evolved > Janitor
ScanBomber > Evolved
Evolved > Slug
DwarvenEngineer > Evolved
HanShotFirst > Evolved
Turbo > Evolved
EasterBunny > Evolved
Paranoid > Evolved
Janitor > FirstTimer
ScanBomber > FirstTimer
FirstTimer > Slug
DwarvenEngineer > FirstTimer
HanShotFirst > FirstTimer
Turbo > FirstTimer
FirstTimer > EasterBunny
FirstTimer > Paranoid
ScanBomber > Janitor
Janitor > Slug
DwarvenEngineer > Janitor
HanShotFirst > Janitor
Turbo > Janitor
Janitor > EasterBunny
Janitor > Paranoid
ScanBomber > Slug
DwarvenEngineer > ScanBomber
HanShotFirst > ScanBomber
Turbo > ScanBomber
ScanBomber > EasterBunny
ScanBomber > Paranoid
DwarvenEngineer > Slug
HanShotFirst > Slug
Turbo > Slug
EasterBunny > Slug
Paranoid > Slug
DwarvenEngineer > HanShotFirst
Turbo > DwarvenEngineer
DwarvenEngineer > EasterBunny
DwarvenEngineer > Paranoid
Turbo > HanShotFirst
HanShotFirst > EasterBunny
HanShotFirst > Paranoid
Turbo > EasterBunny
Turbo > Paranoid
Paranoid > EasterBunny

Bản cập nhật mới nhất (phiên bản mới của Turbo và Paranoid) mất khoảng 5 phút để chạy trên một máy tính xách tay cũ. Tôi muốn cảm ơn Ilmari Karonen vì những cải tiến của anh ấy đối với bộ điều khiển . Nếu bạn có một bản sao cục bộ của bộ điều khiển, bạn nên cập nhật các tệp của mình.


Điều gì xảy ra nếu hai bot cạnh tranh cố gắng sử dụng cùng một nhãn?
mbomb007

1
@ mbomb007 Nhãn là thứ tiền xử lý và được tính là tệp nguồn của bot đang được phân tích cú pháp. Nhãn của bạn sẽ không tương tác với bất kỳ nhãn đối thủ.
PhiNotPi

1
@ mbomb007 Để các chương trình không trùng nhau. Ngoài ra, tôi không có kế hoạch thêm bất kỳ tính năng nào nữa vào phiên bản này, hãy lưu những tính năng này cho Micro Core War.
PhiNotPi

1
@ mbomb007 Địa chỉ gián tiếp tham chiếu cùng một trường đang tạo tham chiếu (thứ 1 hoặc thứ 2). Không có sửa đổi hướng dẫn. Tôi không dựa trên thách thức này theo tiêu chuẩn '94.
PhiNotPi

2
@Thrax Tôi sẽ nói không, rằng bạn không giới hạn trong một lần gửi. Các quy tắc đa đệ trình điển hình được áp dụng (không có nhóm gắn thẻ, v.v.), mặc dù không có nhiều chỗ để hợp tác trong các cuộc chiến cốt lõi.
PhiNotPi 11/03/2015

Câu trả lời:


9

Kỹ sư người lùn

Một người lùn mới và được cải thiện. Thắng chống lại mọi thứ khác gửi cho đến nay. Kích thước bước corestep -optimized lạ mắt có lẽ là quá mức cần thiết ở đây.

        MOV bomb    @aim
aim     MOV bomb    @-6326
        SUB step    aim
step    JMZ #0      6328
        MOV 0       1
bomb    DAT 0       3164

Các tính năng đáng chú ý bao gồm vòng ném bom nhanh ném hai quả bom trong bốn chu kỳ, với tốc độ ném bom trung bình 0,5c trong biệt ngữ Core War cũ và sử dụng JMZđể phát hiện khi quá trình ném bom hoàn tất và đã đến lúc chuyển sang kế hoạch B ( đây, một Imp).


Tôi đã từng chơi Core War trở lại vào những năm 90 (một số bạn có thể đã xem cuốn sách hướng dẫn cơ bản mà tôi đã viết lại vào năm 97), vì vậy tôi nghĩ sẽ rất thú vị khi xem những chiến lược cũ từ thế giới RedCode '88 / '94 có thể có ích trong biến thể này.

Suy nghĩ đầu tiên của tôi là:

  • Không có SPL, do đó không có máy sao chép (và không có vòng imp / xoắn ốc). Điều này sẽ làm cho máy bay ném bom mạnh mẽ. (Ngoài ra, tất cả những chiến lược đánh bom lạ mắt được thiết kế để đối phó với bộ sao và imp xoắn ốc? Hoàn toàn không cần thiết và vô dụng ở đây. Chỉ cần bom với bất kỳ DATs.)

  • Sau đó, một lần nữa, CMPquét vẫn có khả năng nhanh hơn ném bom, vì vậy một máy quét nhanh có thể có cơ hội.

  • Việc không có trong / giảm làm cho việc xóa lõi rất chậm. Trên thực tế, một lõi rõ ràng trong biến thể này gần như chỉ là một máy bay ném bom với kích thước bước (dưới mức tối ưu) là 1. Một lần nữa, điều này cũng làm tổn thương máy quét; một máy quét one-shot → chiến lược máy bay ném bom có thể hoạt động, mặc dù.

  • Quickscanners / quickbombers (một chiến lược đầu trò chơi sử dụng vòng quét / ném bom không được kiểm soát, đối với những người không quen thuộc với biệt ngữ Core War) vẫn có khả năng hữu ích, nhưng chỉ chống lại các chương trình dài (mà chính họ là vậy, vì vậy có một loại phản hồi có hiệu lực ở đây). Thật khó để nói nếu nó thực sự có giá trị rắc rối.

  • Hệ thống tính điểm rất thú vị. Ties ghi được một nửa số điểm như một chiến thắng (thay vì 1/3, như trong Chiến tranh lõi truyền thống), khiến chúng trở nên hấp dẫn hơn. Sau đó, một lần nữa, về chương trình duy nhất có khả năng ghi được nhiều mối quan hệ theo các quy tắc này là một imp. (Ngoài ra, sự vắng mặt của tăng / giảm làm cho cổng imp trở nên khó khăn, do đó, ngay cả những người chơi đơn giản thực sự cũng có cơ hội ghi điểm nếu họ tiếp cận đối thủ còn sống.)

  • Ngoài ra, bởi vì bảng xếp hạng cuối cùng chỉ phụ thuộc vào chương trình bạn đánh bại, chứ không phải bạn đánh bại họ bao nhiêu , nên nó có xu hướng ủng hộ các mục chung. Tốt hơn hết là chỉ cần đánh bại tất cả các đối thủ của bạn, hơn là tiêu diệt hoàn toàn một nửa trong số họ và chỉ thua phần còn lại.

  • Vì mã là công khai, nên luôn có thể tìm thấy một chương trình có thể đánh bại bất kỳ nội dung nào được gửi trước đó - thậm chí có thể là một vài trong số chúng - bất kể chúng nói chung tốt như thế nào. Những thủ thuật như vậy (như điều chỉnh kích thước bước của bạn để đánh đối thủ ngay trước khi chúng đánh bạn) có thể dễ dàng có vẻ rẻ tiền. Và, tất nhiên, người chơi mục tiêu luôn có thể gửi phiên bản mới với các hằng số khác nhau.

Dù sao, kết quả của tất cả những điều này là tôi đã quyết định rằng tôi nên cố gắng viết một máy bay ném bom nhanh hoặc máy quét rất nhanh, và có thể xử lý một máy bay ném bom / máy bay ném bom lên nó. Trong số các lựa chọn đó, một máy bay ném bom nhanh dường như đơn giản nhất và có khả năng hoạt động tốt nhất.

Vào thời điểm đó, tôi đã dành quá nhiều thời gian để tinh chỉnh và tối ưu hóa mã trình thông dịch của PhiNotPi, bởi vì tôi nghĩ rằng có lẽ tôi đang chạy nhiều thử nghiệm vũ lực để tối ưu hóa các hằng số. Khi điều đó xảy ra, tôi không bao giờ phải làm điều đó - đoạn mã trên gần như là phiên bản đầu tiên thực sự hoạt động (sau một vài lần thất bại chỉ tự tử do lỗi ngớ ngẩn).


Thủ thuật khiến máy bay ném bom của tôi nhanh là sử dụng địa chỉ gián tiếp để ném hai quả bom cho mỗi quả bom ADD. Đây là cách nó hoạt động:

  1. Trên chu kỳ đầu tiên, chúng tôi thực hiện MOV bomb @aim. Điều này sao chép bombhướng dẫn đến bất kỳ nơi nào trong lõi B của trường aimđiểm (ban đầu, chính xác là 6326 hướng dẫn trước aimhoặc 6328 hướng dẫn trước step; bạn sẽ thấy lý do tại sao những con số đó quan trọng sau).

  2. Bước tiếp theo, chúng tôi thực hiện aimhướng dẫn chính nó! Trên đường chuyền đầu tiên, nó trông như thế này : MOV bomb @-6326. Do đó, nó sao chép bombvào vị trí mà trường B của lệnh tại 6326 dòng trước khi chính nó trỏ đến.

    Vì vậy, những gì có ở 6326 dòng trước aim? Tại sao, đó là bản sao của bombchúng tôi vừa đặt ở đó một chu kỳ trước đó! Và chúng tôi tình cờ sắp xếp mọi thứ sao cho trường B bombcó giá trị khác không, vì vậy quả bom mới sẽ không được sao chép trên đầu cũ, nhưng ở khoảng cách xa (thực tế, ở đây khoảng cách là 3164, đó là một nửa kích thước bước danh nghĩa 6328 của chúng tôi, nhưng các phần bù khác có thể hoạt động, thậm chí có thể tốt hơn).

  3. Trên chu kỳ tiếp theo, chúng tôi điều chỉnh mục tiêu của chúng tôi với SUB step aim, mà trừ đi giá trị của các stephướng dẫn (mà cũng sẽ xảy ra là khi nhảy chúng ta sẽ thực hiện tiếp theo, mặc dù nó có thể đã được chỉ đơn giản DATở đâu đó) từ aim.

    (Một chi tiết cần lưu ý ở đây là chúng ta loại muốn A-giá trị steplà zero, vì vậy mà chúng ta vẫn sẽ ném bom tương tự trên phiên bản kế tiếp Thậm chí đó là không thực sự cần thiết, mặc dù,. Chỉ những quả bom ném bởi lệnh đầu tiên cần có trường B của chúng bằng 3164, phần còn lại có thể là bất cứ thứ gì.)

  4. Tiếp theo, JMZkiểm tra xem lệnh 6328 cách nó vẫn bằng không, và nếu vậy, nhảy trở lại đầu mã. Bây giờ, 6328 là kích thước bước của máy bay ném bom của chúng tôi và chia hết cho 8 (nhưng không chia cho 16); do đó, nếu chúng ta cứ ném bom cứ sau 6328 bước, cuối cùng chúng ta sẽ quay trở lại nơi chúng ta bắt đầu, đã ném bom mọi hướng dẫn thứ tám trong lõi (và với những quả bom bổ sung được bù đắp bởi 3163 = 6328/2 4 (mod 8) , chúng tôi đã đạt được mọi chỉ dẫn thứ tư ).

    Nhưng chúng tôi bắt đầu chạy ném bom của chúng tôi tại 6328 hướng dẫn trước khi các JMZ, và lùi lại bởi -6328 tại mỗi lần lặp, vì vậy chúng ta sẽ đánh bom địa điểm 6328 bước sau sự JMZchỉ là một sự lặp lại trước khi chúng tôi sẽ nhấn JMZriêng của mình. Vì vậy, khi JMZphát hiện ra một quả bom theo hướng dẫn 6328 sau đó, đó là dấu hiệu cho thấy chúng ta đã che hết phần lõi có thể mà không cần đánh vào chính mình, và nên chuyển sang chiến lược dự phòng trước khi chúng ta tự sát.

  5. Đối với chiến lược sao lưu, nó chỉ là một xu hướng cũ MOV 0 1, bởi vì bây giờ tôi không thể nghĩ ra điều gì tốt hơn. Theo cách tôi nhìn thấy, nếu chúng ta ném bom mọi vị trí thứ tư của lõi mà vẫn không chiến thắng, có lẽ chúng ta đang chiến đấu với thứ gì đó rất nhỏ hoặc rất phòng thủ, và cũng có thể cố gắng sống sót và giải quyết một trận hòa. Không sao, bởi vì các chương trình nhỏ hoặc phòng thủ như vậy thường không tốt trong việc tiêu diệt bất cứ thứ gì khác, và vì vậy ngay cả khi chúng tôi chỉ chiến thắng một vài trận chiến một cách tình cờ, có lẽ chúng tôi vẫn sẽ tiếp tục tiến lên.


Thi thiên Trong trường hợp bất cứ ai khác muốn nó, đây là ngã ba mã giải đấu PhiNotPi's được cải thiện đôi chút của tôi . Tốc độ nhanh gấp đôi, lưu kết quả trận chiến cũ để bạn không cần phải chạy lại chúng và sửa những gì tôi cho là lỗi nhỏ trong tính toán kết quả trận chiến. Các thay đổi đã được PhiNotPi sáp nhập vào phiên bản chính . Cảm ơn!


1
Chỉ để bạn biết, các bài kiểm tra chấm điểm MỌI sự kết hợp có thể của các vị trí bắt đầu chương trình và chương trình ghi được nhiều điểm nhất. Điều này làm cho các mối quan hệ không thể hoặc hoàn toàn không thuận lợi vì miễn là một chương trình không bao giờ tự giết mình và đánh bom ít nhất một địa chỉ một lần, nó sẽ đánh bại một kẻ thù, có một chiến thắng và các mối quan hệ còn lại.
mbomb007

9

Xem biểu đồ

Điều này có thể được sử dụng như một công cụ gỡ lỗi. Nó hiển thị lõi và hiển thị vị trí của người chơi. Để sử dụng nó, bạn phải gọi nó từ mã. Tôi cũng đã cung cấp một bản sửa đổi Game.javatự động hiển thị GraphView.

PhiNotPi và Ilmari Karonen gần đây đã thay đổi Bộ điều khiển. Ilmari Karonen đã rất tốt bụng khi cung cấp một GameView cập nhật tại địa điểm này .

import javax.swing.*;
import java.awt.*;

public class GameView extends JComponent{

    final static Color[] commandColors = new Color[]{
            Color.black, //DAT
            Color.blue,  //MOV
            Color.blue,  //ADD
            Color.blue,  //SUB
            Color.blue,  //JMP
            Color.blue,  //JMZ
            Color.blue,  //CMP
    };

    final static Color[] specialColors = new Color[]{
            new Color(0,0,0),
            new Color(190, 255, 152),
            Color.yellow,
            new Color(0, 93, 14),
            new Color(96, 92, 4),
            new Color(0, 93, 14),
            new Color(96, 92, 4),
            new Color(0, 93, 14),
            new Color(96, 92, 4)
    };

    final static Color playerOneColor = Color.green;
    final static Color playerTwoColor = Color.white;

    final Game game;

    int playerOneLocation;
    int playerTwoLocation;

    final static int width = 128;
    final static int height = 64;

    public GameView(Game game) {
        this.game = game;
    }

    @Override
    public void paint(Graphics g) {
        int pixelWidth = getSize().width;
        int pixelHeight = getSize().height;
        if (width > pixelWidth){
            pixelWidth = width;
            setSize(width, pixelHeight);
        }
        if (height > pixelHeight){
            pixelHeight = height;
            setSize(pixelWidth, height);
        }
        int squareWidth = Math.min(pixelWidth / width, pixelHeight / height);
        for (int x = 0; x < squareWidth * width; x += squareWidth){
            for (int y = 0; y < squareWidth * height; y += squareWidth){
                int index = (y / squareWidth) * width + (x / squareWidth);
                Color color = commandColors[game.core[index][0]];
                if (game.coreData[index] != 0){
                    color = specialColors[game.coreData[index]];
                }
                if (index == playerOneLocation){
                    color = playerOneColor;
                }
                if (index == playerTwoLocation){
                    color = playerTwoColor;
                }
                g.setColor(color);
                g.fillRect(x, y, squareWidth, squareWidth);
            }
        }
    }

    public void setLocations(int p1loc, int p2loc){
        this.playerOneLocation = p1loc;
        this.playerTwoLocation = p2loc;
    }
}

Đã sửa đổi Game.java:

import javax.swing.*;
import java.util.Random;
import java.util.ArrayList;
import java.util.Arrays;
/**
 * This runs a game of Core Wars between two players.  It can be called mutiple times.
 * 
 * @author PhiNotPi 
 * @version 3/10/15
 */
public class Game
{
    final Player p1;
    final Player p2;
    final int coreSize;
    final int coreSizeM1;
    final int maxTime;
    final int debug;
    public int[][] core;
    public int[] coreData; //Used in debugging.
    int offset1;
    int offset2;
    Random rand;
    ArrayList<int[]> p1code;
    ArrayList<int[]> p2code;
    int p1size;
    int p2size;
    GameView gameView;
    int time = 1000000; //Time in nanoseconds between frames
    public Game(Player A, Player B, int coreSize, int maxTime, int debug)
    {
        p1 = A;
        p2 = B;

        coreSize--;
        coreSize |= coreSize >> 1;
        coreSize |= coreSize >> 2;
        coreSize |= coreSize >> 4;
        coreSize |= coreSize >> 8;
        coreSize |= coreSize >> 16;
        coreSize++;

        this.coreSize = coreSize;
        this.coreSizeM1 = coreSize - 1;
        this.maxTime = maxTime / 2;
        this.debug = debug;
        core = new int[coreSize][5];
        rand = new Random();
        p1code =  p1.getCode();
        p1size = p1code.size();
        p2code =  p2.getCode();
        p2size = p2code.size();
        if (debug == 1){
            gameView = new GameView(this);
            JFrame frame = new JFrame("Game");
            frame.add(gameView);
            frame.setVisible(true);
            frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
            frame.setSize(128, 64);
            coreData = new int[coreSize];
        }
    }

    public int runAll()
    {
        int sum = 0;
        for(int i = 0; i < coreSize - p1size - p2size; i++)
        {
            sum += run(i) - 1;
        }
        if(sum > 0)
        {
            return 1;
        }
        if(sum < 0)
        {
            return -1;
        }
        return 0;
    }

    public int run()
    {
        return run(rand.nextInt(coreSize - p1size - p2size + 1));
    }

    public int run(int deltaOffset)
    {
        core = new int[coreSize][5];
        //offset1 = rand.nextInt(coreSize);
        offset1 = 0;
        for(int i = 0; i != p1size; i++)
        {
            //System.arraycopy(p1.getCode().get(i), 0, core[(offset1 + i) % coreSize], 0, 5 );
            int[] line = p1code.get(i);
            int loc = (offset1 + i) & coreSizeM1;
            core[loc][0] = line[0];
            core[loc][1] = line[1];
            core[loc][2] = line[2];
            core[loc][3] = line[3];
            core[loc][4] = line[4];
            if (debug != 0){
                coreData[loc] = 1;
            }
        }
        offset2 = offset1 + p1size + deltaOffset;
        for(int i = 0; i != p2size; i++)
        {
            //System.arraycopy(p2.getCode().get(i), 0, core[(offset2 + i) % coreSize], 0, 5 );
            int[] line = p2code.get(i);
            int loc = (offset2 + i) & coreSizeM1;
            core[loc][0] = line[0];
            core[loc][1] = line[1];
            core[loc][2] = line[2];
            core[loc][3] = line[3];
            core[loc][4] = line[4];
            if (debug != 0){
                coreData[loc] = 2;
            }
        }

        int p1loc = offset1 & coreSizeM1;
        int p2loc = offset2 & coreSizeM1;
        for(int time = 0; time != maxTime; time++)
        {
            if(debug != 0)
            {
                //printCore(p1loc,p2loc);
                //System.out.println("p1loc " + p1loc);
                //System.out.println("offset " + offset1);
                gameView.setLocations(p1loc, p2loc);
                gameView.repaint();
                try {
                    Thread.sleep(time / 1000000, time % 1000000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

            if(core[p1loc][0] == 0)
            {
                return 0;
            }
            p1loc = execute(p1loc, offset1, 1);

            if(debug != 0)
            {
                //printCore(p1loc,p2loc);
                //System.out.println("p2loc " + p2loc);
                //System.out.println("offset " + offset2);
                gameView.setLocations(p1loc, p2loc);
                gameView.repaint();
                /*try {
                    Thread.sleep(time);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }*/
            }
            if(core[p2loc][0] == 0)
            {
                return 2;
            }
            p2loc = execute(p2loc, offset2, 2);

        }
        return 1;
    }
    public int execute(int ploc, int offset, int player)
    {
        int line1 = offset + core[ploc][3];
        if(core[ploc][1] != 0)
        {
            line1 += ploc - offset;
        }
        if(core[ploc][1] == 2)
        {
            line1 += core[line1 & coreSizeM1][3];
        }
        int line2 = offset + core[ploc][4];
        if(core[ploc][2] != 0)
        {
            line2 += ploc - offset;
        }
        if(core[ploc][2] == 2)
        {
            line2 += core[line2 & coreSizeM1][4];
        }
        line1 = line1 & coreSizeM1;
        line2 = line2 & coreSizeM1;
        int opcode = core[ploc][0];
        ploc = (ploc + 1) & coreSizeM1;
        //String opDescription = "";
        if(opcode == 1)
        {
            core[line2][0] = core[line1][0];
            core[line2][1] = core[line1][1];
            core[line2][2] = core[line1][2];
            core[line2][3] = core[line1][3];
            core[line2][4] = core[line1][4];
            if (debug != 0) {
                coreData[line2] = player + 2;
            }
            return ploc;
            //opDescription = "Moved from " + line1 + " to " + line2;
        }
        if(opcode == 2)
        {
            core[line2][3] += core[line1][3];
            core[line2][4] += core[line1][4];
            if (debug != 0) {
                coreData[line2] = player + 4;
            }
            return ploc;
            //opDescription = "Added " + line1 + " to " + line2;
        }
        if(opcode == 3)
        {
            core[line2][3] -= core[line1][3];
            core[line2][4] -= core[line1][4];
            if (debug != 0) {
                coreData[line2] = player + 6;
            }
            return ploc;
                //opDescription = "Subtracted " + line1 + " to " + line2;
        }
        if(opcode == 4)
        {
            ploc = line1;
            return ploc;
                //opDescription = "Jumped to " + line1;
        }
        if(opcode == 5)
        {
                if(core[line2][3] == 0 && core[line2][4] == 0)
                {
                    ploc = line1;
                    //opDescription = "Jumped to " + line1;
                }
                else
                {
                    //opDescription = "Did not jump to " + line1;
                }
                return ploc;
        }
        if(opcode == 6)
        {
            if(core[line1][3] == core[line2][3] && core[line1][4] == core[line2][4])
            {
                //opDescription = "Did not skip because " + line1 + " and " + line2 + " were equal.";
            }
            else
            {
                ploc = (ploc + 1) & coreSizeM1;
                //opDescription = "Skipped because " + line1 + " and " + line2 + " were not equal.";
            }
            return ploc;
        }
        if(debug != 0)
        {
            //System.out.println(opDescription);
        }
        return ploc;
    }
    /*public void printCore(int p1loc, int p2loc)
    {
        int dupCount = 0;
        int[] dupLine = new int[]{0,0,0,0,0};
        for(int i = 0; i < core.length; i++)
        {
            int[] line = core[i];
            if(Arrays.equals(line, dupLine) && i != p1loc && i != p2loc)
            {
                if(dupCount == 0)
                {
                    System.out.println(Player.toString(line));
                }
                dupCount++;
            }
            else
            {
                if(dupCount == 2)
                {
                    System.out.println(Player.toString(dupLine));
                }
                else if(dupCount > 2)
                {
                    System.out.println("    " + (dupCount - 1) + " lines skipped.");
                }
                System.out.println(Player.toString(line));
                if(i == p1loc)
                {
                    System.out.print(" <- 1");
                }
                if(i == p2loc)
                {
                    System.out.print(" <- 2");
                }
                dupLine = line;
                dupCount = 1;
            }
        }
        if(dupCount == 2)
        {
            System.out.println(Player.toString(dupLine));
        }
        else if(dupCount > 2)
        {
            System.out.println("    " + (dupCount - 1) + " lines skipped.");
        }
    }*/
}

Có vẻ như bạn cũng đã sửa đổi cho Người chơi. Tôi nhận được./Game.java:275: error: method toString in class Object cannot be applied to given types; System.out.println(Player.toString(line)); ^ required: no arguments found: int[]
AShelly

@AShelly Xin lỗi về điều đó. Tôi nên bình luận ra printCore()phương pháp.
TheNumberOne

9

Turbo

main   add three target
test   jmz -1 @target
bomb   mov three @target
       sub j1 target 
       mov jump @target
       sub j1 target 
       mov copy @target
       sub j1 target
two    mov decr @target
j1     jmp @target 1
target dat -8 -8   
decr   sub #two 3
copy   mov 2 @2
jump   jmp -2 0
three dat -9 -9

Lần thử thứ 2 của tôi là CoreWar. Được thiết kế để đánh bại Người lùn. Quét 3 giây để tìm dữ liệu, sau đó đặt một quả bom cứ sau 2. Mỗi giai đoạn chỉ chạy theo 3 hướng dẫn, với hy vọng rằng bom của Dwarf bỏ lỡ nó.

Turbo ++ MỚI : Bây giờ được tăng cường. Nó quét ngược cho đến khi tìm thấy dữ liệu, sau đó tự di chuyển đến đó, sau đó ném bom ngược. Hy vọng là việc di chuyển hoặc chặn đối thủ, hoặc đến một nơi đã bị ném bom và do đó an toàn (ish).

... Và một chỉnh sửa để làm cho nó quét một cách thưa thớt hơn làm cho nó đánh bại tất cả mọi người!


Có vẻ để đánh bại nhiều hơn chỉ là Lùn. Xin chúc mừng! Tôi nghĩ bạn có thể đạt vị trí thứ ba nếu bạn chỉ có thể đánh bại Imp.
Ilmari Karonen

Tôi đã cập nhật cái này, nhưng nó thực sự là một sự tiến hóa khá lớn so với cái trước. Tôi có nên thực hiện một mục mới thay thế?
HỎI

Tôi không cho là nói cho PhiNotPi, nhưng tôi đoán nó tùy thuộc vào bạn. Thực hiện cập nhật tại chỗ về cơ bản có nghĩa là rút lại mục nhập cũ của bạn. Dù sao, thậm chí nhiều lời chúc mừng hơn về việc tránh bom thành công theo cách của bạn đến vị trí thứ ba! Tôi nghĩ rằng bạn là mục duy nhất cho đến nay để đánh bại DwarvenEngineer theo cặp.
Ilmari Karonen

Làm tốt ;). bây giờ bạn là người đánh bại!
Lượt

8

Quỷ lùn

Một chương trình phổ biến và đơn giản đại diện cho một người lùn ném đá. Nó đặt một DAThướng dẫn cứ bốn địa chỉ.

add 2 3
mov 2 @2
jmp -2 #4
dat #0 #4

EDIT: Sửa địa chỉ. Rõ ràng các chế độ địa chỉ khác với thông số kỹ thuật mà OP liên kết đến.


Tôi nghĩ đó là "thêm số 3 3" cho dòng đầu tiên, phải không?
Lượt

@Hit Không. Tôi muốn đánh mỗi địa chỉ thứ 4. Tôi có thể sử dụng add 3 3, nhưng sau đó nó sẽ tăng gấp đôi mỗi vòng thay vì thêm và điều đó sẽ không hữu ích. #4là một ngay lập tức, vì vậy nó thêm số 4vào giá trị thứ 2 trong địa chỉ 3sau địa chỉ hiện tại.
mbomb007

Tôi nghĩ rằng bạn đang hiểu sai #chế độ địa chỉ trong thử thách. Như đã nêu trong thông số kỹ thuật, tôi đã thay đổi #chế độ địa chỉ.
PhiNotPi 11/03/2015

Bạn nên đi như sau: "thêm 2 3 Mov 2 @ 2 jmp -2 4 dat 0 4"
Lượt

Với hành vi đúng, nó thậm chí còn đánh bại tiến hóa
Lượt

7

Phát triển

Tôi thực sự không hiểu làm thế nào nó hoạt động. Nó dường như xây dựng mã nguồn của nó trước khi làm bất cứ điều gì. Tôi sẽ thích nó nếu ai đó cho tôi một lời giải thích cho cách nó hoạt động.

Sau khi nghiên cứu nó, tôi thấy rằng nó chỉ đơn giản là một người lùn được sửa đổi với một người bảo vệ bốc đồng. Thay vì ném bom kẻ thù bằng DATchỉ dẫn, nó xáo trộn mã kẻ thù. Nó cũng đánh bom mỗi hai thanh ghi thay vì bốn thanh ghi. Cho đủ thời gian, nó chắc chắn sẽ tự hủy diệt.

MOV -2 #-1
MOV #4 -9
SUB -5 #6
MOV #1 1
MOV #-6 #4
SUB @8 @7
JMP -3 @4
DAT #-4 8
JMP -1 9
JMP 5 #-10
CMP @-1 #0
SUB 3 #-10
JMP @10 #-9
JMZ #1 10
MOV #3 2
ADD @9 @-3
CMP #-3 @7
DAT @0 @-2
JMP @-7 #6
DAT @-8 -6
MOV @0 #9
MOV #2 1
DAT @6882 #-10
JMP @3 4
CMP @8 2
ADD -7 @11
ADD @1 #-9
JMZ @-5 7
CMP 11 5526
MOV @8 6
SUB -6 @0
JMP 1 11
ADD @-3 #-8
JMZ @-14 @-5
ADD 0 @-8
SUB #3 @9
JMP #-1 5
JMP #9 @1
CMP -9 @0
SUB #4 #-2
JMP #-8 5
DAT -1 @-10
MOV 6 #2
CMP @-11 #-14
ADD @4 @-3
MOV @5 #-6
SUB -3 -2
DAT @-10 #-1
MOV #-13 #-6
MOV #1 5
ADD 5 #-5
MOV -8 @-1
DAT 0 10
DAT #5 #7
JMZ 6 -5
JMZ -12 -11
JMP 5 @-7
MOV #7 -3
SUB #-7 @-3
JMP -4 @-11
CMP @-5 #-2
JMZ @-1 #0
ADD #3 #2
MOV #5 @-6

1
Sau đó, bạn đã nhận được nó ở đâu?
PyRulez 11/03/2015

4
@PyRulez Đó là máy tính được tạo thông qua thuật toán di truyền.
TheNumberOne 11/03/2015

1
Có vẻ như việc thực thi không thực sự tiến triển xa hơn dòng # 6, bởi vì nó nhảy trở lại trong chương trình. Tôi tin rằng lý do nó thành công là có nhiều chuyển động / vòng lặp hơn so với đối thủ cạnh tranh.
PhiNotPi 11/03/2015

6

Giờ đầu tiên

Nếu nó hoạt động, nó nên cố gắng giữ vị trí ở đầu lõi và tạo một defens

main MOV 5 #0
     ADD #data #main
     CMP #main #max
     JMP #0 0
     JMP #main 0
     MOV #data #100
     ADD #data -1
     JMP -2 0
data DAT 1 1
max  DAT 8 3

Nó không hoàn toàn hoạt động theo cách tôi nghĩ bạn đã nghĩ: sẽ #0đề cập đến sự khởi đầu của chương trình của bạn (tức là giống như#main ), không phải là sự khởi đầu của cốt lõi (dù sao đó không thực sự là một khái niệm có ý nghĩa - cốt lõi là thông tư, mã của bạn không thể cho biết nơi nó bắt đầu hoặc kết thúc). Điều gì xảy ra là lệnh đầu tiên ( main) của bạn ghi đè lên chính nó MOV #data #100, sau đó mã của bạn thực sự biến thành một lõi chuyển tiếp 0,25c (= một lệnh trong bốn chu kỳ).
Ilmari Karonen

@IlmariKaronen ơi, cảm ơn đã giải thích. Tôi đã làm sai #0cho sự khởi đầu của cốt lõi. 5 hướng dẫn đầu tiên là hoàn toàn vô dụng sau đó.
Thrax

6

CopyPasta

Không bao giờ tham gia vào CoreWar, chương trình đơn giản này chỉ cố gắng tự sao chép-dán và sau đó thực hiện sao chép. Nó có thể không có hành vi chính xác, xin vui lòng cho tôi biết nếu đó là trường hợp.

Đó là quá hòa bình và thực tế không thể chiến thắng.

MOV 6 0
MOV @-1 @-1
CMP @-2 3
JMP 4242 0
SUB -3 -4
JMP -4 0
DAT 0 4244

Chỉnh sửa hiện tại này có thể sẽ không có trong bản cập nhật bảng xếp hạng tiếp theo (Tôi đang điều hành giải đấu ngay bây giờ). Phiên bản cũ, tuy nhiên, đã giành được kết quả sơ bộ (kích thước lõi nhỏ).
PhiNotPi 10/03/2015

Được rồi :) Phiên bản cũ hơn không đi ra khỏi loop1, nó không thực sự là hành vi mong muốn, tôi đang cố gắng sửa nó.
Lượt

Phiên bản hiện tại có vẻ bị hỏng. Tôi không biết tại sao.
PhiNotPi 10/03/2015

1
Tôi đã sửa lại các công cụ sửa lỗi, vì vậy bây giờ tôi có thể chẩn đoán vấn đề. Điều đang xảy ra là chương trình chỉ sao chép nửa sau của chính nó (bắt đầu từ JMP loop 0). Sau đó, khi nó nhảy đến nơi bắt đầu của bản sao, nó chỉ là khoảng trống và nó bị mất.
PhiNotPi 10/03/2015

2
Hãy bỏ qua bình luận trước đó (bây giờ đã xóa) của tôi; Tôi đã kiểm tra phiên bản mã của bạn không chính xác (trớ trêu thay, vì lỗi sao chép-dán), đó là lý do tại sao nó hoạt động rất kém đối với tôi.
Ilmari Karonen

6

Người gác cổng

Nó nên kiểm tra xem các địa chỉ sau có trống không và nếu không nó sẽ xóa chúng (do đó, hy vọng, xóa bot đối thủ).

Chỉnh sửa: Phiên bản mới này sẽ nhanh hơn (bây giờ tôi đã hiểu JMZlệnh và @tham chiếu chính xác).

JMZ 2 6
MOV 4 @-1
ADD 2 -2
JMP -3 0
DAT 0 1
DAT 0 0

Không phải người gác cổng tự tử với JMZ đầu tiên sao? Nó phải là ít nhất JMZ 2 8. Bằng cách sử dụng @ bạn có thể giảm hai lần thêm xuống chỉ còn một. Một cái gì đó như: "JMZ 2 @ 5 MOV 5 @ 4 THÊM 2 3 JMP -3 0 ĐẠT 0 1 ĐẠT 0 2 ĐẠT 0 0" (chưa được kiểm tra)
Lượt

@ Tôi không nhảy, vì địa chỉ 2 từ đó là ADD 3 -2, nhưng bạn nói đúng là anh ấy nên thay đổi nó, tôi nghĩ vậy.
mbomb007 15/03/2015

Có, tôi đã đọc sai hướng dẫn JMZvà nghĩ rằng JMZ A Bđang kiểm tra Avà nhảy tới Bnếu 0 khi rõ ràng nó ngược lại. Cảm ơn vì đã chú ý vì tôi đã không :)
plannapus

5

ScanBomber

Xóa ý kiến ​​của tôi trước khi biên dịch. Quét một lúc, sau đó đánh bom khi tìm thấy chương trình. Nó có lẽ vẫn sẽ thua Người lùn của tôi, mặc dù.

scan add #eight #range  ; scan
jmz #scan @range
sub #six #range
fire mov #zero @range   ; bombs away! (-6)
add #two #range
mov #zero @range
add #two #range
mov #zero @range
add #two #range
mov #zero @range        ; (+0)
add #two #range
mov #zero @range
add #two #range
mov #zero @range
add #two #range
mov #zero @range
add #two #range
mov #zero @range        ; (+8)
range jmp #scan 6
two dat 0 2
six dat 0 6
zero dat 0 0
eight dat 0 8

OP định nghĩa #hoàn toàn khác với thông số kỹ thuật (đọc liên kết mà anh ấy liên kết đến), tôi vẫn chưa sửa chương trình này cho nó.
mbomb007

@TheBestOne Tôi nghĩ rằng tôi đã sửa nó. Có vẻ như nó có ý nghĩa bây giờ? Hoặc tôi cần phải đặt #trước mỗi tài liệu tham khảo zero? Vâng, tôi nghĩ rằng tôi cần phải ...
mbomb007

Nó hoạt động tốt bây giờ. Nó đánh bại mọi bot trừ Dwarf và Imp.
TheNumberOne 13/03/2015

@TheBestOne Dwarf quá nhỏ và sẽ chỉ được phát hiện trong 50% vị trí chương trình có thể. Nó có khả năng chỉ thua Imp vì nó tự đánh bom sau khi đi vòng quanh toàn bộ bộ nhớ.
mbomb007

5

Han Shot đầu tiên (v2)

Tôi cho rằng cuộc thi có thể sử dụng sự đa dạng hơn, vì vậy đây là mục thứ hai của tôi: CMPmáy quét một lần.

Đây là phiên bản 2 , với khả năng phòng thủ chống Imp được cải thiện - giờ đây nó có thể đánh bại Imp, nếu chỉ bằng một điểm. Nó vẫn thua Kỹ sư Dwarven, nhưng đánh bại mọi thứ khác cho đến nay, đặt nó ở vị trí đầu tiên.

scan    ADD bomb    aim
aim     CMP 17      12
        JMZ scan    #-3
loop    MOV bomb    @aim
        ADD step    aim
step    JMP loop    #2
bomb    DAT 10      10

Nó hoạt động bằng cách so sánh các vị trí lõi liền kề cách nhau 5 bước, tại các khoảng thời gian 10 bước, cho đến khi tìm thấy sự khác biệt. Khi đó, nó bắt đầu ném bom theo các bước 2 bước cho đến khi giết chết đối thủ hoặc vòng quanh lõi để tự chạm tới.

Nếu quá trình quét không tìm thấy gì khác, cuối cùng nó sẽ lặp lại và tìm mã riêng và tấn công nó. Điều này sẽ là tự sát, nhưng vì sự trùng hợp may mắn là quả bom đầu tiên rơi thẳng xuống aimđường, khiến quả bom tiếp theo bị ném 12 vị trí (chứ không phải 2) thông thường xuống lõi, thuận tiện bỏ qua mã. (Điều này cũng xảy ra với xác suất 50% nếu quá trình quét tìm thấy thứ gì đó, nhưng không giết được đối thủ.) Vì kích thước lõi là bội số của hai, điều này cũng sẽ tiếp tục xảy ra nếu việc ném bom chạy vòng quanh, loại bỏ sự cần thiết của một chiến lược dự phòng hơn nữa.

(Thủ thuật tự ném bom này ban đầu chỉ là một sự trùng hợp thuần túy - Tôi đã lên kế hoạch cho một cách hoàn toàn khác để chuyển từ chế độ quét sang chế độ ném bom nếu không tìm thấy gì, nhưng khi tôi lần đầu tiên kiểm tra mã, các hằng số đã tình cờ làm đúng làm việc theo cách này và tôi quyết định gắn bó với nó.)


4

Imp

MOV 0 1

Đơn giản chỉ cần inch thông qua chương trình.


4

Sên

     mov    ones    @-1024
     mov    from    -3
     mov    here    -3
loop mov    @-5 @-4
     add    ones  -5
     jmz    -17 -6
     add    ones  -8    
     jmp    loop    42
ones dat    1   1
from dat    2   2
here dat    -11 -11

Bò qua không gian bộ nhớ ngược. Thỉnh thoảng ném một quả bom ở xa.


3

thỏ Phục Sinh

Anh ấy thích nhảy lùi :)

loop mov 0 -10
     add data loop
     cmp -7 data
     jmp -13 0
     jmp loop 0
data dat 1 1

3

Bệnh hoang tưởng

Một loại pasta nhưng nó sẽ kiểm tra xem mã đã được sửa đổi bằng cách ném bom. Nếu vậy nó sao chép qua một người lùn và thực hiện nó. Nếu tôi quản lý để tạo lại GameView, tôi sẽ cố gắng thay đổi một số hằng số.

copy    MOV data copy
loop    MOV @-1 @-1
    CMP @copy end
out JMP check 0
    SUB loop copy
    JMP loop 0
data    DAT 0 4109
check   MOV data copy
loop2   CMP @copy @copy
    JMP ok 0
    MOV aah 2
ok  CMP @copy end
    JMP 4098 0
    SUB loop copy
    JMP loop2 0
panic   MOV end copy
    MOV jump out
    JMP loop 0
jump    JMP 4124 0
dwarf   ADD 2 bomb
    MOV bomb @bomb
    JMP dwarf 4
bomb    DAT 0 4
aah JMP 3 0
end DAT 19 4127

Được rồi, trên thực tế nó đang hoạt động và tôi chỉ loay hoay, cảm ơn vì cuộc chạy mới;)
Lượt
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.