make sure the red snowflakes are sprite 005 at the end of the game when the player loses at the "Game Over" screen -- define constants for block size and sprites
block_size = 8
grid_width = 15
grid_height = 13 -- adjusted grid height to fit the screen
green_sprite_idx = 2 -- sprite index for green block
gray_sprite_idx = 3  -- sprite index for gray blocks
golden_snowflake_sprite_idx = 4 -- sprite index for golden snowflakes
red_snowflake_sprite_idx = 5 -- sprite index for red snowflakes

-- calculate ui and game offsets
ui_height = 8 -- height reserved for ui
game_offset_x = (128 - grid_width * block_size) / 2 -- center grid horizontally
game_offset_y = ui_height -- start grid beneath the ui
ui_margin = 4 -- margin for ui elements

-- player position (cursor)
player_x = 0
player_y = 0

-- grid to store blocks
blocks = {}

-- player score and game state
score = 0
time_limit = 60 * 5 -- 5 minutes in seconds
start_time = time()
game_over = false
game_won = false
final_time_str = "" -- to store final time string

function init_blocks()
    for x=1,grid_width do
        blocks[x] = {}
        for y=1,grid_height do
            blocks[x][y] = 0
        end
    end
end

-- initialize game state
function _init()
    init_blocks()
end

-- update game state
function _update()
    if game_over or game_won then
        return
    end

    -- check time
    local elapsed_time = time() - start_time
    if elapsed_time > time_limit then
        if score < 8000 then
            game_over = true
        end
    end

    -- check win condition
    if score >= 8000 then
        game_won = true
        final_time_str = "final time: " .. to_minutes(time_limit - elapsed_time) -- capture final time
    end

    -- move cursor
    if (btnp(0)) then player_x = max(0, player_x - 1) end
    if (btnp(1)) then player_x = min(grid_width - 1, player_x + 1) end
    if (btnp(2)) then player_y = max(0, player_y - 1) end
    if (btnp(3)) then player_y = min(grid_height - 1, player_y + 1) end

    -- place block
    if (btnp(4)) then
        if blocks[player_x + 1][player_y + 1] == 0 then
            if rnd() < 0.25 then
                blocks[player_x + 1][player_y + 1] = green_sprite_idx
            else
                blocks[player_x + 1][player_y + 1] = gray_sprite_idx
            end
            check_for_scoring()
        end
    end

    -- erase block
    if (btnp(5)) then
        if blocks[player_x + 1][player_y + 1] ~= 0 then
            blocks[player_x + 1][player_y + 1] = 0
        end
    end
end

-- check for 3-in-a-row green blocks to score points and play sound
function check_for_scoring()
    -- horizontal
    for y=1,grid_height do
        for x=1,grid_width-2 do
            if blocks[x][y] == green_sprite_idx and blocks[x+1][y] == green_sprite_idx and blocks[x+2][y] == green_sprite_idx then
                score += 300
                sfx(2) -- play sound 02 when score increases by 300
                blocks[x][y], blocks[x+1][y], blocks[x+2][y] = 0, 0, 0
            end
        end
    end

    -- vertical
    for x=1,grid_width do
        for y=1,grid_height-2 do
            if blocks[x][y] == green_sprite_idx and blocks[x][y+1] == green_sprite_idx and blocks[x][y+2] == green_sprite_idx then
                score += 300
                sfx(2) -- play sound 02 when score increases by 300
                blocks[x][y], blocks[x][y+1], blocks[x][y+2] = 0, 0, 0
            end
        end
    end

    -- diagonal (down-right)
    for x=1,grid_width-2 do
        for y=1,grid_height-2 do
            if blocks[x][y] == green_sprite_idx and blocks[x+1][y+1] == green_sprite_idx and blocks[x+2][y+2] == green_sprite_idx then
                score += 300
                sfx(2) -- play sound 02 when score increases by 300
                blocks[x][y], blocks[x+1][y+1], blocks[x+2][y+2] = 0, 0, 0
            end
        end
    end

    -- diagonal (up-right)
    for x=1,grid_width-2 do
        for y=3,grid_height do
            if blocks[x][y] == green_sprite_idx and blocks[x+1][y-1] == green_sprite_idx and blocks[x+2][y-2] == green_sprite_idx then
                score += 300
                sfx(2) -- play sound 02 when score increases by 300
                blocks[x][y], blocks[x+1][y-1], blocks[x+2][y-2] = 0, 0, 0
            end
        end
    end
end

-- draw the game
function _draw()
    cls()

    if game_over then
        print_centered("game over", 64, 64, 8)
        scatter_red_snowflakes() -- show red snowflakes
        return
    elseif game_won then
        print_centered("you win", 64, 64, 10)
        print_centered(final_time_str, 64, 76, 7) -- display captured final time below
        scatter_snowflakes()
        return
    end

    -- prepare score and time strings
    local score_str = "score: "..tostr(score)
    local time_str = "time: "..to_minutes(time_limit - (time() - start_time))
    
    -- calculate positions for score and time
    local ui_total_text = score_str.."  "..time_str
    local ui_x = 128 - ui_margin - (#ui_total_text * 4)

    -- draw score and time side by side in the top right corner
    print(score_str, ui_x, ui_margin, 7)
    print(time_str, ui_x + (#score_str * 4) + 8, ui_margin, 7)

    -- draw game grid below the ui
    for x=1,grid_width do
        for y=1,grid_height do
            local bx = game_offset_x + (x - 1) * block_size
            local by = game_offset_y + (y - 1) * block_size
            if blocks[x][y] > 0 then
                spr(blocks[x][y], bx, by)
            end
        end
    end

    -- draw cursor (outline of the currently selected block)
    local cx = game_offset_x + player_x * block_size
    local cy = game_offset_y + player_y * block_size
    rect(cx, cy, cx + block_size - 1, cy + block_size - 1, 7)
end

-- print text centered on the screen
function print_centered(text, x, y, color)
    local length = #text * 4
    print(text, x - length / 2, y, color)
end

-- convert seconds to a mm:ss format
function to_minutes(sec)
    return flr(sec/60)..":"..sub("0"..flr(sec%60), -2)
end

-- scatter golden snowflakes using sprite 004
function scatter_snowflakes()
    for i = 1, 50 do
        -- randomize x and y positions across the screen
        local x = rnd(128 - block_size)
        local y = rnd(128 - block_size)
        spr(golden_snowflake_sprite_idx, x, y)
    end
end

-- scatter slow moving red snowflakes using sprite 005
function scatter_red_snowflakes()
    for i = 1, 50 do
        -- randomize x and y positions and move them slowly
        local x = rnd(128 - block_size)
        local y = rnd(128 - block_size)
        spr(red_snowflake_sprite_idx, x, y)
    end
end