Sfide di abilità D&D


14

In Dungeons & Dragons , quasi tutto viene deciso lanciando un dado. In genere, se il tiro è maggiore o uguale a un valore specificato, il tuo tentativo di fare qualunque cosa tu voglia fare ha successo e fallisce altrimenti. Più comunemente, un dado a 20 facce (aka d20) è usato per tirare.

Altre volte, viene utilizzato il sistema di sfida delle abilità. È simile al semplice sistema sopra descritto, ma il successo è determinato dal fatto che il giocatore (i) riesca o meno a tirare un certo numero di volte prima di fallire un certo numero di volte. Ad esempio, i giocatori potrebbero provare a scegliere più blocchi su una porta con un numero limitato di blocchi. I singoli tiri riusciti rappresentano la scelta corretta di uno dei blocchi, mentre i singoli tiri falliti rappresentano la rottura di un blocco. Il successo complessivo significherebbe selezionare con successo tutti i blocchi prima di rompere tutti i blocchi.

Inoltre, alcuni rotoli possono essere rotoli critici. Su un d20, tirare un 1 è un fallimento critico, con il risultato di fallire immediatamente l'intera sfida (nell'esempio sopra, i giocatori potrebbero allertare accidentalmente una guardia). Tirare un 20 è un successo critico, con conseguente successo immediato dell'intera sfida (nell'esempio sopra, i giocatori potrebbero trovare un set di chiavi per i blocchi, eliminando la necessità di selezionarli). Nel caso di un tiro critico, la sfida è immediatamente finita e il risultato è deciso, indipendentemente dal numero precedente di successi e fallimenti.

In questa sfida, ti verrà data una difficoltà, il numero di successi necessari e il numero di fallimenti in cui la sfida è fallita. Devi simulare un giocatore che tenta la sfida e produrre il risultato.

Ingresso

3 numeri interi, che rappresentano il valore che deve essere soddisfatto o superato per avere successo in un singolo tiro, il numero di successi necessari per avere successo nella sfida e il numero di fallimenti in cui la sfida è fallita. L'ordine e il formato degli input non contano, purché si specifichi l'ordine da utilizzare. La difficoltà sarà compresa tra 1 e 20, inclusi, e il numero di successi e fallimenti sarà compreso tra 1 e 100, inclusi.

Produzione

I risultati di ciascuno dei tiri di d20 (numeri interi, in ordine) e il risultato complessivo della sfida (un valore di verità / falsità). Il formato non ha importanza, fintanto che i singoli risultati sono in ordine, il risultato complessivo viene prima o dopo tutti i singoli rotoli (ad esempio, non è possibile produrre il risultato complessivo nel mezzo dei rotoli), e specifichi quale formato di output usi e lo usi in modo coerente.

Esempi (i valori tra parentesi sono indicativi e non devono essere inclusi):

Ingresso:

12 5 3 (difficulty successes failures)

Produzione:

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)

Ingresso:

15 2 3 (difficulty failures successes)

Produzione:

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

Ingresso:

5 5 10 (successes failures difficulty)

Produzione:

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

Ingresso:

3 10 3 (failures difficulty successes)

Produzione:

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

Regole

  • Questo è , quindi vince il codice più breve in byte
  • Devi scegliere casualmente un valore intero compreso tra 1 e 20 (incluso) per ogni lancio. Ogni valore dovrebbe avere la stessa probabilità di essere scelto (o il più vicino possibile a uguale).

@ BradGilbertb2gills the number of successes and failures will both be between 1 and 100, inclusive.Quindi, sì, c'è la possibilità che un singolo errore provochi il fallimento dell'intera sfida.
Mego

Dovrei supporre che il vero valore che rappresenta il successo complessivo debba sempre essere lo stesso vero valore? O potrebbe essere solo il numero di guasti rimasti?
Brad Gilbert b2gills

@ BradGilbertb2gills Non deve essere lo stesso vero valore; Uso il numero di errori rimasti nella mia risposta Python .
Mego

Ehh, probabilmente lo lascerò semplicemente restituendo un Bool, dato che è solo un byte, e aiuta a migliorare la leggibilità dell'output.
Brad Gilbert b2gills il

@ BradGilbertb2gills La leggibilità è molto meno importante del punteggio.
Mego,

Risposte:


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)

Questo codice ricorre in modo ricorsivo alla rovescia successi e insuccessi man mano che si verificano. Quando successes ( s) o failures ( f) hanno contato fino a 0, finiamo con il truevalore !squando sè 0o con il valore di falsy dif when fis0 .

