Search code examples
countfunctional-programmingschemeracketmud

Item collection count - Racket/Sceme


I am in the process of designing a small MUD game using racket. In my game, gems which are collected by the player are used to bribe guards. Currently if the player possesses more than 1 gem, the game will not let them bribe a guard.

Here is the relevant code:

;; This code processes the bribe command.
((equal? cmd 'bribe)
 (if (get-area-item rid 'guard)
     (begin
       (if (eq? (user-attribute 'gem) 1)
           (begin
             (hash-table-set! areasdb rid (replace-area-item (get-area rid) 'guard '(guard #f)))
             (user-add-value 'gem -1))
           (describe 'bribe-no-gem))
       (describe 'bribe))
     (describe 'bribe-blank)))

Solution

  • Change the (eq? (user-attribute 'gem) 1) to this, instead:

    (>= (user-attribute 'gem) 1)
    

    By the way, don't use eq? to compare numbers. Use = or (if you need to compare against generic objects) eqv?.


    The OP asked how to suppress the bribe message if there are no gems. Here's how it might be done (I'm going for minimal changes to existing code, not for best style):

    ((equal? cmd 'bribe)
     (if (get-area-item rid 'guard)
         (if (>= (user-attribute 'gem) 1)
             (begin
               (hash-table-set! areasdb rid (replace-area-item (get-area rid) 'guard '(guard #f)))
               (user-add-value 'gem -1)
               (describe 'bribe))
             (describe 'bribe-no-gem))
         (describe 'bribe-blank)))
    

    By the way, if the only reason you're using (describe 'bribe-blank) is because if requires an else branch, you can use when instead, like so:

    ((equal? cmd 'bribe)
     (when (get-area-item rid 'guard)
       (if (>= (user-attribute 'gem) 1)
           (begin
             (hash-table-set! areasdb rid (replace-area-item (get-area rid) 'guard '(guard #f)))
             (user-add-value 'gem -1)
             (describe 'bribe))
           (describe 'bribe-no-gem))))