/tic-tac-toe.scm

http://srcc.googlecode.com/ · Scheme · 252 lines · 223 code · 2 blank · 27 comment · 0 complexity · d48ddae5a500b122a6654a88c3c4bfb0 MD5 · raw file

  1. ; tic-tac-toe.ss
  2. ;
  3. ; Copyright (c) 2010-2011 Mikhail Mosienko <netluxe@gmail.com>
  4. ;
  5. ; Permission is hereby granted, free of charge, to any person obtaining a copy
  6. ; of this software and associated documentation files (the "Software"), to deal
  7. ; in the Software without restriction, including without limitation the rights
  8. ; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. ; copies of the Software, and to permit persons to whom the Software is
  10. ; furnished to do so, subject to the following conditions:
  11. ;
  12. ; The above copyright notice and this permission notice shall be included in
  13. ; all copies or substantial portions of the Software.
  14. ;
  15. ; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. ; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. ; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. ; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. ; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. ; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21. ; THE SOFTWARE.
  22. ;
  23. (define (tic-tac-toe)
  24. (letrec ((area
  25. '((0-0 . #f) (0-1 . #f) (0-2 . #f)
  26. (1-0 . #f) (1-1 . #f) (1-2 . #f)
  27. (2-0 . #f) (2-1 . #f) (2-2 . #f)))
  28. (figure?
  29. (lambda(f)
  30. (if (or (eq? f 0)
  31. (eq? f 'x)) #t #f)))
  32. (position?
  33. (lambda(p)
  34. (let ((pos (assq p area)))
  35. (if (and pos
  36. (not (cdr pos))) p #f))))
  37. (clear-area
  38. (lambda()
  39. (for-each
  40. (lambda(p)
  41. (set-cdr! p #f))
  42. area)))
  43. (user-figure #f)
  44. (cpu-figure #f)
  45. (end-game?
  46. (lambda(v)
  47. (cond
  48. ((and (eq? (cdr (assq '0-0 area)) v)
  49. (eq? (cdr (assq '0-1 area)) v)
  50. (eq? (cdr (assq '0-2 area)) v)) #t)
  51. ((and (eq? (cdr (assq '1-0 area)) v)
  52. (eq? (cdr (assq '1-1 area)) v)
  53. (eq? (cdr (assq '1-2 area)) v)) #t)
  54. ((and (eq? (cdr (assq '2-0 area)) v)
  55. (eq? (cdr (assq '2-1 area)) v)
  56. (eq? (cdr (assq '2-2 area)) v)) #t)
  57. ((and (eq? (cdr (assq '0-0 area)) v)
  58. (eq? (cdr (assq '1-0 area)) v)
  59. (eq? (cdr (assq '2-0 area)) v)) #t)
  60. ((and (eq? (cdr (assq '0-1 area)) v)
  61. (eq? (cdr (assq '1-1 area)) v)
  62. (eq? (cdr (assq '2-1 area)) v)) #t)
  63. ((and (eq? (cdr (assq '0-2 area)) v)
  64. (eq? (cdr (assq '1-2 area)) v)
  65. (eq? (cdr (assq '2-2 area)) v)) #t)
  66. ((and (eq? (cdr (assq '0-0 area)) v)
  67. (eq? (cdr (assq '1-1 area)) v)
  68. (eq? (cdr (assq '2-2 area)) v)) #t)
  69. ((and (eq? (cdr (assq '0-2 area)) v)
  70. (eq? (cdr (assq '1-1 area)) v)
  71. (eq? (cdr (assq '2-0 area)) v)) #t)
  72. (else #f))))
  73. (set-user-figure
  74. (lambda()
  75. (display "???????? ??????? ??? ????? (x ??? 0): ")
  76. (let ((f (read)))
  77. (if (figure? f)
  78. (set! user-figure f)
  79. (begin
  80. (newline)
  81. (set-user-figure))))))
  82. (set-cpu-figure
  83. (lambda()
  84. (if (eq? user-figure 'x)
  85. (set! cpu-figure 0)
  86. (set! cpu-figure 'x))))
  87. (get-move
  88. (lambda()
  89. (display "??? ???: ")
  90. (let ((p (read)))
  91. (if (position? p)
  92. (set-cdr! (assq p area) user-figure)
  93. (begin
  94. (newline)
  95. (get-move))))))
  96. (print-cage
  97. (lambda()
  98. (let ((get-value
  99. (lambda(p)
  100. (let ((val (cdr (assq p area))))
  101. (if val val #\space)))))
  102. (display " 0 1 2\n")
  103. (display "0 ") (display (get-value '0-0)) (display "|")
  104. (display (get-value '0-1)) (display "|") (display (get-value '0-2))
  105. (newline)
  106. (display " -------") (newline)
  107. (display "1 ") (display (get-value '1-0)) (display "|")
  108. (display (get-value '1-1)) (display "|") (display (get-value '1-2))
  109. (newline)
  110. (display " -------") (newline)
  111. (display "2 ") (display (get-value '2-0)) (display "|")
  112. (display (get-value '2-1)) (display "|") (display (get-value '2-2))
  113. (newline))))
  114. (find-move
  115. (lambda()
  116. (let ((lines
  117. (list
  118. (cons
  119. (list '0-0 '0-1 '0-2)
  120. (list (cdr (assq '0-0 area)) (cdr (assq '0-1 area)) (cdr (assq '0-2 area))))
  121. (cons
  122. (list '1-0 '1-1 '1-2)
  123. (list (cdr (assq '1-0 area)) (cdr (assq '1-1 area)) (cdr (assq '1-2 area))))
  124. (cons
  125. (list '2-0 '2-1 '2-2)
  126. (list (cdr (assq '2-0 area)) (cdr (assq '2-1 area)) (cdr (assq '2-2 area))))
  127. (cons
  128. (list '0-0 '1-0 '2-0)
  129. (list (cdr (assq '0-0 area)) (cdr (assq '1-0 area)) (cdr (assq '2-0 area))))
  130. (cons
  131. (list '0-1 '1-1 '2-1)
  132. (list (cdr (assq '0-1 area)) (cdr (assq '1-1 area)) (cdr (assq '2-1 area))))
  133. (cons
  134. (list '0-2 '1-2 '2-2)
  135. (list (cdr (assq '0-2 area)) (cdr (assq '1-2 area)) (cdr (assq '2-2 area))))
  136. (cons
  137. (list '0-0 '1-1 '2-2)
  138. (list (cdr (assq '0-0 area)) (cdr (assq '1-1 area)) (cdr (assq '2-2 area))))
  139. (cons
  140. (list '2-0 '1-1 '0-2)
  141. (list (cdr (assq '2-0 area)) (cdr (assq '1-1 area)) (cdr (assq '0-2 area)))))))
  142. (call-with-current-continuation
  143. (lambda (return)
  144. ; check win positions
  145. (for-each
  146. (lambda(l)
  147. (cond
  148. ((equal? (cdr l) `(,cpu-figure ,cpu-figure #f))
  149. (return (caddr (car l))))
  150. ((equal? (cdr l) `(,cpu-figure #f ,cpu-figure))
  151. (return (cadr (car l))))
  152. ((equal? (cdr l) `(#f ,cpu-figure ,cpu-figure))
  153. (return (car (car l))))))
  154. lines)
  155. ; check user positions
  156. (for-each
  157. (lambda(l)
  158. (cond
  159. ((equal? (cdr l) `(,user-figure ,user-figure #f))
  160. (return (caddr (car l))))
  161. ((equal? (cdr l) `(,user-figure #f ,user-figure))
  162. (return (cadr (car l))))
  163. ((equal? (cdr l) `(#f ,user-figure ,user-figure))
  164. (return (car (car l))))))
  165. lines)
  166. (if (equal? (cdr (assoc '(0-0 0-1 0-2) lines)) `( #f ,user-figure #f))
  167. (cond
  168. ((equal? (cdr (assoc '(0-0 1-0 2-0) lines)) `( #f ,user-figure #f))
  169. (return '0-0))
  170. ((equal? (cdr (assoc '(0-2 1-2 2-2) lines)) `( #f ,user-figure #f))
  171. (return '0-2))))
  172. (if (equal? (cdr (assoc '(0-0 1-0 2-0) lines)) `( #f ,user-figure #f))
  173. (cond
  174. ((equal? (cdr (assoc '(0-0 0-1 0-2) lines)) `( #f ,user-figure #f))
  175. (return '0-0))
  176. ((equal? (cdr (assoc '(2-0 2-1 2-2) lines)) `( #f ,user-figure #f))
  177. (return '2-0))))
  178. (if (equal? (cdr (assoc '(2-0 2-1 2-2) lines)) `( #f ,user-figure #f))
  179. (cond
  180. ((equal? (cdr (assoc '(0-2 1-2 2-2) lines)) `( #f ,user-figure #f))
  181. (return '2-2))
  182. ((equal? (cdr (assoc '(0-0 1-0 2-0) lines)) `( #f ,user-figure #f))
  183. (return '2-0))))
  184. (if (equal? (cdr (assoc '(0-2 1-2 2-2) lines)) `( #f ,user-figure #f))
  185. (cond
  186. ((equal? (cdr (assoc '(2-0 2-1 2-2) lines)) `( #f ,user-figure #f))
  187. (return '2-2))
  188. ((equal? (cdr (assoc '(0-0 0-1 0-2) lines)) `( #f ,user-figure #f))
  189. (return '0-2))))
  190. ; check second positions
  191. (for-each
  192. (lambda(l)
  193. (cond
  194. ((equal? (cdr l) `(,cpu-figure #f #f))
  195. (return (caddr (car l))))
  196. ((equal? (cdr l) `(#f #f ,cpu-figure))
  197. (return (car (car l))))
  198. ((equal? (cdr l) `(#f ,cpu-figure #f))
  199. (return (car (car l))))))
  200. lines)
  201. ; find empty position
  202. (if (not (cdr (assq '1-1 area)))
  203. (return '1-1))
  204. (for-each
  205. (lambda(l)
  206. (if (not (cdr l))
  207. (return (car l))))
  208. area)
  209. #f)))))
  210. (game
  211. (lambda()
  212. (call-with-current-continuation
  213. (lambda (return)
  214. (if (or (end-game? cpu-figure)
  215. (end-game? user-figure))
  216. (return))
  217. (if (eq? user-figure 'x)
  218. (begin
  219. (print-cage)
  220. (get-move)
  221. (if (end-game? user-figure)
  222. (return)
  223. (let ((m (find-move)))
  224. (if m
  225. (set-cdr! (assq m area) cpu-figure)
  226. (return)))))
  227. (begin
  228. (set-cdr! (assq (find-move) area) cpu-figure)
  229. (print-cage)
  230. (if (or (end-game? cpu-figure)
  231. (not (find-move)))
  232. (return)
  233. (get-move))))
  234. (game)))))
  235. )
  236. (clear-area)
  237. (set-user-figure)
  238. (set-cpu-figure)
  239. (display "??? ??? ????? ??? {? ??????}-{? ???????}\n????????, 1-2, 1-1, 2-0.\n")
  240. (game)
  241. (display "------------------------\n")
  242. (print-cage)
  243. (cond
  244. ((end-game? cpu-figure)
  245. (display "?? ?????????!"))
  246. ((end-game? user-figure)
  247. (display "?? ????????!"))
  248. (else
  249. (display "?????!")))))
  250. ;(tic-tac-toe)