added Janet port
This commit is contained in:
@@ -0,0 +1,193 @@
|
||||
#!/usr/bin/env janet
|
||||
# Scoundrel roguelike game port to Janet
|
||||
# Created by Luxferre in 2026, released into public domain
|
||||
|
||||
# helper method section
|
||||
|
||||
# RNG helpers
|
||||
(def rng (math/rng (os/cryptorand 8)))
|
||||
(defn randint [max] (math/rng-int rng max))
|
||||
|
||||
# Shuffle helper
|
||||
(defn shuffle [vec]
|
||||
(def l (length vec))
|
||||
(var j 0)
|
||||
(var t 0)
|
||||
(for i 1 l
|
||||
(set j (randint (+ i 1)))
|
||||
(set t (vec i))
|
||||
(put vec i (vec j))
|
||||
(put vec j t)))
|
||||
|
||||
# Read a single-letter choice from the stdin
|
||||
(defn get-choice [prompt]
|
||||
(let [rawc (getline prompt)]
|
||||
(if (> (length rawc) 0)
|
||||
(string/ascii-lower (string/slice rawc 0 1))
|
||||
nil)))
|
||||
|
||||
# Ask user for y/n confirmation (with custom prompt)
|
||||
(defn get-confirm [prompt]
|
||||
(var resp nil)
|
||||
(var valid false)
|
||||
(while (not valid)
|
||||
(set resp (get-choice prompt))
|
||||
(set valid (case resp "y" true "n" true false)))
|
||||
(= resp "y"))
|
||||
|
||||
# data section
|
||||
|
||||
# The Deck
|
||||
(def deck (array/concat (range 1 14) (range 1 32)))
|
||||
|
||||
# The Room
|
||||
(def room (array/new 4))
|
||||
|
||||
# The State
|
||||
(def state @{
|
||||
:score -208
|
||||
:hp 20
|
||||
:can-run true
|
||||
:engaged false
|
||||
:drank false
|
||||
:weapon 0
|
||||
:durability 0
|
||||
:rooms-cleared 0
|
||||
})
|
||||
|
||||
# last potion value (for special scoring)
|
||||
(var last-potion-val 0)
|
||||
|
||||
# game logic section
|
||||
|
||||
# display the current stats and room
|
||||
(defn game-field-display []
|
||||
(print "--------------------------")
|
||||
(printf "H%02d | W%02d | D%02d | Deck: %02d"
|
||||
(state :hp)
|
||||
(state :weapon)
|
||||
(state :durability)
|
||||
(length deck))
|
||||
(print "--------------------------")
|
||||
(each x room (cond
|
||||
(< x 14) (prinf "M%02d " (+ x 1))
|
||||
(< x 23) (prinf "W%02d " (- x 12))
|
||||
(prinf "P%02d " (- x 21))))
|
||||
(prin "\n 1 2 3 4")
|
||||
(if (and (state :can-run) (not (state :engaged))) (prin " r)un->"))
|
||||
(print))
|
||||
|
||||
# get valid user's choice
|
||||
(defn get-valid-choice []
|
||||
(var valid false)
|
||||
(var ch "")
|
||||
(while (not valid)
|
||||
(set ch (get-choice "Your choice: "))
|
||||
(set valid (cond
|
||||
(= ch "r")
|
||||
(and (state :can-run) (not (state :engaged)))
|
||||
(has-value? ["1" "2" "3" "4"] ch)
|
||||
(<= (scan-number ch) (length room))
|
||||
false)))
|
||||
ch)
|
||||
|
||||
# monster handling logic (adds monster value to the score)
|
||||
(defn handle-monster [val]
|
||||
(var healthlost val)
|
||||
(printf "You encounter a monster of strength %d." val)
|
||||
(if (and (> (state :weapon) 0) (>= (state :durability) val))
|
||||
(do # can use weapon
|
||||
(if (get-confirm "Use weapon? (y/n) ")
|
||||
(do
|
||||
(var weapondiff (- val (state :weapon)))
|
||||
(if (< weapondiff 0) (set weapondiff 0))
|
||||
(printf "You fight the monster with your %d-level weapon." (state :weapon))
|
||||
(set healthlost weapondiff)
|
||||
(put state :durability (- val 1))
|
||||
(if (< (state :durability) 2) (do
|
||||
(put state :weapon 0)
|
||||
(put state :durability 0))))
|
||||
(print "You fight the monster barehanded.")))
|
||||
( # barehanded encounter
|
||||
print "You fight the monster barehanded."
|
||||
))
|
||||
(-= (state :hp) healthlost)
|
||||
(if (< (state :hp) 0) (put state :hp 0))
|
||||
(printf "Lost %d HP. New HP: %d" healthlost (state :hp))
|
||||
val)
|
||||
|
||||
# weapon handling logic (adds 0 score)
|
||||
(defn handle-weapon [val]
|
||||
(put state :weapon val)
|
||||
(put state :durability 14)
|
||||
(printf "Equipped a %d-level weapon." val)
|
||||
0)
|
||||
|
||||
# potion handling logic (adds 0 score)
|
||||
(defn handle-potion [val]
|
||||
(if (state :drank)
|
||||
(print "Already drank a potion here! Discarding...")
|
||||
(do
|
||||
(if (and (= (length room) 1) (= (length deck) 0))
|
||||
(set last-potion-val val))
|
||||
(+= (state :hp) val)
|
||||
(if (> (state :hp) 20) (put state :hp 20))
|
||||
(put state :drank true)
|
||||
(printf "Drank a %d-level potion. New HP: %d" val (state :hp))))
|
||||
0)
|
||||
|
||||
# entrypoint
|
||||
|
||||
(defn main [& args]
|
||||
# print the banner
|
||||
(print "----- Scoundrel 2026 -----")
|
||||
(print " Janet port by Luxferre")
|
||||
(print " Good luck!")
|
||||
# shuffle the deck
|
||||
(shuffle deck)
|
||||
# start the main game loop
|
||||
(var choice nil)
|
||||
(var item nil)
|
||||
(var itemidx nil)
|
||||
(while (and (> (+ (length deck) (length room)) 0) (> (state :hp) 0))
|
||||
(if (not (state :engaged)) # build the room
|
||||
(while (and (< (length room) 4) (> (length deck) 0))
|
||||
(array/push room (array/pop deck))))
|
||||
(game-field-display)
|
||||
(set choice (get-valid-choice))
|
||||
(if (= choice "r")
|
||||
(do # running logic
|
||||
(put state :can-run false) # cannot run twice in a row
|
||||
(shuffle room) # shuffle this room
|
||||
(while (> (length room) 0)
|
||||
(array/insert deck 0 (array/pop room)))
|
||||
(print "You run from the room.")
|
||||
)
|
||||
(do # engagement logic
|
||||
(put state :engaged true)
|
||||
# get the current item from the choice character
|
||||
(set itemidx (- (scan-number choice) 1))
|
||||
(set item (get room itemidx))
|
||||
# remove the element under itemidx from the room
|
||||
(array/remove room itemidx)
|
||||
# handling routines may or may not modify your score
|
||||
(+= (state :score) (cond
|
||||
(< item 14) (handle-monster (+ item 1))
|
||||
(< item 23) (handle-weapon (- item 12))
|
||||
(handle-potion (- item 21))))
|
||||
# now, evaluate whether we can move to the next room
|
||||
(if (and (= (length room) 1) (> (length deck) 0)) (do
|
||||
(put state :can-run true)
|
||||
(put state :engaged false)
|
||||
(put state :drank false)
|
||||
(++ (state :rooms-cleared)))))))
|
||||
|
||||
# now score and output the game result
|
||||
(if (> (state :hp) 0)
|
||||
(do # win condition
|
||||
(put state :score (state :hp))
|
||||
(if (= (state :hp) 20)
|
||||
(+= (state :score) last-potion-val))
|
||||
(prin "You win!"))
|
||||
(prin "You lose!"))
|
||||
(printf " Your score: %d. Rooms cleared: %d" (state :score) (state :rooms-cleared)))
|
||||
Reference in New Issue
Block a user