;; Hi and welcome to team Gilded Rose. As you know, we are a small inn ;; with a prime location in a prominent city ran by a friendly ;; innkeeper named Allison. We also buy and sell only the finest goods. ;; Unfortunately, our goods are constantly degrading in quality as they ;; approach their sell by date. We have a system in place that updates ;; our inventory for us. It was developed by a no-nonsense type named ;; Leeroy, who has moved on to new adventures. Your task is to add the ;; new feature to our system so that we can begin selling a new ;; category of items. ;; First an introduction to our system: ;; All items have a SellIn value which denotes the number of days we have to sell the item ;; All items have a Quality value which denotes how valuable the item is ;; At the end of each day our system lowers both values for every item ;; Pretty simple, right? Well this is where it gets interesting: ;; Once the sell by date has passed, Quality degrades twice as fast ;; The Quality of an item is never negative ;; "Aged Brie" actually increases in Quality the older it gets ;; The Quality of an item is never more than 50 ;; "Sulfuras", being a legendary item, never has to be sold or decreases in Quality ;; "Backstage passes", like aged brie, increases in Quality as it's ;; SellIn value approaches; Quality increases by 2 when there are 10 ;; days or less and by 3 when there are 5 days or less but Quality ;; drops to 0 after the concert ;; We have recently signed a supplier of conjured items. This requires an update to our system: ;; "Conjured" items degrade in Quality twice as fast as normal items ;; Feel free to make any changes to the UpdateQuality method and add ;; any new code as long as everything still works correctly. However, ;; do not alter the Item class or Items property as those belong to the ;; goblin in the corner who will insta-rage and one-shot you as he ;; doesn't believe in shared code ownership (you can make the ;; UpdateQuality method and Items property static if you like, we'll ;; cover for you). ;; Just for clarification, an item can never have its Quality increase ;; above 50, however "Sulfuras" is a legendary item and as such its ;; Quality is 80 and it never alters. ;; https://github.com/emilybache/GildedRose-Refactoring-Kata ;; Common Lisp functional version: Manfred Bergmann, 2022 ;;; ================================================================ ;;; Code (defpackage :gilded-rose (:use :cl)) (in-package :gilded-rose) ;;; Class ITEM (defstruct item (name "" :type string :read-only t) (sell-in 0 :type integer) (quality 0 :type integer)) (defun update-quality (items) (mapcar #'update-item items)) (defun update-item (item) (let ((new-item (copy-structure item))) (with-slots (name quality sell-in) new-item (if (and (not (equalp name "Aged Brie")) (not (equalp name "Backstage passes to a TAFKAL80ETC concert"))) (if (> quality 0) (if (not (equalp name "Sulfuras, Hand of Ragnaros")) (setf quality (- quality 1)))) (when (< quality 50) (setf quality (+ quality 1)) (when (equalp name "Backstage passes to a TAFKAL80ETC concert") (if (< sell-in 11) (if (< quality 50) (setf quality (+ quality 1)))) (if (< sell-in 6) (if (< quality 50) (setf quality (+ quality 1))))))) (if (not (equalp name "Sulfuras, Hand of Ragnaros")) (setf sell-in (- sell-in 1))) (if (< sell-in 0) (if (not (equalp name "Aged Brie")) (if (not (equalp name "Backstage passes to a TAFKAL80ETC concert")) (if (> quality 0) (if (not (equalp name "Sulfuras, Hand of Ragnaros")) (setf quality (- quality 1)))) (setf quality (- quality quality))) (if (< quality 50) (setf quality (+ quality 1)))))) new-item)) ;;; Example (defun to-string (item) (with-slots (name quality sell-in) item (format nil "~a, ~a, ~a" name sell-in quality))) (defun print-day (day items) (format t "-------- day ~a --------~%" day) (format t "name, sell-in, quality~%") (dolist (item items) (write-line (to-string item))) (terpri)) (defun run-gilded-rose (days) (write-line "OMGHAI!") (let* ((descriptions '(("+5 Dexterity Vest" 10 20) ("Aged Brie" 2 0) ("Elixir of the Mongoose" 5 7) ("Sulfuras, Hand of Ragnaros" 0 80) ("Sulfuras, Hand of Ragnaros" -1 80) ("Backstage passes to a TAFKAL80ETC concert" 15 20) ("Backstage passes to a TAFKAL80ETC concert" 10 49) ("Backstage passes to a TAFKAL80ETC concert" 5 49) ;; this conjured item does not work properly yet ("Conjured Mana Cake" 3 6))) (items (loop :for (name sell-in quality) :in descriptions :collect (make-item :name name :sell-in sell-in :quality quality)))) (loop :for day :upto days :with the-items = items :do (progn (print-day day the-items) (setf the-items (update-quality the-items)))))) ;;; ================================================================