View difference between Paste ID: ESw5H1x8 and EFSBwvDi
SHOW: | | - or go back to the newest paste.
1-
--tic tac toe
1+
local AGUI_VERSION = "0.6"
2-
----SETTINGS----
2+
local component = require("component")
3-
size=9 --size of field
3+
local success, gui
4-
len=5  --length of line which you must solve
4+
repeat
5-
----------------
5+
  success, gui = pcall(require, "AGUI")
6-
tex={
6+
  if not success then
7-
 x={"▄   ▄",
7+
    print(gui)
8-
    " ▀▄▀ ",
8+
    io.write("For the application need a library AGUI (https://pastebin.com/s4UFSFwn).\n")
9-
    "▄▀ ▀▄",
9+
    if not component.isAvailable("internet") then
10-
 },
10+
      os.exit()
11-
 o={"  ▄  ",
11+
    end
12-
    "▄▀ ▀▄",
12+
    io.write("Do you want to install?[Y/n] ")
13-
    " ▀▄▀ "
13+
    if not ((io.read() or "n").."y"):match("^%s*[Yy]") then
14-
 }
14+
      os.exit()
15-
}
15+
    end
16-
isEnded=false
16+
    loadfile("/bin/wget.lua")("https://pastebin.com/raw/s4UFSFwn", "/lib/AGUI.lua", "-f")
17-
turn="x"
17+
  end
18-
nextTurn={x="o",o="x"}
18+
until success
19-
local event=require("event")
19+
20-
local gpu=require("component").gpu
20+
if gui.Version ~= AGUI_VERSION then
21-
map={}
21+
  io.write("Recommended version of AGUI library ("..AGUI_VERSION..") does not match installed ("..(gui.Version or "unknown")..")\n")
22-
22+
  io.write("Do you want to continue?[Y/n] ")
23-
for i=1,size*size do
23+
    if not ((io.read() or "n").."y"):match("^%s*[Yy]") then
24-
  map[i]=" "
24+
      os.exit()
25-
end
25+
    end
26-
function toXY(num)
26+
end
27-
  local y=math.floor((num-1)/size)+1
27+
28-
  return num-(y-1)*size,y
28+
-- gui.Init()
29-
end
29+
-- gui.backend.MessageBox:Create("Game Over", "Draw!"):Modify{ButtonHandle = function() GameForm.Elements["Exit"]:OnElementClick() end}:Init():Paint()
30-
function fromXY(x,y)
30+
-- gui.Destroy()
31-
  return (y-1)*size+x
31+
-- os.exit()
32-
end
32+
33-
function win(s)
33+
local gpu = component.gpu
34-
  gpu.set(90,1,"WIN: "..s)
34+
local event = require("event")
35-
  isEnded=true
35+
----SETTINGS----
36-
end
36+
local cfg = {}
37-
function draw(name,x,y)
37+
cfg.MapWidth = 9
38-
  if name=="x" then
38+
cfg.MapHeight = 9
39-
    gpu.setForeground(0x0000ff)
39+
cfg.WinLine = 5
40-
  elseif name=="o" then
40+
cfg.ReqAuth = true
41-
    gpu.setForeground(0xff0000)
41+
42-
  else
42+
function InRange(value, left, right)
43-
    return
43+
  return left <= value and value <= right
44-
  end
44+
end
45-
  for i=1,3 do
45+
46-
    gpu.set(x,y+i-1,tex[name][i])
46+
function UpdateScreenSettings()
47-
  end
47+
  cfg.ScreenWidth  = cfg.MapWidth  * 8 - 1
48-
  gpu.setForeground(0xffffff)
48+
  cfg.ScreenHeight = cfg.MapHeight * 4 + 1
49-
end
49+
end
50-
function drawField()
50+
51-
  for y=1,size do
51+
function ValidateConfig()
52-
    if y~=size then
52+
  local MaxScreenWidth, MaxScreenHeight
53-
      gpu.set(1,y*4,string.rep("▄",8*size-1))
53+
  MaxScreenWidth, MaxScreenHeight = gpu.maxResolution()
54-
--      gpu.set(y*9,1,string.rep("█",4*size),true)
54+
  UpdateScreenSettings()
55-
    end
55+
  if not InRange(cfg.ScreenWidth, 1, MaxScreenWidth) then
56-
    for x=1,size do
56+
    return "MapWidthError", "out of bounds"
57-
      draw(map[fromXY(x,y)],(x-1)*8+2,(y-1)*4+1)
57+
  end
58-
    end
58+
  
59-
  end
59+
  if not InRange(cfg.ScreenHeight, 1, MaxScreenHeight) then
60-
  for y=1,size-1 do
60+
    return "MapHeightError", "out of bounds"
61-
      gpu.set(y*8,1,string.rep("█",4*size),true)
61+
  end
62-
  end
62+
end
63-
end
63+
64-
require("term").clear()
64+
--UpdateScreenSettings()
65-
drawField()
65+
local err, msg = ValidateConfig()
66-
--os.exit()
66+
if err ~= nil then
67-
67+
  print(err, msg)
68-
function onClick(_,_,x,y,_,name)
68+
  os.exit()
69-
  if (turn=="o")and(name~="astral17") then
69+
end
70-
    return
70+
71-
  end
71+
local map, players, FreeCells, canvas, curPlayer, isRunning
72-
  if isEnded then
72+
73-
    return false
73+
function fromXY(x, y)
74-
  end
74+
  return (y - 1) * cfg.MapWidth + x
75-
  xC=math.floor(x/8)+1
75+
end
76-
  yC=math.floor((y-1)/4)+1
76+
77-
--  gpu.set(1,1,xC.." "..yC)
77+
tex = {
78-
  if (xC>size)or(yC>size) then
78+
  {
79-
    return
79+
    "▄   ▄",
80-
  end
80+
    " ▀▄▀ ",
81-
  num=fromXY(xC,yC)
81+
    "▄▀ ▀▄",
82-
  if map[num]~=" " then
82+
  },
83-
    return
83+
  {
84-
  end
84+
    "  ▄  ",
85-
  map[num]=turn
85+
    "▄▀ ▀▄",
86-
  for i=1,size do
86+
    " ▀▄▀ "
87-
    for j=1,size do
87+
  }
88-
      if (i<=size-len+1)and(j<=size-len+1) then
88+
}
89-
        bool1,bool2=true,true
89+
90-
        s=map[fromXY(i,j)]
90+
function DrawCell(canvas, x, y, id)
91-
        s2=map[fromXY(i+len-1,j)]
91+
  if id == 1 then
92-
        if s==" " then
92+
    gpu.setForeground(0x0000ff)
93-
          bool1=false
93+
  elseif id == 2 then
94-
        end
94+
    gpu.setForeground(0xff0000)
95-
        if s2==" " then
95+
  else
96-
          bool2=false
96+
    return
97-
        end
97+
  end
98-
        for x=0,len-1 do
98+
  for i = 1, 3 do
99-
          if map[fromXY(i+x,j+x)]~=s then
99+
    canvas.set((x - 1) * 8 + 2, (y - 1) * 4 + i, tex[id][i])
100-
            bool1=false
100+
  end
101-
          end
101+
  gpu.setForeground(0xffffff)
102-
--          io.write(i+len-x-1,j+x,map[fromXY(i+len-x-1,j+x)]," ")
102+
end
103-
          if map[fromXY(i+len-x-1,j+x)]~=s2 then
103+
104-
            bool2=false
104+
function GameInit()
105-
          end
105+
  map = {}
106-
        end
106+
  curPlayer = 1
107-
        if (bool1)or(bool2) then
107+
  isRunning = true
108-
          win((bool1 and s)or(bool2 and s2))
108+
  FreeCells = cfg.MapWidth * cfg.MapHeight
109-
          break
109+
  -- event.listen("touch", OnTouch)
110-
        end
110+
end
111-
      end
