-- NAME: Simon Says -- DESC: Repeat the color sequence -- Game states local STATE_MENU = 0 local STATE_PLAYING = 1 local STATE_SHOWING = 2 local STATE_GAME_OVER = 3 -- Game constants local BUTTON_SIZE = 40 local BUTTON_SPACING = 10 local SHOW_DURATION = 30 -- Frames to show each button local WAIT_DURATION = 20 -- Frames between shows -- Button positions (4 buttons in grid) local BUTTONS = { {x = 20, y = 20, color = 1}, -- Top-left {x = 80, y = 20, color = 2}, -- Top-right {x = 20, y = 80, color = 3}, -- Bottom-left {x = 80, y = 80, color = 4} -- Bottom-right } function init() game.vars.state = STATE_MENU game.vars.score = 0 -- Sequence of button presses game.vars.sequence = {} game.vars.player_seq = {} -- Animation state game.vars.showing_idx = 0 game.vars.show_frame = 0 game.vars.show_button = nil -- Input state game.vars.waiting_for_input = false game.vars.input_idx = 0 -- Enable continuous updates game.set_frame_updates(true) print("Simon Says initialized") end function update(event) local state = game.vars.state if state == STATE_MENU then if event.type == INPUT.TOUCH_DOWN or event.type == INPUT.BUTTON_0 or event.type == INPUT.BUTTON_1 then reset_game() game.vars.state = STATE_PLAYING return true end elseif state == STATE_PLAYING then -- Start showing sequence if event.type == INPUT.FRAME_TICK then game.vars.show_frame = game.vars.show_frame + 1 return true end return false elseif state == STATE_SHOWING then -- Animate sequence if event.type == INPUT.FRAME_TICK then game.vars.show_frame = game.vars.show_frame + 1 -- Move to next button in sequence if game.vars.show_frame > SHOW_DURATION + WAIT_DURATION then game.vars.showing_idx = game.vars.showing_idx + 1 game.vars.show_frame = 0 game.vars.show_button = nil -- Done showing sequence, wait for player input if game.vars.showing_idx > #game.vars.sequence then game.vars.state = STATE_PLAYING game.vars.waiting_for_input = true game.vars.input_idx = 0 end else -- Highlight button during show duration if game.vars.show_frame <= SHOW_DURATION then game.vars.show_button = game.vars.sequence[game.vars.showing_idx] else game.vars.show_button = nil end end return true end return false elseif state == STATE_GAME_OVER then if event.type == INPUT.TOUCH_DOWN or event.type == INPUT.BUTTON_0 or event.type == INPUT.BUTTON_1 then game.vars.state = STATE_MENU return true end end -- Handle player input if game.vars.waiting_for_input and event.type == INPUT.TOUCH_DOWN then local button = get_button_at(event.x, event.y) if button then game.vars.player_seq[#game.vars.player_seq + 1] = button game.vars.input_idx = game.vars.input_idx + 1 -- Check if correct if game.vars.sequence[game.vars.input_idx] ~= button then -- Wrong! Game over game.vars.state = STATE_GAME_OVER return true end -- Check if completed sequence if game.vars.input_idx == #game.vars.sequence then -- Advance to next round game.vars.sequence[#game.vars.sequence + 1] = math.random(1, 4) game.vars.player_seq = {} game.vars.waiting_for_input = false game.vars.showing_idx = 0 game.vars.show_frame = 0 game.vars.show_button = nil game.vars.state = STATE_SHOWING game.vars.score = game.vars.score + 1 return true end return true end end return false end function draw() renderer.clear(false) -- Black background local state = game.vars.state if state == STATE_MENU then renderer.text(game.width() / 2 - 40, game.height() / 2 - 40, "SIMON SAYS", true) renderer.text(game.width() / 2 - 50, game.height() / 2 - 10, "Repeat the sequence", true) renderer.text(game.width() / 2 - 50, game.height() / 2 + 20, "Tap to Start", true) else -- Draw buttons with highlight for i = 1, 4 do local btn = BUTTONS[i] local filled = (game.vars.show_button == i) renderer.rect(btn.x, btn.y, BUTTON_SIZE, BUTTON_SIZE, true, filled) end -- Draw score renderer.text(10, 10, "Level: " .. tostring(game.vars.score + 1), true) if state == STATE_PLAYING and game.vars.waiting_for_input then renderer.text(game.width() / 2 - 40, game.height() - 20, "Your turn!", true) end if state == STATE_GAME_OVER then renderer.text(game.width() / 2 - 40, game.height() / 2 - 20, "GAME OVER", true) renderer.text(game.width() / 2 - 30, game.height() / 2, "Level: " .. tostring(game.vars.score + 1), true) renderer.text(game.width() / 2 - 60, game.height() / 2 + 20, "Tap to Restart", true) end end end function get_button_at(x, y) for i = 1, 4 do local btn = BUTTONS[i] if x >= btn.x and x < btn.x + BUTTON_SIZE and y >= btn.y and y < btn.y + BUTTON_SIZE then return i end end return nil end function reset_game() game.vars.score = 0 game.vars.sequence = {math.random(1, 4)} game.vars.player_seq = {} game.vars.showing_idx = 0 game.vars.show_frame = 0 game.vars.show_button = nil game.vars.waiting_for_input = false game.vars.input_idx = 0 game.vars.state = STATE_SHOWING end