pmacs3/code_examples/demo.scm

73 lines
2.8 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)