Advertisement
CaptainSpaceCat

Fluaow

Jul 14th, 2015
315
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 10.53 KB | None | 0 0
  1. local debug = true
  2. local oTemp = fs.open("console", "w")
  3. local function log(string)
  4.     if debug then
  5.         oTemp.writeLine(string)
  6.         oTemp.flush()
  7.     end
  8. end
  9.  
  10.  
  11. local currentCol
  12. local currentPos = {}
  13. local movementTab = {
  14.     {0, -1, "-"},
  15.     {1, 0, "|"},
  16.     {0, 1, "-"},
  17.     {-1, 0, "|"},
  18.     ["0-2"] = 1,
  19.     ["20"] = 2,
  20.     ["02"] = 3,
  21.     ["-20"] = 4
  22. }
  23.  
  24. local flowTab, choiceTab = {}, {}
  25. local function resetFlowTab()
  26.     for i = 1, 9 do
  27.         flowTab[i] = {}
  28.         for n = 1, 9 do
  29.             flowTab[i][n] = 0
  30.         end
  31.     end
  32. end
  33.  
  34. local flows = {}  --x, y, dir(1/2/3/4)
  35. local flowBases = {} --x, y (base),  --x, y (goal)
  36. local flowStates = {} --true/false (whether or not the flow is completed)
  37. local function resetFlowStuffs()
  38.     for i = 1, 14 do
  39.         flows[2^i] = {}
  40.         flowBases[2^i] = {}
  41.         flowStates[2^i] = false
  42.     end
  43. end
  44.  
  45. local function getNumWalls(xPos, yPos, col, usage)
  46.     col = col or 0
  47.     local num = 0
  48.     local numTab = {}
  49.     if yPos > 1 and (flowTab[xPos][yPos - 1] == 0 or flowTab[xPos][yPos - 1] == col) then
  50.         numTab[#numTab + 1] = 1
  51.     end
  52.     if xPos < 9 and (flowTab[xPos + 1][yPos] == 0 or flowTab[xPos + 1][yPos] == col) then
  53.         numTab[#numTab + 1] = 2
  54.     end
  55.     if yPos < 9 and (flowTab[xPos][yPos + 1] == 0 or flowTab[xPos][yPos + 1] == col) then
  56.         numTab[#numTab + 1] = 3
  57.     end
  58.     if xPos > 1 and (flowTab[xPos - 1][yPos] == 0 or flowTab[xPos - 1][yPos] == col) then
  59.         numTab[#numTab + 1] = 4
  60.     end
  61.     if usage then
  62.         return numTab
  63.     else
  64.         return #numTab
  65.     end
  66. end
  67.  
  68. local function flowGen()
  69.     resetFlowStuffs()                --make a random generator
  70.     resetFlowTab()
  71.     for i = 1, 14 do
  72.         log("generating base " .. tostring(i))
  73.         --[[local choice
  74.         repeat     --== choose base 1
  75.             local timeOut = 0
  76.             repeat
  77.                 choice = {math.random(1, 9), math.random(1, 9)}
  78.                 timeOut = timeOut + 1
  79.                 if timeOut == 500 then error("") end
  80.             until flowTab[choice[1] ][choice[2] ] == 0
  81.             local numWalls = getNumWalls(choice[1], choice[2])
  82.         until numWalls < 4 and numWalls > 0]]--
  83.         local genInfo = {}
  84.         local maxPos = 0
  85.         log("entering loops")
  86.         for n = 1, 9 do
  87.             for j = 1, 9 do
  88.                 if flowTab[n][j] == 0 then
  89.                     genInfo[#genInfo + 1] = {getNumWalls(n, j), math.max(math.abs(5 - n), math.abs(5 - j)), n, j}
  90.                     if math.max(math.abs(5 - n), math.abs(5 - j)) > maxPos then maxPos = math.max(math.abs(5 - n), math.abs(5 - j)) end
  91.                 end
  92.             end
  93.         end
  94.         log("loop 1 done")
  95.         log(maxPos)
  96.         for n = 1, #genInfo do
  97.             if genInfo[n][2] < maxPos then
  98.                 genInfo[n] = nil
  99.             end
  100.         end
  101.         local minSpaces = 4
  102.         log("loop 2 done")
  103.         for k, e in pairs(genInfo) do
  104.             if e[1] < minSpaces and e[1] > 0 then minSpaces = e[1] end
  105.         end
  106.         log("loop 3 done")
  107.         log(minSpaces)
  108.         local count = 1
  109.         local genOutput = {}
  110.         for _, v in pairs(genInfo) do
  111.             genOutput[count] = v
  112.             count = count + 1
  113.         end
  114.         genInfo = genOutput
  115.         for n = 1, #genInfo do
  116.             if genInfo[n][1] > minSpaces or genInfo[n][1] == 0 then
  117.                 genInfo[n] = nil
  118.             end
  119.         end
  120.         log("loop 4 done")
  121.         for _, e in pairs(genInfo) do
  122.             log(tostring(e[1]) .. " " .. tostring(e[2]) .. " " .. tostring(e[3]) .. " " .. tostring(e[4]))
  123.         end
  124.         count = 1
  125.         genOutput = {}
  126.         for _, v in pairs(genInfo) do
  127.             genOutput[count] = v
  128.             count = count + 1
  129.         end
  130.         genInfo = genOutput
  131.         log("loop 5 done")
  132.         local choice = math.random(1, #genInfo)
  133.         choice = {genInfo[choice][3], genInfo[choice][4]}
  134.         log(tostring(choice[1]) .. " " .. tostring(choice[2]))
  135.         flowBases[2^i][1] = {choice[1]*2, choice[2]*2}
  136.         flowTab[choice[1]][choice[2]] = 2^i
  137.         local numTab = getNumWalls(choice[1], choice[2], _, true)
  138.         local len = math.random(4, 8)
  139.         while #numTab > 0 and len > 0 do
  140.             local cTab, cDir, cMin = {}, {}, 5
  141.             for _, e in pairs(numTab) do
  142.                 cTab[e] = getNumWalls(choice[1] + movementTab[e][1], choice[2] + movementTab[e][2], 2^i)
  143.             end
  144.             for _, e in pairs(cTab) do
  145.                 if e < cMin then cMin = e end
  146.             end
  147.             for n = 1, 4 do
  148.                 if cTab[n] == cMin then
  149.                     cDir[#cDir + 1] = n
  150.                 end
  151.             end
  152.             cDir = cDir[math.random(1, #cDir)]
  153.             choice[1] = choice[1] + movementTab[cDir][1]
  154.             choice[2] = choice[2] + movementTab[cDir][2]
  155.             flowTab[choice[1]][choice[2]] = 2^i
  156.             numTab = getNumWalls(choice[1], choice[2], _, true)
  157.             --if math.random(1, 5) == 1 and not first then break end
  158.             len = len - 1
  159.         end
  160.         log("loop 6 done")
  161.         log("base generated")
  162.         flowBases[2^i][2] = {choice[1]*2, choice[2]*2}
  163.     end
  164.     --resetFlowTab()
  165. end
  166.  
  167. local function printFlows()              --probably want to make the printing separate from the updating
  168.     paintutils.drawBox(1, 1, 19, 19, colors.gray)
  169.     for y = 2, 18 do
  170.         for x = 2, 18 do
  171.             term.setBackgroundColor(colors.black)
  172.             term.setTextColor(colors.white)
  173.             term.setCursorPos(x, y)
  174.             if x%2 == 1 and y%2 == 1 then
  175.                 write("+")
  176.             elseif x%2 == 1 then
  177.                 write("|")
  178.             elseif y%2 == 1 then
  179.                 write("-")
  180.             else
  181.                 write(" ")
  182.             end
  183.         end
  184.     end
  185.     for i = 14, 1, -1 do
  186.         if #flows[2^i] > 0 then
  187.             for _, e in pairs(flows[2^i]) do
  188.                 term.setCursorPos(e[1], e[2])
  189.                 term.setBackgroundColor(2^i)
  190.                 term.setTextColor(colors.white)
  191.                 write(" ")
  192.                 if #e > 2 then
  193.                     term.setCursorPos(e[1] + movementTab[e[3]][1], e[2] + movementTab[e[3]][2])
  194.                     write(movementTab[e[3]][3])
  195.                 end
  196.             end
  197.         end
  198.         if #flowBases[2^i] > 0 then
  199.             for _, e in pairs(flowBases[2^i]) do
  200.                 term.setCursorPos(e[1], e[2])
  201.                 term.setBackgroundColor(2^i)
  202.                 if flowStates[2^i] then
  203.                     term.setTextColor(colors.white)
  204.                 else
  205.                     term.setTextColor(colors.black)
  206.                 end
  207.                 write("O")
  208.             end
  209.         end
  210.     end
  211. end
  212.  
  213. local function updateFlows()
  214.     for i = 1, 14 do
  215.         if #flowBases[2^i] > 0 then
  216.             for _, e in pairs(flowBases[2^i]) do
  217.                 flowTab[e[1]/2][e[2]/2] = tostring(2^i)
  218.             end
  219.         end
  220.         if #flows[2^i] > 0 then
  221.             for _, e in pairs(flows[2^i]) do
  222.                 flowTab[e[1]/2][e[2]/2] = 2^i
  223.             end
  224.             if #flows[2^i] > 1 and (flows[2^i][#flows[2^i]][1] == flowBases[2^i][1][1] and flows[2^i][#flows[2^i]][2] == flowBases[2^i][1][2]) or (flows[2^i][#flows[2^i]][1] == flowBases[2^i][2][1] and flows[2^i][#flows[2^i]][2] == flowBases[2^i][2][2]) then
  225.                 flowStates[2^i] = true
  226.             else
  227.                 flowStates[2^i] = false
  228.             end
  229.         end
  230.     end
  231. end
  232.  
  233. local function checkState()
  234.     local flag = true
  235.     for _, v in pairs(flowStates) do
  236.         if not v then flag = false break end
  237.     end
  238.     return flag
  239. end
  240.  
  241. local function eventHandler(events)
  242.     if events[1] == "mouse_click" and events[2] == 1 then
  243. ---=== initializes which flow is active based on where the click is before the drag ===---
  244.         if events[3]%2 == 0 and events[4]%2 == 0 and tonumber(flowTab[events[3]/2][events[4]/2]) > 0 then
  245.             currentCol = tonumber(flowTab[events[3]/2][events[4]/2])
  246.             currentPos = {events[3], events[4]}
  247.         else
  248.             currentCol = nil
  249.             currentPos = {}
  250.         end
  251.     end
  252.     if events[1] == "mouse_drag" and events[2] == 1 and events[3]%2 == 0 and events[4]%2 == 0 and currentCol then
  253.         if (math.abs(events[3] - currentPos[1]) == 2 and math.abs(events[4] - currentPos[2]) == 0) or (math.abs(events[3] - currentPos[1]) == 0 and math.abs(events[4] - currentPos[2]) == 2) then
  254.             local cut = false
  255.             for i = 1, #flows[currentCol] do
  256. ---=== cuts off excess flow when you grab it from a point that isnt the very tip ===---
  257.                 if cut then
  258.                     flowTab[flows[currentCol][i][1]/2][flows[currentCol][i][2]/2] = 0
  259.                     flows[currentCol][i] = nil
  260.                 elseif currentPos[1] == flows[currentCol][i][1] and currentPos[2] == flows[currentCol][i][2] then
  261.                     cut = true
  262.                 end
  263.             end
  264.             if ((currentPos[1] == flowBases[currentCol][1][1] and currentPos[2] == flowBases[currentCol][1][2]) or (currentPos[1] == flowBases[currentCol][2][1] and currentPos[2] == flowBases[currentCol][2][2])) then
  265. ---=== if a base is clicked ===---
  266.                 flowStates[currentCol] = false
  267.                 flows[currentCol] = {}
  268.                 for i = 1, 9 do
  269.                     for n = 1, 9 do
  270.                         if flowTab[i][n] == currentCol then
  271.                             flowTab[i][n] = 0
  272.                         end
  273.                     end
  274.                 end
  275.                 if (flowTab[events[3]/2][events[4]/2] == 0 or (type(flowTab[events[3]/2][events[4]/2]) == "string" and tonumber(flowTab[events[3]/2][events[4]/2]) == currentCol)) then
  276. ---=== resets flowTab values whenever you reset a flow by clicking on one of the bases ===---
  277.                     flows[currentCol] = {{currentPos[1], currentPos[2], movementTab[tostring(events[3] - currentPos[1]) .. tostring(events[4] - currentPos[2])]}, {events[3], events[4]}}
  278.                 end
  279.                 currentPos = {events[3], events[4]}
  280.             elseif #flows[currentCol] > 1 and events[3] == flows[currentCol][#flows[currentCol] - 1][1] and events[4] == flows[currentCol][#flows[currentCol] - 1][2] then
  281. ---=== allows you to backtrack along a flow ===---
  282.                 table.remove(flows[currentCol])
  283.                 flows[currentCol][#flows[currentCol]][3] = nil
  284.                 flowTab[currentPos[1]/2][currentPos[2]/2] = 0
  285.                 currentPos = {events[3], events[4]}
  286.                 if #flows[currentCol] == 1 then flows[currentCol] = {} end
  287.             elseif (flowTab[events[3]/2][events[4]/2] == 0 or (type(flowTab[events[3]/2][events[4]/2]) == "string" and tonumber(flowTab[events[3]/2][events[4]/2]) == currentCol)) and #flows[currentCol] > 0 then
  288. ---=== allows you to drag a flow only to empty squares and its passive base ===---
  289.                 flows[currentCol][#flows[currentCol]][3] = movementTab[tostring(events[3] - currentPos[1]) .. tostring(events[4] - currentPos[2])]
  290.                 flows[currentCol][#flows[currentCol] + 1] = {events[3], events[4]}
  291.                 currentPos = {events[3], events[4]}
  292.             end
  293.         elseif not (events[3] == currentPos[1] and events[4] == currentPos[2]) then
  294.             currentCol = nil
  295.             currentPos = {}                --possibly remove for increased versatility, but could cause instability if not used
  296.         end
  297.     end
  298. end
  299.  
  300. --[[flowBases[2^1] = {{2, 2}, {2, 8}}
  301. flowBases[2^2] = {{18, 2}, {12, 8}}
  302. flowBases[2^3] = {{6, 4}, {12, 4}}
  303. flowBases[2^14] = {{6, 6}, {18, 4}}
  304. flowBases[2^5] = {{16, 6}, {18, 14}}
  305. flowBases[2^6] = {{14, 8}, {16, 12}}
  306. flowBases[2^7] = {{14, 10}, {12, 14}}
  307. flowBases[2^8] = {{14, 12}, {16, 14}}
  308. flowBases[2^9] = {{8, 10}, {2, 18}}
  309. flowBases[2^10] = {{10, 10}, {4, 12}}
  310. flowBases[2^11] = {{4, 18}, {8, 16}}
  311. flowBases[2^12] = {{6, 16}, {10, 18}}
  312. flowBases[2^13] = {{10, 14}, {18, 18}}
  313. flowBases[2^4] = {{12, 18}, {16, 18}}]]--
  314.  
  315.  
  316. repeat
  317.     local ok = pcall(flowGen)
  318.     for i = 1, 9 do
  319.         for j = 1, 9 do
  320.             if flowTab[i][j] == 0 then ok = false end
  321.             --[[term.setCursorPos(i, j)
  322.             if flowTab[i][j] == 0 then
  323.                 write("O")
  324.             elseif flowTab[i][j] > 0 then
  325.                 write("X")
  326.             else
  327.                 write(" ")
  328.             end]]--
  329.         end
  330.     end
  331. until ok
  332. --os.pullEvent("key")
  333.  
  334. local won
  335. while not won do
  336.     printFlows()
  337.     local events = {os.pullEvent()}
  338.     eventHandler(events)
  339.     updateFlows()
  340.     won = checkState()
  341. end
  342. printFlows()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement