astral17

tic tac toe

Oct 8th, 2016
231
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. local AGUI_VERSION = "0.6"
  2. local component = require("component")
  3. local success, gui
  4. repeat
  5.   success, gui = pcall(require, "AGUI")
  6.   if not success then
  7.     print(gui)
  8.     io.write("For the application need a library AGUI (https://pastebin.com/s4UFSFwn).\n")
  9.     if not component.isAvailable("internet") then
  10.       os.exit()
  11.     end
  12.     io.write("Do you want to install?[Y/n] ")
  13.     if not ((io.read() or "n").."y"):match("^%s*[Yy]") then
  14.       os.exit()
  15.     end
  16.     loadfile("/bin/wget.lua")("https://pastebin.com/raw/s4UFSFwn", "/lib/AGUI.lua", "-f")
  17.   end
  18. until success
  19.  
  20. if gui.Version ~= AGUI_VERSION then
  21.   io.write("Recommended version of AGUI library ("..AGUI_VERSION..") does not match installed ("..(gui.Version or "unknown")..")\n")
  22.   io.write("Do you want to continue?[Y/n] ")
  23.     if not ((io.read() or "n").."y"):match("^%s*[Yy]") then
  24.       os.exit()
  25.     end
  26. end
  27.  
  28. -- gui.Init()
  29. -- gui.backend.MessageBox:Create("Game Over", "Draw!"):Modify{ButtonHandle = function() GameForm.Elements["Exit"]:OnElementClick() end}:Init():Paint()
  30. -- gui.Destroy()
  31. -- os.exit()
  32.  
  33. local gpu = component.gpu
  34. local event = require("event")
  35. ----SETTINGS----
  36. local cfg = {}
  37. cfg.MapWidth = 9
  38. cfg.MapHeight = 9
  39. cfg.WinLine = 5
  40. cfg.ReqAuth = true
  41.  
  42. function InRange(value, left, right)
  43.   return left <= value and value <= right
  44. end
  45.  
  46. function UpdateScreenSettings()
  47.   cfg.ScreenWidth  = cfg.MapWidth  * 8 - 1
  48.   cfg.ScreenHeight = cfg.MapHeight * 4 + 1
  49. end
  50.  
  51. function ValidateConfig()
  52.   local MaxScreenWidth, MaxScreenHeight
  53.   MaxScreenWidth, MaxScreenHeight = gpu.maxResolution()
  54.   UpdateScreenSettings()
  55.   if not InRange(cfg.ScreenWidth, 1, MaxScreenWidth) then
  56.     return "MapWidthError", "out of bounds"
  57.   end
  58.  
  59.   if not InRange(cfg.ScreenHeight, 1, MaxScreenHeight) then
  60.     return "MapHeightError", "out of bounds"
  61.   end
  62. end
  63.  
  64. --UpdateScreenSettings()
  65. local err, msg = ValidateConfig()
  66. if err ~= nil then
  67.   print(err, msg)
  68.   os.exit()
  69. end
  70.  
  71. local map, players, FreeCells, canvas, curPlayer, isRunning
  72.  
  73. function fromXY(x, y)
  74.   return (y - 1) * cfg.MapWidth + x
  75. end
  76.  
  77. tex = {
  78.   {
  79.     "▄   ▄",
  80.     " ▀▄▀ ",
  81.     "▄▀ ▀▄",
  82.   },
  83.   {
  84.     "  ▄  ",
  85.     "▄▀ ▀▄",
  86.     " ▀▄▀ "
  87.   }
  88. }
  89.  
  90. function DrawCell(canvas, x, y, id)
  91.   if id == 1 then
  92.     gpu.setForeground(0x0000ff)
  93.   elseif id == 2 then
  94.     gpu.setForeground(0xff0000)
  95.   else
  96.     return
  97.   end
  98.   for i = 1, 3 do
  99.     canvas.set((x - 1) * 8 + 2, (y - 1) * 4 + i, tex[id][i])
  100.   end
  101.   gpu.setForeground(0xffffff)
  102. end
  103.  
  104. function GameInit()
  105.   map = {}
  106.   curPlayer = 1
  107.   isRunning = true
  108.   FreeCells = cfg.MapWidth * cfg.MapHeight
  109.   -- event.listen("touch", OnTouch)
  110. end
  111.  
  112. local DIRS =
  113. {
  114.   { 1, 1},
  115.   { 1, 0},
  116.   { 0, 1},
  117.   {-1, 1},
  118. }
  119.  
  120. function MoveHandle(x, y)
  121.   if map[fromXY(x, y)] then
  122.     return false
  123.   end
  124.   map[fromXY(x, y)] = curPlayer
  125.  
  126.   local cnt
  127.   local curX, curY
  128.   for i = 1, 4 do
  129.     cnt = 0
  130.     local CUR = DIRS[i]
  131.     curX, curY = x - CUR[1], y - CUR[2]
  132.     while InRange(curX, 1, cfg.MapWidth) and InRange(curY, 1, cfg.MapHeight) and map[fromXY(curX, curY)] == curPlayer do
  133.       cnt = cnt + 1
  134.       curX, curY = curX - CUR[1], curY - CUR[2]
  135.     end
  136.     curX, curY = x, y
  137.     while InRange(curX, 1, cfg.MapWidth) and InRange(curY, 1, cfg.MapHeight) and map[fromXY(curX, curY)] == curPlayer do
  138.       cnt = cnt + 1
  139.       curX, curY = curX + CUR[1], curY + CUR[2]
  140.     end
  141.     if cnt >= cfg.WinLine then
  142.       curPlayer = 3 - curPlayer
  143.       return 3 - curPlayer, 3 - curPlayer
  144.     end
  145.   end
  146.  
  147.   FreeCells = FreeCells - 1
  148.   if FreeCells == 0 then
  149.     -- print("GG")
  150.     curPlayer = 3 - curPlayer
  151.     return 3 - curPlayer, 0
  152.   end
  153.  
  154.   curPlayer = 3 - curPlayer
  155.   return 3 - curPlayer
  156. end
  157.  
  158. function GameExit()
  159.   -- event.ignore("touch", OnTouch)
  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()
RAW Paste Data