111+
112-
      if i<=size-len+1 then
112+
local DIRS =
113-
        bool=true
113+
{
114-
        s=map[fromXY(i,j)]
114+
  { 1, 1},
115-
        if s==" " then
115+
  { 1, 0},
116-
          bool=false
116+
  { 0, 1},
117-
        end
117+
  {-1, 1},
118-
        for x=0,len-1 do
118+
}
119-
          if map[fromXY(i+x,j)]~=s then
119+
120-
            bool=false
120+
function MoveHandle(x, y)
121-
            break
121+
  if map[fromXY(x, y)] then
122-
          end
122+
    return false
123-
        end
123+
  end
124-
        if bool then
124+
  map[fromXY(x, y)] = curPlayer
125-
          win(s)
125+
  
126-
          break
126+
  local cnt
127-
        end
127+
  local curX, curY
128-
      end
128+
  for i = 1, 4 do
129-
      if j<=size-len+1 then
129+
    cnt = 0
130-
        bool=true
130+
    local CUR = DIRS[i]
131-
        s=map[fromXY(i,j)]
131+
    curX, curY = x - CUR[1], y - CUR[2]
132-
        if s==" " then
132+
    while InRange(curX, 1, cfg.MapWidth) and InRange(curY, 1, cfg.MapHeight) and map[fromXY(curX, curY)] == curPlayer do
133-
          bool=false
133+
      cnt = cnt + 1
134-
        end
134+
      curX, curY = curX - CUR[1], curY - CUR[2]
135-
        for x=0,len-1 do
135+
    end
136-
          if map[fromXY(i,j+x)]~=s then
136+
    curX, curY = x, y
137-
            bool=false
137+
    while InRange(curX, 1, cfg.MapWidth) and InRange(curY, 1, cfg.MapHeight) and map[fromXY(curX, curY)] == curPlayer do
138-
            break
138+
      cnt = cnt + 1
139-
          end
139+
      curX, curY = curX + CUR[1], curY + CUR[2]
140-
        end
140+
    end
141-
        if bool then
141+
    if cnt >= cfg.WinLine then
142-
          win(s)
142+
      curPlayer = 3 - curPlayer
143-
          break
143+
      return 3 - curPlayer, 3 - curPlayer
144-
        end
144+
    end
145-
      end
145+
  end
146-
    end
146+
  
147-
  end
147+
  FreeCells = FreeCells - 1
148-
  turn=nextTurn[turn]
148+
  if FreeCells == 0 then
149-
  drawField()
149+
    -- print("GG")
150-
--  gpu.set(1,1,turn)
150+
    curPlayer = 3 - curPlayer
151-
end
151+
    return 3 - curPlayer, 0
152-
152+
  end
153-
event.listen("touch",onClick)
153+
  
154-
while true do
154+
  curPlayer = 3 - curPlayer
155-
  _,_,_,_,name=event.pull("key_down")
155+
  return 3 - curPlayer
156-
  if name=="astral17" then
156+
end
157-
    break
157+
158-
  end
158+
function GameExit()
159-
end
159+
  -- event.ignore("touch", OnTouch)
