Tantangan Keterampilan D&D

14

Di Dungeons & Dragons , hampir semuanya diputuskan dengan menggulung dadu. Biasanya, jika gulungan lebih besar dari atau sama dengan nilai yang ditentukan, upaya Anda untuk melakukan apa pun yang ingin Anda lakukan berhasil, dan gagal jika tidak. Paling umum, dadu 20 sisi (alias d20) digunakan untuk menggulung.

Di lain waktu, sistem tantangan keterampilan digunakan. Ini mirip dengan sistem sederhana yang dijelaskan di atas, tetapi keberhasilan ditentukan oleh apakah pemain berhasil menggulung individu beberapa kali sebelum gagal dalam beberapa kali. Sebagai contoh, pemain mungkin mencoba untuk mengambil beberapa kunci pada pintu dengan jumlah kunci yang terbatas. Masing-masing gulungan yang berhasil mewakili secara sukses memetik salah satu kunci, dan gulungan yang gagal secara individu mewakili pemecahan kunci-t. Keberhasilan keseluruhan berarti berhasil mengambil semua kunci sebelum menghancurkan semua kunci-t.

Selanjutnya, gulungan tertentu bisa menjadi gulungan kritis. Pada d20, menggulirkan 1 adalah kegagalan kritis, yang mengakibatkan kegagalan seluruh tantangan secara langsung (dalam contoh di atas, pemain mungkin secara tidak sengaja memberi tahu penjaga). Menggulirkan 20 adalah keberhasilan yang kritis, menghasilkan segera keberhasilan seluruh tantangan (dalam contoh di atas, pemain mungkin menemukan satu set kunci ke kunci, menghilangkan kebutuhan untuk mengambilnya). Dalam kasus roll kritis, tantangan segera berakhir dan hasilnya diputuskan, terlepas dari jumlah keberhasilan dan kegagalan sebelumnya.

Dalam tantangan ini, Anda akan diberikan kesulitan, jumlah keberhasilan yang dibutuhkan, dan jumlah kegagalan di mana tantangan itu gagal. Anda harus mensimulasikan pemain yang mencoba tantangan, dan mengeluarkan hasilnya.

Memasukkan

3 bilangan bulat, mewakili nilai yang harus dipenuhi atau dilampaui untuk berhasil pada roll individu, jumlah keberhasilan yang dibutuhkan untuk berhasil pada tantangan, dan jumlah kegagalan di mana tantangan itu gagal. Urutan dan format input tidak masalah, selama Anda menentukan urutan apa yang akan Anda gunakan. Kesulitannya adalah antara 1 dan 20, inklusif, dan jumlah keberhasilan dan kegagalan keduanya antara 1 dan 100, inklusif.

Keluaran

Hasil masing-masing gulungan d20 (bilangan bulat, berurutan), dan hasil keseluruhan dari tantangan (nilai kebenaran / falsey). Formatnya tidak masalah, selama masing-masing hasil diurutkan, hasil keseluruhan datang sebelum atau setelah semua gulungan individu (Anda tidak dapat menampilkan hasil keseluruhan di tengah gulungan, misalnya), dan Anda menentukan format output apa yang Anda gunakan dan menggunakannya secara konsisten.

Contoh (nilai dalam tanda kurung adalah untuk penjelasan dan tidak perlu disertakan):

Memasukkan:

12 5 3 (difficulty successes failures)

Keluaran:

15 (success, 1-0)
10 (failure, 1-1)
5  (failure, 1-2)
16 (success, 2-2)
12 (success, 3-2)
15 (success, 4-2)
19 (success, 5-2)
True (overall success)

Memasukkan:

15 2 3 (difficulty failures successes)

Keluaran:

0  (overall failure)
15 (success, 1-0)
12 (failure, 1-1)
13 (failure, 1-2)

Memasukkan:

5 5 10 (successes failures difficulty)

Keluaran:

11 (success, 1-0)
5  (failure, 1-1)
20 (critical success)
1  (overall success)

Memasukkan:

3 10 3 (failures difficulty successes)

Keluaran:

12 (success, 1-0)
11 (success, 2-0)
1  (critical failure)
False (overall failure)

Aturan

  • Ini adalah , jadi kode terpendek dalam byte menang
  • Anda harus secara acak memilih nilai integer antara 1 dan 20 (inklusif) untuk setiap roll. Setiap nilai harus memiliki probabilitas yang sama untuk dipilih (atau sedekat mungkin dengan yang sama).
Mego
sumber
@ BradGilbertb2gills the number of successes and failures will both be between 1 and 100, inclusive.Jadi, ya, ada kemungkinan bahwa satu kegagalan menghasilkan kegagalan seluruh tantangan.
Mego
Haruskah saya berasumsi bahwa nilai sebenarnya yang mewakili kesuksesan secara keseluruhan selalu harus sama dengan nilai sebenarnya? Atau mungkinkah hanya jumlah kegagalan yang tersisa?
Brad Gilbert b2gills
@ BradGilbertb2gills Tidak harus sama dengan nilai sebenarnya; Saya menggunakan jumlah kegagalan yang tersisa dalam jawaban Python saya .
Mego
Ehh, saya mungkin akan membiarkannya mengembalikan Bool, karena hanya satu byte, dan ini membantu meningkatkan keterbacaan output.
Brad Gilbert b2gills
@ BradGilbertb2gills Keterbacaan jauh lebih penting daripada skor.
Mego

Jawaban:

3

JavaScript, 83 78 76 75 byte

F=(d,f,s)=>!s||f&&(r=~(Math.random()*20))+""+F(d,~r&&f-(k=d>-r),r+20&&s-!k)

Kode ini menghitung secara rekursi keberhasilan dan kegagalan saat terjadi. Ketika salah satu berhasil (s ) atau kegagalan ( f) telah dihitung ke 0, kami menyelesaikan dengan truenilai !ssaat sini 0atau dengan nilai falsy dari fsaat fini0 .

Output adalah bentuk ekspresi reguler /^(-\d{1,2})+(0|true)$/(atau, lebih tepatnya, /^(-[1-9]|-1[0-9]|-20)+(0|true)$/). Yaitu, input memiliki tanda hubung utama, kemudian nilai roll digambarkan dengan tanda hubung, dan akhirnya hasil akhir ( 0atau true), yang tidak digambarkan dari roll akhir. Namun, ini masih merupakan tata bahasa yang tidak ambigu karena hasil akhir dan roll akhir selalu dapat dibedakan: karakter terakhir dari output (baik 0atau e) selalu menunjukkan hasil, dan final0 selalu dibaca secara terpisah dari nomor (s) dari roll terakhir.

Output sampel untuk F(11,3,4):

-3-14-12-16-16true  // normal success
-2-12-20true        // critical success
-20true             // first-roll critical success
-18-2-8-14-18-90    // normal failure
-18-12-10           // critical failure
-10                 // first-roll critical failure
-4-16-4-100         // normal failure where last roll is a 10

Penjelasan:

Kode ini bekerja dengan menggulirkan negatif d20 dan (ab) menggunakan tanda-tanda negatif sebagai pembatas.

F=(d,f,s)=>    // define function F(difficulty, fails, successes)

!s||   // if zero more successes needed, return true
f &&   // if zero more failures needed, return 0

    (r=~(Math.random()*20)  // add negative d20 to output, store in `r`
    +""+                    // string concatenation
    F(                      // recursive call to F with changed fail/success
       d,                   //   pass along d      
       ~r                   //   if r is -1, zero more fails needed
          &&f-              //   otherwise, reduce fails needed by
              (k=d>-r),     //   the boolean `d>-r` (and store in k)
       r+20                 //   if r is -20, zero more successes needed
           &&s-!k           //   otherwise, reduce successes needed by
                            //   the opposite of `k` (which indicates a fail)
      )
   ]

Ekspresi angka -minus-boolean bekerja karena truedan falsedilemparkan ke 1dan 0dalam konteks numerik. Dalam hal ini, d>-rakan terjadi 1jika gulungan gagal dan0 apakah itu berhasil.

apsillers
sumber
4

Python, 134 byte

Terima kasih Pietu1998 untuk byte yang disimpan

from random import*
def g(a,b,c):
 s,z=[],[c,b]
 while z[0]*z[1]:d=randint(1,20);z[a<d]-=[1,z[a<d]][d in[1,20]];s+=[d]
 return[z[0]]+s

