Advertisement
King0fGamesYami

Infinity Loop

Aug 10th, 2016
1,269
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 20.35 KB | None | 0 0
  1. --[[
  2. Menu stuff
  3. ]]--
  4. function menu( title, ... )
  5.     --edit the background color to make the GUI more unique
  6.         term.setBackgroundColor( colors.black )
  7.         local debug = false --#turn to true to see what it's thinking
  8.         local tArgs = { ... }
  9.         local pages = {[1]={}}
  10.         for i = 1, #tArgs, 1 do
  11.                 if #pages[ #pages ] == 7 then
  12.                         pages[ #pages + 1 ] = {}
  13.                 end
  14.                 pages[ #pages ][ #pages[#pages] + 1 ] = tArgs[ i ]
  15.         end
  16.         local maxLen = 0
  17.         for k, v in ipairs( tArgs ) do
  18.                 if #v > maxLen then maxLen = #v end
  19.         end
  20.         local maxx, maxy = term.getSize()
  21.         if maxLen > maxx - 20 then
  22.                 error( 'largest string is too large', 2 )
  23.         end
  24.         local centerx = math.ceil( maxx/2 )
  25.         local centery
  26.         local yValue = {}
  27.         local page = 1
  28.         local selected = math.ceil( #pages[ page ] / 2 )
  29.         local function render()
  30.                 local tbl = pages[ page ]
  31.                 centery = (maxy/2) - #tbl/2
  32.                 term.clear()
  33.                 term.setCursorPos( centerx - #title/2 + 1, 2 )
  34.                 term.write( title )
  35.                 for i = 1, #tbl do
  36.                         term.setCursorPos( centerx - (#tbl[i]/2), centery + i )
  37.                         yValue[ i ] = centery + i
  38.                         term.write( tbl[ i ] )
  39.                 end
  40.                 if pages[ page - 1 ] then
  41.                         term.setCursorPos( 3, centery + #tbl/2 + 1 )
  42.                         term.write( "previous" )
  43.                 end
  44.                 if pages[ page + 1 ] then
  45.                         term.setCursorPos( maxx - 5, centery + #tbl/2 + 1 )
  46.                         term.write( "next" )
  47.                 end
  48.                 local str = "(" .. page .. "/" .. #pages .. ")"
  49.                 term.setCursorPos( centerx - (#str/2), maxy )
  50.                 term.write( str )
  51.         end
  52.         while true do
  53.                 render()
  54.                 if debug then
  55.                         term.setCursorPos( 1, 1 )
  56.                         term.write( selected )
  57.                         term.setCursorPos( 1, 2 )
  58.                         term.write( page )
  59.                 end
  60.                 if term.isColor() then
  61.                         term.setTextColor( colors.yellow )
  62.                 end
  63.                 if selected == "previous" and not pages[ page - 1 ] then
  64.                         selected = math.ceil( #pages[ page ]/2 )
  65.                 elseif selected == "next" and not pages[ page + 1 ] then
  66.                         selected = math.ceil( #pages[ page ]/2 )
  67.                 end
  68.                 if type( selected ) == "number" then
  69.                         term.setCursorPos( centerx - (#pages[page][selected]/2) - 3, yValue[ selected ] )
  70.                         term.write( "[" )
  71.                         term.setCursorPos( centerx + (#pages[page][selected]/2) + 2, yValue[ selected ] )
  72.                         term.write( "]" )
  73.                 elseif selected == "previous" then
  74.                         term.setCursorPos( 1, centery + #pages[ page ]/2 + 1 )
  75.                         term.write( "[" )
  76.                         term.setCursorPos( 12, centery + #pages[ page ]/2 + 1 )
  77.                         term.write( "]" )
  78.                 elseif selected == "next" then
  79.                         term.setCursorPos( maxx - 7, centery + #pages[ page ]/2 + 1 )
  80.                         term.write( "[" )
  81.                         term.setCursorPos( maxx, centery + #pages[ page ]/2 + 1 )
  82.                         term.write( "]" )
  83.                 end
  84.                 if term.isColor() then
  85.                         term.setTextColor( colors.white )
  86.                 end
  87.                 local event, key = os.pullEvent( "key" )
  88.                 local old = selected
  89.                 if key == 200 and type( selected ) == "number" and pages[ page ][ selected - 1 ] then
  90.                         selected = selected - 1
  91.                 elseif key == 208 and type( selected ) == "number" and pages[ page ][ selected + 1 ] then
  92.                         selected = selected + 1
  93.                 elseif key == 28 then
  94.                         if type( selected ) == "number" then
  95.                                 return pages[ page ][ selected ]
  96.                         elseif selected == "next" and pages[ page + 1 ] then
  97.                                 page = page + 1
  98.                         elseif selected == "previous" and pages[ page - 1 ] then
  99.                                 page = page - 1
  100.                         end
  101.                 elseif key == 203 then
  102.                         if selected == "next" then
  103.                                 selected = math.ceil( #pages[ page ]/2 )
  104.                         elseif type( selected ) == "number" and pages[ page - 1 ] then
  105.                                 selected = "previous"
  106.                         end
  107.                 elseif key == 205 then
  108.                         if selected == "previous" then
  109.                                 selected = math.ceil( #pages[ page ]/2 )
  110.                         elseif type( selected ) == "number" and pages[ page + 1 ] then
  111.                                 selected = "next"
  112.                         end
  113.                 end
  114.         end
  115. end
  116.  
  117. local function minimenu( ... )
  118.         local tArgs = { ... }
  119.         local tSelections = {}
  120.         local _, y = term.getSize()
  121.         local n = 1
  122.         for i, str in ipairs( tArgs ) do
  123.                 tSelections[ i ] = { str = str }
  124.                 tSelections[ i ][ "x1" ] = n
  125.                 tSelections[ i ][ "x2" ] = n + #str + 1
  126.                 n = n + 2 + #str
  127.         end
  128.         for k, v in ipairs( tSelections ) do
  129.                 term.setCursorPos( v["x1"], y )
  130.                 term.write( ' ' .. v.str )
  131.         end
  132.         local slc = 1
  133.         local last = 1
  134.         while true do
  135.                 term.setCursorPos( tSelections[ last ]["x1"], y )
  136.                 term.write( ' ' )
  137.                 term.setCursorPos( tSelections[ last ]["x2"], y )
  138.                 term.write( ' ' )
  139.                 term.setCursorPos( tSelections[ slc ]["x1"], y )
  140.                 term.setTextColor( term.isColor() and colors.black or colors.white )
  141.                 term.write( "[" )
  142.                 term.setCursorPos( tSelections[ slc ]["x2"], y )
  143.                 term.write( "]" )
  144.                 while true do
  145.                         local event, key = os.pullEvent( "key" )
  146.                         if key == 203 and tSelections[ slc - 1 ] then
  147.                                 last = slc
  148.                                 slc = slc - 1
  149.                                 break
  150.                         elseif key == 205 and tSelections[ slc + 1 ] then
  151.                                 last = slc
  152.                                 slc = slc + 1
  153.                                 break
  154.                         elseif key == 28 then
  155.                                 return tSelections[ slc ].str
  156.                         end
  157.                 end
  158.         end
  159. end
  160.  
  161. --[[
  162. drawing awesome stuff
  163. ]]--
  164.  
  165. local characters = { --//TODO: FILL THIS TABLE
  166.     [0] = "\128\128\128|000|000\n\128\128\128|000|000",
  167.     -- single end
  168.     [1] = "\151\143\148|0ff|f00\n\138\140\133|fff|000", -- point up
  169.     [2] = "\151\140\139|0f0|f0f\n\138\140\135|fff|000", -- point right
  170.     [3] = "\151\140\148|0ff|f00\n\138\131\133|f0f|0f0", -- point down
  171.     [4] = "\135\140\148|0ff|f00\n\139\140\133|fff|000", -- point left
  172.     --double curved
  173.     [5] = "\151\143\139|0f0|f0f\n\138\140\135|fff|000", -- up and right
  174.     [6] = "\151\140\139|0f0|f0f\n\138\131\135|f0f|0f0", -- right and down
  175.     [7] = "\135\140\148|0ff|f00\n\139\131\133|f0f|0f0", -- down and left
  176.     [8] = "\135\143\148|0ff|f00\n\139\140\133|fff|000", -- left and up
  177.     --double straight
  178.     [9] = "\128\128\128|f0f|0f0\n\128\128\128|f0f|0f0", -- vertical
  179.     [10] = "\143\143\143|000|fff\n\131\131\131|fff|000", -- horizantal
  180.     --triple
  181.     [11] = "\135\143\139|0f0|f0f\n\139\140\135|fff|000", -- left, up and right
  182.     [12] = "\151\143\139|0f0|f0f\n\138\131\135|f0f|0f0", -- up, right and down
  183.     [13] = "\135\140\139|0f0|f0f\n\139\131\135|f0f|0f0", -- right, down and left
  184.     [14] = "\135\143\148|0ff|f00\n\139\131\133|f0f|0f0", -- down, left and up
  185.     --quadruple
  186.     [15] = "\135\143\139|0f0|f0f\n\139\131\135|f0f|0f0" -- the only position it can be in
  187. }
  188.  
  189. local rotation = {
  190.     [0] = 0,
  191.     -- single end
  192.     [1] = 2,
  193.     [2] = 3,
  194.     [3] = 4,
  195.     [4] = 1,
  196.     -- double curved
  197.     [5] = 6,
  198.     [6] = 7,
  199.     [7] = 8,
  200.     [8] = 5,
  201.     -- double straight
  202.     [9] = 10,
  203.     [10] = 9,
  204.     -- triple
  205.     [11] = 12,
  206.     [12] = 13,
  207.     [13] = 14,
  208.     [14] = 11,
  209.     -- quadruple
  210.     [15] = 15,
  211. }
  212.  
  213. local randomize_location
  214. do
  215.     local single = {1, 2, 3, 4}
  216.     local doublecurve = {5, 6, 7, 8}
  217.     local doublestraight = {9, 10}
  218.     local triple = {11,12,13,14}
  219.     randomize_location = {
  220.         [0] = {0},
  221.         [1] = single,
  222.         [2] = single,
  223.         [3] = single,
  224.         [4] = single,
  225.         [5] = doublecurve,
  226.         [6] = doublecurve,
  227.         [7] = doublecurve,
  228.         [8] = doublecurve,
  229.         [9] = doublestraight,
  230.         [10] = doublestraight,
  231.         [11] = triple,
  232.         [12] = triple,
  233.         [13] = triple,
  234.         [14] = triple,
  235.         [15] = {15}
  236.     }
  237. end
  238.  
  239. local connectionInfo = {
  240.     --blank tile
  241.     [0]={},
  242.     --single end
  243.     [1] = {up=true},
  244.     [2] = {right=true},
  245.     [3] = {down=true},
  246.     [4] = {left=true},
  247.     --double curved
  248.     [5] = {up=true,right=true},
  249.     [6] = {right=true,down=true},
  250.     [7] = {down=true,left=true},
  251.     [8] = {left=true,up=true},
  252.     --double straight
  253.     [9] = {up=true,down=true},
  254.     [10] = {right=true,left=true},
  255.     --triple
  256.     [11] = {left=true,up=true,right=true},
  257.     [12] = {up=true,right=true,down=true},
  258.     [13] = {right=true,down=true,left=true},
  259.     [14] = {down=true,left=true,up=true},
  260.     --quadruple
  261.     [15] = {up=true,right=true,down=true,left=true},
  262. }
  263.  
  264. local chartbl = {
  265.     [0]= "0",
  266.     ["0"] = 0,
  267.     ["1"] = 1,
  268.     ["2"] = 2,
  269.     ["3"] = 3,
  270.     ["4"] = 4,
  271.     ["5"] = 5,
  272.     ["6"] = 6,
  273.     ["7"] = 7,
  274.     ["8"] = 8,
  275.     ["9"] = 9,
  276.     ["a"] = 10,
  277.     ["b"] = 11,
  278.     ["c"] = 12,
  279.     ["d"] = 13,
  280.     ["e"] = 14,
  281.     ["f"] = 15,
  282. }
  283.  
  284. local inverse_chartbl = {}
  285.  
  286. for k, v in pairs( chartbl ) do
  287.     inverse_chartbl[ v ] = k
  288. end
  289.  
  290. local maxx, maxy = term.getSize()
  291.  
  292. local function serialize( tiles )
  293.     local str = ""
  294.     for y, t in ipairs( tiles ) do
  295.         for x, tile in ipairs( t ) do
  296.             str = str .. (inverse_chartbl[ tile ] or "0")
  297.         end
  298.         str = str .. "\n"
  299.     end
  300.     return str
  301. end
  302.  
  303. local function unserialize( str )
  304.     local tiles = {}
  305.     local x, y = 1, 1
  306.     for line in str:gmatch( "[^\r\n]+" ) do
  307.         if line:sub( 1, 5 ) == "theme"  then
  308.             local f, b = line:match( "theme(.)(.)" )
  309.             for k, v in pairs( characters ) do
  310.                 characters[ k ] = v:gsub("0", b ):gsub( "f", f )
  311.             end
  312.         else
  313.             tiles[ y ] = {}
  314.             for char in line:gmatch( "." ) do
  315.                 tiles[ y ][ x ] = chartbl[ char ]
  316.                 x = x + 1
  317.             end
  318.             x = 1
  319.             y = y + 1
  320.         end
  321.     end
  322.     return tiles
  323. end
  324.  
  325. local function checkforwin( tiles )
  326.     for y, t in ipairs( tiles ) do
  327.         for x, tile in ipairs( t ) do
  328.             for k, v in pairs( connectionInfo[ tile ] ) do
  329.                 if k == "right" then
  330.                     local target = connectionInfo[ tiles[ y ][ x + 1 ] or 0 ]
  331.                     if not target or not target.left then
  332.                         return false
  333.                     end
  334.                 elseif k == "left" then
  335.                     local target = connectionInfo[ tiles[ y ][ x - 1 ] or 0 ]
  336.                     if not target or not target.right then
  337.                         return false
  338.                     end
  339.                 elseif k == "down" then
  340.                     local target = connectionInfo[ tiles[ y + 1 ] and tiles[ y + 1 ][ x ] or 0 ]
  341.                     if not target or not target.up then
  342.                         return false
  343.                     end
  344.                 elseif k == "up" then
  345.                     local target = connectionInfo[ tiles[ y - 1 ] and tiles[ y - 1 ][ x ] or 0 ]
  346.                     if not target or not target.down then
  347.                         return false
  348.                     end
  349.                 end
  350.             end
  351.         end
  352.     end
  353.     return true
  354. end
  355.  
  356. local function drawTile( tiles, x, y )
  357.     if not tiles then
  358.         error( "you idiot" )
  359.     end
  360.     if not tiles[ y ] then
  361.         error( "no such tile y: " .. y )
  362.     elseif not tiles[ y ][ x ] then
  363.         error( "No such tile x: " .. x .. ", or y: " .. y )
  364.     elseif not characters[ tiles[ y ][ x ] ] then
  365.         error( "no such character: " .. tiles[ y ][ x ] or "nil" )
  366.     end
  367.     local upper, lower = characters[ tiles[ y ][ x ] ]:match( "(.+)\n(.+)" )
  368.     term.setCursorPos( x * 3 - 2, y * 2 - 1 )
  369.     term.blit( upper:match( "(.-)|(.-)|(.+)" ) )
  370.     term.setCursorPos( x * 3 - 2, y * 2 )
  371.     term.blit( lower:match( "(.-)|(.-)|(.+)" ) )
  372. end
  373.  
  374. local function draw( sFile )
  375.     local file = fs.open( sFile, "r" )
  376.     local data = file.readAll()
  377.     file.close()
  378.     local tbl = unserialize( data )
  379.     term.setBackgroundColor( 2^tonumber( characters[ 0 ]:sub( 6, 6 ), 16 ) )
  380.     term.clear()
  381.     for y, t in pairs( tbl ) do
  382.         for x, tile in pairs( t ) do
  383.             drawTile( tbl, x, y )
  384.         end
  385.     end
  386.     return tbl
  387. end
  388.  
  389. --[[
  390. awesome clicky stuff
  391. ]]--
  392.  
  393. local function getClicks( tiles )
  394.     while true do
  395.         local event, button, x, y = os.pullEvent( "mouse_click" )
  396.         local tilex = math.ceil( x / 3 )
  397.         local tiley = math.ceil( y / 2 )
  398.         if tiles[ tiley ] and tiles[ tiley ][ tilex ] then
  399.             tiles[ tiley ][ tilex ] = rotation[ tiles[ tiley ][ tilex ] ]
  400.             drawTile( tiles, tilex, tiley )
  401.             if checkforwin( tiles ) then
  402.                 break
  403.             end
  404.         end
  405.     end
  406. end
  407.  
  408. local function levelEdit( sName )
  409.     local themecolors = "f0"
  410.     local tiles = {}
  411.     if fs.exists( sName ) then
  412.         local file = fs.open( sName, "r" )
  413.         tiles = unserialize( file.readAll() )
  414.         file.close()
  415.     end
  416.     term.setTextColor( colors.black )
  417.     term.setBackgroundColor( 2^tonumber( characters[ 0 ]:sub( 6, 6 ), 16 ) )
  418.     term.clear()
  419.     for y = 2, maxy, 2 do
  420.         tiles[ y / 2 ] = tiles[ y / 2 ] or {}
  421.         for x = 3, maxx, 3 do
  422.             tiles[ y / 2 ][ x / 3 ] = tiles[ y / 2 ][ x / 3 ] or 0
  423.             drawTile( tiles, x/3, y/2 )
  424.         end
  425.     end
  426.     while true do
  427.         local event, button, x, y = os.pullEvent()
  428.         if event == "mouse_click" and y < #tiles * 2 then
  429.             local tilex, tiley = math.ceil( x / 3 ), math.ceil( y / 2 )
  430.             if button == 1 then
  431.                 tiles[ tiley ][ tilex ] = math.min( 15, tiles[ tiley ][ tilex ] + 1 )
  432.             elseif button == 2 then
  433.                 tiles[ tiley ][ tilex ] = math.max( 0, tiles[ tiley ][ tilex ] - 1 )
  434.             end
  435.             drawTile( tiles, tilex, tiley )
  436.         elseif event == "char" and button == "q" then
  437.             local file = fs.open( sName, "w" )
  438.             file.write( serialize( tiles ) .. "theme" .. themecolors )
  439.             file.close()
  440.             term.setTextColor( colors.white )
  441.             term.setBackgroundColor( colors.black )
  442.             term.clear()
  443.             term.setCursorPos( 1, 1 )
  444.             print( "Saved as " .. sName )
  445.             break
  446.         elseif event == "char" and button == "r" then
  447.             for y, t in pairs( tiles ) do
  448.                 for x, tile in pairs( t ) do
  449.                     local rt = randomize_location[ tile ]
  450.                     t[ x ] = rt[ math.random( 1, #rt ) ]
  451.                     drawTile( tiles, x, y )
  452.                 end
  453.             end
  454.         elseif event == "char" and button == "c" then
  455.             term.setCursorPos( 1, maxy - 1 )
  456.             term.write( "Select Two Colors (Foreground / Background" )
  457.             term.setCursorPos( 1, maxy )
  458.             term.clearLine()
  459.             themecolors = minimenu( "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f" ) .. (term.clearLine() or minimenu( "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e" ) )
  460.             local bc, fc = characters[ 1 ]:match( "|(.)(.)" )
  461.             local newfc, newbc = themecolors:match( "(.)(.)" )
  462.             for k, v in pairs( characters ) do
  463.                 characters[ k ] = v:gsub( bc, newbc ):gsub( fc, newfc )
  464.             end
  465.             term.setBackgroundColor( math.pow( 2, tonumber( newbc, 16 ) ) )
  466.             term.clear()
  467.             for  y, t in pairs( tiles ) do
  468.                 for x, tile in pairs( t ) do
  469.                     drawTile( tiles, x, y )
  470.                 end
  471.             end
  472.         end
  473.         term.setCursorPos( 1, maxy )
  474.         term.write( checkforwin( tiles ) and "Solved  " or "Unsolved" )
  475.     end
  476. end
  477.  
  478. local function getdir( path )
  479.     local handle = http.get( 'https://api.github.com/repos/KingofGamesYami/InfinityLoopCC/contents/' .. path )
  480.     if not handle then
  481.         error( "Download failed", 0 )
  482.     end
  483.     local data = handle.readAll()
  484.     local list = json.decode( data )
  485.     handle.close()
  486.     for k, v in pairs( list ) do
  487.         if v.type == "dir" then
  488.             print( "Found directory: " .. v.path )
  489.             fs.makeDir( fs.combine( "inflooplevels", v.path ) )
  490.             getdir( v.path )
  491.         elseif v.type == "file" and v.name ~= "README.md" then
  492.             print( "Found file: " .. v.path )
  493.             local h = http.get( v.download_url )
  494.             local file = fs.open( fs.combine( "inflooplevels", v.path ), "w" )
  495.             file.write( h.readAll() )
  496.             h.close()
  497.             file.close()
  498.         end
  499.     end
  500. end
  501.  
  502. local function getLevels()
  503.     term.clear()
  504.     term.setCursorPos( 1, 1 )
  505.     fs.makeDir( "inflooplevels" )
  506.     if not json and not os.loadAPI( "json" ) then
  507.         local handle = http.get( "http://pastebin.com/raw/4nRg9CHU" )
  508.         local file = fs.open( "json", "w" )
  509.         file.write( handle.readAll() )
  510.         handle.close()
  511.         file.close()
  512.         os.loadAPI( "json" )
  513.     end
  514.     print( "Getting main list of files" )
  515.     getdir( "" )
  516. end
  517.  
  518. local function randomLevel()
  519.     local tiles = {}
  520.     for y = 2, maxy, 2 do
  521.         tiles[ y / 2 ] = {}
  522.         for x = 3, maxx, 3 do
  523.             tiles[ y / 3 ] = 15
  524.         end
  525.     end
  526. end
  527.  
  528. local result = fs.exists( "solve.lua" ) and
  529.     menu( "Infinity Loop CC", "Play", "Level Editor", "Generate Random Level", "Solve Level", "Download Levels" ) or
  530.     menu( "Infinity Loop CC", "Play", "Level Editor", "Download Levels", "Download solve.lua" )
  531. if result == "Play" then
  532.     local sFile = "inflooplevels"
  533.     while fs.isDir( sFile ) do
  534.         sFile = fs.combine( sFile, menu( "Select A Level", unpack( fs.list( sFile ) ) ) )
  535.     end
  536.     getClicks( draw( sFile ) )
  537.     sleep( 1 )
  538.     term.setTextColor( colors.white )
  539.     term.setBackgroundColor( colors.black )
  540.     term.clear()
  541.     term.setCursorPos( 1, 1 )
  542.     print( "You win!" )
  543. elseif result == "Level Editor" then
  544.     term.clear()
  545.     term.setCursorPos( 1, 1 )
  546.     write( "File Name: " )
  547.     local sFile = fs.combine( "inflooplevels", read() )
  548.     levelEdit( sFile )
  549. elseif result == "Download Levels" then
  550.     getLevels()
  551. elseif result == "Download solve.lua" then
  552.     local handle = http.get( 'https://raw.githubusercontent.com/CoderPuppy/ilcc-solver/master/solve.lua' )
  553.     local file = fs.open( "solve.lua", "w" )
  554.     file.write( handle.readAll() )
  555.     file.close()
  556.     handle.close()
  557.     term.clear()
  558.     term.setCursorPos( 1, 1 )
  559.     print( "Downloaded solve.lua" )
  560. elseif result == "Generate Random Level" then
  561.     local w, h = math.floor( maxx / 3 ), math.floor( maxy / 2 )
  562.     term.clear()
  563.     term.setCursorPos( 1, 1 )
  564.     write( "File Name: " )
  565.     local name = fs.combine( "inflooplevels", read() )
  566.     shell.run( "solve.lua g", name, w, h )
  567. elseif result == "Solve Level" then
  568.     local sFile = "inflooplevels"
  569.     while fs.isDir( sFile ) do
  570.         sFile = fs.combine( sFile, menu( "Select A Level", unpack( fs.list( sFile ) ) ) )
  571.     end
  572.     shell.run( "solve.lua s", sFile )
  573. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement