Kode Bots 3: Antipatterns Pemrograman Paralel

13

Selamat datang kembali! Saya senang dapat menyajikan tantangan CodeBots ke-3. Yang ini sudah lama dibuat. Tantangan ini akan dibagi menjadi 3 bagian: versi pendek, versi panjang, dan detail tambahan.

Versi Pendek

Setiap pesaing akan menulis program 24-perintah. Bot ini akan bergerak di seluruh dunia dan menyalin kodenya ke bot lain, sambil mencoba mencegah bot lain melakukan hal yang sama. Salah satu perintah yang mungkin adalah no-op Flag. Jika bot memiliki lebih banyak dari bot Anda Flagdaripada yang lain Flag, Anda mendapatkan poin. Anda menang dengan memiliki poin terbanyak.

Semua hal di atas berlaku untuk dua tantangan terakhir. Kali ini, bot akan dapat menjalankan beberapa baris kode secara bersamaan.

Versi Panjang

API

Setiap bot memiliki tepat 24 baris, di mana setiap baris dalam format berikut:

$label command parameters //comments

Label dan komentar adalah opsional, dan setiap perintah memiliki jumlah parameter yang berbeda. Semuanya tidak peka huruf besar-kecil.

Parameter

Parameter diketik, dan bisa dalam format berikut:

  1. Nilai dari 0 hingga 23.
  2. Sebuah variabel: A, B, C,D
  3. Nilai menggunakan tambahan: A+3atau2+C
  4. Baris kode, yang ditunjuk menggunakan #tanda ( #4akan mewakili baris 5, sementara #C+2akan mewakili baris yang dihitung oleh C+2).
  5. Anda dapat menggunakan $labelalih - alih menunjuk satu baris kode.
  6. Variabel atau garis kode lawan Anda, yang ditentukan oleh *. Lawan Anda adalah bot di kotak yang Anda hadapi. ( *Bmewakili Bnilai lawan Anda , sementara *#9mewakili garis 10 lawan Anda). Jika tidak ada seorang pun di alun-alun itu, perintah tidak dieksekusi.

Perintah

Pindahkan V

Memindahkan bot North+(V*90 degrees clockwise). Gerakan tidak mengubah arah.

Putar V

Mengubah bot V*90 degreessearah jarum jam.

Salin VW

Menyalin apa pun yang ada di Vdalamnya W. Jika Vnomor baris, maka Wharus nomor baris. Jika Vvariabel atau nilai, maka Wharus variabel.

Bendera

Tidak melakukan apa-apa.

Mulai V

Mulai utas baru yang dilampirkan ke variabel V. Segera, dan pada setiap giliran berikutnya, utas akan mengeksekusi perintah on line V.

Jika Vsudah terlampir pada utas, maka perintah ini adalah no-op. Jika Vvariabel lawan, maka lawan akan memulai utas yang melekat pada variabel itu.

Stop V

Hentikan utas yang terlampir pada variabel Vdi akhir giliran ini.

Kunci V

Cegah baris atau variabel Vagar tidak digunakan dengan cara apa pun kecuali oleh utas yang memanggil Lock. Panggilan berikutnya Lockoleh utas yang sama membuka V. Kunci tidak dapat dipanggil pada variabel atau garis lawan.

Jika Cond VW

Ini akan menguji Cond. Jika kondisinya benar, maka itu akan memindahkan penunjuk utas ke nomor baris V, jika tidak ke nomor baris W. Baris itu kemudian akan segera dieksekusi.

Conditional bisa X=Y, X<Y, !X, atau ?X:

  1. X=Y menguji apakah dua baris dari jenis yang sama dan dari bot yang sama, atau Anda menguji apakah dua nilai sama dengan jumlah yang sama.
  2. X<Ymenguji apakah nilai Xkurang dari Y.
  3. !Xmenguji apakah variabel atau garis Xterkunci (mengembalikan true jika terkunci)
  4. ?X menguji apakah variabel yang diberikan memiliki utas yang melekat padanya

detil tambahan

Interaksi multi-utas

Tindakan dengan tipe yang sama dieksekusi pada waktu yang sama. Tindakan dieksekusi dalam urutan berikut:

  1. Mengunci. Jika beberapa utas mencoba mengunci variabel, semuanya akan gagal. Jika utas membuka kunci variabel sementara yang lain mencoba menguncinya, variabel akan tetap tidak terkunci.

  2. Mulailah. Jika beberapa utas mencoba memulai utas pada variabel, itu akan dihitung sebagai satu permulaan.

  3. Salinan. Jika dua utas sama-sama menyalin ke variabel yang sama, variabel tersebut akan berakhir sebagai nilai acak. Jika keduanya menyalin ke baris yang sama, keduanya tidak akan berfungsi. Jika utas menyalin ke variabel yang sama dengan utas lain, maka utas yang terakhir akan menyalin nilai acak. Jika dua utas sama-sama menyalin dari variabel yang sama, keduanya akan berfungsi dengan baik.

  4. Jika. Semua kondisional akan diuji secara bersamaan, dan kemudian variabel utas akan diperbarui setelahnya. Menjalankan dan Ifdapat menyebabkan tindakan dengan prioritas lebih tinggi akan ditambahkan. Tindakan dengan prioritas lebih tinggi akan dieksekusi sebelum bergerak melewati masa lalu If, sementara tindakan dengan prioritas lebih rendah akan dieksekusi setelah If.

  5. Pindah. Beberapa gerakan pada bot yang sama akan memindahkan bot jumlah dari semua gerakan. Jika beberapa bot berakhir di tempat yang sama, mereka akan dikembalikan ke tempat awal mereka.

  6. Belok. Beberapa belokan pada bot yang sama akan dijumlahkan.

  7. Berhenti. Beberapa perintah berhenti pada variabel yang sama akan dihitung sebagai perhentian tunggal.

Detail lainnya

Utas awal Anda mulai dilampirkan ke Dvariabel

Berulang dengan If(memiliki Ifpernyataan menunjuk ke dirinya sendiri) akan menyebabkan bot Anda tidak melakukan apa pun

Jika utas dihentikan setelah penguncian, kunci itu akan dibuka kuncinya

Tindakan menggunakan variabel atau garis yang dikunci tidak akan menghasilkan apa-apa.

Jika bot lebih pendek dari 24 baris, baris yang tersisa akan diisi Flag

Melakukan penulisan pada variabel yang juga dilampirkan ke utas awal sebenarnya akan membuat utas memulai pelaksanaannya pada nilai baru saat utas memulai belokan berikut.

Bot ditempatkan di dunia toroidal dalam pola berikut:

B...B...B...
..B...B...B.
B...B...B...

Saya telah menambahkan beberapa bot sampel yang dikomentari sebagai referensi bahasa.

Pengontrol terletak di sini . Saya sudah bekerja lama, tapi mungkin masih ada bug. Ketika spec dan controller bertentangan, spec sudah benar.

Papan angka

1. 771  LockedScannerBot
2. 297  CopyAndSelfFlag
3. 289  DoubleTapBot
4. 197  ThreadCutterBot
5. 191  TripleThread
6. 180  ThickShelled
7. 155  Attacker
8. 99   RandomMover
9. 90   BananaBot
10. 56  LockedStationaryDoubleTap
Nathan Merrill
sumber
Wow, setidaknya, DoubleTap tampaknya jauh lebih baik daripada sampel!
Katenkyo
Apa yang harus terjadi jika saya mencoba membaca variabel yang dikunci dari utas lain? Katakan saya lakukan LOCK A lalu di utas lain ada MOVE A. Apakah A mengevaluasi ke 0 atau nilai acak atau apakah langkah itu gagal atau ...?
Sparr
Lakukan apa yang terjadi ketika sebuah utas mencapai garis yang dikunci oleh utas lainnya. Apakah itu noop? Apakah bisa dilewati?
Sparr
Haruskah "Salin $ label A" berfungsi? Ini menafsirkan sebagai "Salin # 11 A" yang tidak valid dan crash penerjemah, bukan "Salin 11 A" seperti yang saya harapkan.
Sparr
kemungkinan bug ... Sepertinya saya bisa membaca garis bendera saya sendiri untuk disalin dari mereka, bahkan ketika mereka dikunci oleh utas lainnya.
Sparr

Jawaban:

3

Bot Pemindai Terkunci

Memindai musuh secepat mungkin dan mengganti garis dengan bendera.

    Lock D
    Copy $a A
    Start A
    Copy $b B
    Start B

$d  Lock $d0
    Lock $d1    
$d0 Copy $flag *#C+1
$d1 If 1=1 $d0 $d0

$a  Lock A
    Lock $a0
    Lock $a1
    Lock $a2
$a0 Copy $flag *#C
$a1 Copy C+2 C
$a2 If !*#C $a1 $a0

$b  Lock B
    Lock $b0
    Lock $b1
    Lock $b2
$b0 Move C
$b1 Turn 1
$b2 If 1=1 $b0 $b0

$flag Flag
TheNumberOne
sumber
Saya ingin tahu tentang persyaratan dalam utas A Anda. ! * # C memeriksa apakah baris target Anda #C (C) Anda terkunci, kan? Bagaimana itu membantu?
Sparr
@Sparr Utas A tidak membuang waktu mengganti garis kode musuh dengan bendera jika terkunci.
TheNumberOne,
Terima kasih. Saya salah membaca spesifikasi awalnya tentang kecepatan pernyataan If.
Sparr
3

DoubleTapBot

Bot ini memiliki 3 utas: Satu untuk bergerak (A), Dua lainnya untuk menandai (B dan D). B flag 1/2 turn, D flag 1/3 turn. Jadi beberapa giliran, dia akan menggandakan bendera lawan :).

Saya berasumsi bahwa C akan kembali ke 0 jika melebihi 23.

Seharusnya cukup aman jika ada giliran untuk mempersiapkan diri (putaran 8), karena ia akan selalu menjaga setidaknya 2 utas (A & B) berjalan normal.

Saya tidak dapat mencobanya saat ini, jadi saya akan melakukan tes ketika saya akan kembali ke Rumah :)

Lock D          //Thread D locks itself
Copy 6 A        //Thread A will start line 6
Start A     
Copy 13 B       //Thread B will start line 13
Start B        
Copy 20 D       //Moving Thread D to an other part of the program
Lock A          //Thread A locks itself and the line it will be using
Lock #10
Lock #11
Lock #12
Move C          //Move in a pseudo random direction
Turn 1      //always turn to the right
If 1=1 #10 #10  //return to Move C
Lock B          //Thread B locks itself and the line it will be using
Lock #13
Lock #14
Copy #18 *#C    //Copy a flag to the Cth line of the opponent
If 1=1 #16 #16  //jump back to the copy
Flag   
Flag   
Copy C+1 C      //Increment C
Copy #19 *#C+1  //Copy a flag to the Cth+1 line of the opponent
If 1=1 #20 #20  //jump back to the increment
Flag 
Katenkyo
sumber
Nomor kunci bukan perintah yang valid. Saya menaruh tanda # di depan masing-masing angka. Juga, perintahnya adalah "Putar", bukan "Putar"
Nathan Merrill
@NathanMerrill How, itu salah ketik, lupakan #, terima kasih sudah menunjukkannya. Dan untuk gilirannya, ubah posting Anda jadi, Anda menulis Turn V Mengubah bot V * 90 derajat searah jarum jam. :)
Katenkyo
Oh, benar. Gilirannya sebenarnya benar, maka, saya akan kembali dan memperbarui kode
Nathan Merrill
Anda mengunci 11,12,13 ketika Anda bermaksud mengunci 10,11,12?
Sparr
Wow, terima kasih sudah menunjukkannya!
Katenkyo
2

