116 lines
4.4 KiB
Common Lisp
116 lines
4.4 KiB
Common Lisp
;;; Copyright 2013 Google Inc.
|
|
;;;
|
|
;;; Licensed under the Apache License, Version 2.0 (the "License");
|
|
;;; you may not use this file except in compliance with the License.
|
|
;;; You may obtain a copy of the License at
|
|
;;;
|
|
;;; http://www.apache.org/licenses/LICENSE-2.0
|
|
;;;
|
|
;;; Unless required by applicable law or agreed to in writing, software
|
|
;;; distributed under the License is distributed on an "AS IS" BASIS,
|
|
;;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
;;; See the License for the specific language governing permissions and
|
|
;;; limitations under the License.
|
|
|
|
;;; In this project, we are going to define a CLOS class representing a simple
|
|
;;; set of dice. There are only two operations on the dice: reading the dice
|
|
;;; values and re-rolling their values.
|
|
|
|
(defclass dice-set ()
|
|
;; Fill in the blank with a proper slot definition.
|
|
((dice-values :initarg :dice-values)))
|
|
|
|
(setq *my-dice* (make-instance 'dice-set :dice-values '(1 2 3 5)))
|
|
(slot-value *my-dice* 'dice-values)
|
|
|
|
;;; This method might be unnecessary, depending on how you define the slots of
|
|
;;; DICE-SET.
|
|
|
|
(defmethod dice-values ((object dice-set))
|
|
(slot-value object 'dice-values))
|
|
|
|
(defmethod roll (count (object dice-set))
|
|
(unless (and (integerp count) (< 0 count)) (signal (make-condition 'type-error
|
|
:datum count
|
|
:expected-type 'integer)))
|
|
(let ((rolls (mapcar (lambda (x) (declare (ignore x)) (+ 1 (random 6))) (make-list count))))
|
|
(setf (slot-value object 'dice-values) rolls)))
|
|
|
|
(roll 5 *my-dice*)
|
|
|
|
(define-test make-dice-set
|
|
(let ((dice (make-instance 'dice-set)))
|
|
(assert-true (typep dice 'dice-set))))
|
|
|
|
(define-test dice-are-six-sided
|
|
(let ((dice (make-instance 'dice-set)))
|
|
(roll 5 dice)
|
|
(assert-true (typep (dice-values dice) 'list))
|
|
(assert-equal 5 (length (dice-values dice)))
|
|
(dolist (die (dice-values dice))
|
|
(assert-true (typep die '(integer 1 6))))))
|
|
|
|
(define-test dice-values-do-not-change-without-rolling
|
|
(let ((dice (make-instance 'dice-set)))
|
|
(roll 100 dice)
|
|
(let ((dice-values-1 (dice-values dice))
|
|
(dice-values-2 (dice-values dice)))
|
|
(assert-equal dice-values-1 dice-values-2))))
|
|
|
|
(define-test roll-returns-new-dice-values
|
|
(let* ((dice (make-instance 'dice-set))
|
|
(dice-values (roll 100 dice)))
|
|
(assert-true (equal dice-values (dice-values dice)))))
|
|
|
|
(define-test dice-values-should-change-between-rolling
|
|
(let* ((dice (make-instance 'dice-set))
|
|
(first-time (roll 100 dice))
|
|
(second-time (roll 100 dice)))
|
|
(assert-false (equal first-time second-time))
|
|
(assert-true (equal second-time (dice-values dice)))))
|
|
|
|
(define-test different-dice-sets-have-different-values
|
|
(let* ((dice-1 (make-instance 'dice-set))
|
|
(dice-2 (make-instance 'dice-set)))
|
|
(roll 100 dice-1)
|
|
(roll 100 dice-2)
|
|
(assert-false (equal (dice-values dice-1) (dice-values dice-2)))))
|
|
|
|
(define-test different-numbers-of-dice
|
|
(let ((dice (make-instance 'dice-set)))
|
|
(assert-equal 5 (length (roll 5 dice)))
|
|
(assert-equal 100 (length (roll 100 dice)))
|
|
(assert-equal 1 (length (roll 1 dice)))))
|
|
|
|
;; this is about signaling error, rhg
|
|
;; but wtf about expected-type being subtype of '(integer 1 6) ???
|
|
;; shouldn't it be any integer?
|
|
|
|
|
|
|
|
(define-test junk-as-dice-count
|
|
(let ((dice (make-instance 'dice-set)))
|
|
(labels ((dice-failure (count)
|
|
(handler-case (progn (roll count dice)
|
|
(error "Test failure"))
|
|
(error (condition) condition)))
|
|
(test-dice-failure (value)
|
|
(let* ((condition (dice-failure value))
|
|
(expected-type (type-error-expected-type condition)))
|
|
(assert-true (typep condition 'type-error))
|
|
(assert-equal value (type-error-datum condition))
|
|
(assert-true (subtypep '(integer 1 6) expected-type)) ; wtf is this?
|
|
; surely it's got to be just integer?
|
|
)))
|
|
(test-dice-failure 0)
|
|
(test-dice-failure "0")
|
|
(test-dice-failure :zero)
|
|
(test-dice-failure 18.0)
|
|
(test-dice-failure -7)
|
|
(test-dice-failure '(6 6 6)))))
|
|
|
|
;; (setq dice *my-dice*)
|
|
;; (dice-failure "0")
|
|
|
|
;;; welp. signaling errors is the most unfamiliar thing for me
|