Cukup sederhana, mungkin bisa bermain golf sedikit lebih, tetapi kami membutuhkan sesuatu untuk memulai ini. Cobalah online .

Mego
sumber
Anda dapat menyimpan beberapa byte: ubah impor ke from random import*dan jatuhkan random., gunakan randint(1,20)alih-alih randrange(20)+1, ganti and dengan *. Anda juga diperbolehkan untuk menempatkan hasil akhir di awal output, menghemat ruang.
PurkkaKoodari
3

Python 2, 123 121 byte

from random import*
def f(a,b,c):
 while c*b:
    r=randint(1,20);print r;c-=r<a;b-=r>=a
    if r in[1,20]:return r>9
 return c

(Jawaban ini menggabungkan spasi dan tab , jadi level indentasi pertama adalah spasi tunggal, sedangkan yang kedua adalah tab tunggal.)

Fungsinya f mengambil argumen berikut:

a, ambang batas untuk setiap die roll dihitung sebagai keberhasilan,

b, jumlah keberhasilan yang dibutuhkan untuk kesuksesan secara keseluruhan,

c, jumlah kegagalan yang dibutuhkan untuk kegagalan keseluruhan.

Pada setiap roll mati batauc dikurangi (tetapi tidak keduanya). Selama keduanya positif, itu akan berulang lagi, kecuali dalam kasus kegagalan kritis atau keberhasilan kritis.

Dengan asumsi tidak ada keberhasilan atau kegagalan kritis, ketika loop selesai batau cakan menjadi nol, tetapi tidak keduanya. Dalam hal ini fungsi hanya mengembalikan nilai saat ini daric , yaitu nol (Falsey) jika kita kehabisan semua kegagalan kita, dan positif (Kebenaran) jika kita berhasil.

Sebagai bonus, hasilnya memberitahu Anda berapa banyak kegagalan yang tersisa, yang bagus jika ada (katakanlah) lebih banyak kunci untuk dipilih nanti. (Kecuali jika diakhiri pada kegagalan atau kesuksesan yang kritis, dalam hal ini hasilnya akan menjadi boolean bukan int.)

mathmandan
sumber
3

Pip , 39 byte

Seseorang berkata mereka ingin melihat solusi dalam bahasa golf.

Wc&b{Pd:1+RR20d<a?--c--bc*:d>1b*:d<20}c

Saya cukup yakin ini tidak menggunakan fitur bahasa yang lebih baru dari pertanyaan. Mengambil input sebagai argumen baris perintah dalam urutan ini: kesulitan, keberhasilan diperlukan, kegagalan diperlukan. Output 0 untuk kegagalan keseluruhan atau bukan nol untuk kesuksesan keseluruhan.Cobalah online!

Pendekatan ini adalah strategi while-loop yang cukup mudah, dengan satu atau dua trik diambil dari solusi lain. Inilah versi dengan komentar, spasi putih, dan beberapa output tambahan:

; a,b,c are initialized to the cmdline args
; a = difficulty (roll >=a succeeds, roll <a fails)
; b = required successes to succeed the task
; c = required failures to fail the task
; d = single die roll

; Loop while c and b are both nonzero:
W c&b {
 ; d gets 1+randrange(20); output it
 O d:1+RR20
 ; If d<a, decrement req'd failures, else decrement req'd successes
 d<a ? --c --b
 ; Verbose output for the ungolfed version
 P " (" . (d=1|d=20 ? "critical " "") . (d<a ? "failure" "success") . ")"
 ; If d=1, req'd failures is * by 0 (becomes 0), else * by 1 (unchanged)
 c *: d>1
 ; If d=20, req'd successes is * by 0 (becomes 0), else * by 1 (unchanged)
 b *: d<20
}
; c, remaining failures, is the output: 0 if overall failure, nonzero if overall success
c . " (overall " . (c ? "success" "failure") . ")"
DLosc
sumber
2

Ruby 2.2, 75 byte

f=->(v,s,f){p(r=rand(20)+1)<2?f=0:r>19?s=0:r<v ?f-=1:s-=1while s*f>0
p s<1}

