2048 · seed-2.0-lite
Build a playable 2048 game with arrow-key tile sliding and merging, smooth animations, a score, and win and lose states.
transcript · 4 messages
Build a playable 2048 game with arrow-key tile sliding and merging, smooth animations, a score, and win and lose states.
thinking
Got it, let's build the 2048 game in a single index.html file. First, I need to structure everything: HTML for the game board, CSS for styling and animations, JavaScript for game logic. Let's start by outlining the components. First, the HTML structure: a container with the game header (title, score), then the game grid, and overlay for win/lose states. Then CSS to style the grid, tiles, animations for sliding and merging, responsive design. Then JavaScript to handle the game state: grid initialization, tile movement, merging, collision detection, score tracking, win (when 2048 is created) and lose (no moves left) conditions. Wait, need to make sure arrow keys work, so add an event listener for keydown, capture arrow up/down/left/right. For animations, use CSS transitions for tile positions, so when we move tiles, their transform changes smoothly. Also, when tiles merge, add a pop animation. The grid is 4x4, standard 2048. Let's initialize the grid with two random tiles at start, either 2 or 4. For the grid logic: when moving in a direction, we process each row or column, combine adjacent tiles that are equal, only merge once per move, shift all tiles to the side they're moving towards. For example, moving left: for each row, iterate through the tiles, slide them left, merge if same value, then add any gaps. Then after a move is successful (something changed), add a new random tile. Then check if the game is won (has 2048) or lost (no possible moves left). Let's structure the CSS first: the game container is centered, the grid is 4x4 with gaps, tiles have different background colors based on their value, transitions for transform and opacity, pop animation for new/merged tiles. The overlay for win/lose is a semi-transparent screen that pops up with the message and a restart button. JavaScript functions: initGame() to reset everything, addRandomTile() to place a new 2 or 4 in an empty cell, canMove() to check if any moves are possible, move(direction) to handle the movement, checkWin() to see if 2048 exists, updateScore() to keep track of the score, updateGrid() to render the tiles correctly with their positions. Wait, to track tile positions, each tile element will have data attributes for its current row and column, and we'll update those, or use CSS grid to place them by translating their position. Or better, use grid-column and grid-row, but with transitions. Wait, no, using transform: translate() is better for smooth sliding, because changing grid positions would jump, but if we set their initial position in the grid, then translate them to the new position, that animates smoothly. Or actually, when we create a tile, we assign it to a grid cell, and when it moves, we update its grid position, but add a transition so it slides. Wait, CSS transitions work on transform, left, top, so if we use absolute positioning for tiles, that's easier. Let's make the grid container position relative, each tile is absolute, with top and left calculated based on grid cell size, so when a tile moves from (row, col) to (newRow, newCol), we change its top and left values, and the transition makes it slide. That works. Let's set the grid size to 400px, so each cell is 100px minus gaps, wait 4 cells with 10px gaps: total width 4*90 + 5*10 = 360 +50=410? Wait no, better to calculate: grid is 400px wide, grid-template-columns: repeat(4, 1fr), gap: 15px, so each cell is (400 - 3*15)/4 = (400-45)/4=355/4≈88.75px, so each tile is that size, rounded corners. Then each tile's position is calculated based on its row and column: left = col*(cellSize + gap), top = row*(cellSize + gap). That way, sliding is smooth. Also, the tile colors: standard 2048 colors: 2 is #eee4da, 4 is #ede0c8, 8 is #f2b179, 16 #f59563, up to 2048 which is #edc22e, higher values use darker yellows/oranges. That's the classic color scheme. For the win condition: when any tile reaches 2048, show the win overlay, but let the user keep playing if they want. The lose condition: when there are no empty cells left, and no two adjacent cells have the same value (so no merges possible), show the lose overlay. Restart button: when clicked, calls initGame() again to reset everything. Now, let's put all this together into one index.html file. Let's write the HTML first: doctype, html, head with style tag, body with the game container, then script tag. Let's make sure all code is inline, no external resources. Let's check that all event listeners are added correctly, the game initializes on load. Let's test the movement logic: for left movement, process each row, collect non-zero tiles, merge them, then pad with zeros to make 4 elements, that's the standard way to do it. Same for right: reverse the row, do the same as left, reverse back. For up: take each column, process like left, for down: reverse the column, process like left, reverse back. That way the merge logic is reused. Wait yes, that's the standard approach. So for any direction, we can extract the rows/columns, process them to slide and merge, then put them back. Then we check if the new grid is different from the old grid; if yes, then the move was valid, add a new tile, check for win/lose. If not, the move didn't change anything, so do nothing. That handles cases where you press an arrow that can't move any tiles, it ignores it. Also, when merging, add the value to the score: if two 2s merge into 4, add 4 to the score, that's how 2048 does it. Correct. For animations: when a new tile is added, add a class that scales it from 0 to 1, so it pops in. When a tile is merged, add the same pop animation, so it grows a little then shrinks back, that's the classic 2048 merge effect. Now, let's write all this code into index.html. Let's start coding it step by step.
/tmp/ws/index.html (12435 bytes)Successfully wrote 12435 bytes to /tmp/ws/index.html
thinking
The file is created successfully. Let's verify that the game has all the required features: arrow key controls, tile sliding/merging, smooth animations, score tracking, win and lose states. All code is self-contained in index.html, no external resources, all CSS and JS are inline. The game initializes with two random tiles, accepts arrow keys, merges tiles correctly, updates the score, detects when 2048 is created (win state) and when no moves are left (lose state), has a restart button, and smooth animations for tile creation and movement. Looks like everything is covered.
The 2048 game is fully implemented in a single self-contained `index.html` file with all required features: - Arrow-key controlled tile sliding (up/down/left/right) - Tile merging mechanics matching the original 2048 rules - Smooth animations for tile movement, creation, and merging - Real-time score tracking - Win state (when reaching 2048) and lose state (no valid moves remaining) with overlay screens - Restart functionality to reset the game - Classic 2048 visual styling and color scheme The file is ready to run locally with no external dependencies or network requests required.
TAKE IT TO CODE
A single self-contained HTML file — copy it and open in any browser, or reuse the prompt with your own pi-agent run.
RUN
EVALUATION
2048 grid renders and arrow keys slide/merge tiles with score updates, but WASD/click/drag/wheel have no effect.
Vision grade · anthropic/claude-sonnet-5
MEASUREMENTS
Raw readings from the capture, not a verdict — the grade above is the only judgement. Percentages are how much of the screen changed; the measure under-reports sparse motion on a dark background.