-- NAME: Memory Match -- DESC: Find matching pairs -- Game states local STATE_MENU = 0 local STATE_PLAYING = 1 local STATE_GAME_OVER = 2 -- Game constants local GRID_COLS = 4 local GRID_ROWS = 4 local CARD_SIZE = 28 local CARD_SPACING = 4 local FLIP_DURATION = 15 -- Frames to show flip animation function init() game.vars.state = STATE_MENU game.vars.score = 0 game.vars.moves = 0 -- Card grid game.vars.cards = {} -- {id, face_up, matched} game.vars.selected = {} -- Indices of selected cards game.vars.flip_frame = 0 game.vars.waiting = false -- Waiting to flip back incorrect pair -- Enable continuous updates game.set_frame_updates(true) print("Memory Match 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 -- Handle card selection if event.type == INPUT.TOUCH_DOWN and not game.vars.waiting then local card_idx = get_card_at(event.x, event.y) if card_idx and not game.vars.cards[card_idx].matched and not game.vars.cards[card_idx].face_up then -- Select card game.vars.cards[card_idx].face_up = true table.insert(game.vars.selected, card_idx) if #game.vars.selected == 2 then game.vars.moves = game.vars.moves + 1 -- Check for match if game.vars.cards[game.vars.selected[1]].id == game.vars.cards[game.vars.selected[2]].id then -- Match! game.vars.cards[game.vars.selected[1]].matched = true game.vars.cards[game.vars.selected[2]].matched = true game.vars.score = game.vars.score + 1 game.vars.selected = {} -- Check win if game.vars.score == (GRID_COLS * GRID_ROWS) / 2 then game.vars.state = STATE_GAME_OVER end else -- No match, wait then flip back game.vars.waiting = true game.vars.flip_frame = 0 end end return true end end -- Handle flip-back animation if game.vars.waiting and event.type == INPUT.FRAME_TICK then game.vars.flip_frame = game.vars.flip_frame + 1 if game.vars.flip_frame >= FLIP_DURATION then -- Flip cards back game.vars.cards[game.vars.selected[1]].face_up = false game.vars.cards[game.vars.selected[2]].face_up = false game.vars.selected = {} game.vars.waiting = false game.vars.flip_frame = 0 end return true end 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 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, "MEMORY MATCH", true) renderer.text(game.width() / 2 - 50, game.height() / 2 - 10, "Find all pairs", true) renderer.text(game.width() / 2 - 50, game.height() / 2 + 20, "Tap to Start", true) elseif state == STATE_PLAYING or state == STATE_GAME_OVER then -- Draw grid local start_x = (game.width() - (GRID_COLS * (CARD_SIZE + CARD_SPACING))) / 2 local start_y = 30 for row = 0, GRID_ROWS - 1 do for col = 0, GRID_COLS - 1 do local idx = row * GRID_COLS + col + 1 local card = game.vars.cards[idx] local x = start_x + col * (CARD_SIZE + CARD_SPACING) local y = start_y + row * (CARD_SIZE + CARD_SPACING) if card.face_up or card.matched then -- Show card value renderer.rect(x, y, CARD_SIZE, CARD_SIZE, true, true) local text = tostring(card.id) renderer.text(x + CARD_SIZE / 2 - 2, y + CARD_SIZE / 2 - 2, text, false) else -- Face down (outline) renderer.rect(x, y, CARD_SIZE, CARD_SIZE, true, false) end end end -- Draw stats renderer.text(10, 10, "Pairs: " .. tostring(game.vars.score) .. "/" .. tostring((GRID_COLS * GRID_ROWS) / 2), true) renderer.text(10, 20, "Moves: " .. tostring(game.vars.moves), true) if state == STATE_GAME_OVER then renderer.text(game.width() / 2 - 40, 5, "YOU WIN!", true) renderer.text(game.width() / 2 - 50, game.height() - 20, "Tap to Menu", true) end end end function get_card_at(x, y) local start_x = (game.width() - (GRID_COLS * (CARD_SIZE + CARD_SPACING))) / 2 local start_y = 30 for row = 0, GRID_ROWS - 1 do for col = 0, GRID_COLS - 1 do local card_x = start_x + col * (CARD_SIZE + CARD_SPACING) local card_y = start_y + row * (CARD_SIZE + CARD_SPACING) if x >= card_x and x < card_x + CARD_SIZE and y >= card_y and y < card_y + CARD_SIZE then return row * GRID_COLS + col + 1 end end end return nil end function reset_game() game.vars.score = 0 game.vars.moves = 0 game.vars.selected = {} game.vars.flip_frame = 0 game.vars.waiting = false -- Create shuffled card pairs local card_ids = {} local num_pairs = (GRID_COLS * GRID_ROWS) / 2 for i = 1, num_pairs do table.insert(card_ids, i) table.insert(card_ids, i) end -- Shuffle for i = #card_ids, 2, -1 do local j = math.random(1, i) card_ids[i], card_ids[j] = card_ids[j], card_ids[i] end -- Create card objects game.vars.cards = {} for i = 1, #card_ids do game.vars.cards[i] = { id = card_ids[i], face_up = false, matched = false } end end