Perang Inti Nano

21

Ini adalah adaptasi dari Perang Inti , sebuah pemrograman KOTH yang berasal dari abad ke-20. Untuk lebih spesifik, itu menggunakan set instruksi yang sangat disederhanakan terutama didasarkan pada proposal asli .

Latar Belakang

Dalam Core War, ada dua program yang berjuang untuk mengendalikan komputer. Tujuan dari setiap program adalah untuk menang dengan mencari dan mengakhiri program yang berlawanan.

Pertempuran terjadi di dalam memori utama komputer. Memori ini disebut Core, dan berisi 8192 alamat. Ketika pertempuran dimulai, kode untuk setiap pesaing (disebut prajurit) ditempatkan dalam memori acak. Eksekusi program bergantian antara prajurit, melakukan satu instruksi masing-masing. Setiap instruksi mampu memodifikasi bagian dari Core, yang mengarah ke kemungkinan program modifikasi diri.

Tujuannya adalah untuk menghentikan program lawan. Suatu program berakhir ketika mencoba untuk menjalankan instruksi yang tidak valid, yang merupakan DATinstruksi apa pun .

Set Instruksi

Setiap program terdiri dari serangkaian instruksi tingkat rendah, yang masing-masingnya mengambil dua bidang, yang disebut bidang A dan B.

Set instruksi ini sangat menarik dari spesifikasi asli. Perubahan utama adalah 1) klarifikasi tentang penambahan / pengurangan perintah, dan 2) perubahan #mode pengalamatan untuk memungkinkannya digunakan di mana saja. Kebanyakan versi lengkap dari Core Wars memiliki lebih dari 20 opcode, 8 mode pengalamatan, dan satu set "pengubah instruksi."

Opcode

Setiap instruksi harus memiliki satu dari tujuh opcode yang berbeda.

  • DAT A B- (data) - Ini hanya menampung angka Adan B. Yang penting, suatu proses mati ketika mencoba untuk menjalankan instruksi DAT.
  • MOV A B- (pindah) - Ini memindahkan isi lokasi Amemori ke lokasi memori B. Berikut ini adalah demonstrasi sebelum dan sesudah:

    MOV 2 1
    ADD @4 #5
    JMP #1 -1
    
    MOV 2 1
    JMP #1 -1
    JMP #1 -1
    
  • ADD A B- (tambah) - Ini menambahkan isi lokasi Amemori ke lokasi memori B. Dua bidang pertama keduanya ditambahkan, dan bidang kedua ditambahkan.

    ADD 2 1
    MOV @4 #5
    JMP #1 -1
    
    ADD 2 1
    MOV @5 #4
    JMP #1 -1
    
  • SUB A B- (kurangi) - Ini mengurangi isi lokasi memori Adari (dan menyimpan hasilnya ke) lokasi memori B.

    SUB 2 1
    MOV @4 #5
    JMP #1 -1
    
    SUB 2 1
    MOV @3 #6
    JMP #1 -1
    
  • JMP A B- (lompat) - Lompat ke lokasi A, yang akan dieksekusi siklus berikutnya. Bharus berupa angka tetapi tidak melakukan apa-apa (Anda dapat menggunakannya untuk menyimpan informasi).

    JMP 2 1337
    ADD 1 2
    ADD 2 3
    

    Lompatan berarti bahwa ADD 2 3akan dieksekusi siklus berikutnya.

  • JMZ A B- (lompat jika nol) - Jika kedua bidang baris Badalah 0, maka program melompat ke lokasi A.

    JMZ 2 1
    SUB 0 @0
    DAT 23 45
    

    Karena dua bidang instruksi 1 adalah 0, perintah DAT akan dieksekusi giliran berikutnya, yang mengarah ke kematian segera.

  • CMP A B- (bandingkan dan lompati jika tidak sama) - Jika bidang dalam instruksi Adan Btidak sama, lewati instruksi berikutnya.

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

    Karena kedua bidang instruksi 1 dan 2 nilainya sama, perintah ADD tidak dilewati dan dieksekusi giliran berikutnya.

Ketika dua instruksi ditambahkan / dikurangi, dua bidang (A dan B) ditambahkan / dikurangi pasangan-bijaksana. Mode pengalamatan dan opcode tidak diubah.

