View difference between Paste ID: Ur5Q8nDd and hABYHWwr
SHOW: | | - or go back to the newest paste.
1-
local gpu=require("component").gpu
1+
local AGUI_VERSION = "0.6"
2-
local event=require("event")
2+
local component = require("component")
3-
3+
local success, gui
4-
fieldWidth=20
4+
repeat
5-
fieldHeight=26
5+
  success, gui = pcall(require, "AGUI")
6-
6+
  if not success then
7-
width=30 --width of mas NOT field
7+
    print(gui)
8-
8+
    io.write("For the application need a library AGUI (https://pastebin.com/s4UFSFwn).\n")
9-
mas={}
9+
    if not component.isAvailable("internet") then
10-
10+
      os.exit()
11-
StockBlocks = { { start_position = { x = 4, y = 1 },
11+
    end
12-
                  color = { 175, 175, 0 },
12+
    io.write("Do you want to install?[Y/n] ")
13-
                  symbol = "T",
13+
    if not ((io.read() or "n").."y"):match("^%s*[Yy]") then
14-
                  transformations = { { { x = -1, y = 0 },
14+
      os.exit()
15-
                                        { x = 0, y = 0 },
15+
    end
16-
                                        { x = 1, y = 0 },
16+
    loadfile("/bin/wget.lua")("https://pastebin.com/raw/s4UFSFwn", "/lib/AGUI.lua", "-f")
17-
                                        { x = 0, y = -1 } },
17+
  end
18-
                                      { { x = 0, y = 0 },
18+
until success
19-
                                        { x = 0, y = -1 },
19+
20-
                                        { x = 0, y = 1 },
20+
if gui.Version ~= AGUI_VERSION then
21-
                                        { x = 1, y = 0 } },
21+
  io.write("Recommended version of AGUI library ("..AGUI_VERSION..") does not match installed ("..(gui.Version or "unknown")..")\n")
22-
                                      { { x = -1, y = 0 },
22+
  io.write("Do you want to continue?[Y/n] ")
23-
                                        { x = 0, y = 0 },
23+
    if not ((io.read() or "n").."y"):match("^%s*[Yy]") then
24-
                                        { x = 1, y = 0 },
24+
      os.exit()
25-
                                        { x = 0, y = 1 } },
25+
    end
26-
                                      { { x = 0, y = 0 },
26+
end
27-
                                        { x = 0, y = -1 },
27+
28-
                                        { x = 0, y = 1 },
28+
local gpu = component.gpu
29-
                                        { x = -1, y = 0 } } } },
29+
local event = require("event")
30-
                { start_position = { x = 4, y = 1 },
30+
31-
                  color = { 0, 255, 0 },
31+
------SETTINGS-------
32-
                  symbol = "Z",
32+
local cfg = {}
33-
                  transformations = { { { x = -1, y = 0 },
33+
cfg.mapWidth = 10
34-
                                        { x = 0, y = 0 },
34+
cfg.mapHeight = 20
35-
                                        { x = 0, y = -1 },
35+
cfg.startX = gui.GetCenter(1, cfg.mapWidth, 1) - 1
36-
                                        { x = 1, y = -1 } },
36+
cfg.drawShadow = true
37-
                                      { { x = 0, y = -1 },
37+
cfg.shadowColor = 0x222222
38-
                                        { x = 0, y = 0 },
38+
cfg.tickDelay = 0.1
39-
                                        { x = 1, y = 0 },
39+
cfg.fallTickCnt = 3
40-
                                        { x = 1, y = 1 } } } },
40+
cfg.fallLinesDelay = 0.3
41-
                { start_position = { x = 4, y = 1 }, 
41+
cfg.backColor = 0x000000
42-
                  color = { 100, 100, 175 },
42+
--
43-
                  symbol = "S",
43+
function InRange(value, left, right)
44-
                  transformations = { { { x = 1, y = 0 },
44+
  return left <= value and value <= right
45-
                                        { x = 0, y = 0 },
45+
end
46-
                                        { x = 0, y = -1 },
46+
47-
                                        { x = -1, y = -1 } },
47+
function ValidateConfig()
48-
                                      { { x = 0, y = 1 },
48+
  local MaxScreenWidth, MaxScreenHeight
49-
                                        { x = 0, y = 0 },
49+
  MaxScreenWidth, MaxScreenHeight = gpu.maxResolution()
50-
                                        { x = 1, y = 0 },
50+
  
51-
                                        { x = 1, y = -1 } } } },
51+
  if not InRange(cfg.mapWidth * 2 + 12, 22, MaxScreenWidth) then
52-
                { start_position = { x = 4, y = 0 }, 
52+
    return "MapWidthError", "out of bounds"
53-
                  color = { 255, 255, 100 },
53+
  end
54-
                  symbol = "J",
54+
  
55-
                  transformations = { { { x = -1, y = 0 },
55+
  if not InRange(cfg.mapHeight, 15, MaxScreenHeight) then
56-
                                        { x = 0, y = 0 },
56+
    return "MapHeightError", "out of bounds"
57-
                                        { x = 1, y = 0 },
57+
  end
58-
                                        { x = -1, y = 1 } },
58+
end
59-
                                      { { x = 0, y = -1 },
59+
60-
                                        { x = 0, y = 0 },
60+
--UpdateScreenSettings()
61-
                                        { x = 0, y = 1 },
61+
local err, msg = ValidateConfig()
62-
                                        { x = 1, y = 1 } },
62+
if err ~= nil then
63-
                                      { { x = -1, y = 0 },
63+
  print(err, msg)
64-
                                        { x = 0, y = 0 },
64+
  os.exit()
65-
                                        { x = 1, y = 0 },
65+
end
66-
                                        { x = 1, y = -1 } },
66+
--
67-
                                      { { x = 0, y = -1 },
67+
68-
                                        { x = 0, y = 0 },
68+
linePoints = {[0] = 0, [1] = 10, [2] = 25, [3] = 50, [4] = 100}
69-
                                        { x = 0, y = 1 },
69+
---------------------
70-
                                        { x = -1, y = -1 } } } },
70+
-- function centerText(x,y,w,text)
71-
                { start_position = { x = 4, y = 0 },
71+
  -- gpu.set(x+math.floor(w/2-string.len(text)/2),y,text)
72-
                  color = { 255, 0, 255 },
72+
-- end
73-
                  symbol = "L",
73+
74-
                  transformations = { { { x = -1, y = 0 },
74+
-- function messageBox(title,text,color)
75-
                                        { x = 0, y = 0 },
75+
  -- local x,y=cfg.mapWidth-9,math.floor(cfg.mapHeight/2)-3
76-
                                        { x = 1, y = 0 },
76+
  -- local len1,len2=string.len(title),string.len(text)
77-
                                        { x = 1, y = 1 } },
77+
  -- local len3=math.max(len1,len2)+2
78-
                                      { { x = 0, y = -1 },
78+
  -- gpu.setBackground(0xffffff)
79-
                                        { x = 0, y = 0 },
79+
  -- gpu.fill(x,y,len3,2+3," ")
80-
                                        { x = 0, y = 1 },
80+
  -- gpu.setForeground(color or 0xFF0000)
81-
                                        { x = 1, y = -1 } },
81+
  -- centerText(x,y+1,len3,title)
82-
                                      { { x = -1, y = 0 },
82+
  -- gpu.setForeground(0x000000)
83-
                                        { x = 0, y = 0 },
83+
  -- centerText(x,y+3,len3,text)
84-
                                        { x = 1, y = 0 },
84+
  -- gpu.setBackground(color or 0xFF0000)
85-
                                        { x = -1, y = -1 } },
85+
  -- gpu.setForeground(0xffffff)
86-
                                      { { x = 0, y = -1 },
86+
  -- gpu.fill(x,y+5,len3,3," ")
87-
                                        { x = 0, y = 0 },
87+
  -- centerText(x,y+6,len3,"OK!")
88-
                                        { x = 0, y = 1 },
88+
-- end
89-
                                        { x = -1, y = 1 } } } },
89+
----------------------------------------------------------------
90-
                { start_position = { x = 4, y = 0 },
90+
StockBlocks = { { start_position = { x = 1, y = 1 },
91-
                  color = { 255, 0, 0 },
91+
                  color = 0xFFFF00,
92-
                  symbol = "I",
92+
                  symbol = "T",
93-
                  transformations = { { { x = -1, y = 0 },
93+
                  transformations = { { { x = -1, y = 0 },
94-
                                        { x = 0, y = 0 },
94+
                                        { x = 0, y = 0 },
95-
                                        { x = 1, y = 0 },
95+
                                        { x = 1, y = 0 },
96-
                                        { x = 2, y = 0 } },
96+
                                        { x = 0, y = -1 } },
97-
                                      { { x = 0, y = -1 },
97+
                                      { { x = 0, y = 0 },
98-
                                        { x = 0, y = 0 },
98+
                                        { x = 0, y = -1 },
99-
                                        { x = 0, y = 1 },
99+
                                        { x = 0, y = 1 },
100-
                                        { x = 0, y = 2 } } } },
100+
                                        { x = -1, y = 0 } },
101-
                { start_position = { x = 4, y = 0 },
101+
                                      { { x = -1, y = 0 },
102-
                  color = { 0, 0, 255 },
102+
                                        { x = 0, y = 0 },
103-
                  symbol = "[]",
103+
                                        { x = 1, y = 0 },
104-
                  transformations = { { { x = 0, y = 0 },
104+
                                        { x = 0, y = 1 } },
105-
                                        { x = 0, y = 1 },
105+
                                      { { x = 0, y = 0 },
106-
                                        { x = 1, y = 0 },
106+
                                        { x = 0, y = -1 },
107-
                                        { x = 1, y = 1 } } } }
107+
                                        { x = 0, y = 1 },
108-
             }
108+
                                        { x = 1, y = 0 } } } },
109-
109+
                                        
110-
function toXY(num,wid)
110+
                { start_position = { x = 1, y = 1 },
111-
  wid=wid or width
111+
                  color = 0x00FF00,
112-
  y=math.floor((num-1)/wid)+1
112+
                  symbol = "Z",
113-
  return num-(y-1)*width,y
113+
                  transformations = { { { x = -1, y = 0 },
114-
end
114+
                                        { x = 0, y = 0 },
115-
function fromXY(x,y,wid)
115+
                                        { x = 0, y = -1 },
116-
  wid=wid or width
116+
                                        { x = 1, y = -1 } },
117-
  return (y-1)*wid+x
117+
                                      { { x = 0, y = -1 },
118-
end
118+
                                        { x = 0, y = 0 },
119-
119+
                                        { x = 1, y = 0 },
120-
for i=-1000,2500 do
120+
                                        { x = 1, y = 1 } } } },
121-
  mas[i]=0
121+
                { start_position = { x = 1, y = 1 }, 
122-
end
122+
                  color = 0x9999CC,
123-
--print(StockBlocks[1].transformations[1][1].y)
123+
                  symbol = "S",
124-
--[[f=7
124+
                  transformations = { { { x = 1, y = 0 },
125-
tr=1
125+
                                        { x = 0, y = 0 },
126-
for i=1,4 do
126+
                                        { x = 0, y = -1 },
127-
  gpu.set(StockBlocks[f].transformations[tr][i].x+5,StockBlocks[f].transformations[tr][i].y+5,"!")
127+
                                        { x = -1, y = -1 } },
128-
end]]--
128+
                                      { { x = 0, y = 1 },
129-
obj={
129+
                                        { x = 0, y = 0 },
130-
  id=-1,
130+
                                        { x = 1, y = 0 },
131-
  x=-1,
131+
                                        { x = 1, y = -1 } } } },
132-
  y=-1,
132+
                { start_position = { x = 1, y = 0 }, 
133-
  dX=0,
133+
                  color = 0xFFFF99,
134-
  dY=0,
134+
                  symbol = "J",
135-
  dR=0,
135+
                  transformations = { { { x = -1, y = 0 },
136-
  rotate=-1,
136+
                                        { x = 0, y = 0 },
137-
}
137+
                                        { x = 1, y = 0 },
138-
function newTile(tile)
138+
                                        { x = -1, y = 1 } },
139-
  tile=tile or (math.random(1,7))
139+
                                      { { x = 0, y = -1 },
140-
  obj.id=tile
140+
                                        { x = 0, y = 0 },
141-
  obj.x,obj.y=StockBlocks[tile].start_position.x+5,StockBlocks[tile].start_position.y
141+
                                        { x = 0, y = 1 },
142-
  obj.rotate=1
142+
                                        { x = 1, y = 1 } },
143-
  if test() then
143+
                                      { { x = -1, y = 0 },
144-
    gpu.setForeground(0xff0000)
144+
                                        { x = 0, y = 0 },
145-
    gpu.set(10,1,"GAME OVER")
145+
                                        { x = 1, y = 0 },
146-
    os.sleep(0.5)
146+
                                        { x = 1, y = -1 } },
147-
    gpu.setForeground(0xffffff)
147+
                                      { { x = 0, y = -1 },
148-
    isRunning=false
148+
                                        { x = 0, y = 0 },
149-
  else
149+
                                        { x = 0, y = 1 },
150-
    clearLines()
150+
                                        { x = -1, y = -1 } } } },
151-
  end
151+
                { start_position = { x = 1, y = 0 },
152-
--  print("!")
152+
                  color = 0xFF00FF,
153-
end
153+
                  symbol = "L",
154-
function drawBlock(x,y,color)
154+
                  transformations = { { { x = -1, y = 0 },
155-
  gpu.set((x-1)*2+1,y,"  ")
155+
                                        { x = 0, y = 0 },
156-
end
156+
                                        { x = 1, y = 0 },
157-
function drawTile(color)
157+
                                        { x = 1, y = 1 } },
158-
  gpu.setBackground(color or 0x005500)
158+
                                      { { x = 0, y = -1 },
159-
--  print(obj.id,obj.rotate)
159+
                                        { x = 0, y = 0 },
160-
  for i=1,4 do
160+
                                        { x = 0, y = 1 },
161-
    drawBlock(StockBlocks[obj.id].transformations[obj.rotate][i].x+obj.x,StockBlocks[obj.id].transformations[obj.rotate][i].y+obj.y)
161+
                                        { x = 1, y = -1 } },
162-
  end
162+
                                      { { x = -1, y = 0 },
163-
  gpu.setBackground(0x000000)
163+
                                        { x = 0, y = 0 },
164-
end
164+
                                        { x = 1, y = 0 },
165-
function testLine(line)
165+
                                        { x = -1, y = -1 } },
166-
  for x=1,fieldWidth-1 do
166+
                                      { { x = 0, y = -1 },
167-
    if mas[fromXY(x,line)]==0 then
167+
                                        { x = 0, y = 0 },
168-
      return false
168+
                                        { x = 0, y = 1 },
169-
    end
169+
                                        { x = -1, y = 1 } } } },
170-
  end
170+
                { start_position = { x = 1, y = 0 },
171-
  return true
171+
                  color = 0xFF0000,
172-
end
172+
                  symbol = "I",
173-
function clearLines()
173+
                  transformations = { { { x = -1, y = 0 },
174-
--  gpu.set(90,1,"!")
174+
                                        { x = 0, y = 0 },
175-
  for i=1,fieldHeight do
175+
                                        { x = 1, y = 0 },
176-
    if testLine(i) then
176+
                                        { x = 2, y = 0 } },
177-
      downTiles(i)
177+
                                      { { x = 0, y = -1 },
178-
--      gpu.set(90,2,"!")
178+
                                        { x = 0, y = 0 },
179-
      gpu.set(1,i,string.rep(" ",fieldWidth*2-2))
179+
                                        { x = 0, y = 1 },
180-
      os.sleep(0.5)
180+
                                        { x = 0, y = 2 } } } },
181-
      gpu.copy(1,i-20,fieldWidth*2-1,20,0,1)
181+
                { start_position = { x = 1, y = 0 },
182-
    end
182+
                  color = 0x0000FF,
183-
  end
183+
                  symbol = "[]",
184-
end
184+
                  transformations = { { { x = 0, y = 0 },
185-
function downTiles(line)
185+
                                        { x = 0, y = 1 },
186-
  for i=line,1,-1 do
186+
                                        { x = 1, y = 0 },
187-
    for j=1,fieldWidth+2 do
187+
                                        { x = 1, y = 1 } } } }
188-
      mas[fromXY(j,i)]=mas[fromXY(j,i-1)]
188+
             }
