(defpackage inventory (:use :cl) (:export :inventory :add-item :remove-item)) (in-package :inventory) (defclass inventory () ((size :initarg :size :reader size) (filled :initform 0 :accessor filled) (items :initform '() :accessor items))) (defmethod find-item ((inv inventory) name) (with-slots (items) inv (find-if #'(lambda (i) (equal (commodities:name (car i)) name)) items))) (defmethod delete-item ((inv inventory) item) ;; removes from inventory list and substracts ;; its stored quantity from the filled attribute (with-slots (filled items) inv (setq items (remove item items)) (setq filled (- filled (cdr item))))) (defmethod add-item ((inv inventory) item quantity) ;; add of to inventory (with-slots (size filled items) inv (when (> size (+ filled quantity)) (let* ((old-item (find-item inv (commodities:name item))) (qt (if old-item (progn (delete-item inv old-item) (+ quantity (cdr old-item))) quantity))) (prog1 (setq filled (+ filled qt)) (push (cons item qt) items)))))) (defmethod remove-item ((inv inventory) name quantity) ;; remove of from inventory ;; quantity must be positive or zero (assert (>= quantity 0)) (with-slots (filled items) inv (let ((item (find-item inv name))) (when item (delete-item inv item) (if (< quantity (cdr item)) (progn (add-item inv (car item) (- (cdr item) quantity)) (cons (car item) quantity)) item)))))