Ketuk Stationary Terkunci Ketuk

Terinspirasi oleh DoubleTapBot @ Katenkyo, yang satu ini memberikan beberapa bendera dan harapan pergerakan sebagai balasan untuk benar-benar mengunci utasnya sendiri sehingga tidak dapat diprogram ulang. Namun, masih rentan untuk memiliki bendera musuh yang ditulis ke area kode non-looping.

Lock $flag              // lock the only flag line, super important!
Lock D                  // lock thread D
Copy 10 A
Start A                 // start thread A at $Astart
Copy 17 B
Start B                 // start thread B at $Bstart
Lock $D1                // lock thread D lines
Lock $D2                // thread D should be safe on turn 8
$D1 Turn C              // Spin in place, once every 2 turns
$D2 If 0=0 $D1 $D1      // thread D loop
$Astart Lock A          // thread A starts here, locks itself
Lock $A1                // lock thread A lines
Lock $A2
Lock $A3                // thread A should be safe on turn 7
$A1 Copy $flag *#C      // ATTACK! once every 3 turns
$A2 Copy C+1 C          // increment C, used for attacks and turning
$A3 If 0=0 $A1 $A1      // thread A loop
$Bstart Lock B          // thread B starts here, locks itself
Lock $B1                // lock thread B lines
Lock $B2                // thread B should be safe on turn 8
$B1 Copy $flag *#C+12   // ATTACK! once every 2 turns
$B2 If 0=0 $B1 $B1      // thread B loop
$flag Flag
Sparr
sumber
Haha, Mengunci bendera adalah Ide yang cukup bagus, aku seharusnya sudah memikirkannya! Bagaimanapun, saya senang bot saya memberikan inspirasi kepada seseorang!
Katenkyo
@Katenkyo itu ide yang bagus jika berhasil, tapi saya rasa itu tidak akan berhasil. Aturan-seperti-tertulis menyarankan bahwa jika D mengunci garis bendera maka A / B tidak akan dapat menyalinnya. Namun, sepertinya tidak demikian. Bug melaporkan di komentar ke pertanyaan.
Sparr
1

Penggerak acak

Bergerak ke arah psuedorandom

