Advertisement
wwwRong

ox_game_fennel

Mar 16th, 2021 (edited)
2,278
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ;;  แปลงมาจาก OX.py ในหนังสือ Artificial Intelligence
  2. ;;  with Machine Learning ของ รศ.ดร.ปริญญา สงวนสัตย์
  3.  
  4. (local M [false false false false false false false false false])
  5. (local win [[1 2 3]
  6.             [4 5 6]
  7.             [7 8 9]
  8.             [1 4 7]
  9.             [2 5 8]
  10.             [3 6 9]
  11.             [1 5 9]
  12.             [3 5 7]])
  13.  
  14. (local rnd math.random)
  15. (local max math.max)
  16.  
  17. (local floor math.floor)
  18.  
  19. (fn floor-n [x]
  20.   (let [n (tonumber x)]
  21.     (if n (floor n)
  22.     0)))
  23.  
  24. ;ทำเรียกใช้ table function สะดวกขึ้น
  25. (local add table.insert)
  26. (local unpak table.unpack)
  27. (local concat table.concat)
  28. ;(local insp (require "inspect"))
  29.  
  30. (fn all [p w]
  31.   "ให้ p เป็น 'O' หรือ 'X'"
  32.   (= (. M (. w 1)) (. M (. w 2)) (. M (. w 3)) p))
  33.  
  34. (fn any [p w m]
  35.   "ให้ p เป็น 'O' หรือ 'X'"
  36.   (var t 0)
  37.   (var move (or m M))
  38.   (when (= p (. move (. w 1))) (set t (+ t 1)))
  39.   (when (= p (. move (. w 2))) (set t (+ t 1)))
  40.   (when (= p (. move (. w 3))) (set t (+ t 1)))
  41.   t)
  42.  
  43. (fn random-choice [args]
  44.   (. args (rnd (length args))))
  45.  
  46. ;(fn check-win [p]
  47. ;  (var (result i) (values true 1))
  48. ;  (while (<= i (length win))
  49. ;    (set result (all p (. win i)))
  50. ;    (if result
  51. ;      (set i (+ (length win) 1))
  52. ;      (set i (+ i 1))))
  53. ;  result)
  54.  
  55. ;(fn check-win [p]
  56. ;  ":until in fennel 0.9+"
  57. ;  (var result false)
  58. ;  (each [_ w (ipairs win) :until result]
  59. ;    (set result (all p w)))
  60. ;  result)
  61.  
  62. ;(fn check-win [p]
  63. ;  "lua escape hatch"
  64. ;  (each [_ w (ipairs win)])
  65. ;    (when (all p w)
  66. ;      (lua "return true")))
  67. ;  false)
  68.  
  69. (fn check-win [p w k r]
  70.   "ตรวจผลชนะแบบ tail recursion"
  71.   (var (key line) (next win k))
  72.   (if (or (not w) (and key (not r)))
  73.     (do
  74.       (check-win p line key (all p line)))
  75.     r))
  76.  
  77. ;(fn check-draw []
  78. ;  (var (draw i) (values true 1))
  79. ;  (while (or draw (<= i 9))
  80. ;    (set draw (and draw (. M i)))
  81. ;    (set i (+ i 1)))
  82. ;  draw)
  83.  
  84. ;(fn check-draw []
  85. ;  (and (. M 1)
  86. ;      (. M 2)
  87. ;      (. M 3)
  88. ;      (. M 4)
  89. ;      (. M 5)
  90. ;      (. M 6)
  91. ;      (. M 7)
  92. ;      (. M 8)
  93. ;      (. M 9)))
  94.  
  95. ;(fn check-draw []
  96. ;  ":until in fennel 0.9+"
  97. ;  (var draw true)
  98. ;  (each [_ v (ipairs M) :until (not draw)]
  99. ;    (when (not v)
  100. ;      (set draw v)))
  101. ;  draw)
  102.  
  103. ;(fn check-draw []
  104. ;  "lua escape hatch"
  105. ;  (each [_ v (ipairs M)]
  106. ;    (when (not v)
  107. ;      (lua "return false"))
  108. ;  true)
  109.  
  110. (fn check-draw [i r]
  111.   "ตรวจสอบว่าเสมอแบบ tail recursion"
  112.   (var n (or i 0))
  113.   (var d (or (and (= r nil) true) r))
  114.   (if (or (= i 9) (= r false))
  115.     r
  116.     (do
  117.       (set n (+ n 1))
  118.       (check-draw n (and d (. M n))))))
  119.  
  120. (fn display []
  121.   "แสดงผลตาราง"
  122.   (for [i 1 9 3]
  123.     (let [m1 (or (and (. M i) (.. "[" (. M i) "]")) "[_]")
  124.           m2 (or (and (. M (+ i 1)) (.. "[" (. M (+ i 1)) "]")) "[_]")
  125.           m3 (or (and (. M (+ i 2)) (.. "[" (. M (+ i 2)) "]")) "[_]")]
  126.       (print (.. m1 m2 m3)))))
  127.  
  128. (fn cal-sox [m]
  129.   (var (so sx) (values 0 0))
  130.   (var critical-move [])
  131.   (each [_ w (pairs win)]
  132.     (let [co (any "O" w m)
  133.           cx (any "X" w m)]
  134.       (when (= 0 cx)
  135.         (set so (+ so co))
  136.         (when (= 2 co)
  137.           (print "critical" (.. "{" (concat w ",") "}"))
  138.           (set critical-move w))
  139.       (when (= 0 co)
  140.         (set sx (+ sx cx))))))
  141.   (values so sx critical-move))
  142.  
  143. (fn eval-ox [m]
  144.   (let [(so sx critical-move) (cal-sox m)]
  145.     (values (- (+ 1 sx) so) critical-move)))
  146.  
  147. (fn ai-method1 [move]
  148.   (var (v i continue) (values nil 1 true))
  149.   (while (and (= v nil) (<= i (length win)))
  150.     (let [w (. win i)
  151.           cx (any "X" w)]
  152.       (when (= cx 2)
  153.         (if (. move (. w 1)) (set v (. w 1))
  154.           (. move (. w 2)) (set v (. w 2))
  155.           (. move (. w 3)) (set v (. w 3)))))
  156.     (set i (+ i 1)))
  157.     v)
  158.  
  159. (fn ai-method2 [move]
  160.   (var V [-100 -100 -100 -100 -100 -100 -100 -100 -100])
  161.   (var c nil)
  162.   (var i 1)
  163.   (while (and (= c nil) (<= i (length move)))
  164.     (when (. move i)
  165.       (var temp-x [(unpak M)])
  166.       (tset temp-x i "X")
  167.       (let [(Vi critical-move) (eval-ox temp-x)]
  168.         (tset V i Vi)
  169.         (when (> (length critical-move) 0)
  170.           (var [c1 c2 c3] critical-move)
  171.           (if (. move c1)
  172.             (set c c1)
  173.           (. move c2)
  174.             (set c c2)
  175.             (set c c3)))))
  176.     (set i (+ i 1)))
  177.   (if c c
  178.     (do
  179.       (var max-v (max (unpak V)))
  180.       (var imax-v [])
  181.       (each [i v (pairs V)]
  182.         (when (= v max-v)
  183.           (add imax-v i)))
  184.       (random-choice imax-v))))
  185.  
  186. (fn ai []
  187.   (var valid-move [true true true true true true true true true])
  188.   (var v nil)
  189.   (for [i 1 9]
  190.     (tset valid-move i (not (. M i))))
  191.   (set v (ai-method1 valid-move))
  192.   (when (= v nil)
  193.       (set v (ai-method2 valid-move)))
  194.   v)
  195.  
  196. (fn main []
  197.   (var continue true)
  198.   (var move nil)
  199.   (while continue
  200.     (if (or (= move nil) (and (< 0 move 10) (not (. M move))))
  201.       (io.write "Choose position [1-9]: ")
  202.       (io.write "Bad move: choose position [1-9]: "))
  203.     (set move (floor-n (io.read)))
  204.     (print "")
  205.     (when (and (< 0 move 10))
  206.       (when (not (. M move))
  207.         (tset M move "O")
  208.         (display)
  209.         (if (check-win "O")
  210.             (do
  211.               (print "O win")
  212.               (set continue false))
  213.           (not= false (check-draw))
  214.             (do
  215.               (print "Draw")
  216.               (set continue false))
  217.           (do
  218.             (tset M (ai) "X")
  219.             (display)
  220.             (when (check-win "X")
  221.               (print "X win")
  222.               (set continue false))))
  223.           (set move nil)))))
  224.  
  225. (main)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement