Nano Çekirdek Savaşı


21

Bu, 20. yüzyıla dayanan bir programlama KOTH olan Core War'ın uyarlamasıdır . Daha spesifik olmak gerekirse, öncelikle orijinal teklife dayanan inanılmaz derecede basitleştirilmiş bir talimat seti kullanıyor .

Arka fon

Çekirdek Savaş'ta, bilgisayarın kontrolü için mücadele eden iki program var. Her programın amacı, karşıt programı bulup sonlandırarak kazanmaktır.

Savaş, bilgisayarın ana hafızasında gerçekleşir. Bu belleğe Çekirdek adı verilir ve 8192 adres içerir. Savaş başladığında, her yarışmacının kodu (savaşçı olarak adlandırılır) rastgele bir hafıza yığınına yerleştirilir. Programın yürütülmesi savaşçılar arasında değişerek her birinin talimatını verir. Her bir talimat Çekirdeğin bir bölümünü değiştirme yeteneğine sahiptir ve bu da kendi kendini değiştiren programların olasılığına neden olmaktadır.

Amaç muhalif programı sonlandırmaktır. Bir program, herhangi bir DATtalimat olan geçersiz bir talimatı çalıştırmayı denediğinde sona erer .

Öğretim Seti

Her program, her biri A ve B alanları olarak adlandırılan iki alan alan bir dizi düşük düzey komuttan oluşur.

Bu talimat seti, orijinal teknik özelliklerden ağır şekilde faydalanır. Ana değişiklikler 1) komutların eklenmesi / çıkarılmasıyla ilgili açıklama ve 2) #herhangi bir yerde kullanılmasına izin vermek için adresleme modunun değiştirilmesi . Çekirdek Savaşlarının çoğu tam sürümünde 20'nin üzerinde opcod, 8 adresleme modu ve bir dizi "talimat değiştirici" var.

opcodes

Her talimat yedi farklı koddan birine sahip olmalıdır.

  • DAT A B- (veri) - Bu sadece sayıları tutan Ave B. Önemli olarak, DAT komutunu yerine getirmeye çalıştığında işlem ölür.
  • MOV A B- (hareket) - Bu hareket Hafızadaki Abellek konumuna B. İşte öncesi ve sonrası gösterimi:

    MOV 2 1
    ADD @4 #5
    JMP #1 -1
    
    MOV 2 1
    JMP #1 -1
    JMP #1 -1
    
  • ADD A B- (ekle) - Bu hafıza konumunun içeriğini ekler Ahafıza konumuna B. Her ikisinin de ilk iki alanı eklenir ve ikinci alanlar eklenir.

    ADD 2 1
    MOV @4 #5
    JMP #1 -1
    
    ADD 2 1
    MOV @5 #4
    JMP #1 -1
    
  • SUB A B- (çıkarma) - Bu, hafıza konumunun içeriğini hafıza konumundan çıkarır A(ve sonucu depolar) B.

    SUB 2 1
    MOV @4 #5
    JMP #1 -1
    
    SUB 2 1
    MOV @3 #6
    JMP #1 -1
    
  • JMP A B- (atlama) - ABir sonraki döngüde yürütülecek yere atla . Bbir sayı olmalıdır, ancak hiçbir şey yapmaz (bilgiyi saklamak için kullanabilirsiniz).

    JMP 2 1337
    ADD 1 2
    ADD 2 3
    

    Atlama, bir ADD 2 3sonraki döngüde yürütülecek anlamına gelir .

  • JMZ A B- (Sıfırsa atla) - Her iki satır alanı Bda 0 ise, program konuma atlar A.

    JMZ 2 1
    SUB 0 @0
    DAT 23 45
    

    1 komutunun iki alanı 0 olduğu için, DAT komutu bir sonraki sırada çalıştırılarak yakın ölüme neden olur.

  • CMP A B- (karşılaştırmak ve eşit değilse atlayın) - talimatlarında alanlar varsa Ave Beşit değildir, bir sonraki talimat atlayın.

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

    Talimatlar 1 ve 2'nin iki alan değerine eşit olduğu için, ADD komutu edilir değil atlanır ve sonraki dönüş yürütülür.