L'output è nella forma di espressione regolare /^(-\d{1,2})+(0|true)$/(o, più rigorosamente, /^(-[1-9]|-1[0-9]|-20)+(0|true)$/). Cioè, l'input ha un trattino iniziale, quindi i valori di rollio delineati dai trattini e infine il risultato finale ( 0o true), che non è delineato dal roll finale. Tuttavia, questa è ancora una grammatica inequivocabile perché il risultato utilmate e il tiro finale possono sempre essere distinti: l'ultimo carattere dell'output (0 o e) è sempre indicativo del risultato, e un finale 0viene sempre letto separatamente dai numeri del tiro finale.

Output di esempio per 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

Spiegazione:

Questo codice funziona facendo rotolare un d20 negativo e (ab) usando i segni negativi come delimitatori.

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

Le espressioni numero-meno-booleano funzionano perché truee falsevengono espresse in 1e 0in un contesto numerico. In questo caso, d>-rsarà 1se il tiro è un fallimento e 0se è stato un successo.


4

Python, 134 byte

Grazie Pietu1998 per i byte salvati

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

Abbastanza semplice, probabilmente si può giocare a golf un po 'di più, ma avevamo bisogno di qualcosa per dare il via a questo. Provalo online .


Puoi salvare un paio di byte: modifica l'importazione in from random import*e rilascia random., usa randint(1,20)invece di randrange(20)+1, sostituisci and con *. È anche possibile inserire il risultato finale all'inizio dell'output, risparmiando spazio.
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

(Questa risposta mescola spazi e tabulazioni , quindi il primo livello di rientro è un singolo spazio, mentre il secondo è una singola tab.)

La funzione f accetta i seguenti argomenti:

a, la soglia in cui un singolo tiro di dado viene considerato un successo,

b, il numero di successi necessari per il successo complessivo,

c, il numero di errori necessari per l'errore generale.

Su ogni tiro di dado boc viene decrementato (ma non entrambi). Fintanto che entrambi sono positivi, si ricicla di nuovo, tranne in caso di fallimento critico o successo critico.

Supponendo che non si verifichino successi o insuccessi critici, quando il ciclo termina bo csarà zero, ma non entrambi. In tal caso la funzione restituisce solo il valore corrente di c, che è zero (Falsey) se abbiamo esaurito tutti i nostri fallimenti e positivo (Verità) se ci siamo riusciti.

Come bonus, l'output ti dice quanti errori hai rimasto, il che è bello nel caso in cui ci siano (diciamo) più blocchi da scegliere in seguito. (A meno che non sia terminato in caso di errore o successo critico, nel qual caso l'output sarà un valore booleano anziché un int.)


3

Pip , 39 byte

Qualcuno ha detto che voleva vedere una soluzione in un linguaggio da golf.

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

Sono abbastanza sicuro che questo non usi alcuna funzionalità linguistica più recente della domanda. Accetta gli input della riga di comando in questo ordine: difficoltà, successi richiesti, errori richiesti. Output 0 per errore generale o diverso da zero per successo complessivo.Provalo online!

L'approccio è una strategia while-loop piuttosto semplice, con uno o due trucchi presi da altre soluzioni. Ecco una versione con commenti, spazi bianchi e alcuni output extra:

; 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 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}

Soluzione iterativa di base. Esempio di esecuzione:

f[12, 5, 3]

Potrebbe uscita:

11
17
8
14
7
false

Puoi vederlo in esecuzione su IDEONE qui .


Mi rende davvero geloso delle lingue in cui 0 è falso!
Paul Prestidge,

1

VBA 180 byte

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

Esempio di output

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

L'ultima cifra dell'output sarà un 0for Falseo un 1for True. Ogni rotolo è separato da una nuova riga. Questo utilizza VBA integrato in RNG rnd()che è noto per essere Not So Random , ma questo dovrebbe soddisfare i requisiti nel miglior modo possibile.

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

L'inserimento deve essere inserito in ordine di difficoltà, successi, guasti.

La nuova versione di SpecBAS ora consente "?" invece diPRINT e rimuove la necessità diLET fronte alle assegnazioni di variabili, quindi questo è stato un bel modo per provarle.

Poiché le matrici sono basate su 1 per impostazione predefinita, la riga 6 restituisce 0/1 se il roll supera la difficoltà e aggiunge 1 per aggiornare l'indice corretto.


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
}

L'input è un array mutabile contenente difficoltà, successi, fallimenti

L'output è un elenco di due elementi, il primo elemento è un elenco dei valori laminati, il secondo elemento è il numero di errori rimanenti.

Uso:

# 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)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.