Magic: the Gathering adalah permainan kartu perdagangan di mana, antara lain, pemain bermain kartu mewakili makhluk, yang kemudian dapat menyerang pemain lain, atau bertahan melawan serangan pemain lain dengan memblokir.
Dalam tantangan kode-golf ini, program Anda akan menggantikan pemain Sihir yang memutuskan cara memblokir dalam pertempuran.
Setiap makhluk memiliki dua atribut yang relevan: Kekuatan, dan ketangguhan. Kekuatan makhluk adalah jumlah kerusakan yang bisa ditimbulkannya dalam pertempuran, dan ketangguhannya adalah jumlah kerusakan yang diperlukan untuk menghancurkannya. Kekuatan selalu minimal 0, dan ketangguhan selalu minimal 1.
Selama pertempuran di Magic, pemain yang gilirannya menyatakan beberapa makhluk mereka untuk menyerang lawan. Kemudian, pemain lain, yang dikenal sebagai pemain bertahan, dapat menetapkan makhluk mereka sebagai pemblokir. Makhluk dapat memblokir hanya satu makhluk per pertempuran, tetapi beberapa makhluk semuanya dapat memblokir makhluk yang sama.
Setelah pemblokir dinyatakan, pemain menyerang memutuskan, untuk setiap makhluk menyerang yang diblokir, cara mendistribusikan kerusakan (sama dengan kekuatannya) yang diberikan makhluk itu kepada makhluk yang memblokirnya.
Kemudian, kerusakan ditangani. Setiap makhluk menghasilkan Damage yang setara dengan kekuatannya. Makhluk penyerang yang diblokir akan memberikan damage seperti yang dijelaskan di atas. Makhluk penyerang yang tidak diblokir memberikan kerusakan pada pemain yang bertahan. Makhluk yang menghalangi memberikan kerusakan pada makhluk yang mereka blokir. Makhluk-makhluk yang termasuk pemain bertahan yang tidak menghalangi transaksi tidak mengalami kerusakan. (Makhluk tidak diharuskan untuk diblokir.)
Akhirnya, semua makhluk yang mengalami kerusakan sama atau lebih besar dari ketangguhannya dihancurkan, dan dikeluarkan dari medan perang. Jumlah kerusakan yang kurang dari ketangguhan makhluk tidak memiliki efek.
Berikut ini contoh proses ini:
Makhluk dengan kekuatan P dan ketangguhan T diwakili sebagai P/T
Attacking:
2/2, 3/3
Defending player's creatures:
1/4, 1/1, 0/1
Defending player declares blockers:
1/4 and 1/1 block 2/2, 0/1 does not block.
Attacking player distributes damage:
2/2 deals 1 damage to 1/4 and 1 damage to 1/1
Damage is dealt:
2/2 takes 2 damage, destroyed.
3/3 takes 0 damage.
1/1 takes 1 damage, destroyed.
1/4 takes 1 damage.
0/1 takes 0 damage.
Defending player is dealt 3 damage.
Pemain yang bertahan memiliki 3 gol dalam pertempuran: Hancurkan makhluk lawan, pertahankan makhluk sendiri, dan serahkan sesedikit mungkin kerusakan. Selain itu, makhluk dengan kekuatan lebih dan ketangguhan lebih berharga.
Untuk menggabungkan ini menjadi satu ukuran, kita akan mengatakan bahwa skor pemain bertahan dari pertempuran sama dengan jumlah kekuatan dan ketangguhan makhluk yang selamat, dikurangi jumlah kekuatan dan ketangguhan makhluk yang masih hidup lawan mereka, minus satu setengah dari jumlah damage yang diberikan kepada pemain bertahan. Pemain yang bertahan ingin memaksimalkan skor ini, sementara pemain yang menyerang ingin menguranginya.
Dalam pertarungan yang ditunjukkan di atas, skornya adalah:
Defending player's surviving creatures:
1/4, 0/1
1 + 4 + 0 + 1 = 6
Attacking player's surviving creature:
3/3
3 + 3 = 6
Damage dealt to defending player:
3
6 - 6 - 3/2 = -1.5
Jika pemain yang bertahan tidak terhalang sama sekali dalam pertempuran yang dijelaskan di atas, skornya akan menjadi
8 - 10 - (5/2) = -4.5
Pilihan optimal untuk pemain bertahan adalah dengan memblokir 2/2
dengan 1/1
dan 1/4
, dan untuk memblokir 3/3
dengan 0/1
. Jika mereka melakukannya, hanya 1/4
dan itu 3/3
akan selamat, dan tidak ada kerusakan akan diberikan kepada pemain bertahan, membuat skor
5 - 6 - (0/2) = -1
Tantangan Anda adalah menulis program yang akan menghasilkan pilihan pemblokiran optimal untuk pemain bertahan. "Optimal" berarti pilihan yang memaksimalkan skor, mengingat bahwa lawan mendistribusikan kerusakan dengan cara yang meminimalkan skor, mengingat cara Anda memblokir.
Ini adalah maximin: Skor maksimum dari distribusi kerusakan yang meminimalkan skor untuk setiap kombinasi pemblokiran.
Input: Input akan terdiri dari dua daftar 2-tupel, di mana masing-masing 2-tupel berbentuk (Daya, Ketangguhan). Daftar pertama akan berisi kekuatan dan ketangguhan dari setiap makhluk yang menyerang (makhluk lawan Anda). Daftar kedua akan berisi kekuatan dan ketangguhan dari masing-masing makhluk Anda.
Tuples dan daftar dapat direpresentasikan dalam format apa pun yang nyaman, seperti:
[[2, 2], [3, 3]]
[[1, 4], [1, 1], [0, 1]]
Keluaran: Hasil akan terdiri dari serangkaian 2-tupel, dalam bentuk (makhluk pemblokiran, makhluk terblokir) - yaitu, salah satu makhluk Anda diikuti oleh salah satu makhluk mereka. Makhluk akan dirujuk oleh indeks mereka dalam daftar input. Indeks mungkin 0 atau 1 diindeks. Sekali lagi, format apa pun yang nyaman. Pesanan apa pun baik-baik saja. Misalnya, skenario pemblokiran optimal dari atas, mengingat input di atas, dapat direpresentasikan sebagai:
[0, 0] # 1/4 blocks 2/2
[1, 0] # 1/1 blocks 2/2
[2, 1] # 0/1 blocks 3/3
Contoh:
Input:
[[2, 2], [3, 3]]
[[1, 4], [1, 1], [0, 1]]
Output:
[0, 0]
[1, 0]
[2, 1]
Input:
[[3, 3], [3, 3]]
[[2, 3], [2, 2], [2, 2]]
Output:
[1, 0]
[2, 0]
or
[1, 1]
[2, 1]
Input:
[[3, 1], [7, 2]]
[[0, 4], [1, 1]]
Output:
[1, 0]
or
[0, 0]
[1, 0]
Input:
[[2, 2]]
[[1, 1]]
Output:
(No output tuples).
Input dan output dapat melalui STDIN, STDOUT, CLA, input fungsi / pengembalian, dll. Celah standar berlaku. Ini adalah kode-golf: kode terpendek dalam byte menang.
Untuk memperjelas spesifikasi dan memberikan ide awal, pastebin ini menyediakan solusi referensi dengan Python. The best_block
fungsi adalah solusi sampel untuk tantangan ini, dan menjalankan program ini akan memberikan masukan yang lebih verbose dan output.
sumber
Jawaban:
JavaScript (ES7),
354348 byteMengambil input sebagai
([attackers], [defenders])
.Cobalah online!
Kurang golf dan diformat
Kode ini identik dengan versi golf, hanya tanpa
map
alias daneval()
pembungkus agar mudah dibaca.Bagaimana?
Inisialisasi dan loop utama
push
Kita akan memblokir makhluk tiruan ini alih-alih memblokir makhluk sama sekali. Ini memungkinkan beberapa penyederhanaan dalam kode.
Pada akhir setiap iterasi, kami menguji apakahM. HAI
Membangun pertahanan kita
Mengoptimalkan serangan
Keputusan para penyerang tidak berkorelasi satu sama lain. Optimal global untuk sisi penyerang adalah jumlah dari optima lokal untuk setiap penyerang.
Kami beralih pada setiap penyerang kekuasaanP T saya .
Untuk menemukan keputusan terbaik bagi penyerang, pertama-tama kita membuat daftar baru yang berasall [ i ] :
Setiap entri dalam daftar ini berisi ketangguhan pemblokir, diikuti oleh nilainya (kekuatan + ketangguhan). Saat membangun daftar ini, kami juga menghitungn yang merupakan jumlah dari kekuatan semua blocker. Kami akan menggunakannya nanti untuk menguji apakah penyerang dihancurkan. (Fakta bahwa jumlah menengah disimpan sebagai entri ke-3 untuk setiap pemblokir hanyalah trik golf untuk menghemat beberapa byte. Entri ke-3 ini tidak digunakan.)
Kami sekarang memanggil fungsi rekursifg dengan 2 parameter: daya P penyerang saat ini dan daftar yang ditentukan di atas. Fungsi ini mencoba semua cara yang mungkin untuk mengirim titik kerusakan di antara pemblokir.
Memperbarui skor bek
Setelah setiap iterasi pada penyerang, kami memperbarui skor bek dengan:
Bagian kiri mengurangi skor penyerang jika itu bertahan. Bagian kanan mengurangi setengah ketangguhan penyerang jika serangan itu tidak diblokir sama sekali, atau menambahkan skor penyerang terbaik sebaliknya (yang merupakan yang terburuk dari perspektif sisi pertahanan).
sumber