İki komut eklendiğinde / çıkarıldığında, iki alan (A ve B) çift olarak eklenir / çıkarılır. Adresleme modu ve opcode değişmedi.

Adresleme Modları

Üç çeşit adresleme modu vardır. Bir komutun iki alanından her biri bu üç adresleme modundan birine sahiptir.

  • Anında#X - Xdoğrudan hesaplamada kullanılacak çizgidir. Örneğin #0, programın ilk satırı. Negatif çizgiler, program başlamadan önce çekirdekteki çizgilere işaret eder.

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

    Bu, iki DAT çizgisinden ilki ikinciye ekleyecektir, çünkü bunlar sırasıyla 3 ve 4 numaralı çizgilerdedir. Bununla birlikte, bu kodu kullanmak istemeyeceksiniz, çünkü DAT bir sonraki döngüde botunuzu öldürecektir.

  • GöreceliX - Sayı X, geçerli adrese göre bir hedef hafıza adresinin konumunu gösterir. Bu konumdaki sayı hesaplamada kullanılır. Satır #35yürütülüyor ve içeriyorsa -5, satır #30kullanılır.

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

    Bu, ikinci DAT satırını birinciye ekleyecektir.

  • Dolaylı@X - Sayı Xgöreceli bir adresi temsil eder. Bu konumdaki içerikler, numaranın alındığı yeni bir göreceli adres oluşturmak için X numarasına geçici olarak eklenir. Satır #35yürütülüyorsa ve ikinci alanı ise @4ve ikinci satır alanı #39sayı içeriyorsa, -7satır #32kullanılır.

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

    Bu, ilk DAT'ı ikinciye ekleyecektir, ancak daha karmaşık bir şekilde. İlk alan, ilk DAT'ın ilk alanı olan bir göreli adresden veri alan @ 1'dir, bu bir 0 olur. Bu, o konumdan ikinci bir göreceli adres olarak yorumlanır, yani 1 + 0 = 1 toplamı verir. orijinal talimattan ofset. İkinci alan için @ 1, bu göreceli adresin değerini alır (ilk DAT'ın ikinci alanındaki 1) ve aynı şekilde kendisine eklenir. Toplam ofset daha sonra 1 + 1 = 2'dir. Yani, bu talimat benzer şekilde yürütülür ADD 1 2.

Her program en fazla 64 talimat içerebilir.

Bir tur başladığında, iki program rastgele 8192 konumlu bir hafıza bankasına yerleştirilir. Her program için komut işaretçisi programın başında başlar ve her çalıştırma döngüsünden sonra artırılır. Program, imleci bir DATtalimatı yerine getirmeye çalıştığında program ölür .

Çekirdek Parametreleri

Çekirdek boyutu 8192'dir, 8192 x 8 = 65536 keneler zaman aşımına uğramıştır. Çekirdek döngüsel olduğundan, 8195 no'lu adrese yazma, 3 no'lu adrese yazma ile aynıdır DAT #0 #0.

Her yarışmacı 64 çizgiden uzun olmamalıdır. Tamsayılar 32 bit işaretli tamsayılar olarak saklanır.

ayrıştırma

Rakipler için programlamayı kolaylaştırmak için, ayrıştırıcıya bir satır etiketi özelliği ekleyeceğim. Bir opcode'dan önce bir satırda oluşan kelimeler satır etiketleri olarak yorumlanacaktır. Örneğin tree mov 4 6, çizgi etiketi vardır tree. Programın herhangi bir yerinde, tree #treeveya içeren bir alan varsa @tree, bir sayı kullanılacaktır. Ayrıca, büyük harf kullanımı dikkate alınmaz.

Satır etiketlerinin nasıl değiştirildiğinin bir örneği:

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

Burada, A, B ve C etiketleri 0, 1 ve 2 satırlarındadır. Örnekleri #labeletiketin satır numarası ile değiştirilecektir. Etiketteki örneklerin örnekleri labelveya @labelbunların yerini alır. Adresleme modları korunur.

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

puanlama

