105 lines
5.6 KiB
BQN
105 lines
5.6 KiB
BQN
#!/usr/bin/env -S rlwrap BQN
|
||
|
||
# String to Int list
|
||
#ToInts ← (+´(10⋆⌽∘↕∘≠)⊸×∘-⟜'0')¨ (+`׬)⊸-∘=⟜' '⊸⊔
|
||
ToInts ← (+´(10⋆⌽∘↕∘≠)⊸×∘-⟜'0')¨ (+`׬)⊸-∘¬∘∊⟜('0'+↕10)⊸⊔
|
||
# Is string a die roll
|
||
IsRoll←∧´∊⟜"d0123456789-+"
|
||
# Takes a die string and rolls it
|
||
Roll←(∨´'d'⊸=)◶(+´(10⋆⌽∘↕∘≠)⊸×∘-⟜'0')‿{ 𝕊str:
|
||
nums ← 0⊸≠⊸/ (+´(10⋆⌽∘↕∘≠)⊸×∘-⟜'0')¨(+`׬)⊸-∘¬∘∊⟜('0'+↕10)⊸⊔ 𝕩
|
||
a‿d‿m← {⟨a,d,m⟩: 𝕩; ⟨a,d⟩:{∨´str∊"+-"? 1∾𝕩; 𝕩∾0}𝕩; ⟨d⟩: 1‿d‿0} nums
|
||
+´∘(1⊸+)∘(a •rand.Range d)⊸+ (∨´'-'=𝕩)◶⟨+,-⟩ m}
|
||
# A string with die rolls to Int list
|
||
RollToInts ← Roll¨ (+`׬)⊸-∘=⟜' '⊸⊔
|
||
# Rolls input and splits input into pairs
|
||
ToPairs←⟨(¯1+´(10⋆⌽∘↕∘≠)⊸×∘-⟜'0')¨, Roll¨⟩ {𝕎𝕩}¨ ((<˘∘⍉ ∘‿2⊸⥊) (+`׬)⊸-∘=⟜' '⊸⊔)
|
||
|
||
# Roll strings
|
||
RollString ← •Out∘(∾ ∾⟜' '¨) •Fmt¨∘RollToInts
|
||
|
||
# Mark the firsts, removing overlaps.
|
||
MarkFirst←{l←-⟜1≠𝕨⋄l=0(-⟜1⌈l×<)`(≠𝕩)↑𝕨⍷𝕩}
|
||
# old‿new ReplaceAll string
|
||
ReplaceAll←{f‿r𝕊𝕩: g←(+`(»⍟(≠f)⊸∨f⊸MarkFirst))⊸⊔𝕩⋄ ∾r¨⌾((g∊⟨f⟩)⊸/)g}
|
||
|
||
macros←⟨⟩
|
||
# Read file of tab sepperated pairs, add contents to macro list.
|
||
FileErr←{•Out "Macro file: "∾𝕩∾" doesn't exist"}
|
||
ReadMacros←{macros ∾↩ ≢⟜⟨⟩¨⊸/ (+`׬)⊸-∘=⟜(@+9)⊸⊔¨ •Flines 𝕩}⎊FileErr
|
||
ReadMacros⎊"No Macros" "macros"
|
||
MacroReplace←{𝕩 ReplaceAll´ macros}
|
||
|
||
# Create graveyard and turnOrder ⟨initiative, name, heath⟩
|
||
turnOrder←graveyard←⟨⟩‿⟨⟩‿⟨⟩‿⟨⟩
|
||
Clear←{𝕊: turnOrder↩graveyard↩⟨⟩‿⟨⟩‿⟨⟩‿⟨⟩}
|
||
# Sorts the turn order acording to a list of indicies
|
||
Sort←<∘⍒∘⊑⊸(⊏¨){𝕩 ⋄ graveyard 𝔽↩ ⋄ turnOrder 𝔽↩}
|
||
|
||
# General Error
|
||
Err←{•Out "Don't understand input: "∾•Fmt 𝕩}
|
||
# Parses input and adds each foe to the turn order.
|
||
_CreateFoe←{𝔽{0=≠𝕩 ? 0;
|
||
IsRoll⊑⊑𝕩 ? 𝔽 ⟨Roll∘⊑,𝔾,Roll∘⊑⟩{𝕎𝕩}¨ 3↑𝕩 ⋄ 𝕊3↓𝕩;
|
||
𝔽 (Roll "d20")∾⟨𝔾,Roll∘⊑⟩{𝕎𝕩}¨ 2↑𝕩 ⋄ 𝕊2↓𝕩}(< ¯1⊸↓∘(∾ ∾⟜' '¨))∘{
|
||
⟨⟩⊸≢¨⊸/ (+`∘+⟜» IsRoll¨)⊸⊔ (+`׬)⊸-∘=⟜' '⊸⊔𝕩}⎊Err∘MacroReplace}
|
||
⟨NewFoe,DeadFoe⟩←{𝕩_CreateFoe}¨{turnOrder ∾¨↩1‿1‿2 /𝕩}‿{graveyard ∾¨↩1‿1‿2 /𝕩}
|
||
# Parse a list of numbers, move said indices from turn order to grave
|
||
KillFoe←{m←¬(1+↕∘≠ ⊑turnOrder)∊𝕩
|
||
graveyard ∾¨↩ (¬m)⊸/¨ turnOrder⋄turnOrder m⊸/¨↩} ToInts
|
||
# Parse a list of numbers, move said indices to turn order from grave
|
||
ResurrectFoe←{m←¬(1+↕∘≠ ⊑graveyard)∊𝕩
|
||
turnOrder ∾¨↩ (¬m)⊸/¨ graveyard⋄graveyard m⊸/¨↩} ToInts
|
||
# Hurt foes, id hurt id hurt format
|
||
HurtFoe←{𝕊id‿dam: turnOrder (-⟜dam)⌾(id⊸⊏)⌾(2⊸⊑)↩} ToPairs
|
||
# Heal foes, id heal id heal format
|
||
HealFoe←{𝕊id‿dam: turnOrder ((id⊏3⊑turnOrder)⊸⌊ +⟜dam)⌾(id⊸⊏)⌾(2⊸⊑)↩} ToPairs
|
||
# Move Foes, id initative, id initative
|
||
MoveFoe←{𝕊id‿init: turnOrder init⌾(id⊸⊏)⌾(0⊸⊑)↩} ToPairs
|
||
|
||
# Turns a turn order into a string
|
||
OrderToString←{𝕨 ∾˜´(∾ " "⊸∾¨)¨<˘∘⍉∘>{⟨•Fmt¨,⊢,•Fmt¨⟩{𝕎𝕩}¨𝕩}𝕩}
|
||
# Writes graveyard and turnorder to a file
|
||
Dump←{𝕩 •Flines "add"‿"add dead" OrderToString¨turnOrder‿graveyard}
|
||
# Reads file, prints message is it doesn't exist
|
||
File←•Flines⎊{•Show "File '"∾𝕩∾"' doesn't exist. Nothing to read"}
|
||
|
||
# Displays each active character in a turn order.
|
||
Display←{id‿i‿n‿hp:•Out∾⟨id,":",i,@+9,n," has ",hp," hit points"⟩⋄@}{
|
||
(𝔽 •Fmt¨⌾(1‿1‿0‿1⊸/))∘(4⊸↑)˘⍉> (<1⊸+∘↕∘≠∘⊑)⊸∾ 𝕩}
|
||
|
||
help←"Commands:
|
||
roll: Roll a specified die. “roll 3d20-7”
|
||
add: Add foes to the turn order. “add grendi d4 d20+3 globlsmark 2d6”
|
||
add dead: Add foes to the graveyard. “add 17 King John 5”
|
||
display: Show turn order, formatted foe id, initative, name and hit points.
|
||
grave: Same as display but for graveyard
|
||
hurt: Using a id, hurt a foe. “hurt 2 d8 4 2d8+3”
|
||
heal: Using a id, heal a foe. “heal 1 2d6 1 2d6”
|
||
move: Using a id and a new initiative, move a foe. “move 3 d20 4 10”
|
||
kill: Using a id, move a foe to the graveyard. “kill 3 4 2”
|
||
resurrect: Using a id, move a foe from the graveyard. “resurrect 3 4 2”
|
||
file: Read in a file as if it was typed right in right now.
|
||
dump: Write out a file in a mannor that it can be read back in.
|
||
clear: Clear the turn order and graveyard.
|
||
help: Displays this message.
|
||
exit: Ends the program.
|
||
"
|
||
|
||
Read←{
|
||
"roll"≡4↑𝕩 ? RollString 5↓𝕩 ; "add dead"≡8↑𝕩 ? DeadFoe 9↓𝕩 ;
|
||
"add"≡3↑𝕩 ? NewFoe 4↓𝕩 ; "move"≡4↑𝕩 ? MoveFoe 5↓𝕩 ;
|
||
"hurt"≡4↑𝕩 ? HurtFoe 5↓𝕩 ; "heal"≡4↑𝕩 ? HealFoe 5↓𝕩 ;
|
||
"kill"≡4↑𝕩 ? KillFoe 5↓𝕩 ; "resurrect"≡9↑𝕩 ? ResurrectFoe 10↓𝕩 ;
|
||
"display"≡𝕩 ? Display turnOrder ; "grave"≡𝕩 ? Display graveyard ;
|
||
"file"≡4↑𝕩 ? Read¨ File 5↓𝕩 ; "dump"≡4↑𝕩 ? Dump 5↓𝕩 ;
|
||
"macros"≡𝕩 ? •Show macros ; "macros"≡6↑𝕩 ? ReadMacros 7↓𝕩 ;
|
||
"clear"≡𝕩 ? Clear @ ; ("?"≡𝕩)∨"help"≡𝕩 ? •Out help ;
|
||
# Debug Commands
|
||
"Display"≡𝕩 ? •Show turnOrder ; "Grave"≡𝕩 ? •Show graveyard ;
|
||
"exit"≡𝕩 ? run↩0 ; 0}
|
||
|
||
run ← 1
|
||
{Sort @⋄ Read •Getline 𝕩} •_While_ {𝕤⋄run≠0} @
|
||
|