Виклики навичок науково-дослідної роботи


14

У Dungeons & Dragons майже все вирішується шляхом прокатки штампу. Як правило, якщо рулон перевищує або дорівнює вказаному значенню, ваша спроба зробити все, що ви хотіли зробити, успішна, і не вдається в іншому випадку. Найчастіше для кочення використовують 20-сторонній штамб (aka d20).

В іншому випадку використовується система виклику навичок. Він схожий на просту систему, описану вище, але успіх визначається тим, чи вдасться гравцеві (або) досягнути певних кількох разів перед тим, як провалити певну кількість разів. Наприклад, гравець (і), можливо, намагаються вибрати кілька замків на дверях з обмеженою кількістю блокувань. Окремі успішні рулони являють собою вдалий вибір одного із замків, а окремі відкатні рулони являють собою злам замка. Загальний успіх означав би успішний вибір усіх замків перед тим, як зламати всі блоки блокування.

Крім того, певні рулони можуть бути критичними. У d20 прокатка 1 - це критичний збій, в результаті якого негайно провалюється весь виклик (у наведеному вище прикладі гравці можуть випадково попередити охоронця). Переміщення 20 - це вирішальний успіх, в результаті якого негайно вдається отримати весь виклик (у наведеному вище прикладі гравець (і) можуть знайти набір ключів до замків, усуваючи необхідність їх вибору). У випадку критичного переліку виклик негайно закінчується, і результат визначається незалежно від попередньої кількості успіхів і невдач.

У цьому виклику вам постануть труднощі, кількість необхідних успіхів та кількість невдач, при яких виклик не виконаний. Ви повинні імітувати гравця, який намагається зіграти виклик, та вивести результат.

Вхідні дані

3 цілих числа, що представляють значення, яке необхідно досягти або перевищити, щоб досягти успіху в індивідуальному рулоні, кількість успіхів, необхідних для успішного виконання виклику, і кількість невдач, при яких виклик не виконаний. Порядок та формат входів не мають значення, якщо ви вкажете, який порядок ви будете використовувати. Складність складе від 1 до 20, включно, а кількість успіхів і невдач становитиме від 1 до 100 включно.

Вихідні дані

Результати кожного з перерахунків d20 (цілі числа, по порядку) та загальний результат виклику (значення truthy / falsey). Формат не має значення, якщо окремі результати в порядку, загальний результат приходить до або після всіх окремих рулонів (наприклад, ви не можете вивести загальний результат у середині рулонів), і Ви вказуєте, який формат виводу використовуєте та послідовно використовуєте.

Приклади (значення в дужках є для пояснення і їх не потрібно включати):

Вхід:

12 5 3 (difficulty successes failures)

Вихід:

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)

Вхід:

15 2 3 (difficulty failures successes)

Вихід:

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

Вхід:

5 5 10 (successes failures difficulty)

Вихід:

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

Вхід:

3 10 3 (failures difficulty successes)

Вихід:

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

Правила

  • Це , тому найкоротший код у байтах виграє
  • Ви повинні випадковим чином вибрати ціле значення від 1 до 20 (включно) для кожного рулону. Кожне значення повинно мати рівну ймовірність вибору (або максимально близьке до рівного).

@ BradGilbertb2gills the number of successes and failures will both be between 1 and 100, inclusive.Отже, так, існує ймовірність, що один провал призводить до збою всього виклику.
Мего

Чи слід вважати, що справжня цінність, що представляє загальний успіх, завжди має бути однаковою? Або може бути просто кількість відмов?
Бред Гілберт b2gills

@ BradGilbertb2gills Це не повинно бути однаковим справжнім значенням; Я використовую кількість відмов, що залишилися у моїй відповіді Python .
Мего

Е-е, я, ймовірно, просто залишу це як повернення Bool, оскільки це лише один байт, і це допомагає поліпшити читабельність результату.
Бред Гілберт b2gills

@ BradGilbertb2gills Читальність набагато менш важлива, ніж оцінка.
Мего

Відповіді:


3

JavaScript, 83 78 76 75 байт

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

Цей код рекурсивно підраховує успіхи та невдачі в міру їх виникнення. Коли відрахували або успіхи ( s), або невдачі ( f) 0, ми закінчуємо trueзначенням, !sколи sє, 0або з помилковим значенням, fколи fє 0.