189-
    end
189+
190-
  end
190+
local width = cfg.mapWidth + 10 --width of map NOT field
191-
end
191+
local score -- = 0
192-
function test()
192+
local map -- = {}
193-
  for i=1,4 do
193+
local control
194-
    local x,y=StockBlocks[obj.id].transformations[obj.rotate][i].x+obj.x,StockBlocks[obj.id].transformations[obj.rotate][i].y+obj.y
194+
local tick
195-
    if (y==fieldHeight)or(mas[fromXY(x,y)]~=0)or(x>=fieldWidth)or(x<1) then
195+
local isRunning = false
196-
      return true
196+
local isInited = false
197-
    end
197+
198-
  end
198+
function toXY(num,wid)
199-
  return false
199+
  wid=wid or width
200-
end
200+
  y=math.floor((num-1)/wid)+1
201-
function putInMap()
201+
  return num-(y-1)*width,y
202-
  for j=1,4 do
202+
end
203-
    mas[fromXY(StockBlocks[obj.id].transformations[obj.rotate][j].x+obj.x,StockBlocks[obj.id].transformations[obj.rotate][j].y+obj.y)]=1
203+
function fromXY(x,y,wid)
204-
  end
204+
  wid = wid or width
205-
end
205+
  return (y-1)*wid+x
