<commit_before>;;;; quest.lisp

(in-package #:quest)

;;; "quest" goes here. Hacks and glory await!
<commit_msg>First toy code<commit_after>;;;; quest.lisp
(in-package #:quest)

(defun char-to-integer (x)
  (- (char-code x) 48))

(defun read-digit ()
  (let ((c (read-char)))
    (read-char)  ; eat the enter char :@
    (char-to-integer c)))

;; the location class
(defstruct location
  (name "")
  (description "")
  (menu nil))

;; the locations

;; the menu for each location is a list of options, each option being
;; itself a list of the form '(command description function)

;; would it possible to use a either a lambda or a function name?
(defvar *town* nil)
(setf *town* (make-location :name "Town"
                            :description "A very nice town."
                            :menu '(("1" "Go to the shop" go-to-shop)
                                    ("2" "Go to the tavern" go-to-tavern))))
(defvar *shop* nil)
(setf *shop* (make-location :name "Shop"
                            :description "A very nice shop."
                            :menu '(("1" "Go to the town" go-to-town)
                                    ("2" "Go to the tavern" go-to-tavern))))

(defvar *tavern* nil)
(setf *tavern* (make-location :name "Tavern"
                              :description "A very nice tavern."
                              :menu '(("1" "Go to the shop" go-to-shop)
                                      ("2" "Go to the town" go-to-town))))

(defvar *location* nil)
(setf *location* *town*)

;; mockup movement functions
(defun go-to-town ()
  (princa :green "You go to the town")
  (setf *location* *town*)
  (fresh-line))

(defun go-to-shop ()
  (princa :green "You go to the shop")
  (setf *location* *shop*)
  (fresh-line))

(defun go-to-tavern ()
  (princa :red "You go to the tavern")
  (setf *location* *tavern*)
  (fresh-line))

(defun go-to (loc)
  (princa :green "You go to the " (location-name loc))
  (setf *location* loc)
  (fresh-line))

;; menu functions
(defun print-menu (loc)
  (dolist (entry (location-menu loc))
    (princa :bold (first entry) ". " (second entry) :reset)
    (fresh-line)))

(defun take-option (opt menu)
  (mapc (lambda (x)
          (when (string-equal opt (first x))
            (funcall (third x))))
        menu))

;; game flow
(defun take-turn (loc)
  (princa :red (location-name loc) :reset)
  (fresh-line)
  (princa (location-description loc))
  (fresh-line)
  (print-menu loc)
  (princa :cyan :bold "Choose: " :reset)
  (finish-output)
  (take-option (read-line) (location-menu loc)))

(defun game-loop ()
  (take-turn *location*)
  (game-loop))

(defun start ()
  (game-loop)
  (princa :bold "Goodbye!" :reset)
  (fresh-line))

;; entry point for making an executable
(defun main (argv)
  (declare (ignore argv))
  (start))
{'fraction_non_alphanumeric': 0.15813953488372093, 'fraction_numerical': 0.0028622540250447226, 'mean_word_length': 2.430674846625767, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4060114', 'n_tokens_mistral': 989, 'n_tokens_neox': 954, 'n_words': 308}