-
Notifications
You must be signed in to change notification settings - Fork 0
/
37.3.4.scm
196 lines (167 loc) · 5.23 KB
/
37.3.4.scm
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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
#lang racket
(require "37.2.1.scm")
;; Data Analysis and Definitions:
;; A letter is a symbol in: 'a ... 'z plus '_
;; A word is a (listof letter).
;; A body-part is one of the following symbols:
(define PARTS '(head body right-arm left-arm right-leg left-leg))
;; Constants:
;; some guessing words:
(define WORDS
'((h e l l o)
(w o r l d)
(i s)
(a)
(s t u p i d)
(p r o g r a m)
(a n d)
(s h o u l d)
(n e v e r)
(b e)
(u s e d)
(o k a y)
))
;; the number of words we can choose from
(define WORDS# (length WORDS))
;; chosen-word : word
;; the word that the player is to guess
(define chosen-word (first WORDS))
;; status-word : word
;; represents which letters the player has and hasn't guessed
(define status-word (first WORDS))
;; body-parts-left : (listof body-part)
;; represents the list of body parts that are still "available"
(define body-parts-left PARTS)
(define new-knowledge false)
(define hidden-letters-count 0)
;; hangman : -> void
;; effect: initialize chosen-word, status-word, and body-parts-left
(define (hangman)
(begin
(set! chosen-word (list-ref WORDS (random (length WORDS))))
(set! status-word (make-status-word chosen-word))
(set! body-parts-left PARTS)
(set! hidden-letters-count 0)))
;; hangman-guess : letter -> response
;; to determine whether the player has won, lost, or may continue to play
;; and, if so, which body part was lost, if no progress was made
;; effects: (1) if the guess represents progress, update status-word
;; (2) if not, shorten the body-parts-left by one
(define (hangman-guess guess)
(local ((define new-status (reveal-list chosen-word status-word guess)))
(cond
[new-knowledge
(cond
[(zero? hidden-letters-count) "You won"]
[else
(begin
(set! status-word new-status)
(list "Good guess!" status-word))])]
[else
(local ((define next-part (first body-parts-left)))
(begin
(set! body-parts-left (rest body-parts-left))
(cond
[(empty? body-parts-left) (list "The End" chosen-word)]
[else (list "Sorry" next-part status-word)])))]
)))
;; reveal-list : word word letter -> word
;; to compute the new status word
;; effect: to set new-knowledge to true if guess reveals new knowledge
(define (reveal-list chosen-word status-word guess)
(local ((define (reveal-one chosen-letter status-letter)
(cond
[(and (symbol=? chosen-letter guess)
(symbol=? status-letter '_))
(begin
(set! hidden-letters-count (sub1 hidden-letters-count))
(set! new-knowledge true)
guess)]
[else status-letter])))
(begin
(set! new-knowledge false)
(map reveal-one chosen-word status-word))))
(require rackunit)
(require rackunit/text-ui)
(define hangman-guess-tests
(test-suite
"Test for hangman-guess"
(test-case
"1. Good guess!"
(set! chosen-word '(b a l l))
(set! status-word '(b _ _ _))
(set! body-parts-left PARTS)
(check-equal? (hangman-guess 'l)
(list "Good guess!" '(b _ l l)))
(check-equal? status-word '(b _ l l))
(check-equal? body-parts-left PARTS)
)
(test-case
"2. You won"
(set! chosen-word '(b a l l))
(set! status-word '(b _ l l))
(set! body-parts-left PARTS)
(check-equal? (hangman-guess 'a)
"You won")
(check-equal? status-word '(b _ l l))
(check-equal? body-parts-left PARTS)
)
(test-case
"3. Sorry"
(set! chosen-word '(b a l l))
(set! status-word '(b _ l l))
(set! body-parts-left '(right-leg left-leg))
(check-equal? (hangman-guess 'l)
(list "Sorry" 'right-leg '(b _ l l)))
(check-equal? status-word '(b _ l l))
(check-equal? body-parts-left '(left-leg))
)
(test-case
"4. The End"
(set! chosen-word '(b a l l))
(set! status-word '(b _ l l))
(set! body-parts-left '(left-leg))
(check-equal? (hangman-guess 'l)
(list "The End" '(b a l l)))
(check-equal? status-word '(b _ l l))
(check-equal? body-parts-left empty)
)
))
(define hangman-new-knowledge-tests
(test-suite
"Test for hangman-new-knowledge"
(test-case
"1."
(set! status-word '(b _ l l))
(set! chosen-word '(b a l l))
(set! body-parts-left PARTS)
(check-equal? (reveal-list chosen-word status-word 'a) '(b a l l))
(check-equal? new-knowledge true)
)
(test-case
"2."
(set! status-word '(b _ _ _))
(set! chosen-word '(b a l l))
(set! body-parts-left PARTS)
(check-equal? (reveal-list chosen-word status-word 'x) '(b _ _ _))
(check-equal? new-knowledge false)
)
(test-case
"3."
(set! status-word '(b _ _ _))
(set! chosen-word '(b a l l))
(set! body-parts-left PARTS)
(check-equal? (reveal-list chosen-word status-word 'l) '(b _ l l))
(check-equal? new-knowledge true)
)
(test-case
"4."
(set! status-word '(b _ l l))
(set! chosen-word '(b a l l))
(set! body-parts-left PARTS)
(check-equal? (reveal-list chosen-word status-word 'l) '(b _ l l))
(check-equal? new-knowledge false)
)
))
(exit (+ (run-tests hangman-new-knowledge-tests)
(run-tests hangman-new-knowledge-tests)))