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 DAT
talimat 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ı tutanA
veB
. Önemli olarak, DAT komutunu yerine getirmeye çalıştığında işlem ölür.MOV A B
- (hareket) - Bu hareket HafızadakiA
bellek konumunaB
. İş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 eklerA
hafıza konumunaB
. 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ırA
(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) -A
Bir sonraki döngüde yürütülecek yere atla .B
bir 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 3
sonraki döngüde yürütülecek anlamına gelir .JMZ A B
- (Sıfırsa atla) - Her iki satır alanıB
da 0 ise, program konuma atlarA
.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 varsaA
veB
eş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
-X
doğ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öreceli
X
- SayıX
, geçerli adrese göre bir hedef hafıza adresinin konumunu gösterir. Bu konumdaki sayı hesaplamada kullanılır. Satır#35
yürütülüyor ve içeriyorsa-5
, satır#30
kullanı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ıX
gö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#35
yürütülüyorsa ve ikinci alanı ise@4
ve ikinci satır alanı#39
sayı içeriyorsa,-7
satır#32
kullanı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 DAT
talimatı 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
#tree
veya 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 #label
etiketin satır numarası ile değiştirilecektir. Etiketteki örneklerin örnekleri label
veya @label
bunları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 DAT
talimat 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.