Solusi iteratif dasar. Contoh dijalankan:

f[12, 5, 3]

Mungkin keluaran:

11
17
8
14
7
false

Anda dapat melihatnya berjalan di IDEONE di sini .

Paul Prestidge
sumber
Membuatku sangat iri pada bahasa dimana 0 adalah falsey!
Paul Prestidge
1

VBA 180 Bytes

Sub P(d,s,f):k=1
Do While x<s And v<f:r=Int(20*Rnd()+1)
If r=20 Then x=s
If r=1 Then v=f
If r>=d Then: x=x+1: Else: v=v+1
Debug.Print r:Loop:If v>=f Then k=0
Debug.Print k:End Sub

Contoh Output

P 12,5,3
 18 
 2 
 19 
 8 
 11 
 0 

Digit terakhir dari output akan menjadi 0untuk Falseatau 1untuk True. Setiap Roll dipisahkan oleh baris baru. Ini menggunakan VBA built in RNG rnd()yang dikenal sebagai Not So Random , Tapi ini harus memenuhi persyaratan sebaik mungkin.

Sub P(d,s,f)
k=1
Do While x<s And v<f               'Keep Rolling while Current Successes and Failures are less then the Maximum Allowed
r=Int(20*Rnd()+1)                'Creates a Randomish Number between 1 and 20
If r=20 Then x=s                   'Checks for Crit Success
If r=1 Then v=f                    'Checks for Crit Failure
If r>=d Then: x=x+1: Else: v=v+1   'Increments Current Success or Fails
Debug.Print r                      'Prints (Could us MSGBOX, it is shorter)
Loop
If v>=f Then k=0                   'Checks & Changes Total Outcome to False
Debug.Print k                      'Prints (Could us MSGBOX, it is shorter)
End Sub
JimmyJazzx
sumber
1

SpecBAS - 165 byte

1 INPUT d,s,f
2 DIM p(2)
3 DO 
4 r=1+INT(RND*20): ?r
5 IF r IN [1,20] THEN EXIT 
6 INC p((r>=d)+1)
7 LOOP UNTIL p(1)>=f OR p(2)>=s
8  ?IIF$(r=1 OR p(1)>=f,"fail","success")

Input harus dimasukkan dalam tingkat kesulitan, keberhasilan, kegagalan.

Rilis baru SpecBAS sekarang memungkinkan "?" bukannya PRINTdan menghilangkan kebutuhanLET di depan penugasan variabel, jadi ini adalah cara yang bagus untuk mencobanya.

Karena array berbasis 1 secara default, baris 6 mengembalikan 0/1 jika roll mengalahkan kesulitan dan menambahkan 1 untuk memperbarui indeks yang tepat.

Brian
sumber
1

Perl 6 ,  101   99 byte

->$/ {(1..20).roll(*).map({$1*$2||last;$2-=$0>$_;$2=0 when 1;$1-=$_>=$0;$1=0 when 20;$_}).eager,$2}
# 101 bytes
->$/ {
  (1..20).roll(*).map({  # roll an infinite sequence, and map over them
    $1*$2||last;         # stop if either counter is 0
    $2-=$0>$_;           # decrement failure counter when a failure
    $2=0 when 1;         # set failure counter to 0  when a critical failure
    $1-=$_>=$0;          # decrement success counter when a success
    $1=0 when 20;        # set success counter to 0  when a critical success
    $_                   # the rolled value
  }).eager,$2            # the value of failure counter
}

Input adalah array yang dapat berubah yang berisi kesulitan, keberhasilan, kegagalan

Output adalah daftar dua elemen, elemen pertama adalah daftar nilai yang digulung, elemen kedua adalah jumlah kegagalan yang tersisa.

Pemakaian:

# give it a name for ease of use
my &code = {...}

for ^10 { say code [12, 5, 3] }
((14 4 15 5 5) 0)
((17 4 16 12 3 8) 0)
((2 14 14 7 14 19 19) 1)
((3 12 13 15 10 1) 0)
((3 17 16 10 11) 0)
((18 11 18 4 6) 0)
((15 13 1) 0)
((13 15 8 2 8) 0)
((16 17 8 10 11) 0)
((9 20) 2)
Brad Gilbert b2gills
sumber