Вихід має форму регулярного вираження /^(-\d{1,2})+(0|true)$/(або, більш строго, /^(-[1-9]|-1[0-9]|-20)+(0|true)$/). Тобто, вхід має провідний дефіс, потім значення рулону, окреслені дефісами, і, нарешті, кінцевий результат ( 0або true), який не відмежований від остаточного згортання. Однак це все одно однозначна граматика, оскільки результат підсумкового користування та остаточний перелік завжди можна розрізнити: останній символ результату (або 0або e) завжди вказує на результат, а фінал 0завжди читається окремо від числа (номерів) остаточного рулону.

Приклади виходів для 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

Пояснення:

Цей код працює шляхом прокатки від'ємних d20 та (ab), використовуючи негативні знаки як роздільники.

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)
      )
   ]

Номер-мінус-логічне вираз працює , тому що trueі falseпідлиті 1і 0в числовому контексті. У цьому випадку d>-rбуде, 1якщо рулон - це провал і 0якщо він мав успіх.


4

Пітон, 134 байти

Дякую Pietu1998 за збережені байти

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

Досить просто, напевно, можна пограти в гольф трохи більше, але нам було потрібно щось для того, щоб розпочати це. Спробуйте в Інтернеті .


Ви можете зберегти пару байтів: змінити імпорт from random import*і залишити random., використовувати randint(1,20)замість randrange(20)+1, замінити and на *. Вам також дозволено ставити кінцевий результат на початку виводу, економлячи місце.
PurkkaKoodari

3

Python 2, 123 121 байт

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

(Ця відповідь змішує пробіли та вкладки , тому перший рівень відступу - це єдиний пробіл, а другий - одна вкладка.)

Функція fбере такі аргументи:

a, поріг для окремої роликової матриці вважається успішним,

b, кількість успіхів, необхідних для загального успіху,

c, кількість відмов, необхідних для загальної несправності.

На кожному валці або bабо cзменшено (але не на обидва). Поки обидва є позитивними, вони повторно зациклюються, за винятком критичного збою чи критичного успіху.

Якщо не досягати критичних успіхів чи невдач, коли цикл закінчується bабо cбуде нульовим, але не тим і іншим. У цьому випадку функція просто повертає поточне значення c, яке дорівнює нулю (Falsey), якщо ми вичерпали всі наші невдачі, і позитивне (Truthy), якщо нам це вдалося.

Як бонус, результат показує, скільки відмов у вас залишилось, що добре, якщо ви можете (скажімо, більше замок вибрати пізніше). (Якщо вона не закінчується при критичному відмові або успіху, тоді вихід буде булевим, а не int.)


3

Піп , 39 байт

Хтось сказав, що хоче бачити рішення гольф-мовою.

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

Я впевнений, що тут не використовуються нові мовні функції, ніж питання. Вводиться в якості аргументів командного рядка в такому порядку: складність, потрібні успіхи, потрібні збої. Виходи 0 за загальний збій або ненульовий результат для загального успіху. Спробуйте в Інтернеті!

Цей підхід є досить простою стратегією "циклу", з фокусом або двома, взяті з інших рішень. Ось версія з коментарями, пробіл та деякий додатковий вихід:

; 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") . ")"

2

Рубін 2,2, 75 байт

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}

Основне ітераційне рішення. Приклад виконання:

f[12, 5, 3]

Можливий вихід:

11
17
8
14
7
false

Ви можете побачити його, що працює на IDEONE тут .


Змушує мене по-справжньому заздрити язикам, де 0 - фальси!
Пол Престиж

1

VBA 180 байт

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

Приклад Вихід

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

Остання цифра вихідного сигналу буде 0для Falseабо 1для True. Кожен рулон відокремлений новим рядком. Для цього використовується VBA, вбудований в RNG, rnd()який відомий тим, що не настільки випадковий , але це повинно якнайкраще відповідати вимогам.

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

1

SpecBAS - 165 байт

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")

Вхід повинен бути введений у складності, успіху, порядку відмов.

Новий реліз SpecBAS тепер дозволяє "?" замістьPRINT і усуває необхідність LETперед змінними завданнями, тому це був хороший спосіб випробувати їх.

Оскільки масиви за замовчуванням засновані на 1, рядок 6 повертає 0/1, якщо рулон перемагає труднощі та додає 1 для оновлення потрібного індексу.


1

Perl 6 ,  101   99 байт

->$/ {(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
}

Вхід - це змінний масив, що містить труднощі, успіхи, невдачі

Вихід - це список двох елементів, перший елемент - це список згорнутих значень, другий - кількість відмов, що залишилися.

Використання:

# 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)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.