Her yarışmacı çifti için, mümkün olan her savaş yapılır. Bir savaşın sonucu iki programın göreli ofsetlerine bağlı olduğundan, her olası ofset (yaklaşık 8000'i) denenir. Ayrıca, her programın her ofsette ilk hareket etme şansı vardır. Bu ofsetlerin çoğunluğunu kazanan program, çiftin galibidir.

Bir savaşçının kazandığı her eşleştirme için 2 puan alır. Her kravat için bir savaşçıya 1 puan verilir.

Birden fazla savaşçı göndermenize izin verilir. Birden fazla başvuru için tipik kurallar geçerlidir; örneğin, etiketleme, işbirliği, krallık, vb., Çekirdek Savaş'ta bunun için herhangi bir yer yoktur, bu yüzden çok fazla bir şey olmamalıdır.

Kontrol eden, denetleyici

Kontrolörün kodu, iki kolay örnek botla birlikte, burada bulunur . Bu yarışma (resmi ayarları kullanarak çalıştırıldığında) tamamen belirleyici olduğu için, yarattığınız afiş resmi afiş ile aynı olacaktır.

Örnek Bot

İşte dilin bazı özelliklerini gösteren örnek bir bot.

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

Bu bot çekirdekteki diğer tüm hafızayı yavaşça silerek "bomba" ile değiştirerek çalışır. Bomba bir DATtalimat olduğundan, bir bombaya ulaşan herhangi bir program imha edilecektir.

Sayıları değiştirmeye yarayan "ana" ve "bomba" olmak üzere iki satır etiketi vardır. Önişlemeden sonra program şöyle görünür:

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

İlk satır, bombayı programın hemen üzerindeki satıra kopyalar. Bir sonraki satır bombanın ( 0 -1) değerini hareket komutuna ekler ve ayrıca @adresleme modunun kullanıldığını gösterir. Bu ekleme, hareket komutunun yeni bir hedefi göstermesine neden olur. Bir sonraki komut kayıtsız şartsız programın başlangıcına atlar.


Güncel Lider Tablosu

24 - Turbo
22 - DwarvenEngineer
20 - HanShotFirst
18 - Cüce
14 - ScanBomber
10 - Paranoyak
10 - FirstTimer
10 - Janitor
10 - Gelişen
6 - EasterBunny
6 - CopyPasta
4 - Imp
2 - Slug

İkili Sonuçlar:

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

En son güncelleme (Turbo ve Paranoidin yeni sürümleri) eski bir dizüstü bilgisayarda çalıştırmak yaklaşık 5 dakika sürdü. Denetleyicideki gelişimi için Ilmari Karonen'e teşekkür ederim . Denetleyicinin yerel bir kopyasına sahipseniz, dosyalarınızı güncellemelisiniz.


İki rakip bot aynı etiketi kullanmaya çalışırsa ne olur?
mbomb007 9:15

1
@ mbomb007 Etiketler ön işleme tabi tutulur ve botun kaynak dosyası ayrıştırılırken hesaplanır. Etiketleriniz rakip etiketlerle etkileşime girmez.
PhiNotPi 9:15

1
@ mbomb007 Böylece programlar üst üste gelmez. Ayrıca, bu sürüme daha fazla özellik eklemeyi planlamıyorum, Mikro Çekirdek Savaşı için sakladım.
PhiNotPi 9:15

1
@ mbomb007 Dolaylı adresleme, referansı yapan alanın aynısını yapar (1. veya 2.). Talimat değiştiricileri yok. Bu mücadeleyi '94 standardı üzerine atmıyorum.
PhiNotPi

2
@Thrax hayır diyeceğim, bir gönderim ile sınırlı değilsiniz. Her ne kadar çekirdek savaşlarda işbirliği için fazla yer olmasa da, tipik çoklu gönderim kuralları geçerlidir (tag-teaming, vb.).
PhiNotPi 11:15

Yanıtlar:


9

Cüce Mühendisi

Yeni ve geliştirilmiş bir cüce. Şimdiye kadar gönderilen her şeye karşı kazanır. Süslü corestep -optimized step size burada muhtemelen overkill.

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

Dikkate değer özellikler arasında, eski Çekirdek Savaş jargonunda ortalama 0,5 c'lik bombalama hızı için dört devirde iki bomba atan hızlı bomba döngüsü JMZve bombalama işleminin ne zaman tamamlandığını ve B planına geçmenin zamanı geldiğinde burada, bir Imp).


Ben 90'lı yıllarda Çekirdek Savaşı oynuyordum (bazılarınız '97'de yazdığım temel rehber kitabını görmüş olabilirsiniz ), bu yüzden Red88ode '88 / '94 dünyasındaki hangi eski stratejilerin olabileceğini görmenin ilginç olacağını düşündüm. bu varyantta faydalı olun.

İlk düşüncelerim:

  • Hayır SPL, dolayısıyla çoğalıcılar yok (ve imp'lar / spiraller yok). Bu bombardıman uçaklarını güçlü yapmalı. (Ayrıca, tüm bu fantazi bombalama stratejileri, çoğalıcılar ve spirallerle başa çıkmak için tasarlandı mı? Tamamen gereksiz ve burada işe yaramazlar DAT.

  • Sonra tekrar, CMPtarama hala bombalamadan potansiyel olarak daha hızlıdır, bu nedenle hızlı bir tarayıcının şansı olabilir .

  • İçeride / azalmanın yokluğu, çekirdeği çok yavaşlatır. Aslında, bu varyanttaki açık bir çekirdek hemen hemen sadece ± 1 (en düşük) basamak boyutuna sahip bir bombardıman uçağıdır. Yine, bu da tarayıcıları incitiyor; bir kerelik tarayıcı → bombardıman stratejisi işe yarayabilir.

  • Quickscanners / quickbombers (Çekirdek Savaşı jargonuna sahip olmayanlar için kontrolsüz bir tarama / bombalama döngüsü kullanan erken oyun stratejisi) hala potansiyel olarak faydalıdır, ancak yalnızca uzun programlara karşı (kendileri oldukları gibi, bu nedenle bir tür geri bildirim vardır) burada etkisi). Gerçekten zahmete değip değmeyeceğini söylemek zor.

  • Puanlama sistemi ilginç. Kravatlar galibiyetin yarısı kadar puan alır (geleneksel Çekirdek Savaş'ta olduğu gibi 1/3 değil), onları daha çekici yapar. Sonra tekrar, bu kurallar altında çok sayıda bağ kurabilecek tek program hakkında bir etkidir. (Ayrıca, de yokluğu / artışlarla imp kapıları sert, bu yüzden bile basit göst aslında yapar yapmak onların rakibi hayatta ulaşırsanız bir kravat gol şansı vardır.)

  • Ayrıca, final sıralamaları yalnızca hangi programları yediğinize ve onları ne kadar yendiğinize bağlı olmadığından , genelci girişleri destekleme eğilimindedir. Bu zar zor yenmek için daha iyi tüm tamamen zar zor kaybetmek geri kalanına bunların yarısını yok etmek ve daha, rakiplerinize.

  • Kurallar herkese açık olduğundan, genel olarak ne kadar iyi olursa olsun, daha önce verilmiş olanları - muhtemelen birkaçını bile - yenebilecek bir program bulmak her zaman mümkündür. Bu tür püf noktaları (sizin rakibinizi size çarpmadan hemen önce vurmak için adım boyutunuzu ayarlamak gibi) yine de kolayca ucuz görünebilir. Ve elbette, hedef oyuncu her zaman farklı sabitler içeren yeni bir sürüm sunabilir.

Her neyse, tüm bunların sonucu olarak, hızlı bir bombardıman ya da çok hızlı bir tarayıcı yazmayı denemem gerektiğine karar vermem ve belki de hızlı bir tarayıcı / bombardıman ile uğraşmak zorunda kalmam gerektiğine karar verdim . Bu seçeneklerin dışında hızlı bir bombardıman çalışması en basit ve en muhtemel gibiydi.

Bu noktada, PhiNotPi'nin tercüman kodunu ayarlayıp optimize etmek için çok fazla zaman harcadım, çünkü sabitleri optimize etmek için muhtemelen çok fazla kaba kuvvet denemesi yapacağımı düşündüm. Olduğu gibi, bunu yapmak zorunda kalmamıştım - yukarıdaki kod hemen hemen işe yarayan ilk versiyondu (aptalca hatalardan dolayı intihar eden birkaç başarısız girişimden sonra).


Bombacımı hızlı kılan numara, her biri için iki bomba atmak için dolaylı adresleme kullanıyor ADD. İşte nasıl çalışıyor:

  1. İlk döngüde, yürütürüz MOV bomb @aim. Bu, bombtalimatı çekirdeğin neresinde B-alanının aimişaret ettiği yere (ilk önce tam olarak 6326 talimat aimveya daha önce 6328 talimat step; neden bu sayıların önemli olduğunu göreceksiniz) kopyalar .

  2. Bir sonraki adımda aimtalimatı kendimiz uygularız ! Ilk seferde, o şöyle görünür: MOV bomb @-6326. Bu nedenle, bombtalimatın B-alanının 6326 satırdaki kendisinin işaret ettiği yere kopyalar .

    Peki, daha önce 6326 satırında ne var aim? Neden, bomboraya daha yeni bir döngü daha yerleştirdik. Ve sadece B-alanının bombsıfır olmayan bir değere sahip olması için bazı şeyleri düzenlemeye başladık , bu nedenle yeni bomba eskisinin üzerine kopyalanmayacak, bir süre uzakta (aslında, mesafe 3164, nominal adım büyüklüğümüzün yarısı olan 6328; ancak diğer ofsetler belki daha da iyi çalışabilir).

  3. Bir sonraki döngüde, biz bizim amacı ayarlayın SUB step aimdeğerlerini çıkarır step(o halde, aynı zamanda bir sonraki yürütmek için gidiyoruz atlama olur talimat olabilirdi sadece basit olmuş DATbir yerden) aim.

    (Burada nota bir detayda o zamanın tür A-değerini istemek stepsıfır olmasını biz hala bir sonraki denemede aynı bomba atacağım böylece, olsa da, kesinlikle gerekli olmadığı;. Sadece bombalar atılmış tarafından ilk 3164 eşit onların B-alanı olması talimat ihtiyacı, dinlenme şey olabilir.)

  4. Daha sonra JMZ, talimat 6328'in bundan uzaklaştığı kontrol hala sıfırdır ve öyleyse, kodun başına geri atlar. Şimdi, 6328 bombardıman uçağının basamak büyüklüğüdür ve 8 ile bölünebilir (ancak 16 değil); bu nedenle, her 6328 adımda bir bomba atmaya devam edersek, sonunda her başladığımız yere geri dönüp çekirdekte her sekizinci talimatı bombaladıktan sonra (ve 3163 = 6328/2 ≡ 4 (mod 8) fazladan bombalar dengeleydik. her dördüncü öğretiye vururduk).

    Ama biz 6328 talimatlar bizim bombalama çalıştırmak başladı önceJMZ ve biz konuma 6328 adımlarını bombalayacaklar yüzden, her işleminde -6328 tarafından geriye doğru adım attı sonraJMZ biz vururdu önce sadece bir yineleme JMZkendisini. Bu yüzden JMZ, 6328 talimatlarında bir bomba tespit edildiğinde, bu, kendimizi vurmadan yapabileceğimiz en fazla çekirdeği kapattığımızın bir işaretidir ve kendimizi öldürmeden önce yedek bir stratejiye geçmemiz gerekir.

  5. Yedekleme stratejisine gelince, bu sadece eski bir MOV 0 1şey. Çünkü şimdilik daha iyi bir şey düşünemedim. Gördüğüm gibi, çekirdeğin her dördüncü bölgesini bombaladıysak ve hala kazanamadıysak, muhtemelen çok küçük ya da çok savunmacı bir şeyle savaşıyoruz ve sadece hayatta kalmak ve bir bağ kurmaya çalışmak için deneyebiliriz. Sorun değil, çünkü bu tür küçük veya savunma programları genelde başka bir şeyi öldürmekte pek iyi değiller ve bu yüzden sadece birkaç şansla kazanma şansımız olsa bile, muhtemelen hala öne çıkacağız.


Ps. Başka birinin istemesi durumunda, işte biraz PhiNotPi'nin turnuva kodu çatalını geliştirdim . Yaklaşık iki kat daha hızlı, eski savaş sonuçlarını kaydederek yeniden çalıştırmanıza gerek kalmaması ve savaş sonuçları hesaplamasında küçük bir hata olduğuna inandığım şeyi düzeltir . Değişiklikler PhiNotPi tarafından ana sürümde birleştirildi . Teşekkürler!


1
Sadece bildiğiniz gibi, puanlama, program başlangıç ​​konumlarının HER ZAMAN kombinasyonunu ve en fazla puan alan programı test eder. Bu, bağları imkansız veya tamamen elverişsiz kılar çünkü bir program kendini asla öldürmez ve en az bir kez bir kez bombalarsa, bir kazancı, bir galibiyetini ve diğer bağları atar.
mbomb007 18:15

9

Grafik görünümü

Bu bir hata ayıklama aracı olarak kullanılabilir. Çekirdeği görüntüler ve oynatıcının yerini gösterir. Bunu kullanmak için koddan çağırmanız gerekir. Ayrıca Game.javaGraphView'ı otomatik olarak gösteren bir değişiklik yaptım .

PhiNotPi ve Ilmari Karonen yakın zamanda Denetleyiciyi değiştirdi. Ilmari Karonen bu konumda güncellenmiş bir GameView sunmak için yeterince nazikti .

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

Değiştirilmiş 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.");
        }
    }*/
}

Player'da da bir değişiklik yaptınız. Anladım./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 Bunun için üzgünüm. printCore()Yöntemi yorumlamalıyım .
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

Benim 2 CoreWar girişimi. Cüceyi yenmek için tasarlandı. Veriyi 3'e kadar tarar, sonra her 2'ye bir bomba koyar. Her aşamada sadece 3 komutla çalıştırılır, umarım Dwarf'un bombaları onu kaçırır.

YENİ Turbo ++ : Şimdi geliştirildi. Veri bulana kadar geriye doğru tarar, daha sonra kendisini oraya taşır, sonra geriye doğru bombalar. Umut, hareketin ya rakibi engelliyor ya da çoktan bombalanmış ve bu nedenle güvenli (ish) olduğu bir yer.

... Ve daha seyrek tarama yapmak için bir düzenleme onu herkesi yenmek yapar!


Cüceden daha çok yenmiş gibi görünüyor. Tebrikler! Sadece Imp'i yenebilseydin üçüncü sıraya çıkabileceğini düşünüyorum.
Ilmari Karonen

Bunu güncelledim, ama aslında öncekinden oldukça büyük bir gelişme. Bunun yerine yeni bir giriş yapmalı mıydım?
AShelly

PhiNotPi için konuşacağımı sanmıyorum ama sanırım sana kalmış. Yerinde güncelleme yapılması, temel olarak eski girişinizi geri almak anlamına gelir. Her neyse, başarılı bir şekilde üçüncü sıranıza giderken bomba atmaya başladığınız için tebrikler! Sanırım seninki şu ana kadar DwarvenEngineer'ı çift olarak yenen tek giriş.
Ilmari Karonen