160-
event.ignore("touch",onClick)
160+
end
161
162
-------------------- GUI --------------------
163
gui.Init()
164
165
AuthForm = gui.backend.Form:Create(21, 9,
166
  {
167
    gui.backend.Text:Create(1, 1, 21, "Auth plz..."),
168
    
169
    player1 = gui.backend.Button:Create(1, 3, 10, 3, "", function(self, x, y, b, name)
170
      if self.Text ~= "" then
171
        return
172
      end
173
      self:Modify{BackColor = 0x009900, Text = name}:Paint()
174
      if self.Parent.Elements["player1"].Text ~= "" and self.Parent.Elements["player2"].Text ~= "" then
175
        players[1] = self.Parent.Elements["player1"].Text
176
        players[2] = self.Parent.Elements["player2"].Text
177
        AuthForm:Disable(true)
178
        GameForm:Enable():Paint()
179
      end
180
    end),
181
    player2 = gui.backend.Button:Create(12, 3, 10, 3, "", function(self, x, y, b, name)
182
      if self.Text ~= "" then
183
        return
184
      end
185
      self:Modify{BackColor = 0x009900, Text = name}:Paint()
186
      if self.Parent.Elements["player1"].Text ~= "" and self.Parent.Elements["player2"].Text ~= "" then
187
        players[1] = self.Parent.Elements["player1"].Text
188
        players[2] = self.Parent.Elements["player2"].Text
189
        AuthForm:Disable(true)
190
        GameForm:Enable():Paint()
191
      end
192
    end),
193
    
194
    gui.backend.Button:Create(1, 7, 21, 3, "Back", function()
195
      AuthForm:Disable(true)
196
      MainForm:Enable():Paint()
197
    end),
198
  }
199
):Modify
200
{
201
  OnEnable = function(self)
202
    self.Elements["player1"]:Modify{Text = "", BackColor = 0x666666}
203
    self.Elements["player2"]:Modify{Text = "", BackColor = 0x666666}
204
    players = {}
205
  end,
206
}:Init()
207
208
GameForm = gui.backend.Form:Create(cfg.ScreenWidth, cfg.ScreenHeight,
209
  {
210
    Exit = gui.backend.Button:Create(1, 1, 8, 1, "[Return]", function()
211
      GameExit()
212
      GameForm:Disable(true)
213
      MainForm:Enable():Paint()
214
    end),
215
    
216
    -- status = gui.ba
217
    
218
    canvas = gui.backend.Canvas:Create(1, 2, cfg.ScreenWidth, cfg.ScreenHeight - 1):Modify
219
    {
220
      OnElementClick = function(self, x, y, b, name)
221
        if not isRunning then
222
          return false
223
        end
224
        if cfg.ReqAuth and players[curPlayer] ~= name then
225
          return false
226
        end
227
        x, y = math.floor((x - 1) / 8) + 1, math.floor((y - 1) / 4) + 1
228
        -- print(x, y)
229
        local moved, ended = MoveHandle(x, y)
230
        if moved then
231
          DrawCell(self, x, y, moved)
232
        end
233
        
234
        if ended ~= nil then
235
          isRunning = false
236
          if ended == 0 then
237
            gui.backend.MessageBox:Create("Game Over", "Draw!"):Modify{ButtonHandle = function() GameForm.Elements["Exit"]:OnElementClick() end}:Init():Paint()
238
          else
239
            gui.backend.MessageBox:Create("Game Over", "Winner: "..players[ended]):Modify{ButtonHandle = function() GameForm.Elements["Exit"]:OnElementClick() end}:Init():Paint()
240
          end
241
        end
242
      end,
243
      OnPaint = function(self)
244
        -- for x = 1, cfg.MapWidth do
245
          -- for y = 1, cfg.MapHeight do
246
            -- DrawCell(self, x, y, 1)
247
          -- end
248
        -- end
249
        
250
        for y = 1, cfg.MapHeight - 1 do
251
          self.set(1, y * 4, string.rep("▄",8 * cfg.MapWidth - 1))
252
          -- for x = 1, cfg.mapWidth do
253
            -- draw(map[fromXY(x, y)], (x - 1) * 8 + 2, (y - 1) * 4 + 1)
254
          -- end
255
        end
256
        for x = 1, cfg.MapWidth - 1 do
257
            self.set(x * 8, 1, string.rep("█", 4 * cfg.MapHeight - 1).."▀", true)
258
        end
259
      end,
260
    },
261
    
262
    -- algo = gui.backend.Text:Create(10, 1, nil, cfg.Algorithm),
263
  }
264
):Modify
265
{
266
  OnPaint = function(self)
267
    self.Width  = cfg.ScreenWidth
268
    self.Height = cfg.ScreenHeight
269
    self.Elements["canvas"].Width  = cfg.ScreenWidth
270
    self.Elements["canvas"].Height = cfg.ScreenHeight - 1
271
  end,
272
  OnEnable = function(self)
273
    if not cfg.ReqAuth then
274
      players = {"x", "o"}
275
    end
276
    GameInit()
277
  end,
278
}:Init()
279
280
SettingsForm = gui.backend.Form:Create(20, 16,
281
  {
282
    gui.backend.Text:Create(1, 1, 20, "Settings"),
283
    
284
    gui.backend.Text:Create(1, 3, nil, "Width"),
285
    MapWidth = gui.backend.TextBox:Create(1, 4, 20, cfg.MapWidth .. "", "0123456789"),
286
    MapWidthError = gui.backend.Text:Create(1, 5, nil, ""):Modify{TextColor = 0xff0000},
287
    
288
    gui.backend.Text:Create(1, 6, nil, "Height"),
289
    MapHeight = gui.backend.TextBox:Create(1, 7, 20, cfg.MapHeight .. "", "0123456789"),
290
    MapHeightError = gui.backend.Text:Create(1, 8, nil, ""):Modify{TextColor = 0xff0000},
291
    
292
    gui.backend.Text:Create(1, 9, nil, "WinLine"),
293
    WinLine = gui.backend.TextBox:Create(1, 10, 20, cfg.WinLine .. "", "0123456789"),
294
    WinLineError = gui.backend.Text:Create(1, 11, nil, ""):Modify{TextColor = 0xff0000},
295
    
296
    ReqAuth = gui.backend.CheckBox:Create(1, 12, 0, "Require Auth", cfg.ReqAuth),
297
    
298
    gui.backend.Button:Create(1, 14, 20, 3, "Back", function()
299
      cfg.MapWidth = SettingsForm.Elements["MapWidth"].Text + 0
300
      cfg.MapHeight = SettingsForm.Elements["MapHeight"].Text + 0
301
      cfg.WinLine = SettingsForm.Elements["WinLine"].Text + 0
302
      cfg.ReqAuth = SettingsForm.Elements["ReqAuth"].Checked
303
      SettingsForm.Elements["MapWidthError"]:Modify{Text = ""}:Paint()
304
      SettingsForm.Elements["MapWidth"]:Modify{TextColor = 0xffffff}:Paint()
305
      SettingsForm.Elements["MapHeightError"]:Modify{Text = ""}:Paint()
306
      SettingsForm.Elements["MapHeight"]:Modify{TextColor = 0xffffff}:Paint()
307
      SettingsForm.Elements["WinLineError"]:Modify{Text = ""}:Paint()
308
      SettingsForm.Elements["WinLine"]:Modify{TextColor = 0xffffff}:Paint()
309
      
310
      local err, msg = ValidateConfig()
311
      if err ~= nil then
312
        SettingsForm.Elements[err]:Modify{Text = msg}:Paint()
313
        SettingsForm.Elements[unicode.sub(err, 1, -6)]:Modify{TextColor = 0xff0000}:Paint()
314
        return false
315
      end
316
      SettingsForm:Disable(true)
317
      MainForm:Enable():Paint()
318
    end),
319
  }
320
):Init()
321
322
MainForm = gui.backend.Form:Create(20, 11,
323
  {
324
    gui.backend.Button:Create(1, 1, 20, 3, "Start", function()
325
      MainForm:Disable(true)
326
      if cfg.ReqAuth then
327
        AuthForm:Enable():Paint()
328
      else
329
        GameForm:Enable():Paint()
330
      end
331
    end),
332
    gui.backend.Button:Create(1, 5, 20, 3, "Settings", function() MainForm:Disable(true) SettingsForm:Enable():Paint() end),
333
    gui.backend.Button:Create(1, 9, 20, 3, "Exit", function() quit = true end),
334
  }
335
):Init():Enable():Paint()
336
337
canvas = GameForm.Elements["canvas"]
338
quit = false
339
pcall(function()
340
  while not quit do
341
    event.pull()
342
  end
343
end)
344
345
-- event.ignore("touch", OnTouch)
346
gui.Destroy()