Mengatasi Mode

Ada tiga jenis mode pengalamatan. Masing-masing dari dua bidang instruksi memiliki salah satu dari tiga mode pengalamatan ini.

  • Immediate#X - Xadalah garis yang akan digunakan secara langsung dalam perhitungan. Misalnya, #0adalah baris pertama dari program. Garis negatif merujuk pada garis dalam inti sebelum dimulainya program.

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

    Ini akan menambahkan yang pertama dari dua garis DAT ke yang kedua, karena mereka berada di baris 3 dan 4, masing-masing. Anda tidak ingin menggunakan kode ini, karena DAT akan membunuh bot Anda pada siklus berikutnya.

  • RelatifX - Angka tersebut Xmenunjukkan lokasi alamat memori target, relatif terhadap alamat saat ini. Nomor di lokasi ini digunakan dalam perhitungan. Jika baris #35dieksekusi dan berisi -5, maka baris #30digunakan.

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

    Ini akan menambahkan baris DAT kedua ke yang pertama.

  • Tidak Langsung@X - Nomor tersebut Xmewakili alamat relatif. Konten di lokasi itu sementara ditambahkan ke nomor X untuk membentuk alamat relatif baru, dari mana nomor tersebut diambil. Jika baris #35dieksekusi, dan bidang kedua adalah @4, dan bidang baris kedua #39berisi nomor -7, maka baris #32digunakan.

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

    Ini akan menambahkan DAT pertama ke yang kedua, tetapi dengan cara yang lebih berbelit-belit. Bidang pertama adalah @ 1, yang mendapatkan data dari alamat relatif itu, yang merupakan bidang pertama dari DAT pertama, angka 0. Ini ditafsirkan sebagai alamat relatif kedua dari lokasi itu, sehingga 1 + 0 = 1 memberikan total diimbangi dari instruksi asli. Untuk bidang kedua, @ 1 mendapatkan nilai dari alamat relatif itu (1 di bidang kedua DAT pertama) dan menambahkannya ke dirinya sendiri dengan cara yang sama. Total offset adalah 1 + 1 = 2. Jadi, instruksi ini dijalankan mirip dengan ADD 1 2.

Setiap program dapat berisi hingga 64 instruksi.

Ketika putaran dimulai, kedua program ditempatkan secara acak di bank memori dengan 8192 lokasi. Pointer instruksi untuk setiap program dimulai pada awal program dan bertambah setelah setiap siklus eksekusi. Program mati setelah penunjuk instruksinya mencoba mengeksekusi DATinstruksi.

Parameter Inti

Ukuran inti adalah 8192, dengan batas waktu 8192 * 8 = 65536 kutu. Inti adalah siklik, jadi penulisan ke alamat 8195 sama dengan penulisan ke alamat 3. Semua alamat yang tidak digunakan diinisialisasi ke DAT #0 #0.

Setiap pesaing tidak boleh lebih dari 64 baris. Integer akan disimpan sebagai integer bertanda 32-bit.

Parsing

Untuk membuat pemrograman lebih mudah bagi pesaing, saya akan menambahkan fitur label-baris ke parser. Kata-kata apa pun yang muncul pada baris sebelum opcode akan ditafsirkan sebagai label baris. Misalnya, tree mov 4 6memiliki label garis tree. Jika, di mana pun dalam program ini, ada bidang yang berisi tree #treeatau @tree, nomor akan diganti. Selain itu, kapitalisasi diabaikan.

Berikut adalah contoh bagaimana label garis diganti:

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

Di sini, label A, B, dan C ada di baris 0, 1, dan 2. Contoh #labelakan diganti dengan nomor baris label. Contoh labelatau @labeldiganti dengan lokasi relatif label. Mode pengalamatan dipertahankan.

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

Mencetak gol

Untuk setiap pasangan kontestan, setiap pertempuran yang mungkin dilakukan. Karena hasil pertempuran tergantung pada offset relatif dari kedua program, setiap kemungkinan offset (sekitar 8000 dari mereka) dicoba. Selanjutnya, setiap program memiliki kesempatan untuk bergerak terlebih dahulu di setiap offset. Program yang memenangkan sebagian besar penyeimbangan ini adalah pemenang pasangan.

Untuk setiap pasangan yang dimenangkan seorang pejuang, diberikan 2 poin. Untuk setiap seri, seorang prajurit diberikan 1 poin.

Anda diizinkan mengirimkan lebih dari satu prajurit. Aturan umum untuk banyak pengiriman berlaku, seperti tidak ada tag-teaming, tidak ada kerjasama, tidak ada raja, dll. Sebenarnya tidak ada ruang untuk ini dalam Perang Inti, jadi itu seharusnya tidak menjadi masalah besar.

Pengendali

Kode untuk pengontrol, bersama dengan dua bot contoh mudah, terletak di sini . Karena kompetisi ini (saat dijalankan menggunakan pengaturan resmi) sepenuhnya deterministik, leaderboard yang Anda buat akan sama persis dengan leaderboard resmi.

Bot Contoh

Berikut adalah contoh bot yang menunjukkan beberapa fitur bahasa.

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

Bot ini beroperasi dengan perlahan menghapus semua memori lain di inti dengan menggantinya dengan "bom." Karena bom adalah DATinstruksi, program apa pun yang mencapai bom akan dihancurkan.

Ada dua label garis, "utama" dan "bom" yang berfungsi untuk menggantikan angka. Setelah preprocessing, programnya terlihat seperti ini:

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

Baris pertama menyalin bom ke garis tepat di atas program. Baris berikutnya menambahkan nilai bomb ( 0 -1) ke perintah move, dan itu juga menunjukkan penggunaan @mode pengalamatan. Tambahan ini menyebabkan perintah pindah ke target baru. Perintah selanjutnya tanpa syarat melompat kembali ke awal program.


Papan Peringkat Saat Ini

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

Hasil Berpasangan:

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

Pembaruan terbaru (versi baru Turbo dan Paranoid) membutuhkan waktu sekitar 5 menit untuk berjalan di laptop lama. Saya ingin mengucapkan terima kasih kepada Ilmari Karonen untuk perbaikannya pada controller . Jika Anda memiliki salinan controller lokal, Anda harus memperbarui file Anda.

PhiNotPi
sumber
Apa yang terjadi jika dua bot yang bersaing mencoba menggunakan label yang sama?
mbomb007
1
@ mbomb007 Label adalah hal preprocessing dan dihitung sebagai file sumber bot sedang diuraikan. Label Anda tidak akan berinteraksi dengan label pesaing.
PhiNotPi
1
@ mbomb007 Agar program tidak tumpang tindih. Juga, saya tidak berencana menambahkan lebih banyak fitur ke versi ini, kecuali untuk Micro Core War.
PhiNotPi
1
@ mbomb007 Mengalamatkan referensi tidak langsung bidang yang sama yang membuat referensi (1 atau 2). Tidak ada pengubah instruksi. Saya tidak mendasarkan tantangan ini dari standar '94.
PhiNotPi
2
@ Thrax saya akan mengatakan tidak, bahwa Anda tidak terbatas pada satu pengiriman. Aturan multi-submission khas berlaku (tidak ada tag-teaming, dll), meskipun tidak ada banyak ruang untuk kerjasama dalam perang inti.
PhiNotPi

Jawaban:

9

Insinyur Kerdil

Kurcaci baru dan lebih baik. Menang melawan semua yang disampaikan sejauh ini. Ukuran langkah mewah yang dioptimalkan untuk corestep mungkin berlebihan di sini.

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

Fitur-fitur penting termasuk loop pemboman cepat yang melemparkan dua bom dalam empat siklus, untuk kecepatan pemboman rata-rata 0,5c dalam jargon Perang Inti yang lama, dan penggunaan JMZuntuk mendeteksi kapan proses pemboman selesai dan saatnya untuk beralih ke rencana B ( di sini, seorang Imp).


Saya dulu bermain Core War di tahun 90-an (beberapa dari Anda mungkin telah melihat buku panduan dasar yang saya tulis di tahun '97), jadi saya pikir akan menarik untuk melihat strategi lama dari dunia RedCode '88 / '94 yang mungkin berguna dalam varian ini.

Pikiran pertama saya adalah:

  • Tidak ada SPL, jadi tidak ada replikator (dan tidak ada cincin / spiral). Ini harus membuat pembom kuat. (Juga, semua strategi pengeboman mewah yang dirancang untuk menangani replikator dan spiral? Benar-benar tidak berguna dan tidak berguna di sini. Hanya bom dengan DATs.)

  • Kemudian lagi, CMPpemindaian masih berpotensi lebih cepat daripada pengeboman, sehingga pemindai cepat dapat memiliki kesempatan.

  • Tidak adanya in / decrements membuat core membersihkan sangat lambat. Bahkan, inti yang jelas dalam varian ini cukup banyak hanya pembom dengan ukuran langkah (suboptimal) ± 1. Sekali lagi, ini juga menyakitkan pemindai; pemindai sekali pakai → strategi bomber mungkin berhasil.

  • Quickscanners / quickbombers (strategi gim awal menggunakan loop pemindaian / pemboman yang tidak dikontrol, bagi mereka yang tidak begitu terbiasa dengan jargon Perang Inti) masih berpotensi berguna, tetapi hanya terhadap program-program panjang (seperti itu sendiri, sehingga ada semacam umpan balik efek di sini). Sulit dikatakan apakah itu benar-benar sepadan dengan masalahnya.

  • Sistem penilaiannya menarik. Ikatan mencetak setengah poin sebanyak kemenangan (daripada 1/3, seperti dalam Perang Inti tradisional), membuat mereka lebih menarik. Kemudian lagi, tentang satu-satunya program yang cenderung mencetak banyak ikatan di bawah aturan ini adalah imp. (Juga, tidak adanya penambahan / peningkatan membuat gerbang imp sulit, bahkan imp sederhana pun benar - benar memiliki kesempatan untuk mencetak dasi jika mereka mencapai lawan mereka hidup-hidup.)

  • Juga, karena peringkat akhir hanya bergantung pada program mana yang Anda kalahkan, dan bukan seberapa banyak Anda mengalahkannya, ia cenderung lebih menyukai entri umum. Lebih baik untuk hanya mengalahkan semua lawan Anda, daripada benar-benar menghancurkan setengah dari mereka dan hanya kalah dari sisanya.

  • Karena kodenya bersifat publik, selalu memungkinkan untuk menemukan program yang dapat mengalahkan setiap pengajuan yang diberikan sebelumnya - bahkan mungkin beberapa di antaranya - tidak peduli seberapa bagusnya mereka secara umum. Trik seperti itu (seperti menyetel ukuran langkah Anda untuk mengenai lawan tepat sebelum mereka mengenai Anda) dapat dengan mudah tampak murah. Dan, tentu saja, pemain target selalu bisa hanya mengirimkan versi baru dengan konstanta yang berbeda.

Bagaimanapun, hasil dari semua ini adalah bahwa saya memutuskan bahwa saya harus mencoba untuk menulis pembom cepat atau pemindai yang sangat cepat, dan mungkin memasang quickscanner / bomber ke dalamnya. Dari opsi-opsi itu, seorang pembom cepat sepertinya yang paling sederhana dan paling mungkin bekerja.

Pada saat itu, saya menghabiskan terlalu banyak waktu mengutak-atik dan mengoptimalkan kode juru bahasa PhiNotPi, karena saya pikir saya mungkin akan menjalankan banyak uji coba brute force untuk mengoptimalkan konstanta. Seperti yang terjadi, saya tidak pernah melakukan itu - kode di atas adalah versi pertama yang benar-benar berfungsi (setelah beberapa upaya gagal yang baru saja melakukan bunuh diri karena bug konyol).


Trik yang membuat pembom saya cepat adalah menggunakan pengalamatan tidak langsung untuk melemparkan dua bom untuk masing-masing ADD. Begini cara kerjanya:

  1. Pada siklus pertama, kami mengeksekusi MOV bomb @aim. Ini menyalin bombinstruksi ke mana saja di inti B-bidang aimpoin ke (awalnya, tepatnya 6326 instruksi sebelumnya aim, atau 6328 instruksi sebelumnya step; Anda akan melihat mengapa angka-angka itu penting nanti).

  2. Pada langkah selanjutnya, kami menjalankan aiminstruksi itu sendiri! Pada lulus pertama, terlihat seperti ini: MOV bomb @-6326. Dengan demikian, itu menyalin bombke lokasi yang B-bidang instruksi di 6326 baris sebelum itu sendiri menunjuk ke.

    Jadi, apa yang ada di 6326 baris sebelumnya aim? Mengapa, itu salinan bombkami baru saja menempatkan di sana satu siklus sebelumnya! Dan kita kebetulan mengatur hal-hal sehingga B-field bombmemiliki nilai bukan nol, sehingga bom baru tidak akan disalin di atas yang lama, tapi agak jauh (sebenarnya, di sini jaraknya 3164, yang merupakan setengah dari ukuran langkah nominal kami 6328; tetapi offset lainnya dapat bekerja, mungkin lebih baik).

  3. Pada siklus berikutnya, kita menyesuaikan tujuan kita SUB step aim, yang mengurangi nilai-nilai stepinstruksi (yang juga merupakan lompatan yang akan kita laksanakan selanjutnya, walaupun itu bisa saja hanya suatu DATtempat sederhana ) dari aim.

    (Satu detail untuk catatan di sini adalah bahwa kita semacam ingin A-nilai stepmenjadi nol, sehingga kita masih akan melemparkan bom yang sama pada iterasi berikutnya Bahkan yang tidak benar-benar diperlukan, meskipun;. Hanya bom dilemparkan dengan instruksi pertama harus memiliki B-field mereka sama dengan 3164, sisanya bisa apa saja.)

  4. Selanjutnya, JMZperiksa apakah instruksi 6328 menjauh darinya masih nol, dan jika demikian, lompat kembali ke atas kode. Sekarang, 6328 adalah ukuran langkah pembom kita, dan dapat dibagi dengan 8 (tetapi bukan 16); jadi, jika kita terus melempar bom setiap 6328 langkah, kita akhirnya akan kembali ke tempat kita mulai, setelah membom setiap instruksi kedelapan di inti (dan dengan bom tambahan diimbangi oleh 3163 = 6328/2 ≡ 4 (mod 8) , kami akan menekan setiap instruksi keempat ).

    Tapi kami mulai pengeboman kami dijalankan pada 6328 petunjuk sebelum itu JMZ, dan melangkah mundur oleh -6328 di setiap iterasi, jadi kita akan mengebom lokasi 6328 langkah setelah itu JMZhanya satu iterasi sebelum kita akan memukul JMZitu sendiri. Jadi ketika JMZmendeteksi bom di 6328 instruksi setelahnya, itu pertanda bahwa kita telah membahas inti sebanyak yang kita bisa tanpa mengenai diri kita sendiri, dan harus beralih ke strategi cadangan sebelum kita bunuh diri.

  5. Adapun strategi cadangan, itu hanya MOV 0 1imp tua , karena saya tidak bisa memikirkan yang lebih baik untuk saat ini. Cara saya melihatnya, jika kita telah mengebom setiap lokasi inti keempat dan masih belum menang, kita mungkin bertarung dengan sesuatu yang sangat kecil atau sangat defensif, dan mungkin juga mencoba bertahan dan puas dengan dasi. Tidak apa-apa, karena program kecil atau defensif seperti itu pada umumnya tidak pandai membunuh hal lain, dan bahkan jika kita hanya memenangkan beberapa perkelahian secara kebetulan, kita mungkin masih akan unggul.


Ps. Jika ada orang lain yang menginginkannya, inilah garpu saya yang lebih baik dari kode turnamen PhiNotPi . Ini sekitar dua kali lebih cepat, menyimpan hasil pertempuran lama sehingga Anda tidak perlu menjalankannya kembali, dan memperbaiki apa yang saya yakini sebagai bug minor dalam perhitungan hasil pertempuran. Perubahan telah digabungkan ke dalam versi arus utama oleh PhiNotPi. Terima kasih!

Ilmari Karonen
sumber
1
Asal tahu saja, penilaian mencetak SETIAP kemungkinan kombinasi lokasi awal program, dan program penilaian poin paling banyak menang. Ini membuat ikatan tidak mungkin atau sama sekali tidak menguntungkan karena selama sebuah program tidak pernah membunuh dirinya sendiri dan mengebom setidaknya satu alamat sekali, itu akan mengalahkan imp, menang satu, dan sisanya mengikat.
mbomb007
9

Tampilan Grafik

Ini dapat digunakan sebagai alat debugging. Ini menampilkan inti dan menunjukkan lokasi pemain. Untuk menggunakannya, Anda harus memanggilnya dari kode. Saya juga menyediakan modifed Game.javayang secara otomatis menampilkan GraphView.

PhiNotPi dan Ilmari Karonen baru-baru ini mengganti Controller. Ilmari Karonen telah berbaik hati untuk menyediakan GameView yang diperbarui di lokasi ini .

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

Game.java yang Dimodifikasi:

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.");
        }
    }*/
}
TheNumberOne
sumber
Sepertinya Anda membuat modifikasi untuk Player juga. Saya mendapatkan./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
@ Maaf Maaf tentang itu. Saya harus berkomentar tentang printCore()metode ini.
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

Upaya CoreWar ke-2 saya. Dirancang untuk mengalahkan Dwarf. Memindai dengan 3 untuk data, lalu menempatkan bom setiap 2. Setiap tahap berjalan hanya dalam 3 instruksi, dengan harapan bahwa bom Dwarf melewatkannya.

Turbo BARU ++ : Sekarang ditingkatkan. Memindai mundur hingga menemukan data, lalu bergerak sendiri ke sana, lalu mengebom ke belakang. Harapannya adalah bahwa gerakan itu akan mengacaukan lawan, atau ke suatu tempat yang sudah dibom dan karenanya aman (ish).

... Dan hasil edit untuk membuatnya memindai lebih jarang membuatnya mengalahkan semua orang!

ASHelly
sumber
Tampaknya untuk mengalahkan lebih dari sekedar Dwarf. Selamat! Saya pikir Anda bisa mencapai tempat ketiga jika Anda juga bisa mengalahkan Imp.
Ilmari Karonen
Saya memperbarui yang ini, tetapi sebenarnya ini adalah evolusi yang cukup besar dari yang sebelumnya. Haruskah saya membuat entri baru?
AShelly
Saya tidak berani berbicara untuk PhiNotPi, tapi saya kira itu terserah Anda. Melakukan pembaruan di tempat pada dasarnya berarti menarik entri lama Anda. Ngomong-ngomong, lebih banyak lagi ucapan selamat karena berhasil menghindari jalan Anda ke tempat ketiga! Saya pikir milik Anda adalah satu-satunya entri sejauh ini untuk mengalahkan DwarvenEngineer berpasangan.
Ilmari Karonen
Sudah selesai dilakukan dengan baik ;). kaulah yang harus dikalahkan sekarang!
Hit
8