206-
function mapUpdate()
206+
end
207-
  drawTile(0x000000)
207+
208-
  if step2 then
208+
-- TODO DELETE
209-
    obj.y=obj.y+1
209+
-- for i=-1000,2500 do
210-
  end
210+
  -- map[i]=0
211-
--  obj.x=obj.x+obj.dX
211+
-- end
212-
  if (test())and(step2) then
212+
--print(StockBlocks[1].transformations[1][1].y)
213-
--    obj.x=obj.x-obj.dX
213+
--[[f=7
214-
      obj.y=obj.y-1
214+
tr=1
215-
    drawTile()
215+
for i=1,4 do
216-
    putInMap()
216+
  gpu.set(StockBlocks[f].transformations[tr][i].x+5,StockBlocks[f].transformations[tr][i].y+5,"!")
217-
    newTile()
217+
end]]--
218-
  else
218+
local fObj, nextObj, sObj
219-
    if obj.dY==1 then
219+
local gCanvas, pCanvas
220-
      drawTile(0x000000)
220+
221-
      obj.y=obj.y+1
221+
local scoreObj
222-
      if test() then
222+
function GetScore()
223-
        obj.y=obj.y-1
223+
  return tonumber(scoreObj.Text)
224-
        drawTile()
224+
end
225-
        putInMap()
225+
226-
        newTile()
226+
function SetScore(value)
227-
      end
227+
  scoreObj:Modify{Text = tostring(value)}:Paint()
228-
    end
228+
end
229-
    if obj.dX~=0 then
229+
230-
      drawTile(0x000000)
230+
function IncreaseScore(amount)
231-
      obj.x=obj.x+obj.dX
231+
  SetScore(GetScore() + amount)
232-
      if test() then
232+
end
233-
        obj.x=obj.x-obj.dX
233+
234-
      end
234+
function randomID()
235-
    end
235+
  -- return 6
236-
    if obj.dR~=0 then
236+
  return math.random(1, 7)
237-
      local tmp=obj.rotate
237+
end
238-
      drawTile(0x000000)
238+
239-
      obj.rotate=(obj.rotate+#StockBlocks[obj.id].transformations)%(#StockBlocks[obj.id].transformations)+1
239+
function createObject(id, x, y)
240-
      if test() then
240+
  id = id or randomID()
241-
        obj.rotate=tmp
241+
  local obj = {}
242-
      end
242+
  obj.id = id
243-
--      obj.rotate=obj.rotate+1
243+
  obj.x, obj.y = StockBlocks[id].start_position.x + (x or cfg.startX), StockBlocks[id].start_position.y + (y or 0)
244-
    end
244+
  obj.color = StockBlocks[id].color
245-
  end
245+
  obj.rotate = 1
246-
  obj.dX=0
246+
  return obj
247-
  obj.dY=0
247+
end
248-
  obj.dR=0
248+
249-
  drawTile()
249+
function cloneObject(obj, x, y, r)
250-
end
250+
  local nObj = {}
251-
function onKey(ev,_,code1,code2,player)
251+
  for index, value in pairs(obj) do
252-
  if (code1==113)and(code2==16) then
252+
    nObj[index] = value
253-
    isRunning=false
253+
  end
254-
  elseif (code1==0) then
254+
  nObj.x = nObj.x + (x or 0)
255-
    if code2==203 then--left
255+
  nObj.y = nObj.y + (y or 0)
256-
      obj.dX=-1
256+
  nObj.rotate = (nObj.rotate - 1 + (r or 0) + #StockBlocks[obj.id].transformations) % (#StockBlocks[obj.id].transformations) + 1
257-
    elseif code2==200 then--up
257+
  return nObj
258-
      obj.dR=1
258+
end
259-
    elseif code2==205 then--right
259+
260-
      obj.dX=1
260+
function createShadow(obj)
261-
    elseif code2==208 then--down
261+
  local sObj = cloneObject(obj)
262-
      obj.dY=1
262+
  while check(sObj) do
263-
    end
263+
    sObj.y = sObj.y + 1
264-
  end
264+
  end
265-
end
265+
  sObj.y = sObj.y - 1
266-
newTile()
266+
  return sObj
267-
drawTile()
267+
end
268-
isRunning=true
268+
269-
event.ignore("key_down",onKey)
269+
function drawBlock(canvas, x, y, color)
270-
event.listen("key_down",onKey)
270+
  canvas.set(x * 2 - 1, y, "  ")
271-
step2=false
271+
end
272-
gpu.setBackground(0x222222)
272+
273-
require("term").clear()
273+
function drawObject(canvas, obj, color)
274-
gpu.setBackground(0x000000)
274+
  gpu.setBackground(color or obj.color)
275-
gpu.fill(1,1,fieldWidth*2-2,fieldHeight-1," ")
275+
  for i = 1, 4 do
276-
while isRunning do
276+
    drawBlock(canvas, StockBlocks[obj.id].transformations[obj.rotate][i].x + obj.x,StockBlocks[obj.id].transformations[obj.rotate][i].y + obj.y)
277-
  step2=not step2
277+
  end
278-
  os.sleep(0.15)
278+
  gpu.setBackground(0x000000)
279-
  mapUpdate()
279+
end
280-
--  for i=1,fieldWidth do
280+
281-
--    gpu.set(70+i,3,tostring(mas[fromXY(i,25)]))
281+
function drawPredict(obj)
282-
--  end
282+
  gpu.setBackground(cfg.backColor)
283-
end
283+
  pCanvas.fill(1, 1, 8, 4, " ")
284-
event.ignore("key_down",onKey)
284+
  drawObject(pCanvas, obj)
285
end
286
287
function checkLine(line)
288
  for x = 1, cfg.mapWidth do
289
    if not map[fromXY(x, line)] then
290
      return false
291
    end
292
  end
293
  return true
294
end
295
296
function fallBlocks(line)
297
  for i = line, 1, -1 do
298
    for j = 1, cfg.mapWidth do
299
      map[fromXY(j,i)] = map[fromXY(j,i-1)]
300
    end
301
  end
302
end
303
304
function clearLines()
305
  local cnt, offset = 0, 0
306
  -- for i = cfg.mapHeight, 1, -1 do
307
    -- if checkLine(i) then
308
      -- cnt = cnt + 1
309
      -- offset = offset + 1
310
      -- gpu.set(1, i - offset, string.rep(" ", cfg.mapWidth * 2))
311
      -- os.sleep(cfg.fallLinesDelay)
312
      -- gpu.copy(1, i - cfg.mapHeight, cfg.mapWidth * 2, cfg.mapHeight, 0, 1)
313
    -- end
314
    -- if offset > 0 then
315
      -- for j = 1, cfg.mapWidth do
316
        -- map[fromXY(j, i - offset)] = map[fromXY(j, i)]
317
      -- end
318
    -- end
319
  -- end
320
  for i = 1, cfg.mapHeight do
321
    if checkLine(i) then
322
      cnt = cnt + 1
323
      fallBlocks(i) -- ... TODO SPEEDUP
324
      gpu.set(1, i, string.rep(" ", cfg.mapWidth * 2))
325
      os.sleep(cfg.fallLinesDelay)
326
      gpu.copy(1, i - cfg.mapHeight, cfg.mapWidth * 2, cfg.mapHeight, 0, 1)
327
    end
328
  end
329
  return cnt
330
end
331
332
function check(obj)
333
  for i = 1, 4 do
334
    local x, y = StockBlocks[obj.id].transformations[obj.rotate][i].x + obj.x, StockBlocks[obj.id].transformations[obj.rotate][i].y + obj.y
335
    if (y == cfg.mapHeight + 1) or (map[fromXY(x,y)]) or (x > cfg.mapWidth) or (x < 1) then
336
      return false
337
    end
338
  end
339
  return true
340
end
341
342
function putInMap(obj)
343
  for j = 1, 4 do
344
    map[fromXY(StockBlocks[obj.id].transformations[obj.rotate][j].x + obj.x, StockBlocks[obj.id].transformations[obj.rotate][j].y + obj.y)] = 1
345
  end
346
end
347
348
function GameInit()
349
  map = {}
350
  control = {}
351
  SetScore(0)
352
  fObj = createObject()
353
  sObj = createShadow(fObj)
354
  nextObj = createObject(nil, 1, 2)
355
  tick = 0
356
end
357
358
function DrawMap()
359
  -- gpu.setBackground(0x222222)
360
  -- require("term").clear()
361
  gpu.setBackground(cfg.backColor)
362
  gCanvas:Paint()
363
  -- gpu.fill(1, 1, cfg.mapWidth * 2, cfg.mapHeight, " ")
364
  drawPredict(nextObj)
365
  if cfg.drawShadow then
366
    drawObject(gCanvas, sObj, cfg.shadowColor)
367
  end
368
end
369
370
function GameHandle()
371
  local dX = 0
372
  local dY = 0
373
  local dR = 0
374
  if control.l then
375
    dX = dX - 1
376
  end
377
  if control.r then
378
    dX = dX + 1
379
  end
380
  if control.d then
381
    dY = 1
382
  end
383
  if control.u then
384
    dR = -1
385
    control.u = false
386
  end
387
  -- control = {}
388
389
  tick = (tick + 1) % cfg.fallTickCnt
390
  
391
  local moved = false
392
  local shadowMoved = false
393
  local tObj = cloneObject(fObj)
394
  
395
  if dX ~= 0 then
396
    fObj.x = fObj.x + dX
397
    if not check(fObj) then
398
      fObj.x = fObj.x - dX
399
    else
400
      moved = true
401
      shadowMoved = true
402
    end
403
  end
404
  if dR ~= 0 then
405
    fObj.rotate = (fObj.rotate - 1 + dR + #StockBlocks[fObj.id].transformations) % (#StockBlocks[fObj.id].transformations) + 1
406
    if not check(fObj) then
407
      fObj.rotate = (fObj.rotate - 1 - dR + #StockBlocks[fObj.id].transformations) % (#StockBlocks[fObj.id].transformations) + 1
408
    else
409
      moved = true
410
      shadowMoved = true
411
    end
412
  end
413
  
414
  local freeze = false
415
  if dY ~= 0 then
416
    tick = 0
417
    fObj.y = fObj.y + dY
418
    if not check(fObj) then
419
      freeze = true
420
      fObj.y = fObj.y - dY
421
    else
422
      moved = true
423
    end
424
  elseif tick == 0 then
425
    fObj.y = fObj.y + 1
426
    if not check(fObj) then
427
      freeze = true
428
      fObj.y = fObj.y - 1
429
    else
430
      moved = true
431
    end
432
  end
433
  
434
  if cfg.drawShadow and shadowMoved then
435
    drawObject(gCanvas, sObj, cfg.backColor)
436
    sObj = createShadow(fObj)
437
    drawObject(gCanvas, sObj, cfg.shadowColor)
438
  end
439
  if moved then
440
    drawObject(gCanvas, tObj, cfg.backColor)
441
    drawObject(gCanvas, fObj)
442
  end
443
  if freeze then
444
    putInMap(fObj)
445
    IncreaseScore(linePoints[clearLines()])
446
    fObj = nextObj
447
    fObj.x, fObj.y = StockBlocks[fObj.id].start_position.x + cfg.startX, StockBlocks[fObj.id].start_position.y
448
    if not check(fObj) then
449
      gui.backend.MessageBox:Create("GAME OVER", "Your score: "..GetScore()):Modify{ScreenWidth = cfg.mapWidth * 2, ScreenHeight = cfg.mapHeight}:Init():Paint()
450
      -- messageBox("GAME OVER","Your score: "..GetScore())
451
      -- gpu.setForeground(0xffffff)
452
      isRunning = false
453
    else
454
      clearLines()
455
    end
456
    if cfg.drawShadow then
457
      sObj = createShadow(fObj)
458
      drawObject(gCanvas, sObj, cfg.shadowColor)
459
    end
460
    drawObject(gCanvas, fObj)
461
    nextObj = createObject(nil, 1, 2)
462
    drawPredict(nextObj)
463
  end
464
  
465
  os.sleep(cfg.tickDelay)
466
end
467
468
function onKeyDown(ev, _, code1, code2, player)
469
  if (code1==113)and(code2==16) then
470
    isRunning = false -- TODO REMOVE
471
  elseif (code1==0) then
472
    if code2 == 203 then--left
473
      control.l = true
474
    elseif code2==200 then--up
475
      control.u = true
476
    elseif code2==205 then--right
477
      control.r = true
478
    elseif code2==208 then--down
479
      control.d = true
480
    end
481
  end
482
end
483
484
function onKeyUp(ev, _, code1, code2, player)
485
  if code2 == 203 then--left
486
    control.l = false
487
  elseif code2==200 then--up
488
    -- control.u = false
489
  elseif code2==205 then--right
490
    control.r = false
491
  elseif code2==208 then--down
492
    control.d = false
493
  end
494
end
495
-------------------- GUI --------------------
496
local quit = false
497
gui.Init()
498
499
GameForm = gui.backend.Form:Create(cfg.mapWidth * 2 + 12, cfg.mapHeight,
500
  {
501
    canvas = gui.backend.Canvas:Create(1, 1, cfg.mapWidth * 2, cfg.mapHeight),
502
    panel = gui.CreateGroup(
503
    {
504
      OnPaint = function(self)
505
        gpu.setBackground(0x222222)
506
        gpu.fill(self.X, 1, self.Width, cfg.mapHeight, " ")
507
      end
508
    },
509
    {
510
      canvas = gui.backend.Canvas:Create(3, 1, 8, 4),
511
      gui.backend.Text:Create(1, 6, 12, "Score:"):Modify{BackColor = 0x222222},
512
      score = gui.backend.Text:Create(1, 7, 12, "0"):Modify{BackColor = 0x222222},
513
      -- gui.backend.CheckBox:Create(1, 9, 12, "Shadow", true):Modify{BackColor = 0x222222},
514
      gui.backend.Button:Create(1, 9, 12, 1, "New Game", function(self)
515
        -- if isRunning then
516
          -- self.Text = "Start"
517
        -- else
518
          -- self.Text = "Restart"
519
        -- end
520
        -- self:Paint()
521
        -- gpu.set(1, 1, self.Parent.Elements["pause"].X .. " " .. self.Parent.Elements["pause"].Y)os.sleep(1)
522
        self.Parent.Elements["pause"]:Modify{Text = "Pause"}:Paint()
523
        GameInit()
524
        DrawMap()
525
        isInited = true
526
        isRunning = true
527
      end),
528
      pause = gui.backend.Button:Create(1, 11, 12, 1, "Pause", function(self)
529
        if not isInited then
530
          return
531
        end
532
        if isRunning then
533
          self.Text = "Resume"
534
        else
535
          self.Text = "Pause"
536
        end
537
        -- isRunning = false
538
        isRunning = not isRunning
539
        self:Paint()
540
      end),
541
      gui.backend.Button:Create(1, 13, 12, 1, "Settings", function(self)
542
        -- self.Parent.Elements["pause"]:OnElementClick()
543
        isRunning = false
544
        isInited = false
545
        self.Parent.Elements["pause"].Text = "Pause"
546
        GameForm:Disable(true)
547
        SettingsForm:Enable():Paint()
548
      end),
549
      gui.backend.Button:Create(1, 15, 12, 1, "Exit", function() quit = true end),
550
    }, cfg.mapWidth * 2 + 1, gui.GetCenter(1, cfg.mapHeight, 15), 12, cfg.mapHeight),
551
  }
552
):Init()
553
554
SettingsForm = gui.backend.Form:Create(20, 13,
555
  {
556
    gui.backend.Text:Create(1, 1, 20, "Settings"),
557
    
558
    gui.backend.Text:Create(1, 3, nil, "Width"),
559
    MapWidth = gui.backend.TextBox:Create(1, 4, 20, cfg.mapWidth .. "", "0123456789"),
560
    MapWidthError = gui.backend.Text:Create(1, 5, nil, ""):Modify{TextColor = 0xff0000},
561
    
562
    gui.backend.Text:Create(1, 6, nil, "Height"),
563
    MapHeight = gui.backend.TextBox:Create(1, 7, 20, cfg.mapHeight .. "", "0123456789"),
564
    MapHeightError = gui.backend.Text:Create(1, 8, nil, ""):Modify{TextColor = 0xff0000},
565
    
566
    DrawShadow = gui.backend.CheckBox:Create(1, 9, 0, "Draw Shadow", cfg.drawShadow),
567
    
568
    gui.backend.Button:Create(1, 11, 20, 3, "Back", function()
569
      cfg.mapWidth = SettingsForm.Elements["MapWidth"].Text + 0
570
      cfg.startX = gui.GetCenter(1, cfg.mapWidth, 1) - 1
571
      width = cfg.mapWidth + 10
572
      cfg.mapHeight = SettingsForm.Elements["MapHeight"].Text + 0
573
      cfg.drawShadow = SettingsForm.Elements["DrawShadow"].Checked
574
      SettingsForm.Elements["MapWidthError"]:Modify{Text = ""}:Paint()
575
      SettingsForm.Elements["MapWidth"]:Modify{TextColor = 0xffffff}:Paint()
576
      SettingsForm.Elements["MapHeightError"]:Modify{Text = ""}:Paint()
577
      SettingsForm.Elements["MapHeight"]:Modify{TextColor = 0xffffff}:Paint()
578
      
579
      local err, msg = ValidateConfig()
580
      if err ~= nil then
581
        SettingsForm.Elements[err]:Modify{Text = msg}:Paint()
582
        SettingsForm.Elements[unicode.sub(err, 1, -6)]:Modify{TextColor = 0xff0000}:Paint()
583
        return false
584
      end
585
      
586
      GameForm.Width = cfg.mapWidth * 2 + 12
587
      local offsetX = cfg.mapWidth * 2 + 1 - GameForm.Elements["panel"].X
588
      local offsetY = gui.GetCenter(1, cfg.mapHeight, 15) - GameForm.Elements["panel"].Y
589
      -- GameForm.Elements["panel"].X = cfg.mapWidth * 2 + 1
590
      for index, element in pairs(GameForm.Elements["panel"].Elements) do
591
        element.X = element.X + offsetX
592
        element.Y = element.Y + offsetY
593
      end
594
      GameForm.Elements["panel"].Elements["canvas"]:Init() -- kostil need fix
595
      GameForm.Elements["panel"].X = GameForm.Elements["panel"].X + offsetX
596
      GameForm.Elements["panel"].Y = GameForm.Elements["panel"].Y + offsetY
597
      GameForm.Height = cfg.mapHeight
598
      SettingsForm:Disable(true)
599
      GameForm:Enable():Paint()
600
    end),
601
  }
602
):Init()
603
604
GameForm:Enable():Paint()
605
606
gCanvas = GameForm.Elements["canvas"]
607
pCanvas = GameForm.Elements["panel"].Elements["canvas"]
608
scoreObj = GameForm.Elements["panel"].Elements["score"]
609
610
611
-- GameInit()
612
-- DrawMap()
613
event.ignore("key_down", onKeyDown)
614
event.listen("key_down", onKeyDown)
615
event.ignore("key_up", onKeyUp)
616
event.listen("key_up", onKeyUp)
617
618
local suc, err = pcall(function()
619
  while not quit do
620
    if isRunning then
621
      GameHandle()
622
    else
623
      event.pull()
624
    end
625
  end
626
end)
627
628
if not suc then
629
  print(err)
630
  os.sleep(3)
631
end
632
633
gui.Destroy()
634
event.ignore("key_down", onKeyDown)
635
event.ignore("key_up", onKeyUp)
636
gpu.setBackground(0x000000)
637
gpu.setForeground(0xffffff)