72 lines
2.4 KiB
Scheme
72 lines
2.4 KiB
Scheme
|
; a helper function which prints each argument seperated by a space
|
||
|
(define output
|
||
|
(lambda (. things)
|
||
|
(cond
|
||
|
((null? things) (display #\newline))
|
||
|
(else
|
||
|
(display (car things))
|
||
|
(display #\space)
|
||
|
(apply output (cdr things))))))
|
||
|
|
||
|
; a helper function which shows arguments before calling them
|
||
|
(define explicit-apply
|
||
|
(lambda (f . args)
|
||
|
(let ((result (apply f args)))
|
||
|
(output f args result)
|
||
|
result)))
|
||
|
|
||
|
; determine whether or not a given attack roll will hit
|
||
|
(define is-hit?
|
||
|
(lambda (roll attack ac)
|
||
|
(or (= roll 20) (and (< 1 roll) (>= (+ roll attack) ac)))))
|
||
|
|
||
|
; determine whether or not a given attack roll will crit
|
||
|
(define is-crit?
|
||
|
(lambda (roll attack ac threat)
|
||
|
(or (= roll 20) (and (is-hit? roll attack ac) (>= roll threat)))))
|
||
|
|
||
|
; determine the expected damage of a particular attack roll
|
||
|
(define roll-dmg
|
||
|
(lambda (roll attack ac dmg threat mult)
|
||
|
(cond
|
||
|
((is-crit? roll attack ac threat) (* dmg mult))
|
||
|
((is-hit? roll attack ac) dmg)
|
||
|
(else 0))))
|
||
|
|
||
|
; determine the expected damage across all attack rolls
|
||
|
(define expected-dmg
|
||
|
(lambda (. args)
|
||
|
(define adder
|
||
|
(lambda (total roll)
|
||
|
(if (> roll 20)
|
||
|
total
|
||
|
(adder (+ total (apply roll-dmg roll args)) (+ roll 1)))))
|
||
|
(/ (adder 0 1) 20)))
|
||
|
|
||
|
; find the best power attack score (and expected damage) versus an AC
|
||
|
(define find-best-power
|
||
|
(lambda (power-max attack ac dmg threat mult)
|
||
|
(define checker
|
||
|
(lambda (power best-power best-dmg)
|
||
|
(if (> power power-max)
|
||
|
(list best-power best-dmg)
|
||
|
(let* ((a (- attack power))
|
||
|
(d (+ dmg power))
|
||
|
(ed (expected-dmg a ac d threat mult)))
|
||
|
(if (> ed best-dmg)
|
||
|
(checker (+ power 1) power ed)
|
||
|
(checker (+ power 1) best-power best-dmg))))))
|
||
|
(checker 0 0 0)))
|
||
|
|
||
|
; iterate across a range of armor classes
|
||
|
(define iter
|
||
|
(let ((max-power 6)
|
||
|
(attack 6)
|
||
|
(dmg 5.5)
|
||
|
(threat 20)
|
||
|
(mult 3))
|
||
|
(lambda (ac max-ac)
|
||
|
(explicit-apply find-best-power max-power attack ac dmg threat mult)
|
||
|
(if (> ac max-ac) #f (iter (+ ac 1) max-ac)))))
|
||
|
(iter 10 30)
|