Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local debug = (select(2,...))=='debug';
- local termW, termH = term.getSize();
- local w, h = math.floor(termW/2), math.floor(termH/2-1)
- --w, h = tonumber(w) or 9, tonumber(h) or 9;
- --[[local]] text = ((...) or 'Hello_World!'):gsub('%s', '_'):sub(1,16);
- local movePos = function(pos, dir)
- local newpos = {pos[1], pos[2]}
- newpos[2-dir%2] = newpos[2-dir%2] + dir-dir%2-1;
- return newpos;
- end
- local getWallPos = function(pos, wall)
- pos = {2*pos[2],2*pos[1]};
- --[
- local dir = wall%2+1;
- wall = wall-dir
- pos[dir]=pos[dir]+wall
- --]]
- --pos = movePos(pos, wall);
- return pos[2], pos[1];
- end
- checkWalls = function(pos, count, _maze)
- if debug then term.setCursorPos(21,9); term.clearLine(); term.write('checkWalls called'); end
- if pos[1] < 1 or pos[2] < 1 or pos[1] > w or pos[2] > h then return false end
- local walls = 4;
- for i = 0,3 do
- local charX, charY = getWallPos(pos, i);
- if _maze[charX][charY]==' ' then
- if debug then term.setCursorPos(21,10); term.clearLine(); term.write('Missing walls at {'..table.concat(pos,', ')..', '..i..'}'); end
- if count then walls = walls - 1 else return false; end
- end
- end
- if debug then term.setCursorPos(21,10); term.clearLine(); term.write('All walls at {'..table.concat(pos, ', ')..'}'); end
- return count and walls or true;
- end
- local removeWall = function(pos, wall, _maze)
- local charX, charY = getWallPos(pos, wall);
- _maze[charX][charY] = ' '
- end
- local centerText = function(y, text)
- term.setCursorPos((termW-#text)/2,y)
- term.write(text);
- end
- local MAZECHARS = {'+', '-', '|', ' '};
- function generateMaze(--[[w,h]])
- local maze = {};
- for x = 0, 2*w do
- local col = {};
- for y = 0, 2*h do
- col[y+1] = MAZECHARS[x%2 + (y%2)*2 + 1];
- end
- maze[x+1]=col;
- end
- local cells = {}; --LIFO stack containing visited cells
- local total = w*h; --Total number of cells to visit
- local visited = 1;
- local currentCell = {math.random(1,w), math.random(1,h)};
- while visited < total do
- if debug and currentCell then term.setCursorPos(24, 2); term.clearLine(); term.write('{'..table.concat(currentCell, ', ')..'}') end
- local adjacentCells = {};
- for j = 0, 3 do
- --[
- cell = {currentCell[1], currentCell[2]};
- cell[2-j%2] = cell[2-j%2] + j-j%2-1;
- --]]
- --local cell = movePos(currentCell, j)
- if debug then term.clear(); term.setCursorPos(1,1); term.write(tostring(visited)..'/{'..table.concat(cell, ', ')..'}'); end
- if checkWalls(cell, false, maze) then
- cell[3] = j;
- adjacentCells[#adjacentCells+1] = cell;
- if debug then term.setCursorPos(24+j, 19); term.clearLine(); term.write(tostring(j+1)); end
- end
- if debug then term.setCursorPos(24, 13+j); term.clearLine(); term.write('{'..table.concat(cell, ', ')..'}') end
- end
- if #adjacentCells >= 1 then
- local cell = adjacentCells[math.random(1,#adjacentCells)];
- removeWall(currentCell, cell[3], maze);
- cells[#cells+1]=currentCell;
- currentCell = cell;
- visited = visited + 1;
- else
- currentCell = cells[#cells];
- cells[#cells]=nil;
- end
- if debug then --[[draw(true);]] term.write(visited..' '); for k=1,4 do local zcf = adjacentCells[k]; term.setCursorPos(24,2+k); term.clearLine(); term.write(not zcf and '---' or '{'..table.concat(zcf, ', ')..'}') end term.setCursorPos(24,7); term.clearLine(); term.write(#adjacentCells); term.setCursorPos(1,1) end
- end
- return maze
- end
- local maze;
- local deadEnds = {};
- local letters = {};
- local playerPos;
- local collectedText = '';
- local completed = false;
- local easterEgg = false;
- local attempts = 0;
- repeat
- deadEnds = {};
- maze = generateMaze(--[[w,h]])
- for x = 1, w do
- for y = 1, h do
- if checkWalls({x,y}, true, maze) == 3 then
- deadEnds[#deadEnds+1] = {x, y};
- end
- end
- end
- attempts = attempts+1;
- until #deadEnds >= #text+1 or attempts>=16;
- if attempts>=16 then
- term.clear()
- term.setCursorPos(1,1)
- print('Failed to generate a maze with at least ',#text+1,' dead ends within 16 attempts. Try again with a larger screen size.')
- return
- end
- --[[repeat]] playerPos = {math.random(1,w), math.random(1,h)}
- --until not letters[playerPos[1]*w+playerPos[2]];
- local assignToDeadEnd = function(letter)
- local num = math.random(1,#deadEnds)
- if (playerPos[1] == deadEnds[num][1] and playerPos[2] == deadEnds[num][2]) then
- num = num % #deadEnds + 1
- end
- local deadEnd = table.remove(deadEnds, num);
- letters[deadEnd[1]-1+(deadEnd[2]-1)*w]=letter;
- end
- for i = 1, #text do
- assignToDeadEnd(text:sub(i,i));
- end
- local checkForLetter = function()
- --if playerPos[1]%2 ==1 or playerPos[2]%2 ==1 then return end
- local pos = playerPos[1]-1+(playerPos[2]-1)*w;
- local letter = letters[pos];
- if letter then
- collectedText = collectedText .. letter;
- letters[pos] = nil;
- deadEnds[#deadEnds+1]={playerPos[1],playerPos[2]};
- if collectedText == text then completed = true; return end
- if collectedText == text:reverse() then completed = true; easterEgg = true; return end
- end
- end
- local returnLetter = function()
- if #collectedText < 1 then return end
- assignToDeadEnd(collectedText:sub(-1,-1));
- collectedText=collectedText:sub(1,-2);
- end
- local movePlayer = function(dir)
- local wallX, wallY = getWallPos(playerPos, dir)
- if maze[wallX][wallY] ~= ' ' then return end
- playerPos = movePos(playerPos, dir)
- checkForLetter();
- end
- local draw = function()
- term.clear();
- local w1, h1 = math.min(2*w+1,(term.getSize())), math.min(2*h+1, (select(2,term.getSize())));
- for x = 1, w1 do
- for y = 1, h1 do
- term.setCursorPos(x, y);
- term.write(maze[x][y]);
- end
- end
- for i, v in pairs(letters) do
- local x = i%w+1;
- local y = (i-x+1)/w+1;
- term.setCursorPos(2*x, 2*y);
- term.write(v)
- end
- term.setCursorPos(playerPos[1]*2, playerPos[2]*2);
- term.write('#');
- term.setCursorPos(1,termH);
- centerText(termH,collectedText);
- term.setCursorPos(1,1);
- end
- local controls = {
- [keys.up] = function() movePlayer(0) end,
- [keys.left] = function() movePlayer(1) end,
- [keys.down] = function() movePlayer(2) end,
- [keys.right] = function() movePlayer(3) end,
- [keys.space] = returnLetter
- }
- term.clear()
- centerText(3, 'Instructions')
- centerText(math.floor(termH/2)-2, 'Arrow keys to move')
- centerText(math.floor(termH/2)-1, 'SPACE to return letter to maze')
- centerText(math.floor(termH/2), '_ is a space')
- centerText(math.floor(termH/2)+1, 'You control the #')
- centerText(termH-2, 'Press ENTER to continue')
- for evt, key in os.pullEvent do if evt=='key' and key==keys.enter then break end end
- draw();
- while not completed do
- local evt, key = os.pullEvent('key');
- if controls[key] then
- controls[key]();
- draw()
- end
- end
- for i = 1, termH-1 do
- term.setCursorPos(1,i);
- term.clearLine();
- sleep(0.1);
- end
- for i = 1,5 do
- centerText(math.floor(termH/2), not easterEgg and text or ({'!oot', 'sdrawkcab', 'etirw', 'nac', 'I'})[i])
- sleep(0.6)
- term.clearLine()
- sleep(0.4)
- end
- term.setCursorPos(1,1)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement