Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local abstk = require 'abstk'
- local scr = abstk.new_screen("Tic-Tac-Toe v0.1")
- local O = {false,false,false,false,false,false,false,false,false}
- local X = {false,false,false,false,false,false,false,false,false}
- local win = {{1,2,3},
- {4,5,6},
- {7,8,9},
- {1,4,7},
- {2,5,8},
- {3,6,9},
- {1,5,9},
- {3,5,7}}
- local rnd = math.random
- local max = math.max
- local floor = math.floor
- local add = table.insert
- local unpak = table.unpack
- local concat = table.concat
- local defMap = "[_][_][_]\n[_][_][_]\n[_][_][_]\n"
- local inpLabel1 = "Choose position [1-9]: "
- local inpLabel2 = "Bad move: choose position [1-9]: "
- function all(t1, t2)
- return t1[t2[1]] and t1[t2[2]] and t1[t2[3]]
- end
- function any(t1, t2)
- local t = 0
- t = t + (t1[t2[1]] and 1 or 0)
- t = t + (t1[t2[2]] and 1 or 0)
- t = t + (t1[t2[3]] and 1 or 0)
- return t
- end
- function randomChoice(args)
- return args[rnd(#args)]
- end
- function checkWin(P)
- for _, w in pairs(win) do
- if all(P, w) then
- return true
- end
- end
- return false
- end
- function displayOX()
- local map = ""
- for i = 1, 9, 3 do
- map = map .. (O[i] and "[O]" or (X[i] and "[X]" or "[_]"))
- map = map .. (O[i+1] and "[O]" or (X[i+1] and "[X]" or "[_]"))
- map = map .. (O[i+2] and "[O]" or (X[i+2] and "[X]" or "[_]")) .."\n"
- end
- scr:set_value("board",map)
- end
- function ai()
- local validMove = {true,true,true,true,true,true,true,true,true}
- for i = 1, 9 do
- validMove[i] = not (O[i] or X[i]) and validMove[i]
- end
- for _, w in pairs(win) do
- local cX = any(X,w)
- for _, v in pairs(w) do
- if cX == 2 and validMove[v] then
- return v
- end
- end
- end
- local V = {-100,-100,-100,-100,-100,-100,-100,-100,-100}
- for i, v in ipairs(validMove) do
- if v then
- local tempX, criticalMove = {unpak(X)}, {}
- tempX[i] = v
- V[i], criticalMove = evalOX(O,tempX)
- if #criticalMove > 0 then
- for _, c in pairs(criticalMove) do
- if validMove[c] then
- return c
- end
- end
- end
- end
- end
- local maxV = max(unpak(V))
- local imaxV = {}
- for i, v in pairs(V) do
- if v == maxV then
- add(imaxV,i)
- end
- end
- return randomChoice(imaxV)
- end
- function evalOX(o,x)
- local SO, SX, criticalMove =calSOX(o,x)
- return (1 + SX - SO), criticalMove
- end
- function calSOX(o,x)
- local SO, SX = 0, 0
- local criticalMove = {}
- for _, w in pairs(win) do
- local cO = any(o,w)
- local cX = any(x,w)
- if cX == 0 then
- SO = SO + cO
- if cO == 2 then
- scr:set_value("critical", "{".. concat(w,",").."}")
- criticalMove = w
- end
- end
- if cO == 0 then
- SX = SX + cX
- end
- end
- return SO, SX, criticalMove
- end
- function checkInput(id,opos)
- local o = tonumber(scr:get_value("opoint"))
- if not o or (floor(o) > 9 or o < 1) then
- scr:set_value("inplb", inpLabel2)
- else
- o = floor(o)
- if O[o] or X[o] then
- scr:set_value("inplb", inpLabel2)
- else
- scr:set_value("inplb", inpLabel1)
- main(o)
- end
- end
- scr:set_value("opoint", "")
- end
- function clear()
- scr:set_value("board",defMap)
- end
- function main(opos)
- scr:set_value("critical","")
- O[opos] = true
- displayOX()
- local d = true
- for i = 1, 9 do
- d = (O[i] or X[i]) and d
- end
- if d then
- scr:show_message_box("Draw")
- clear()
- elseif checkWin(O) then
- scr:show_message_box("O win")
- clear()
- else
- X[ai()] = true
- displayOX()
- if checkWin(X) then
- scr:show_message_box("X win")
- clear()
- end
- end
- end
- abstk.set_mode(...)
- scr:add_label("board", defMap)
- scr:add_label("inplb", inpLabel1)
- scr:add_text_input("opoint",nil,nil,nil, checkInput)
- scr:add_button("ok", "Ok", nil, checkInput)
- scr:add_label("critical","")
- scr:run()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement