Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local termW, termH = term.getSize()
- local debug = false
- function drawRelevantImage(img, xPos, yPos) --update this!!!
- for i, v in pairs(img) do
- for k, e in pairs(v) do
- if i + yPos - 1 >= 1 and i + yPos - 1 <= termH and k + xPos - 1 >= 1 and k + xPos - 1 <= termW then
- term.setCursorPos(k + xPos - 1, i + yPos - 1)
- term.setBackgroundColor(e)
- term.write(" ")
- end
- end
- end
- end
- function gameGen(mapW, mapH)
- pLocation = math.random(1, 4)
- if pLocation == 1 then
- pLocation = {2, 2}
- gLocation = {mapW*2, mapH*2}
- elseif pLocation == 2 then
- pLocation = {mapW*2, 2}
- gLocation = {2, mapH*2}
- elseif pLocation == 3 then
- pLocation = {2, mapH*2}
- gLocation = {mapW*2, 2}
- elseif pLocation == 4 then
- pLocation = {mapW*2, mapH*2}
- gLocation = {2, 2}
- end
- return pLocation, gLocation
- end
- function mazeGenBranching(mapW, mapH)
- local maze = {}
- for y = 1, mapH do
- maze[y] = {}
- for x = 1, mapW do
- maze[y][x] = {}
- for i = 1, 4 do
- maze[y][x][i] = true
- end
- end
- end
- local current = {1, 1}
- local list = {}
- list[1] = {math.random(1, mapH), math.random(1, mapW)} --y, x
- while #list > 0 do
- local choice = math.random(1, #list)
- current = {list[choice][1], list[choice][2]}
- local openWalls = {}
- if current[1] > 1 and maze[current[1] - 1][current[2]][1] and maze[current[1] - 1][current[2]][2] and maze[current[1] - 1][current[2]][3] and maze[current[1] - 1][current[2]][4] then
- openWalls[#openWalls + 1] = 1
- end
- if current[1] < mapH and maze[current[1] + 1][current[2]][1] and maze[current[1] + 1][current[2]][2] and maze[current[1] + 1][current[2]][3] and maze[current[1] + 1][current[2]][4] then
- openWalls[#openWalls + 1] = 3
- end
- if current[2] > 1 and maze[current[1]][current[2] - 1][1] and maze[current[1]][current[2] - 1][2] and maze[current[1]][current[2] - 1][3] and maze[current[1]][current[2] - 1][4] then
- openWalls[#openWalls + 1] = 4
- end
- if current[2] < mapW and maze[current[1]][current[2] + 1][1] and maze[current[1]][current[2] + 1][2] and maze[current[1]][current[2] + 1][3] and maze[current[1]][current[2] + 1][4] then
- openWalls[#openWalls + 1] = 2
- end
- if #openWalls > 0 then
- openWalls = openWalls[math.random(1, #openWalls)]
- maze[current[1]][current[2]][openWalls] = false
- if openWalls == 1 then
- maze[current[1] - 1][current[2]][3] = false
- list[#list + 1] = {current[1] - 1, current[2]}
- elseif openWalls == 2 then
- maze[current[1]][current[2] + 1][4] = false
- list[#list + 1] = {current[1], current[2] + 1}
- elseif openWalls == 3 then
- maze[current[1] + 1][current[2]][1] = false
- list[#list + 1] = {current[1] + 1, current[2]}
- elseif openWalls == 4 then
- maze[current[1]][current[2] - 1][2] = false
- list[#list + 1] = {current[1], current[2] - 1}
- end
- else
- table.remove(list, choice)
- end
- end
- local gen = maze
- maze = {}
- for i = 1, mapH*2 + 1 do
- maze[i] = {}
- end
- for i = 1, mapW*2 + 1 do
- maze[1][i] = 1
- maze[mapH*2 + 1][i] = 1
- end
- for y = 2, mapH*2 do
- for x = 1, mapW*2 + 1 do
- if x == 1 or x == mapW*2 + 1 then
- maze[y][x] = 1
- elseif y%2 == 0 and x%2 == 0 then
- maze[y][x] = 2^15
- elseif y%2 == 1 and x%2 == 1 then
- maze[y][x] = 1
- else
- if y%2 == 0 then
- if gen[y/2][(x - 1)/2][2] then
- maze[y][x] = 1
- else
- maze[y][x] = 2^15
- end
- elseif y%2 == 1 then
- if gen[(y - 1)/2][x/2][3] then
- maze[y][x] = 1
- else
- maze[y][x] = 2^15
- end
- end
- end
- end
- end
- return maze
- end
- function mazeGenRecursive(mapW, mapH)
- local maze = {}
- for y = 1, mapH do
- maze[y] = {}
- for x = 1, mapW do
- maze[y][x] = {}
- for i = 1, 4 do
- maze[y][x][i] = true
- end
- end
- end
- local current = {1, 1} --y, x
- local stack = {}
- local cellsRemaining = mapW * mapH
- while cellsRemaining > 1 do
- local fullCells = {}
- if current[1] > 1 and maze[current[1] - 1][current[2]][1] and maze[current[1] - 1][current[2]][2] and maze[current[1] - 1][current[2]][3] and maze[current[1] - 1][current[2]][4] then
- fullCells[#fullCells + 1] = 1
- end
- if current[1] < mapH and maze[current[1] + 1][current[2]][1] and maze[current[1] + 1][current[2]][2] and maze[current[1] + 1][current[2]][3] and maze[current[1] + 1][current[2]][4]then
- fullCells[#fullCells + 1] = 3
- end
- if current[2] > 1 and maze[current[1]][current[2] - 1][1] and maze[current[1]][current[2] - 1][2] and maze[current[1]][current[2] - 1][3] and maze[current[1]][current[2] - 1][4] then
- fullCells[#fullCells + 1] = 4
- end
- if current[2] < mapW and maze[current[1]][current[2] + 1][1] and maze[current[1]][current[2] + 1][2] and maze[current[1]][current[2] + 1][3] and maze[current[1]][current[2] + 1][4] then
- fullCells[#fullCells + 1] = 2
- end
- if #fullCells > 0 then
- cellsRemaining = cellsRemaining - 1
- stack[#stack + 1] = {current[1], current[2]}
- fullCells = fullCells[math.random(1, #fullCells)]
- maze[current[1]][current[2]][fullCells] = false
- if fullCells == 1 then
- maze[current[1] - 1][current[2]][3] = false
- current = {current[1] - 1, current[2]}
- elseif fullCells == 2 then
- maze[current[1]][current[2] + 1][4] = false
- current = {current[1], current[2] + 1}
- elseif fullCells == 3 then
- maze[current[1] + 1][current[2]][1] = false
- current = {current[1] + 1, current[2]}
- elseif fullCells == 4 then
- maze[current[1]][current[2] - 1][2] = false
- current = {current[1], current[2] - 1}
- end
- else
- current = table.remove(stack)
- end
- end
- local gen = maze
- maze = {}
- for i = 1, mapH*2 + 1 do
- maze[i] = {}
- end
- for i = 1, mapW*2 + 1 do
- maze[1][i] = 1
- maze[mapH*2 + 1][i] = 1
- end
- for y = 2, mapH*2 do
- for x = 1, mapW*2 + 1 do
- if x == 1 or x == mapW*2 + 1 then
- maze[y][x] = 1
- elseif y%2 == 0 and x%2 == 0 then
- maze[y][x] = 2^15
- elseif y%2 == 1 and x%2 == 1 then
- maze[y][x] = 1
- else
- if y%2 == 0 then
- if gen[y/2][(x - 1)/2][2] then
- maze[y][x] = 1
- else
- maze[y][x] = 2^15
- end
- elseif y%2 == 1 then
- if gen[(y - 1)/2][x/2][3] then
- maze[y][x] = 1
- else
- maze[y][x] = 2^15
- end
- end
- end
- end
- end
- return maze
- end
- function solveMaze(maze, pX, pY, gX, gY)
- local stack = {}
- visited = {}
- local file = fs.open("debug", "w")
- file.writeLine(tostring(pX) .. " " .. tostring(pY) .. " " .. tostring(gX) .. " " .. tostring(gY))
- local mapW, mapH = #maze[1], #maze
- for i, _ in pairs(maze) do
- visited[i] = {}
- end
- for y, v in pairs(maze) do
- file.write(tostring(y) .. " ")
- for x, e in pairs(v) do
- file.write(tostring(e) .. ":")
- end
- file.writeLine("")
- end
- local sLocation = {pY, pX} --y, x
- visited[pY][pX] = true
- while true do
- file.flush()
- local adjCells = {}
- if sLocation[1] > 1 and maze[sLocation[1] - 1][sLocation[2]] ~= 1 and not visited[sLocation[1] - 1][sLocation[2]] then
- adjCells[#adjCells + 1] = 1
- end
- if sLocation[2] < mapW and maze[sLocation[1]][sLocation[2] + 1] ~= 1 and not visited[sLocation[1]][sLocation[2] + 1] then
- adjCells[#adjCells + 1] = 2
- end
- if sLocation[1] < mapH and maze[sLocation[1] + 1][sLocation[2]] ~= 1 and not visited[sLocation[1] + 1][sLocation[2]] then
- adjCells[#adjCells + 1] = 3
- end
- if sLocation[2] > 1 and maze[sLocation[1]][sLocation[2] - 1] ~= 1 and not visited[sLocation[1]][sLocation[2] - 1] then
- adjCells[#adjCells + 1] = 4
- end
- if #adjCells > 0 then
- stack[#stack + 1] = {sLocation[1], sLocation[2]}
- adjCells = adjCells[math.random(1, #adjCells)]
- if adjCells == 1 then
- sLocation[1] = sLocation[1] - 1
- file.writeLine("up")
- elseif adjCells == 2 then
- sLocation[2] = sLocation[2] + 1
- file.writeLine("right")
- elseif adjCells == 3 then
- sLocation[1] = sLocation[1] + 1
- file.writeLine("down")
- elseif adjCells == 4 then
- sLocation[2] = sLocation[2] - 1
- file.writeLine("right")
- end
- visited[sLocation[1]][sLocation[2]] = true
- if sLocation[1] == gY and sLocation[2] == gX then
- --stack[#stack + 1] = {sLocation[1], sLocation[2]}
- break
- end
- else
- file.writeLine("back")
- sLocation = table.remove(stack)
- end
- end
- return stack
- end
- function toggleSolution(maze, solution, state)
- local color = nil
- if state then
- color = colors.yellow
- else
- color = 2^15
- end
- for i, v in pairs(solution) do
- maze[v[1]][v[2]] = color
- end
- return maze
- end
- local prevLocation = nil
- local solutionToggle = false
- local typeList = {"Recursive", "Branching"}
- term.setBackgroundColor(colors.black)
- term.clear()
- local logo = typeList[math.random(1, #typeList)]
- if logo == "Recursive" then
- logo = mazeGenRecursive(5, 5)
- elseif logo == "Branching" then
- logo = mazeGenBranching(5, 5)
- end
- term.setCursorPos(termW/2 - 4, 3)
- term.write("Maze Game")
- logo[2][2] = colors.lightBlue
- logo[10][10] = colors.orange
- drawRelevantImage(logo, termW/2 - 5, 6)
- term.setCursorPos(termW/2 - 7, termH - 2)
- term.setBackgroundColor(colors.black)
- term.setTextColor(colors.white)
- term.write("Press any key...")
- os.pullEvent("key")
- sleep(.05)
- term.setBackgroundColor(colors.black)
- term.clear()
- term.setCursorPos(1, 1)
- term.write("Enter maze width: ")
- local mapW = read()
- while not tonumber(mapW) do
- term.setCursorPos(1, 1)
- term.clearLine()
- term.write("Enter maze width: ")
- mapW = read()
- end
- term.setCursorPos(1, 2)
- term.write("Enter maze height: ")
- local mapH = read()
- mapW, mapH = tonumber(mapW), tonumber(mapH)
- while not tonumber(mapH) do
- term.setCursorPos(1, 2)
- term.clearLine()
- term.write("Enter maze height: ")
- mapH = read()
- end
- term.setCursorPos(1, 3)
- term.write("Choose maze type: ")
- local begun = false
- local maze = {}
- while not begun do
- for i, v in pairs(typeList) do
- term.setCursorPos(termW/2 - #v/2 + 1, i + 3)
- term.write(v)
- end
- local click = {os.pullEvent("mouse_click")}
- for i, v in pairs(typeList) do
- if click[4] == i + 3 then
- term.setBackgroundColor(colors.blue)
- term.setCursorPos(termW/2 - #v/2 + 1, i + 3)
- term.write(v)
- sleep(.2)
- begun = true
- if v == "Recursive" then
- maze = mazeGenRecursive(mapW, mapH)
- elseif v == "Branching" then
- maze = mazeGenBranching(mapW, mapH)
- end
- break
- end
- end
- end
- local pLocation, gLocation = gameGen(mapW, mapH)
- local solDist = #(solveMaze(maze, pLocation[1], pLocation[2], gLocation[1], gLocation[2]))
- maze[gLocation[2]][gLocation[1]] = 2
- if debug then
- paintutils.drawImage(maze, 1, 1)
- term.setCursorPos(pLocation[1], pLocation[2])
- term.setBackgroundColor(colors.lightBlue)
- term.write(" ")
- end
- term.setBackgroundColor(colors.black)
- term.setTextColor(colors.white)
- term.clear()
- term.setCursorPos(1, 1)
- print("You are the blue square...")
- term.setCursorPos(termW/2 + 1, termH/2 + 1)
- term.setBackgroundColor(colors.lightBlue)
- term.write(" ")
- term.setCursorPos(termW/2 - 7, termH - 1)
- term.setBackgroundColor(colors.black)
- term.setTextColor(colors.white)
- term.write("Press any key...")
- os.pullEvent("key")
- term.setBackgroundColor(colors.black)
- term.setTextColor(colors.white)
- term.clear()
- term.setCursorPos(1, 1)
- print("Get to the orange square...")
- term.setCursorPos(termW/2 + 1, termH/2 + 1)
- term.setBackgroundColor(colors.orange)
- term.write(" ")
- term.setCursorPos(termW/2 - 7, termH - 1)
- term.setBackgroundColor(colors.black)
- term.setTextColor(colors.white)
- term.write("Press any key...")
- os.pullEvent("key")
- term.setBackgroundColor(colors.black)
- term.setTextColor(colors.white)
- term.clear()
- term.setCursorPos(termW/2 - 4, 1)
- print([[Controls:
- ARROW KEYS to move
- TAB to show/hide solution
- Q to quit]])
- term.setCursorPos(termW/2 - 7, termH - 1)
- term.write("Press any key...")
- os.pullEvent("key")
- local startTime = os.clock()
- local pressedtab = false
- local distance = 0
- while true do
- term.setBackgroundColor(colors.black)
- term.clear()
- if solutionToggle and prevLocation and (prevLocation[1] ~= pLocation[1] or prevLocation[2] ~= pLocation[2]) then
- if maze[pLocation[2]][pLocation[1]] == 2^15 then
- maze[pLocation[2]][pLocation[1]] = colors.yellow
- else
- maze[prevLocation[2]][prevLocation[1]] = 2^15
- end
- end
- --term.setCursorPos(10, 1)
- --write(tostring(pLocation[1]) .. " " .. tostring(pLocation[2]))
- drawRelevantImage(maze, termW/2 - pLocation[1] + 2, termH/2 - pLocation[2] + 2)
- term.setBackgroundColor(colors.lightBlue)
- term.setCursorPos(termW/2 + 1, termH/2 + 1)
- term.write(" ")
- if pLocation[1] == gLocation[1] and pLocation[2] == gLocation[2] then
- local endTime = os.clock()
- local score = (mapW*mapH)*(solDist*.5)/(distance*.5) - (endTime - startTime)*.2
- if pressedtab then
- score = score*.1
- end
- for i = 1, 7 do
- term.setCursorPos(termW/2 - 11, 1)
- term.setBackgroundColor(colors.black)
- term.setTextColor(colors.yellow)
- term.clearLine()
- term.write("You won! Congratulations!")
- sleep(.1)
- term.setCursorPos(termW/2 - 11, 1)
- term.setBackgroundColor(colors.black)
- term.setTextColor(colors.blue)
- term.clearLine()
- term.write("You won! Congratulations!")
- sleep(.1)
- end
- term.setBackgroundColor(colors.black)
- term.clear()
- term.setCursorPos(1, 1)
- for i = 1, termW do
- write("-")
- end
- term.setCursorPos(termW/2 - 2, 1)
- term.write("STATS")
- term.setCursorPos(1, 2)
- print("Time spent: " .. tostring(math.floor((endTime - startTime)/60)) .. ":" .. tostring(math.ceil((endTime - startTime)%60)))
- print("Distance travelled: " .. tostring(distance))
- print("Minimum distance possible: " .. tostring(solDist))
- print("Pressed tab: " .. tostring(pressedtab))
- print("FINAL SCORE: " .. tostring(score))
- os.pullEvent()
- break
- end
- local events = {os.pullEvent()}
- if solutionToggle then
- prevLocation = {pLocation[1], pLocation[2]}
- end
- if events[1] == "key" then
- if events[2] == 200 then
- if maze[pLocation[2] - 1][pLocation[1]] ~= 1 then
- pLocation[2] = pLocation[2] - 1
- distance = distance + 1
- end
- elseif events[2] == 203 then
- if maze[pLocation[2]][pLocation[1] - 1] ~= 1 then
- pLocation[1] = pLocation[1] - 1
- distance = distance + 1
- end
- elseif events[2] == 208 then
- if maze[pLocation[2] + 1][pLocation[1]] ~= 1 then
- pLocation[2] = pLocation[2] + 1
- distance = distance + 1
- end
- elseif events[2] == 205 then
- if maze[pLocation[2]][pLocation[1] + 1] ~= 1 then
- pLocation[1] = pLocation[1] + 1
- distance = distance + 1
- end
- end
- if events[2] == keys.tab then
- pressedtab = true
- if solutionToggle then
- solutionToggle = false
- else
- solutionToggle = true
- end
- maze = toggleSolution(maze, solveMaze(maze, pLocation[1], pLocation[2], gLocation[1], gLocation[2]), solutionToggle)
- end
- if events[2] == keys.q then
- sleep(.05)
- term.setBackgroundColor(colors.black)
- term.clear()
- term.setCursorPos(1, 1)
- break
- end
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement