13
(defun play (first second) ;4.18 p. 125 (cond ((equal first 'rock) (cond ((equal second 'rock) 'tie) ((equal second 'paper) 'second-wins) (t 'first-wins))) ((equal first 'paper) (cond ((equal second 'rock) 'first-wins) ((equal second 'paper) 'tie) (t 'second- wins))) ((equal first 'scissors) (cond ((equal second 'rock) 'second-wins) ((equal second 'paper) 'first-wins) (t 'tie))))) For each possible value of first player, decide based on second player Note: This version isn’t robust with respect to inappropriate input (i.e., something that isn’t rock, paper, scissors) Return value

(defun play (first second) ;4.18 p. 125 (cond ((equal first 'rock) (cond ((equal second 'rock) 'tie) ((equal second 'paper) 'second-wins) (t 'first-wins)))

Embed Size (px)

DESCRIPTION

(defun play (first second) (cond ((equal first 'rock) (cond ((equal second 'rock) 'tie) ((equal second 'paper) 'second-wins) (t 'first-wins))) ((equal first 'paper) (cond ((equal second 'rock) 'first-wins) ((equal second 'paper) 'tie) (t 'second-wins))) ((equal first 'scissors) (cond ((equal second 'rock) 'second-wins) ((equal second 'paper) 'first-wins) (t 'tie))))) play (paper, scissors) COND – a decision list

Citation preview

Page 1: (defun play (first second) ;4.18 p. 125 (cond ((equal first 'rock) (cond ((equal second 'rock) 'tie) ((equal second 'paper) 'second-wins) (t 'first-wins)))

(defun play (first second) ;4.18 p. 125 (cond ((equal first 'rock) (cond ((equal second 'rock) 'tie) ((equal second 'paper) 'second-wins) (t 'first-wins))) ((equal first 'paper) (cond ((equal second 'rock) 'first-wins) ((equal second 'paper) 'tie) (t 'second-wins))) ((equal first 'scissors) (cond ((equal second 'rock) 'second-wins) ((equal second 'paper) 'first-wins) (t 'tie)))))

For each possible value of first player,decide based on second player

Note: This version isn’t robust with respect to inappropriate input (i.e., something that isn’t rock, paper, scissors)

Return value

Page 2: (defun play (first second) ;4.18 p. 125 (cond ((equal first 'rock) (cond ((equal second 'rock) 'tie) ((equal second 'paper) 'second-wins) (t 'first-wins)))

(defun play (first second) (cond ((equal first 'rock) (cond ((equal second 'rock) 'tie) ((equal second 'paper) 'second-wins) (t 'first-wins))) ((equal first 'paper) (cond ((equal second 'rock) 'first-wins) ((equal second 'paper) 'tie) (t 'second-wins))) ((equal first 'scissors) (cond ((equal second 'rock) 'second-wins) ((equal second 'paper) 'first-wins) (t 'tie)))))

IF THISTHEN THIS

ELSEIF THISTHEN THIS

ELSEIF THISTHEN THIS

COND – a decision list

Page 3: (defun play (first second) ;4.18 p. 125 (cond ((equal first 'rock) (cond ((equal second 'rock) 'tie) ((equal second 'paper) 'second-wins) (t 'first-wins)))

(defun play (first second) (cond ((equal first 'rock) (cond ((equal second 'rock) 'tie) ((equal second 'paper) 'second-wins) (t 'first-wins))) ((equal first 'paper) (cond ((equal second 'rock) 'first-wins) ((equal second 'paper) 'tie) (t 'second-wins))) ((equal first 'scissors) (cond ((equal second 'rock) 'second-wins) ((equal second 'paper) 'first-wins) (t 'tie)))))

play (paper, scissors)

COND – a decision list

Page 4: (defun play (first second) ;4.18 p. 125 (cond ((equal first 'rock) (cond ((equal second 'rock) 'tie) ((equal second 'paper) 'second-wins) (t 'first-wins)))

; nice goal one: simplify -- nice to do for YOUR understanding of solution

(defun play (first second) (cond ((equal first second) 'tie) ; factor out easily checked common case ((equal first 'rock) (cond ((equal second 'paper) 'second-wins) (t 'first-wins))) ; second must be scissors ((equal first 'paper) (cond ((equal second 'rock) 'first-wins) (t 'second-wins))) (t ; first must be scissors (cond ((equal second 'rock) 'second-wins) (t 'first-wins)))))

Again – it doesn’t guard against inappropriate input

Page 5: (defun play (first second) ;4.18 p. 125 (cond ((equal first 'rock) (cond ((equal second 'rock) 'tie) ((equal second 'paper) 'second-wins) (t 'first-wins)))

; and simplify again

(defun play (first second) (cond ((equal first second) 'tie) ((equal first 'rock) (cond ((equal second 'paper) 'second-wins) (t 'first-wins))) ((equal first 'paper) (cond ((equal second 'rock) 'first-wins) (t 'second-wins))) ((equal second 'rock) 'second-wins) (t 'first-wins)))

BTW: Simplest code (given equal functionality) is often not best in terms ofcomprehensibility and (even) efficiency

Page 6: (defun play (first second) ;4.18 p. 125 (cond ((equal first 'rock) (cond ((equal second 'rock) 'tie) ((equal second 'paper) 'second-wins) (t 'first-wins)))

; nice goal two: make robust (and comprehensible)

(defun play (first second) (cond ((equal first 'rock) (cond ((equal second 'rock) 'tie) ((equal second 'paper) 'second-wins) ((equal second 'scissors) 'first-wins) (t (list 'second 'unknown)))) ((equal first 'paper) (cond ((equal second 'rock) 'first-wins) ((equal second 'paper) 'tie) ((equal second 'scissors) 'second-wins) (t (list 'second 'unknown)))) ((equal first 'scissors) (cond ((equal second 'rock) 'second-wins) ((equal second 'paper) 'first-wins) ((equal second 'scissors) 'tie) (t (list 'second 'unknown)))) (t (list 'first 'unknown))))

Page 7: (defun play (first second) ;4.18 p. 125 (cond ((equal first 'rock) (cond ((equal second 'rock) 'tie) ((equal second 'paper) 'second-wins) (t 'first-wins)))

; Other formulations

(defun play (first second) (if (equal first second) ; IF 'tie ; THEN (if (equal first 'rock) ; ELSE (if (equal second 'paper) 'second-wins 'first-wins) (if (equal first 'paper) (if (equal second 'rock) 'first-wins 'second-wins) (if (equal second 'rock) 'second-wins 'first-wins)))))

When I wrote this, it was harder for me to keep track of the explicit nesting-- much harder than keeping track of the logic in the COND (decision list) format

Page 8: (defun play (first second) ;4.18 p. 125 (cond ((equal first 'rock) (cond ((equal second 'rock) 'tie) ((equal second 'paper) 'second-wins) (t 'first-wins)))

(defun play (first second) (cond ((and (equal first 'rock) (equal second 'rock)) 'tie) ((and (equal first 'rock) (equal second 'paper)) 'second-wins) ((and (equal first 'rock) (equal second 'scissors)) 'first-wins) ((and (equal first 'paper) (equal second 'rock)) 'first-wins) ((and (equal first 'paper) (equal second 'paper)) 'tie) ((and (equal first 'paper) (equal second 'scissors)) 'second-wins) ((and (equal first 'scissors) (equal second 'rock)) 'second-wins) ((and (equal first 'scissors) (equal second 'paper)) 'first-wins) ((and (equal first 'scissors) (equal second 'scissors)) 'tie) (t 'unknown-confuguration)))

Doesn’t factor out common conditions at all – a bit unwieldy, but this minimallystructured decision list might also be something that would be more amenable toautomated construction/revision

Page 9: (defun play (first second) ;4.18 p. 125 (cond ((equal first 'rock) (cond ((equal second 'rock) 'tie) ((equal second 'paper) 'second-wins) (t 'first-wins)))

;5.6 pp. 151-152

(defun throw-die () (+ 1 (random 6))) ;a

(defun throw-dice () (list (throw-die) (throw-die))) ;b; (defun throw-dice () (cons (throw-die) (list (throw-die))))

(defun snake-eyes-p (throw) (equal throw '(1 1))) ;c(defun boxcars-p (throw) (equal throw '(6 6)))

(defun instant-win-p (throw) ;d (or (equal (eval (cons '+ throw)) 3) ; code should be stylistically consistent (equal (apply #'+ throw) 11))) ; to aid comprehensibility. I’m trying to(defun instant-loss-p (throw) ; illustrate different possibilities (let ((x (apply #'+ throw))) (or (< x 4) (= x 12))))

Page 10: (defun play (first second) ;4.18 p. 125 (cond ((equal first 'rock) (cond ((equal second 'rock) 'tie) ((equal second 'paper) 'second-wins) (t 'first-wins)))

(defun say-throw (throw) ;e (cond ((snake-eyes-p throw) 'snake-eyes) ((boxcars-p throw) 'boxcars) (t (apply #'+ throw))));;(defun say-throw (throw); (let ((x (apply #'+ throw))); (cond ((equal x 2) 'snake-eyes); ((equal x 12) 'boxcars); (t x))))

Using previously defined functions is often good, as it eliminates redundancy (in effect defining the same functionality repeatedly), which in turn can guard against bugs being introduced when a function is changed (you only have tochange one, not many). However, the it can also sometimes result in less efficient code – example later perhaps

Page 11: (defun play (first second) ;4.18 p. 125 (cond ((equal first 'rock) (cond ((equal second 'rock) 'tie) ((equal second 'paper) 'second-wins) (t 'first-wins)))

(defun craps () ;f (let* ((throw (throw-dice)) (point (say-throw throw)) (suffix (cond ((instant-win-p throw) (list point '-- 'you 'win)) ((instant-loss-p throw) (list point '-- 'you 'lose)) (t (list 'your 'point 'is point))))) (cons 'throw (cons (car throw) (cons 'and (cons (cadr throw) (cons '-- suffix)))))))

Page 12: (defun play (first second) ;4.18 p. 125 (cond ((equal first 'rock) (cond ((equal second 'rock) 'tie) ((equal second 'paper) 'second-wins) (t 'first-wins)))

;(defun craps () ; (let* ((throw (throw-dice)); (point (say-throw throw)); (suffix (cond ((instant-win-p throw) ; (list point '-- 'you 'win)); ((instant-loss-p throw) ; (list point '-- 'you 'lose)); (t (list 'your 'point 'is point))))); (append (list 'throw (car throw) 'and (cadr throw) '--); suffix)))

Page 13: (defun play (first second) ;4.18 p. 125 (cond ((equal first 'rock) (cond ((equal second 'rock) 'tie) ((equal second 'paper) 'second-wins) (t 'first-wins)))

(defun try-for-point (winpoint) ;g (let* ((throw (throw-dice)) (throwpoint (say-throw throw)) (suffix (cond ((equal throwpoint 7) (list 'you 'lose)) ((equal throwpoint winpoint) (list 'you 'win)) (t (list 'throw 'again))))) (cons 'throw (cons (car throw) (cons 'and (cons (cadr throw) (cons '-- (cons throwpoint (cons '-- suffix)))))))))