Advertisement
wwwRong

abstk-ox

Dec 19th, 2019
458
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 4.07 KB | None | 0 0
  1. local abstk = require 'abstk'
  2. local scr = abstk.new_screen("Tic-Tac-Toe v0.1")
  3. local O = {false,false,false,false,false,false,false,false,false}
  4. local X = {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. local rnd = math.random
  14. local max = math.max
  15. local floor = math.floor
  16. local add = table.insert
  17. local unpak = table.unpack
  18. local concat = table.concat
  19. local defMap = "[_][_][_]\n[_][_][_]\n[_][_][_]\n"
  20. local inpLabel1 = "Choose position [1-9]: "
  21. local inpLabel2 = "Bad move: choose position [1-9]: "
  22.  
  23. function all(t1, t2)
  24.   return t1[t2[1]] and t1[t2[2]] and t1[t2[3]]
  25. end
  26.  
  27. function any(t1, t2)
  28.   local t = 0
  29.   t = t + (t1[t2[1]] and 1 or 0)
  30.   t = t + (t1[t2[2]] and 1 or 0)
  31.   t = t + (t1[t2[3]] and 1 or 0)
  32.   return t
  33. end
  34.  
  35. function randomChoice(args)
  36.     return args[rnd(#args)]
  37. end
  38.  
  39. function checkWin(P)
  40.   for _, w in pairs(win) do
  41.     if all(P, w) then
  42.       return true
  43.     end
  44.   end
  45.   return false
  46. end
  47.  
  48. function displayOX()
  49.   local map = ""
  50.   for i = 1, 9, 3 do
  51.     map = map .. (O[i] and "[O]" or (X[i] and "[X]" or "[_]"))
  52.     map = map .. (O[i+1] and "[O]" or (X[i+1] and "[X]" or "[_]"))
  53.     map = map .. (O[i+2] and "[O]" or (X[i+2] and "[X]" or "[_]")) .."\n"
  54.   end
  55.   scr:set_value("board",map)
  56. end
  57.  
  58. function ai()
  59.   local validMove = {true,true,true,true,true,true,true,true,true}
  60.   for i = 1, 9 do
  61.     validMove[i] = not (O[i] or X[i]) and validMove[i]
  62.   end
  63.   for _, w in pairs(win) do
  64.     local cX = any(X,w)
  65.     for _, v in pairs(w) do
  66.       if cX == 2 and validMove[v] then
  67.         return v
  68.       end
  69.     end
  70.   end
  71.   local V = {-100,-100,-100,-100,-100,-100,-100,-100,-100}
  72.   for i, v in ipairs(validMove) do
  73.     if v then
  74.       local tempX, criticalMove = {unpak(X)}, {}
  75.       tempX[i] = v
  76.       V[i], criticalMove = evalOX(O,tempX)
  77.       if #criticalMove > 0 then
  78.         for _, c in pairs(criticalMove) do
  79.           if validMove[c] then
  80.             return c
  81.           end
  82.         end
  83.       end
  84.     end
  85.   end
  86.   local maxV = max(unpak(V))
  87.   local imaxV = {}
  88.   for i, v in pairs(V) do
  89.     if v == maxV then
  90.       add(imaxV,i)
  91.     end
  92.   end
  93.   return randomChoice(imaxV)
  94. end
  95.  
  96. function evalOX(o,x)
  97.   local SO, SX, criticalMove =calSOX(o,x)
  98.   return (1 + SX - SO), criticalMove
  99. end
  100.  
  101. function calSOX(o,x)
  102.   local SO, SX = 0, 0
  103.   local criticalMove = {}
  104.   for _, w in pairs(win) do
  105.     local cO = any(o,w)
  106.     local cX = any(x,w)
  107.     if cX == 0 then
  108.       SO = SO + cO
  109.       if cO == 2 then  
  110.         scr:set_value("critical", "{".. concat(w,",").."}")
  111.         criticalMove = w
  112.       end
  113.     end
  114.     if cO == 0 then
  115.       SX = SX + cX
  116.     end
  117.   end
  118.   return SO, SX, criticalMove
  119. end
  120.  
  121. function checkInput(id,opos)
  122.   local o = tonumber(scr:get_value("opoint"))
  123.   if not o or (floor(o) > 9 or o < 1) then
  124.     scr:set_value("inplb", inpLabel2)
  125.   else
  126.     o = floor(o)
  127.     if O[o] or X[o] then
  128.       scr:set_value("inplb", inpLabel2)
  129.     else
  130.       scr:set_value("inplb", inpLabel1)
  131.       main(o)
  132.     end
  133.   end
  134.   scr:set_value("opoint", "")
  135. end
  136.  
  137. function clear()
  138.   scr:set_value("board",defMap)
  139. end
  140.  
  141. function main(opos)
  142.   scr:set_value("critical","")
  143.   O[opos] = true
  144.   displayOX()
  145.   local d = true
  146.   for i = 1, 9 do
  147.     d = (O[i] or X[i]) and d
  148.   end
  149.   if d then
  150.     scr:show_message_box("Draw")
  151.     clear()
  152.   elseif checkWin(O) then
  153.     scr:show_message_box("O win")
  154.     clear()
  155.   else
  156.     X[ai()] = true
  157.     displayOX()
  158.     if checkWin(X) then
  159.       scr:show_message_box("X win")
  160.       clear()
  161.     end
  162.   end
  163. end
  164.  
  165. abstk.set_mode(...)
  166. scr:add_label("board", defMap)
  167. scr:add_label("inplb", inpLabel1)
  168. scr:add_text_input("opoint",nil,nil,nil, checkInput)
  169. scr:add_button("ok", "Ok", nil, checkInput)
  170. scr:add_label("critical","")
  171. scr:run()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement