blob: c81e90cd29644fa317b9271a83efe40c9c7993b0 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; OVERVIEW:
;;
;;
;; The PLAY-LOOP procedure takes as its arguments two prisoner's
;; dilemma strategies, and plays an iterated game of approximately
;; one hundred rounds. A strategy is a procedure that takes
;; two arguments: a history of the player's previous plays and
;; a history of the other player's previous plays. A history consists
;; of a sentence of C's and D's. Likewise, a strategy procedure
;; returns either the word C (for "cooperate") or D ("defect").
;; We also need a way to find out the player's scores; GET-SCORES
;; takes two histories and computes the net score for one player.
;;
;; Note that we are inventing various types of objects: strategies,
;; histories, etc. Each type of thing has certain specified
;; properties. For example, a history is a sentence with zero or
;; more words, each of which is a C or D. To help us use these
;; objects, we write procedures that let us forget the details and
;; think about things in terms of histories and rounds, not in terms
;; of sentences and words. (For example, see GET-NTH-FROM-LAST-PLAY,
;; ADD-TO-HISTORY, etc.)
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define (play-loop strategy1 strategy2)
;; returns final scores
(define (play-loop-helper strat1 strat2 history1 history2 counter limit)
(if (= counter limit)
(final-scores history1 history2 limit)
(let ((result1 (strat1 history1 history2))
(result2 (strat2 history2 history1)))
;; note that the strategy's
;; own history comes first
(play-loop-helper strat1 strat2
(add-to-history result1 history1)
(add-to-history result2 history2)
(1+ counter)
limit)))) ; end of helper
(play-loop-helper strategy1 strategy2 ; play-loop body
empty-history empty-history
0
(+ 90 (random 21))))
(define (final-scores history1 history2 num-of-rounds)
;; returns average score per round for the two histories
(se (/ (get-scores history1 history2) num-of-rounds)
(/ (get-scores history2 history1) num-of-rounds) ))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Procedures about histories
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define empty-history '())
(define empty-history? empty?)
(define (add-to-history result history)
(se history result))
(define (last-play history)
(last history))
(define (previous-history history)
(bl history))
(define (get-nth-to-last-play n history)
(cond ((empty? history) '())
((= n 1) (last history))
(else (get-nth-to-last-play (1- n) (butlast history)))))
(define (get-scores my-hist other-hist)
;; returns total score for first player
(if (or (empty? my-hist) (empty? other-hist))
0
(+ (get-score (first my-hist) (first other-hist))
(get-scores (bf my-hist) (bf other-hist)))))
(define (get-score my-play other-play)
;; returns the score of the first player for this round
(let ((round (se my-play other-play)))
(cond ((equal? round '(C C)) 3)
((equal? round '(C D)) 0)
((equal? round '(D C)) 5)
((equal? round '(D D)) 1) )))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Some strategies.
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define (all-defect my-history other-history)
'D)
(define (poor-trusting-fool my-history other-history)
'C)
(define (unforgiving my-history other-history)
(define (ever-defected? history)
(if (empty-history? history)
#f
(or (equal? (last-play history) 'D)
(ever-defected? (previous-history history)))))
(if (ever-defected? other-history) 'D 'C))
(define (tit-for-tat my-history other-history)
(if (empty-history? other-history)
'C
(last-play other-history)))
(define (random-strategy my-history other-history)
(nth (random 2) '(C D)))
|