Kerdil

Program umum dan sederhana yang mewakili pelemparan batu kerdil. Itu menempatkan DATinstruksi setiap empat alamat.

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

EDIT: Memperbaiki pengalamatan. Rupanya mode pengalamatan berbeda dari spesifikasi OP yang ditautkan.

mbomb007
sumber
Saya pikir ini "tambahkan # 3 3" untuk baris pertama, bukan?
Hit
@Hit Tidak. Saya ingin menekan setiap alamat ke-4. Saya bisa menggunakan add 3 3, tetapi kemudian akan menggandakan setiap loop alih-alih menambahkan, dan itu tidak akan berguna. #4langsung, jadi itu menambah angka 4ke nilai 2 di alamat yang 3setelah alamat saat ini.
mbomb007
Saya pikir Anda salah menafsirkan #mode pengalamatan dalam tantangan. Seperti yang dinyatakan dalam spesifikasi, saya membuat perubahan ke #mode pengalamatan.
PhiNotPi
Anda harus pergi seperti: "tambahkan 2 3 mov 2 @ 2 jmp -2 4 dat 0 4"
Hit
Dengan perilaku yang benar bahkan kekalahan berevolusi
Hit
7

Berkembang

Sejujurnya saya tidak mengerti cara kerjanya. Tampaknya untuk membangun kode sumbernya sebelum melakukan apa pun. Saya akan senang jika seseorang memberi saya penjelasan tentang cara kerjanya.

Setelah mempelajarinya, saya menemukan bahwa itu hanyalah katai dimodifikasi dengan penjaga imp. Alih-alih membom musuh dengan DATinstruksi, itu mengocok kode musuh. Itu juga mengebom setiap dua register, bukan setiap empat register. Diberi cukup waktu, itu pasti akan menghancurkan dirinya sendiri.

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
TheNumberOne
sumber
1
Lalu dari mana Anda mendapatkannya?
PyRulez
4
@PyRulez Komputer ini dihasilkan melalui algoritma genetika.
TheNumberOne
1
Sepertinya eksekusi tidak benar-benar berkembang lebih jauh dari baris # 6, karena ada lompatan kembali dalam program. Saya percaya alasan itu berhasil adalah bahwa ada lebih banyak gerakan / loop daripada para pesaingnya.
PhiNotPi
6

FirstTimer

Jika berhasil, ia harus mencoba untuk mengambil posisi di awal inti dan membuat pertahanan

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
Thrax
sumber
Itu tidak cukup bekerja seperti yang saya kira Anda asumsikan: #0mengacu pada awal program Anda (yaitu sama dengan #main), bukan ke awal inti (yang sebenarnya bukan konsep yang bermakna - intinya adalah melingkar, kode Anda tidak dapat mengetahui di mana ia mulai atau berakhir). Apa yang terjadi adalah bahwa instruksi pertama Anda ( main) menimpa dirinya sendiri dengan MOV #data #100, setelah itu kode Anda secara efektif berubah menjadi 0,25c (= satu instruksi per empat siklus) forward core clear.
Ilmari Karonen
@IlmariKaronen Oh, terima kasih atas penjelasannya. Saya melakukan kesalahan #0untuk memulai inti. 5 instruksi pertama sama sekali tidak berguna.
Thrax
6

CopyPasta

Tidak pernah berpartisipasi dalam CoreWar, program sederhana ini hanya mencoba menyalin-menempel dirinya sendiri dan kemudian menjalankan salinannya. Mungkin tidak memiliki perilaku yang benar, tolong beri tahu saya jika itu masalahnya.

Itu terlalu pasifis dan tidak bisa menang sebenarnya.

MOV 6 0
MOV @-1 @-1
CMP @-2 3
JMP 4242 0
SUB -3 -4
JMP -4 0
DAT 0 4244
Memukul
sumber
Hasil edit saat ini mungkin tidak akan ada dalam pembaruan papan peringkat berikutnya (saya sedang menjalankan turnamen sekarang). Versi lama, bagaimanapun, memenangkan hasil awal (ukuran inti kecil).
PhiNotPi
Oke :) Versi yang lebih lama tidak keluar dari loop1, tidak benar-benar perilaku yang diinginkan, saya mencoba untuk memperbaikinya.
Tekan
Versi saat ini tampaknya rusak. Saya belum tahu mengapa.
PhiNotPi
1
Saya telah memperbaiki alat debugging, jadi sekarang saya dapat mendiagnosis masalahnya. Apa yang terjadi adalah bahwa program hanya menyalin bagian kedua dari dirinya sendiri (mulai dari JMP loop 0). Kemudian, ketika melompat ke tempat awal salinan seharusnya, itu hanya ruang kosong dan hilang.
PhiNotPi
2
Harap abaikan komentar saya sebelumnya (sekarang dihapus); Saya telah menguji versi kode Anda yang salah (ironisnya, karena kesalahan salin-tempel), dan itulah sebabnya ia bekerja sangat buruk bagi saya.
Ilmari Karonen
6

Pesuruh

Ini harus memeriksa apakah alamat berikut kosong dan jika tidak membersihkannya (dengan demikian, semoga, menghapus bot lawan).

Sunting: Versi baru ini harus lebih cepat (sekarang saya mengerti JMZperintah dan @referensi dengan benar).

JMZ 2 6
MOV 4 @-1
ADD 2 -2
JMP -3 0
DAT 0 1
DAT 0 0
plannapus
sumber
Bukankah petugas kebersihan melakukan bunuh diri dengan JMZ pertama? Paling tidak harus JMZ 2 8. Ngomong-ngomong menggunakan @ Anda bisa mengurangi dua tambah hanya satu. Sesuatu seperti: "JMZ 2 @ 5 MOV 5 @ 4 ADD 2 3 JMP -3 0 DAT 0 1 DAT 0 2 DAT 0 0" (belum diuji)
Hit
@Hit Itu tidak melompat, karena alamat 2 dari sana ADD 3 -2, tetapi Anda benar bahwa dia harus mengubahnya, saya pikir.
mbomb007
Ya saya salah membaca instruksi untuk JMZdan berpikir JMZ A Bsedang memeriksa Adan melompat ke B0 jika ternyata sebaliknya. Terima kasih telah memperhatikan karena saya tidak :)
plannapus
5

ScanBomber

Hapus komentar saya sebelum kompilasi. Memindai sebentar, lalu mengebom ketika menemukan program. Mungkin masih akan kalah oleh Kurcaci saya.

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
mbomb007
sumber
OP didefinisikan #sepenuhnya berbeda dari spec (baca tautan yang dia tautkan), saya belum memperbaiki program ini untuk itu.
mbomb007
@TheBestOne saya pikir saya memperbaikinya. Apakah itu terlihat masuk akal sekarang? Atau apakah saya harus meletakkan #sebelum setiap referensi zero? Ya, saya pikir saya perlu ...
mbomb007
Ini bekerja dengan baik sekarang. Ini mengalahkan setiap bot kecuali Dwarf dan Imp.
TheNumberOne
@TheBestOne Dwarf terlalu kecil dan hanya akan terdeteksi di 50% dari kemungkinan penempatan program. Sepertinya hanya akan hilang ke Imp karena mengebom sendiri setelah berkeliling seluruh memori.
mbomb007
5

Han Shot First (v2)

Saya pikir kompetisi dapat menggunakan lebih banyak keanekaragaman, jadi inilah entri kedua saya: CMPpemindai satu-shot .

Ini adalah versi 2 , dengan peningkatan pertahanan anti-Imp - sekarang dapat mengalahkan Imp, jika hanya dengan satu poin. Itu masih kalah dari Dwarven Engineer, tetapi mengalahkan segalanya sejauh ini, menempatkannya saat ini di urutan pertama.

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

Ia bekerja dengan membandingkan lokasi inti yang berdekatan, terpisah 5 langkah, pada interval 10 langkah, hingga ia menemukan perbedaan. Ketika itu terjadi, ia mulai melempar bom pada interval 2 langkah sampai membunuh lawannya atau loop sepanjang jalan di sekitar inti untuk mencapai dirinya sendiri.

Jika pemindaian dilakukan tidak menemukan hal lain, pada akhirnya akan berputar dan menemukan kode sendiri dan menyerang Ini akan menjadi bunuh diri, tetapi untuk kebetulan yang beruntung bahwa bom pertama mendarat tepat di aimgaris, menyebabkan bom berikutnya dilemparkan 12 posisi (daripada 2 yang biasa) ke bawah, dengan mudah melewatkan kode. (Ini juga terjadi dengan kemungkinan 50% jika pemindaian menemukan sesuatu, tetapi gagal membunuh lawan.) Karena ukuran inti adalah kelipatan dari dua, ini juga akan terus terjadi jika pengeboman berjalan berputar-putar, menghilangkan kebutuhan untuk strategi cadangan lebih lanjut.

(Trik pemboman diri ini pada awalnya adalah kebetulan murni - saya telah merencanakan cara yang sama sekali berbeda untuk beralih dari pemindaian ke mode pemboman jika tidak ada yang ditemukan, tetapi ketika saya pertama kali menguji kode, konstanta kebetulan benar untuk membuatnya bekerja dengan cara ini, dan saya memutuskan untuk tetap menggunakannya.)

Ilmari Karonen
sumber
4

Imp

MOV 0 1

Cukup beberapa inci melalui program.

TheNumberOne
sumber
4

Siput

     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

Merayap melalui ruang memori mundur. Sesekali melempar bom jauh-jauh.

ASHelly
sumber
3

kelinci Paskah

Dia menikmati melompat mundur :)

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

Paranoid

Jenis salin-pasta tetapi akan memeriksa apakah kode telah dimodifikasi oleh pemboman. Jika demikian, salin melewati kurcaci dan jalankan. Jika saya berhasil membuat GameView lagi saya akan mencoba mengubah beberapa konstanta.

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
Memukul
sumber
Oke, sebenarnya itu bekerja dan saya hanya berpura-pura, terima kasih untuk menjalankan baru;)
Hit