1 / 55

Lists and Card Games: Lab #1 and Homework #1

This article explores the internals of lists and their operations, focusing on an extended example in Lab #1. It also covers Homework #1, discussing different card games and their point values. The article concludes with a discussion on dealing with card games using data-driven functions and anonymous functions.

jaclynp
Download Presentation

Lists and Card Games: Lab #1 and Homework #1

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Lists CSC 358/458 4.3.2006

  2. Outline • Lab #1 / Homework #1 • Lists • A question • List • Internals of Lists • List operations • Extended Example

  3. Lab #1 (defun add-car (lst1 lst2) (+ (car lst1) (car lst2))) (defun deal-hand (size deck) (let ((hand '())) (dotimes (i size) (push (pop deck) hand)) hand)) (defun count-face-cards (hand) (let ((counter 0)) (dolist (card hand) (if (face-cardp card) (incf counter))) counter)) (defun face-cardp (card) (not (numberp (card-rank card))))

  4. Lab #1 (Extra credit) (defun average-face-cards (trials size) (let ((deck (make-deck)) (count 0)) (dotimes (k trials) (setf deck (shuffle-deck deck)) (incf count (count-face-cards (deal-hand size deck)))) (/ (float count) trials)))

  5. Homework #1 ;; Cheating version (using case) (defun card-blackp (card) (case (card-suit card) ((H D) nil) ((S C) t))) ;; Non-cheating version (using cond) (defun card-blackp (card) (let ((suit (card-suit card))) (cond ((or (eq suit 'H) (eq suit 'D)) nil) (t t)))) ;; Functional version with boolean return value (defun card-blackp (card) (let ((suit (card-suit card))) (or (eq suit 'S) (eq suit 'C))))

  6. Homework #1 (defun not-twenty-onep (card1 card2) (let ((rank1 (card-rank card1)) (rank2 (card-rank card2))) (if (and (= rank1 1) (= rank2 1)) ;; special case 12 (let ((value1 (card-points-bj rank1)) (value2 (card-points-bj rank2))) (let ((value-sum (+ value1 value2))) (if (= value-sum 21) nil value-sum)))))) (defun card-points-bj (rank) (case rank ((k q j) 10) (1 11) (otherwise rank)))

  7. Homework #1 (defun card-points-skat (rank) (case rank (1 11) (10 10) (k 4) (q 3) (j 2) (otherwise 0))) (defun skat-trick (trick) (let ((score 0)) (dolist (card trick) (incf score (card-points-skat (card-rank card)))) score))

  8. Homework #1 (XC) (defun can-buildp (hand center) (dolist (hand-card hand) (dolist (center-card center) (if (can-build-cards hand-card center-card hand) (return-from can-buildp (list hand-card center-card))))))) (defun can-build-cards (hand-card center-card hand) (let ((hand-value (card-points-cassino (card-rank hand-card))) (center-value (card-points-cassino (card-rank center-card)))) (let ((build-value (+ hand-value center-value))) (dolist (card hand) (if (= build-value (card-points-cassino (card-rank card))) (return-from can-build-cards t)))))) (defun card-points-cassino (rank) (case rank (k 13) (q 12) (j 11) (otherwise rank)))

  9. Homework #1 (defun can-buildp (hand center) (let ((ans nil)) (dolist (hand-card hand) (dolist (center-card center) (if (can-build-cards hand-card center-card hand) (setf ans (list hand-card center-card))))) ans))

  10. Last week • How to deal with card games with different point values? • One possibility • lots of named functions • ick • Better approach • be data-driven • let the functions be defined by the data • Problem • don't want an extra argument to a comparison operator • suppose I want to supply the comparison to a sort function?

  11. Lisp solution • Create an anonymous function using the data • use this function for comparing • Benefits • can create as many as needed • symbol table not filled with unnecessary stuff

  12. card-comparator (defvar *default-card-values* '((K 13) (Q 12) (J 11))) (defvar *ace-high-values* '((1 14) (K 13) (Q 12) (J 11))) (defvar *skat-card-values* '((1 14) (10 13) (K 12) (Q 11) (J 10))) (defun rank-to-number2 (rank card-values) (let ((value-pair (assoc rank card-values))) (if value-pair (cadr value-pair) rank))) (defun card-comparator (&optional (card-values *default-card-values*)) #'(lambda (card1 card2) (let ((rank1 (card-rank card1)) (rank2 (card-rank card2))) (< (rank-to-number2 rank1 card-values) (rank-to-number2 rank2 card-values)))))

  13. Some syntax: lambda • lambda • a lot more about this next week • this is how we define an anonymous function • defun is just a convenience • (setf (function foo) #'(lambda (x y) (+ x y))) • the same as • (defun foo (x y) (+ x y)) • lambda is fundamental

  14. Optional arguments • More about this next week • I can specify in the parameter list that some arguments are optional • and then supply default values • Optional arguments must be at the end • for obvious reasons

  15. Closure • Note • the function I define using lambda • refers to a parameter defined in the enclosing scope • card-values • the function is returned to the caller • the enclosing scope disappears • can I do this? • Yes! • technical term = "lexical closure" • more about this next week

  16. Lists

  17. A Question • Why can’t I really deal from my deck? • Why does this function not change the value of its argument? (defun mypop (lst) (pop lst)) > (setf l1 '(a b c)) > (mypop l1) A > l1 (A B C)

  18. Lists • sequences of items • atoms or lists • car • first element • cdr • rest • cons • builds a list

  19. Other List Builders • list • a list containing the arguments • append • a list combining the arguments

  20. Internals (a b c)

  21. Nested List

  22. Improper List

  23. What Does It Do?* • (setf l1 '(a (b c))) • (setf l2 '((d) e)) • (car l2) • (cdr l1) • (cons 'b l1) • (list l2 'd) • (append l1 l2)

  24. What does it do? • (pop l1) • special form • short for • (setf l1 (cdr l1)) • (defun mypop (lst) (pop lst)) • (defun my pop (lst) (setf lst (cdr lst))) • (mypop l1) • l1 doesn't change • why should it? • it is still bound to the same thing

  25. How can we achieve this? • Global variable • ick • Game state structure • pass in and out • contents manipulated • better

  26. Example: Blackjack (defun make-bj-game (player-count) (list (shuffle-deck (make-deck)) (make-list player-count :initial-element nil))) (defun player-count (game) (length (hands game))) (defun deck (game) (cadr game)) (defun hands (game) (caddr game)) (defun hand (player game) (nth player (hands game)))

  27. New function • make-list • note the function call • :initial-element • keyword argument • we'll see this again later

  28. Shared Structure • It is easy to create lists that share structure • (setf c (append a b)) • Not a problem unless a or b is destructively modified

  29. List Functions • Accessors • navigating around in lists • Operations • manipulate the whole list • Destructive operations • modify the list

  30. List Accessors • car, cdr • positional • first, second, third • (nth i lst) • (nthcdr i lst) • end of the list • last • actually returns last cdr

  31. List Operations • Many! • Mapping functions • Boolean operations • Finding • Modifying (copy) • Reduce

  32. Mapping • Functions that apply a function over and over across a list • (mapcar #’fn lst) • applies the function to each element in the list • returns a list of the results • Also works with multiple lists • (mapcar #’fn lst1 lst2)

  33. Example • Matt's question • What if I want to add 5 to everything in a list? • (mapcar #'(lambda (x) (+ x 5)) '(1 2 3))

  34. Other Mapping Functions • maplist • applies to successive cdrs • mapcan • joins results with append • mapc, mapl • like mapcar and maplist but doesn't return results

  35. Boolean Operations • logical summary of a list • relative to a function • (some #’fn lst) • true if any element of lst returns true when the function is applied • every • false if any element returns false • notany • notevery

  36. Example • flushp • is a poker hand a flush? • 5-card hand, please • logic • all cards the same suit • simple method • all spades or all clubs or ... • better way?

  37. Finding Operations • (member elem lst) • if elem is in list, returns the cdr headed by elem • (position elem lst) • if elem is in list, return position index • both return nil is absent

  38. Modifications • (remove elem lst) • returns a copy of lst with elem removed • not “destructive” • Also "if" version • remove-if • has a test instead of an element • (substitute old new lst) • returns a copy of lst with old replaced by new

  39. Reduce • “reduce” list into a single value • (reduce #’fn lst) • applies fn to first two elements • applies fn to that result and next element • etc. • (reduce #’+ ‘(1 2 3 4)) => 10

  40. Example • count-face-cards • mapcar and reduce • Original version (defun count-face-cards (hand) (let ((counter 0)) (dolist (card hand) (if (face-cardp card) (incf counter))) counter)) (defun face-cardp (card) (not (numberp (card-rank card))))

  41. Destructive Operations I • Most Lisp operations return “new” lists • remove • (setf lst ‘(b a b a b)) • (remove ‘a lst) => (b b b) • lst => (b a b a b) • Use the result of the function • New cons cells created • not always what you want

  42. Destructive Operations II • Alter the contents of cons cells • rplaca = replace the car • rplacd = replace the cdr • nconc = destructive append • delete = destructive remove • nsubst = destructive subst • Others • “n” means “non-consing”

  43. Generalized Variables • setf • can be similarly used • (setf (car lst) val) • (setf (cdr lst) val) • Main reason to use • efficiency • creating new cons cells • creating garbage

  44. Problems with Destructive Operations • Shared structure • Effects hard to predict • Not necessary • Main reason to use • efficiency • but remember Knuth • “Premature optimization is the root of all evil.”

  45. Example • Look at deck after shuffle-deck

  46. defsetf • One principle of Lisp is that the programmer has the same power as the language designer • You can create your own generalized variables • use defsetf

  47. Example (defun 3rd (lst) (nth 2 lst)) (defun set-3rd (lst value) (setf (nth 2 lst) value)) (defsetf 3rd set-3rd) (setf lst '( a b c d)) (setf (3rd lst) 'q) lst => (a b q d) (setf (3rd lst))

  48. Association List • Allows lookup of values associated with keys • ((key1 . val1) (key2 . val2) ... (keyn . valn)) • OK for short associations • large associations a hash table is better • (assoc key alist) • returns the pair • (rassoc val alist) • returns the pair

  49. Keyword parameters • what if the value is not an atom? (rassoc '(21 M) '((John 21 M) (Jane 19 F) (Joe 25 M))) • doesn’t work because rassoc uses eq • extra arguments to rassoc • :test • specifies which function to use instead of default (rassoc '(21 M) '((John 21 M) (Jane 19 F) (Joe 25 M)):test #'equal)

  50. Keyword Parameters • Many functions have these • Most common • :test • :key • specifies a function to apply before testing (rassoc '21 '((John 21 M) (Jane 19 F) (Joe 25 M)):key #'car) • :start • :end

More Related