-- 2048 Game for SimpleOS -- CC: Tweaked compatible local w, h = term.getSize() -- Game settings local gridSize = 4 local cellWidth = 6 local startX = math.floor((w - gridSize * cellWidth) / 2) local startY = 4 -- Game state local grid = {} local score = 0 local bestScore = 0 local gameOver = false local gameWon = false -- Colors for tiles local tileColors = { [2] = colors.white, [4] = colors.lightGray, [8] = colors.orange, [16] = colors.orange, [32] = colors.red, [64] = colors.red, [128] = colors.yellow, [256] = colors.yellow, [512] = colors.yellow, [1024] = colors.yellow, [2048] = colors.lime } local textColors = { [2] = colors.black, [4] = colors.black, [8] = colors.white, [16] = colors.white, [32] = colors.white, [64] = colors.white, [128] = colors.white, [256] = colors.white, [512] = colors.white, [1024] = colors.white, [2048] = colors.white } -- Initialize grid local function initGrid() grid = {} for y = 1, gridSize do grid[y] = {} for x = 1, gridSize do grid[y][x] = 0 end end score = 0 gameOver = false gameWon = false end -- Add random tile local function addRandomTile() local empty = {} for y = 1, gridSize do for x = 1, gridSize do if grid[y][x] == 0 then table.insert(empty, {x = x, y = y}) end end end if #empty > 0 then local pos = empty[math.random(#empty)] grid[pos.y][pos.x] = math.random(10) == 1 and 4 or 2 end end -- Check if moves available local function movesAvailable() for y = 1, gridSize do for x = 1, gridSize do if grid[y][x] == 0 then return true end if x < gridSize and grid[y][x] == grid[y][x+1] then return true end if y < gridSize and grid[y][x] == grid[y+1][x] then return true end end end return false end -- Move tiles in direction local function move(dx, dy) local moved = false local merged = {} for y = 1, gridSize do merged[y] = {} for x = 1, gridSize do merged[y][x] = false end end local startX, endX, stepX = 1, gridSize, 1 local startY, endY, stepY = 1, gridSize, 1 if dx > 0 then startX, endX, stepX = gridSize, 1, -1 end if dy > 0 then startY, endY, stepY = gridSize, 1, -1 end for y = startY, endY, stepY do for x = startX, endX, stepX do if grid[y][x] ~= 0 then local newX, newY = x, y while true do local nextX = newX + dx local nextY = newY + dy if nextX < 1 or nextX > gridSize or nextY < 1 or nextY > gridSize then break end if grid[nextY][nextX] == 0 then newX, newY = nextX, nextY elseif grid[nextY][nextX] == grid[y][x] and not merged[nextY][nextX] then newX, newY = nextX, nextY merged[newY][newX] = true break else break end end if newX ~= x or newY ~= y then moved = true if grid[newY][newX] == grid[y][x] then grid[newY][newX] = grid[y][x] * 2 score = score + grid[newY][newX] if score > bestScore then bestScore = score end if grid[newY][newX] == 2048 then gameWon = true end else grid[newY][newX] = grid[y][x] end grid[y][x] = 0 end end end end return moved end -- Draw a tile local function drawTile(x, y, value) local screenX = startX + (x - 1) * cellWidth local screenY = startY + (y - 1) * 2 local bgColor = tileColors[value] or colors.purple local fgColor = textColors[value] or colors.white if value == 0 then bgColor = colors.gray end term.setBackgroundColor(bgColor) term.setCursorPos(screenX, screenY) term.write(string.rep(" ", cellWidth)) term.setCursorPos(screenX, screenY + 1) term.write(string.rep(" ", cellWidth)) if value > 0 then term.setTextColor(fgColor) local str = tostring(value) local offset = math.floor((cellWidth - #str) / 2) term.setCursorPos(screenX + offset, screenY) term.write(str) end end -- Draw game local function draw() term.setBackgroundColor(colors.black) term.clear() -- Title term.setTextColor(colors.yellow) term.setCursorPos(math.floor(w/2) - 2, 1) term.write("2048") -- Score term.setTextColor(colors.white) term.setCursorPos(2, 2) term.write("Score: " .. score) term.setCursorPos(w - 12, 2) term.write("Best: " .. bestScore) -- Draw grid for y = 1, gridSize do for x = 1, gridSize do drawTile(x, y, grid[y][x]) end end -- Controls term.setBackgroundColor(colors.black) term.setTextColor(colors.gray) term.setCursorPos(2, startY + gridSize * 2 + 1) term.write("Arrow keys: Move [Q] Quit [R] Restart") end -- Game over screen local function showGameOver() term.setBackgroundColor(colors.black) term.setTextColor(colors.red) term.setCursorPos(math.floor(w/2) - 4, startY + gridSize) term.write("GAME OVER!") end -- Win screen local function showWin() term.setBackgroundColor(colors.black) term.setTextColor(colors.lime) term.setCursorPos(math.floor(w/2) - 4, startY + gridSize) term.write("YOU WIN!") end -- Main game loop local function run() initGrid() addRandomTile() addRandomTile() while true do draw() if not movesAvailable() then gameOver = true showGameOver() elseif gameWon then showWin() end local event, key = os.pullEvent("key") local moved = false if key == keys.up then moved = move(0, -1) elseif key == keys.down then moved = move(0, 1) elseif key == keys.left then moved = move(-1, 0) elseif key == keys.right then moved = move(1, 0) elseif key == keys.r then initGrid() addRandomTile() addRandomTile() elseif key == keys.q then return end if moved then addRandomTile() end end end run()