Aferin ;). Şimdi yenecek olan sensin!
Hit

8

Cüce

Bir cüce atma taşını temsil eden yaygın ve basit bir program. DATHer dört adrese bir talimat verir.

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

EDIT: Adreslemeyi düzeltir. Görünüşe göre adresleme modları OP'nin bağlantılı olduğu şartlardan farklı.


Sanırım ilk satır için "# 3 3 ekle" değil mi?
Hit

@Hit Hayır. Her 4. adrese ulaşmak istiyorum. Kullanabilirdim add 3 3, ama sonra ekleme yerine her döngüyü iki katına çıkarırdı ve bu kullanışlı olmazdı. #4bir acil durumdur, bu nedenle sayı , geçerli adresin arkasındaki 4adresteki 2. değere eklenir 3.
mbomb007 11:15

Bence #meydan okumada adresleme modunu yanlış yorumluyorsunuz . Spesifikasyonda belirtildiği gibi, #adresleme modunda bir değişiklik yaptım .
PhiNotPi 11:15

"2 JMP -2 4 dat 0 4 @ 2 3 mov 2 add": Sen gibi gitmeli
Hit

Doğru davranış ile, hatta gelişti yenilgiler
Hit

7

Evolved

Açıkçası nasıl çalıştığını anlamıyorum. Herhangi bir şey yapmadan önce kaynak kodunu oluşturuyor gibi görünüyor. Birisi bana nasıl çalıştığı hakkında bir açıklama yaptıysa çok isterim.

Bunu inceledikten sonra, bunun basitçe bir koruma görevlisi ile değiştirilmiş bir cüce olduğunu buldum. Düşmanları DATtalimatlarla bombalamak yerine , düşman kodunu karıştırır. Ayrıca, her dört kayıt yerine her iki kaydı bombalar. Yeterli zaman verildiğinde, hiç şüphesiz kendisini yok edecektir.

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
O zaman nereden aldın?
PyRulez

4
@PyRulez Bu bilgisayar genetik algoritma ile oluşturuldu.
TheNumberOne

1
Görünüşe göre, idam aslında 6 numaralı satırdan daha fazla ilerlemiyor çünkü programa geri dönüyor. Başarısının sebebinin, rakiplerinden daha fazla hamle / döngü olduğunun olduğuna inanıyorum.
PhiNotPi 11:15

6

FirstTimer

İşe yararsa, çekirdeğin başında pozisyon almaya çalışmalı ve bir savunma oluşturmalıdır

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

Tam olarak sandığınızı düşündüğünüz şekilde çalışmaz: programınızın#0 başlangıcına (yani aynı şekilde ), çekirdeğin başlangıcına değil (bu aslında anlamlı bir kavram değil - çekirdeğin başlangıcına işaret eder) Genel olarak, kodunuz nerede başladığını veya bittiğini söyleyemez). Olan ilk şey, talimatınızın ( ) kendisinin üzerine yazmasıdır, daha sonra kodunuz etkin bir şekilde 0.25c'ye (= dört döngü başına bir komut) dönüşür. #mainmainMOV #data #100
Ilmari Karonen

@IlmariKaronen Oh, açıklama için teşekkürler. #0Çekirdeğin başlangıcında hata yaptım . İlk 5 talimat o zaman tamamen işe yaramaz.
Thrax

6

CopyPasta

Bir CoreWar'a hiç katılmamış, bu basit program sadece kendini kopyalayıp yapıştırmaya ve kopyayı çalıştırmaya çalışıyor. Doğru davranışa sahip olmayabilir, lütfen böyle olup olmadığını söyleyin.

Çok pasifist ve aslında kazanamıyor.

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

Bu güncel düzenleme muhtemelen bir sonraki liderlik güncellemesinde olmayacak (şu anda turnuvayı çalıştırıyorum). Eski versiyon, ancak, (küçük çekirdek boyutu) ön sonuçları kazanıyordu.
PhiNotPi 10:15

Tamam :) Eski sürüm loop1 dışına çıkmıyor, gerçekten istenen bir davranış değil, düzeltmeye çalışıyorum.
Hit

Geçerli sürüm bozuk görünüyor. Nedenini henüz bilmiyorum.
PhiNotPi

1
Hata ayıklama araçlarını yenilediğim için şimdi problemi teşhis edebiliyorum. Olan şudur ki, program sadece ikinci yarısını kopyalar (başlayarak JMP loop 0). Sonra, kopyanın başlangıcının olması gerektiği yere atlarsa, bu sadece boş bir alandır ve kaybeder.
PhiNotPi

2
Lütfen önceki (şimdi silinmiş) yorumumu yoksay; Kodunuzun yanlış bir sürümünü test ettim (ironik bir şekilde kopyala yapıştır hatası nedeniyle), bu yüzden benim için bu kadar kötü çalıştı.
Ilmari Karonen

6

Kapıcı

Aşağıdaki adreslerin boş olup olmadığını kontrol etmeli ve onları temizlemiyorsa kontrol etmelidir (bu nedenle umarım rakip botu siler).

Düzenleme: Bu yeni sürüm daha hızlı olmalı (şimdi JMZkomutu ve @referansı doğru anladım ).

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

Kapıcı ilk JMZ ile intihar etmiyor mu? En az JMZ 2 8 olmalıdır. @ Kullanarak bu arada iki eklentiyi sadece bir tanesine düşürebilirsiniz. Gibi: "JMZ 2 R5 MOV 5 R4 ADD 2 3 JMP -3 0 DAT 0 1 DAT 0 2, DAT 0 0" (denenmemiş)
Hit

