Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- 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()
Advertisement