Copy 5 C
Copy 8 B
Start C
Move A // If you can't catch me, you can't modify me
If 1=1 #3 #3 //Continue to execute the above line
Start B
Copy 4 A
If 1=1 #6 #6 //Continue to execute the above line
Flag
Copy 5 A
If 1=1 #9 #9 //Continue to execute the above line
Nathan Merrill
sumber
1

Tebal dikupas

Mengunci barang-barangnya sebanyak yang dia bisa

Copy 5 B //Designating that the B thread will start on line 5
Start B //Starting the B thread
Lock C //Preventing C from being used
Copy A+1 A //The two threads are offset, meaning that the two threads shouldn't access this at the same time
Lock #A
Copy 2 B
Nathan Merrill
sumber
1

Bot Penyerang

Menyalin bendera ke berbagai lokasi

Copy A+1 A // Increment A
Move A //Move in the Ath direction
Turn A //Rotate A times
Copy #8 *#A //Copy my flag over
Copy 23 D //Loop back to the beginning.  (I use 23 here as threads auto-increment)
Nathan Merrill
sumber
0

Triple Thread

Bot sederhana ini menjalankan tiga utas dengan kode yang sama. Setiap utas menyerang 1/3 putaran, bergerak 1/6, putaran 1/6, dan melakukan pembukuan 1/3.

Move 0
Start A
Start B
$loop Copy #A+9 *#C
Move C
Copy #A+9 *#C
Turn C
Copy C+1 C
If 0=0 $loop $loop
Sparr
sumber
0

Bot Pisang

Mencoba melempar pisang ke roda musuh sebelum musuh dapat melakukan apa saja. Cenderung terjepit.

$d     If !*D $d1 $d0
$d0    Copy 24 *D
$d1    If !D $d2 $start
$d2    If !*B $d5 $d3
$d3    Copy 24 *B
$d4    Copy $d D

$start Lock D             //Banana's like to split.
       Copy $a A
       Start A
       Copy $b B
       Start B
       Lock $flag

$d5    Copy $start *C     //It's okay if enemy messes up our start.
       Copy $d d

$a     Lock A
$a1    Move C
       Turn 1
       Copy $a1 A

$b     Lock B
$b0    Copy C+1 C
       If !*#C $b0 $b1    //Banana's are good at slipping.
$b1    Copy $flag *#C
$b2    Copy $b0 B

$flag  Flag
TheNumberOne
sumber
0

Bot Pemotong Thread

   Lock D
   Lock $f
   Copy 16 C
$S If ?*D $1 $2
   Move 1
   Copy $S D
$f Flag
$1 Stop *D
$2 If ?*A $3 $4
$3 Stop *A
$4 If ?*B $5 $6
$5 Stop *B
$6 Copy $f *#C
   Copy C+1 C
   If *#C=#C $E $6
   Copy 2 D
$E Start *D

Hentikan semua utas musuh sebelum diisi dengan kode Anda.

MegaTom
sumber
0

Salin dan Tandai Sendiri

Bot ini menjalankan tiga utas. Thread D bergerak hingga berjalan ke musuh, lalu mencoba menyalin bendera ke dalamnya, lalu bergerak ke arah acak. Utas A menyalin benderanya sendiri di atas baris yang tidak penting dari kode bot. Thread B hanyalah sebuah penghitung. Variabel, bendera, dan baris kode yang digunakan oleh setiap utas sepenuhnya dikunci dalam 15 putaran pertama, dan bot menimpa hampir semua kode permulaannya dengan benderanya sendiri. Saya tidak berpikir itu mungkin untuk mengubah bot ini ke spanduk tim lain setelah giliran 15 tanpa bot serangan khusus tidak melakukan apa-apa selain menulis bendera untuk itu.

    Lock D              // Lock D thread
    Copy $AS A
    Start A             // Start A thread at $AS
    Start B             // B is just a counter
    Copy $DL D          // Jump to D thread startup code
$DC Start B             // Don't let B thread get stopped
$D0 If !*#B $D1 $D2
$D1 Copy $DF *#B
$D2 If !*#B+6 $D3 $DM
$D3 Copy $DF *#B
$DM Move B              // Move some direction after attacking
$DA Move 0              // Move north ...
    If ?*D $DC $DA      // until we hit a live target
$DF Flag                // Flag to copy
$DL Lock #B+3           // Lock the D thread's lines
    If B<12 $DL $DA     // jump to `Move 0` when D thread is safe
$AS Lock A
$AL Lock #B+20
    If B<4 $AL $AD
    Copy 23 B           // reset B so A doesn't overwrite its own code
$AF Flag
    Flag
$AD Copy $AF #B+1       // Copy a safe flag over every unused line of code
    If B<18 $AD $AF
Sparr
sumber
Move 0bergerak ke utara, bukan ke depan.
MegaTom
@MegaTom aha, terima kasih. Saya melewatkan itu.
Sparr