-- Snake Game for SimpleOS
-- CC: Tweaked compatible
local w, h = term.getSize()
h = h - 1 -- Leave room for score
-- Game state
local snake = {}
local direction = "right"
local food = {}
local score = 0
local gameOver = false
local speed = 0.15
-- Initialize game
local function init()
snake = {
{x = math.floor(w/2), y = math.floor(h/2)},
{x = math.floor(w/2) - 1, y = math.floor(h/2)},
{x = math.floor(w/2) - 2, y = math.floor(h/2)}
}
direction = "right"
score = 0
gameOver = false
spawnFood()
end
-- Spawn food at random location
function spawnFood()
local valid = false
while not valid do
food = {x = math.random(1, w), y = math.random(1, h)}
valid = true
for _, segment in ipairs(snake) do
if segment.x == food.x and segment.y == food.y then
valid = false
break
end
end
end
end
-- Draw game
local function draw()
term.setBackgroundColor(colors.black)
term.clear()
-- Draw border
term.setBackgroundColor(colors.gray)
for x = 1, w do
term.setCursorPos(x, h + 1)
term.write(" ")
end
-- Draw score
term.setCursorPos(1, h + 1)
term.setTextColor(colors.white)
term.write("Score: " .. score .. " [Q]uit")
-- Draw food
term.setBackgroundColor(colors.black)
term.setCursorPos(food.x, food.y)
term.setTextColor(colors.red)
term.write("@")
-- Draw snake
for i, segment in ipairs(snake) do
term.setCursorPos(segment.x, segment.y)
if i == 1 then
term.setTextColor(colors.lime)
term.write("O")
else
term.setTextColor(colors.green)
term.write("o")
end
end
end
-- Move snake
local function move()
local head = {x = snake[1].x, y = snake[1].y}
if direction == "up" then head.y = head.y - 1
elseif direction == "down" then head.y = head.y + 1
elseif direction == "left" then head.x = head.x - 1
elseif direction == "right" then head.x = head.x + 1
end
-- Wrap around
if head.x < 1 then head.x = w
elseif head.x > w then head.x = 1
elseif head.y < 1 then head.y = h
elseif head.y > h then head.y = 1
end
-- Check self collision
for _, segment in ipairs(snake) do
if segment.x == head.x and segment.y == head.y then
gameOver = true
return
end
end
-- Add new head
table.insert(snake, 1, head)
-- Check food
if head.x == food.x and head.y == food.y then
score = score + 10
spawnFood()
if speed > 0.05 then
speed = speed - 0.005
end
else
table.remove(snake)
end
end
-- Game over screen
local function showGameOver()
term.setBackgroundColor(colors.black)
term.setTextColor(colors.red)
term.setCursorPos(math.floor(w/2) - 4, math.floor(h/2))
term.write("GAME OVER")
term.setTextColor(colors.white)
term.setCursorPos(math.floor(w/2) - 6, math.floor(h/2) + 1)
term.write("Score: " .. score)
term.setCursorPos(math.floor(w/2) - 10, math.floor(h/2) + 3)
term.write("Press ENTER to restart")
term.setCursorPos(math.floor(w/2) - 7, math.floor(h/2) + 4)
term.write("Press Q to quit")
end
-- Main game loop
local function run()
init()
while true do
draw()
if gameOver then
showGameOver()
while true do
local event, key = os.pullEvent("key")
if key == keys.enter then
init()
break
elseif key == keys.q then
return
end
end
end
local timer = os.startTimer(speed)
while true do
local event, p1 = os.pullEvent()
if event == "key" then
if p1 == keys.up and direction ~= "down" then
direction = "up"
elseif p1 == keys.down and direction ~= "up" then
direction = "down"
elseif p1 == keys.left and direction ~= "right" then
direction = "left"
elseif p1 == keys.right and direction ~= "left" then
direction = "right"
elseif p1 == keys.q then
return
end
elseif event == "timer" and p1 == timer then
break
end
end
move()
end
end
run()