@Hit Zıplamaz, çünkü oradaki adres 2 ADD 3 -2, ama değiştirmesi gerektiği konusunda haklısın, sanırım.
mbomb007

Evet talimatı JMZve düşünceyi yanlış okudumJMZ A B kontrol ediyordu Ave atlama Bgörünüşe tersiyiz zaman eğer 0. Farkettiğin için teşekkürler ben :) yoktu çünkü
plannapus

5

ScanBomber

Derlemeden önce yorumlarımı kaldır. Bir süre tarar, bir program bulduğunda bombalar. Yine de muhtemelen hala Cüceme kaybedecek.

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 #, şartnameden tamamen farklı bir şekilde tanımlandı (bağlantılı olduğu linki okuyun), henüz bu programı düzeltmedim.
mbomb007

@ TheBestOne Sanırım çözdüm. Şimdi mantıklı gibi görünüyor mu? Yoksa #her referanstan önce koymam gerekir zeromi? Evet, sanırım ihtiyacım var ...
mbomb007 12:15

Şimdi iyi çalışıyor. Cüce ve Imp hariç her botu yener.
TheNumberOne

@BestOne Cüce çok küçük ve olası program yerleşiminin% 50'sinde tespit edilebilir. Muhtemelen sadece Imp'i kaybeder çünkü hafızanın tamamıyla dolaştığında kendisini bombalar.
mbomb007

5

Han İlk Çekim (v2)

Yarışmanın daha fazla çeşitlilik kullanabileceğini düşündüm, işte ikinci girişim: bir kerelik CMPtarayıcı.

Bu, geliştirilmiş Anti-Imp savunma sistemli versiyon 2'dir - şimdi sadece bir puanla Imp'i yenebilir. Hala Cüce Mühendisi'ni kaybeder, ancak şu ana kadar her şeyi ilk etapta koyarak, şimdiye kadar her şeyi yener.

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

Bitişik merkez konumlarını 5 adım aralıklarla 10 adım aralıklarla bir fark bulana kadar karşılaştırarak çalışır. Bunu yaptığında, rakibini öldürene veya kendisine ulaşmak için çekirdeğin etrafından dolanıncaya kadar 2 adım aralıklarla bomba atmaya başlar.

Tarama yaparsa değil başka bir şey bulmak, sonunda döngü etrafında olacak ve kendi kodunu bulup saldırır. Bu intihar olur, ancak şanslı bir tesadüf için ilk bombanın kareye iniş yapması.aim hatta düştüğü, bir sonraki bombanın çekirdeğin altına 12 pozisyon (her zamanki 2 yerine) atılmasına ve uygun şekilde kodu atlamasına neden oldu. (Eğer tarama bir şey bulursa, ancak rakibi öldürmeyi başaramazsa, bu% 50 olasılıkla da olur.) Çekirdek büyüklüğü iki katından fazla olduğu için, bombalama hareketi dönerse, bu da bir süreklilik ihtiyacını ortadan kaldıracaktır. daha fazla yedekleme stratejisi.

(Bu kendi kendini bombalama püf noktası aslında saf bir tesadüf oldu - Eğer hiçbir şey bulunmazsa, taramadan bombalama moduna geçmek için tamamen farklı bir yol planlamıştım, ancak kodu ilk test ettiğimde, sabitler doğru yapmak için doğru oldu. bu şekilde çalış, ben de buna bağlı kalmaya karar verdim.



4

sümüklüböcek

     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

Bellek alanı içinde geriye doğru tarar. Arada sırada bir bomba atar.


3

Paskalya Tavşanı

Geriye atlamaktan hoşlanıyor :)

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

3

Paranoyak

Bir çeşit makarnalık ama kodun bombalanarak değiştirilip değiştirilmediğini kontrol edecek. Eğer öyleyse, bir cücenin arkasından kopyalayıp uygular. GameView'ı tekrar yapmayı başarırsam sabitlerin bir kısmını değiştirmeye çalışacağım.

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

Tamam, aslında çalışıyor ve ben sadece, yeni çalışması için teşekkür etrafında messign edildi;)
Hit
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.