D & D Навыки Навыков


14

В Dungeons & Dragons почти все решается броском кубика. Как правило, если бросок больше или равен указанному значению, ваша попытка сделать то, что вы хотели сделать, увенчается успехом и в противном случае не удастся. Чаще всего для броска используется 20-сторонний штамп (он же d20).

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

Кроме того, определенные броски могут быть критическими бросками. На d20 бросок 1 - критический сбой, приводящий к немедленному провалу всего вызова (в приведенном выше примере игрок (-ы) могут случайно предупредить охранника). Бросок 20 - это критический успех, который приводит к немедленному выполнению всего вызова (в приведенном выше примере игрок (-ы) может найти набор ключей для замков, что устраняет необходимость их взлома). В случае критического броска, задача немедленно заканчивается и результат определяется независимо от количества предыдущих успехов и неудач.

В этом задании вам будет предоставлена ​​сложность, количество необходимых успехов и количество неудач, при которых испытание было неудачным. Вы должны смоделировать игрока, пытающегося выполнить вызов, и вывести результат.

вход

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

Выход

Результаты каждого броска d20 (целые числа по порядку) и общий результат испытания (значение truey / 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или с falsy значением , 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

Python, 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

Ruby 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 здесь .


Заставляет меня ревновать к langues, где 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, встроенная в ГСЧ, 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.