17:31Testing Gemini 3.8 Flash on Real Coding Challenges (vs. other models)
Sep 2, 2026 · YouTube
17:37Tencent Hy4 Preview Tested: Is It Really Better Than Kimi K3 and GLM 5.3?
Aug 28, 2026 · YouTube
23:58Qwen 3.8 Flash Tested: UI, Coding, Physics & more - compared to Opus 5, Sol Pro, Grok
Aug 27, 2026 · YouTube
Build a memory game — also called concentration or pairs — as one self-contained HTML page.
The theme is fascinating animals. You choose the eight animals and the art style.
The player must be able to see how many moves they have made and how many pairs are left.
When a pair is matched, show that animal's fact.
When the game is won, say so clearly.
Clicking a card is the main interaction.
You may add exactly one button: New game.
Do not add:
Choose 8 animals that are genuinely fascinating — something about each one is strange, extreme, or surprising.
For each animal, provide:
The facts must be true. They will be checked.
Do not use the eight most obvious zoo animals. Lion, tiger, elephant, giraffe, panda, penguin, dolphin and zebra are all forbidden.
You do not create the artwork yourself. You write the prompts, and an image model draws them afterwards.
The art is delivered as one PNG:
art/cards.png
The file is a 2048×2048 3×3 contact sheet:
The grid layout, numbering, and background are fixed. Your job is to specify what belongs in each cell.
The path art/cards.png must appear exactly once in your HTML.
You may slice it with CSS background positioning, a canvas, clipped elements, or another technique.
Because the PNG has a black background, make sure the artwork sits properly on your card design.
The game must be playable before art/cards.png exists.
If the image cannot be loaded, each face-up card must show a readable fallback — the animal's name, a drawn shape, or a styled placeholder. Blank cards are not acceptable, because a memory game with blank faces cannot be played at all.
You may request one additional image, such as a table surface or background.
It must use the form art/<id>.png and it must be optional decoration — the page must look finished without it.
The page must support one URL mode.
#demoDeal a board where 7 of the 8 pairs are already matched and only one pair is left to find.
This exists so the win can be filmed without playing a whole game.
It must be a real board state that the normal game logic plays out — not a fake animation.
The game must be a single HTML file.
It must:
art/ filesDo not use:
localStoragesessionStorageindexedDBThe page must have no scrollbars at any window size. The board should scale to fit whatever space it is given.
Sound is optional. If you add any, generate it with the Web Audio API — no audio files.
Your response must contain exactly these four sections.
One line: what the game is called and what it looks like.
Provide exactly one fenced html code block containing the complete HTML page and nothing else.
Provide exactly one fenced json code block using this structure:
{
"game": { "name": "TURN TWO CARDS" },
"sheet": {
"style": "One paragraph, appended to every cell prompt below: medium, palette, lighting, line quality. This is what makes nine separate images look like one deck.",
"cells": [
{
"cell": 0,
"id": "axolotl",
"name": "Axolotl",
"role": "animal",
"prompt": "What to draw in this cell. One animal.",
"fact": "It regrows lost limbs, and even parts of its brain, without scarring."
},
{ "cell": 8, "id": "back", "name": "Card back", "role": "back", "prompt": "The pattern on the back of every card." }
]
},
"extras": [{ "id": "table", "aspect": "16:9", "prompt": "..." }]
}
Rules:
cells contains exactly 9 entries.cell values are 0–8 with no gaps or duplicates."role": "animal" and a fact."role": "back" and no fact.id is a single lowercase token and is unique.fact is 120 characters or fewer.extras may contain at most one entry, or be left out.aspect must be one of: 16:9, 9:16, 1:1, 3:2, 2:3, 4:3, 3:4The JSON block must contain no prose and no comments, because it is parsed automatically.
Four bullets:
art/cards.png is unavailable.TURN TWO CARDS — a dark, elegant memory game where players flip hand-painted naturalist plates to match eight fascinating creatures, each revealing a surprising fact upon pairing.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Turn Two Cards</title>
<style>
:root {
--bg: #0e0d0b;
--panel: #1a1815;
--border: #2e2a24;
--text: #f0e9dc;
--text-dim: #a89980;
--accent: #c9a86c;
--accent-dim: #8a7050;
--gold: #d4b87a;
--card-gap: 7px;
--radius: 8px;
--board-size: min(calc(100vw - 2rem), calc(100vh - 150px));
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html, body {
height: 100%;
overflow: hidden;
font-family: Georgia, 'Times New Roman', serif;
background: var(--bg);
color: var(--text);
user-select: none;
-webkit-user-select: none;
-webkit-tap-highlight-color: transparent;
}
body {
display: flex;
flex-direction: column;
align-items: center;
justify-content: flex-start;
padding: 0.8rem 1rem 1rem;
gap: 0.7rem;
min-height: 100vh;
}
header {
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
max-width: var(--board-size);
flex-shrink: 0;
gap: 0.8rem;
flex-wrap: wrap;
}
.title {
font-size: clamp(1rem, 2.5vw, 1.5rem);
letter-spacing: 0.3em;
font-weight: bold;
color: var(--gold);
text-transform: uppercase;
white-space: nowrap;
}
.stats {
display: flex;
gap: 1.2rem;
font-size: clamp(0.8rem, 1.8vw, 1.05rem);
color: var(--text-dim);
white-space: nowrap;
}
.stats span {
color: var(--text);
font-weight: bold;
letter-spacing: 0.05em;
}
button {
background: transparent;
border: 1.5px solid var(--accent);
color: var(--accent);
padding: 0.5rem 1.2rem;
font-size: clamp(0.8rem, 1.6vw, 0.95rem);
cursor: pointer;
letter-spacing: 0.15em;
text-transform: uppercase;
border-radius: 4px;
transition: background 0.2s, color 0.2s, border-color 0.2s;
font-family: Georgia, 'Times New Roman', serif;
white-space: nowrap;
}
button:hover {
background: var(--accent);
color: var(--bg);
border-color: var(--accent);
}
button:active {
transform: scale(0.96);
}
.board-wrapper {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
width: 100%;
min-height: 0;
}
.board {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: repeat(4, 1fr);
gap: var(--card-gap);
width: var(--board-size);
height: var(--board-size);
flex-shrink: 0;
}
.card {
perspective: 900px;
cursor: pointer;
position: relative;
}
.card-inner {
position: relative;
width: 100%;
height: 100%;
transition: transform 0.45s cubic-bezier(0.23, 1, 0.32, 1);
transform-style: preserve-3d;
border-radius: var(--radius);
}
.card.flipped .card-inner,
.card.matched .card-inner {
transform: rotateY(180deg);
}
.card-front,
.card-back {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
backface-visibility: hidden;
-webkit-backface-visibility: hidden;
border-radius: var(--radius);
overflow: hidden;
border: 1.5px solid var(--border);
background-color: #1c1a16;
background-size: 300% 300%;
background-repeat: no-repeat;
}
.card-back {
background-position: 100% 100%;
background-color: #161410;
border-color: #332d24;
}
.card-front {
transform: rotateY(180deg);
}
.card-back::after {
content: '';
position: absolute;
inset: 0;
background:
repeating-linear-gradient(45deg,
transparent 0px, transparent 6px,
rgba(201, 168, 108, 0.07) 6px, rgba(201, 168, 108, 0.07) 7px);
border-radius: var(--radius);
pointer-events: none;
}
.card.flipped:not(.matched) {
cursor: default;
}
.card.matched {
cursor: default;
opacity: 0.92;
}
.card:not(.flipped):not(.matched) .card-inner {
cursor: pointer;
}
.card:not(.flipped):not(.matched):hover .card-back {
border-color: var(--accent-dim);
}
.fallback-label {
position: absolute;
inset: 0;
display: flex;
align-items: center;
justify-content: center;
font-size: clamp(0.7rem, 1.8vw, 1.05rem);
letter-spacing: 0.08em;
text-transform: uppercase;
color: var(--text);
text-align: center;
padding: 0.3rem;
font-weight: bold;
z-index: 2;
pointer-events: none;
text-shadow: 0 1px 4px rgba(0, 0, 0, 0.8);
}
body.art-loaded .fallback-label {
display: none;
}
body.art-loaded .card-front {
background-color: #1c1a16;
}
.toast {
position: fixed;
bottom: 1.2rem;
left: 50%;
transform: translateX(-50%) translateY(80px);
background: var(--panel);
border: 1.5px solid var(--accent-dim);
border-radius: var(--radius);
padding: 0.9rem 1.4rem;
max-width: min(90vw, 420px);
text-align: center;
opacity: 0;
transition: transform 0.4s ease, opacity 0.4s ease;
pointer-events: none;
z-index: 50;
box-shadow: 0 6px 24px rgba(0, 0, 0, 0.6);
}
.toast.visible {
transform: translateX(-50%) translateY(0);
opacity: 1;
pointer-events: auto;
}
.toast .toast-name {
font-size: 1rem;
color: var(--gold);
letter-spacing: 0.1em;
text-transform: uppercase;
font-weight: bold;
}
.toast .toast-fact {
font-size: 0.9rem;
color: var(--text);
margin-top: 0.35rem;
line-height: 1.4;
}
.toast .toast-close {
display: block;
margin: 0.5rem auto 0;
font-size: 0.7rem;
color: var(--text-dim);
text-transform: uppercase;
letter-spacing: 0.15em;
cursor: pointer;
background: none;
border: none;
padding: 0.2rem;
}
.overlay {
position: fixed;
inset: 0;
background: rgba(10, 9, 7, 0.88);
display: flex;
align-items: center;
justify-content: center;
z-index: 100;
opacity: 0;
pointer-events: none;
transition: opacity 0.5s ease;
}
.overlay.visible {
opacity: 1;
pointer-events: auto;
}
.overlay-content {
text-align: center;
padding: 2rem;
max-width: 90vw;
}
.overlay h2 {
font-size: clamp(1.6rem, 5vw, 2.5rem);
color: var(--gold);
letter-spacing: 0.2em;
text-transform: uppercase;
margin-bottom: 0.6rem;
}
.overlay p {
font-size: clamp(1rem, 2.5vw, 1.3rem);
color: var(--text);
margin-bottom: 0.4rem;
}
.overlay .moves-final {
color: var(--text-dim);
font-size: 1rem;
letter-spacing: 0.08em;
}
@media (max-width: 420px) {
header {
gap: 0.4rem;
}
.title {
letter-spacing: 0.15em;
}
.stats {
gap: 0.6rem;
font-size: 0.72rem;
}
button {
padding: 0.4rem 0.8rem;
font-size: 0.72rem;
}
}
</style>
</head>
<body>
<header>
<div class="title">Turn Two Cards</div>
<div class="stats">
Moves: <span id="moves">0</span>
|
Pairs left: <span id="pairsLeft">8</span>
</div>
<button id="newGameBtn">New game</button>
</header>
<div class="board-wrapper">
<div class="board" id="board"></div>
</div>
<div class="toast" id="toast">
<div class="toast-name" id="toastName"></div>
<div class="toast-fact" id="toastFact"></div>
</div>
<div class="overlay" id="winOverlay">
<div class="overlay-content">
<h2>You found all 8 pairs!</h2>
<p>Total moves: <strong id="finalMoves">0</strong></p>
<p class="moves-final">A brilliant memory indeed.</p>
</div>
</div>
<script>
(function() {
'use strict';
const ART_PATH = 'art/cards.png';
const animals = [
{ id: 'axolotl', name: 'Axolotl', fact: 'It regrows lost limbs, spinal cord, and even parts of its brain without forming scar tissue.', cell: 0, fallbackColor: '#d4a0a0' },
{ id: 'tardigrade', name: 'Tardigrade', fact: 'It can survive in the vacuum of space, extreme radiation, and being frozen for decades.', cell: 1, fallbackColor: '#98b8ae' },
{ id: 'mantis-shrimp', name: 'Mantis Shrimp', fact: 'Its club-like claws strike with the speed of a bullet, creating cavitation bubbles that stun prey.', cell: 2, fallbackColor: '#e0b878' },
{ id: 'platypus', name: 'Platypus', fact: 'A venomous, egg-laying mammal that uses electrolocation to find prey underwater with its eyes shut.', cell: 3, fallbackColor: '#b89a7a' },
{ id: 'narwhal', name: 'Narwhal', fact: 'Its spiral tusk is actually a tooth packed with nerve endings, thought to sense water conditions.', cell: 4, fallbackColor: '#90a8b8' },
{ id: 'pangolin', name: 'Pangolin', fact: 'The only mammal covered in protective keratin scales, it rolls into a tight ball when threatened.', cell: 5, fallbackColor: '#b0b078' },
{ id: 'kakapo', name: 'Kakapo', fact: 'This flightless, nocturnal parrot can live over 90 years and has a musty, sweet scent.', cell: 6, fallbackColor: '#88a870' },
{ id: 'okapi', name: 'Okapi', fact: 'The giraffe\'s only living relative, its striped legs camouflage it in dense rainforests.', cell: 7, fallbackColor: '#987050' }
];
const BACK_CELL = 8;
const boardEl = document.getElementById('board');
const movesEl = document.getElementById('moves');
const pairsLeftEl = document.getElementById('pairsLeft');
const newGameBtn = document.getElementById('newGameBtn');
const toastEl = document.getElementById('toast');
const toastNameEl = document.getElementById('toastName');
const toastFactEl = document.getElementById('toastFact');
const winOverlayEl = document.getElementById('winOverlay');
const finalMovesEl = document.getElementById('finalMoves');
let board = [];
let flippedCards = [];
let moves = 0;
let matchedPairs = 0;
let isLocked = false;
let artLoadedFlag = false;
let toastTimeout = null;
function shuffle(arr) {
for (let i = arr.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[arr[i], arr[j]] = [arr[j], arr[i]];
}
return arr;
}
function getBackgroundPosition(cell) {
if (cell === BACK_CELL) {
return '100% 100%';
}
const col = cell % 3;
const row = Math.floor(cell / 3);
return (col * 50) + '% ' + (row * 50) + '%';
}
function getFallbackColor(animalIndex) {
return animals[animalIndex].fallbackColor;
}
function renderBoard() {
boardEl.innerHTML = '';
board.forEach((card, position) => {
const cardEl = document.createElement('div');
cardEl.className = 'card';
cardEl.dataset.position = position;
const animal = animals[card.animalIndex];
const state = card.state;
if (state === 'flipped' || state === 'matched') {
cardEl.classList.add('flipped');
}
if (state === 'matched') {
cardEl.classList.add('matched');
}
const inner = document.createElement('div');
inner.className = 'card-inner';
const backEl = document.createElement('div');
backEl.className = 'card-back';
backEl.style.backgroundImage = 'url("' + ART_PATH + '")';
backEl.style.backgroundPosition = getBackgroundPosition(BACK_CELL);
const frontEl = document.createElement('div');
frontEl.className = 'card-front';
frontEl.style.backgroundImage = 'url("' + ART_PATH + '")';
frontEl.style.backgroundPosition = getBackgroundPosition(animal.cell);
frontEl.style.backgroundColor = animal.fallbackColor;
const label = document.createElement('span');
label.className = 'fallback-label';
label.textContent = animal.name;
frontEl.appendChild(label);
inner.appendChild(backEl);
inner.appendChild(frontEl);
cardEl.appendChild(inner);
cardEl.addEventListener('click', () => handleCardClick(position));
boardEl.appendChild(cardEl);
});
}
function handleCardClick(position) {
if (isLocked) return;
const card = board[position];
if (!card || card.state === 'flipped' || card.state === 'matched') return;
if (flippedCards.length >= 2) return;
card.state = 'flipped';
updateCardVisual(position, true);
flippedCards.push(position);
if (flippedCards.length === 2) {
const pos1 = flippedCards[0];
const pos2 = flippedCards[1];
moves++;
movesEl.textContent = moves;
if (board[pos1].animalIndex === board[pos2].animalIndex) {
board[pos1].state = 'matched';
board[pos2].state = 'matched';
matchedPairs++;
pairsLeftEl.textContent = 8 - matchedPairs;
const animal = animals[board[pos1].animalIndex];
showFactToast(animal);
flippedCards = [];
if (matchedPairs === 8) {
setTimeout(() => showWinOverlay(), 900);
}
} else {
isLocked = true;
setTimeout(() => {
board[pos1].state = 'down';
board[pos2].state = 'down';
updateCardVisual(pos1, false);
updateCardVisual(pos2, false);
flippedCards = [];
isLocked = false;
}, 900);
}
}
}
function updateCardVisual(position, flipped) {
const cardEl = boardEl.querySelector('.card[data-position="' + position + '"]');
if (!cardEl) return;
if (flipped) {
cardEl.classList.add('flipped');
} else {
cardEl.classList.remove('flipped');
cardEl.classList.remove('matched');
}
const card = board[position];
if (card && card.state === 'matched') {
cardEl.classList.add('matched');
}
}
function showFactToast(animal) {
if (toastTimeout) clearTimeout(toastTimeout);
toastNameEl.textContent = animal.name;
toastFactEl.textContent = animal.fact;
toastEl.classList.add('visible');
toastTimeout = setTimeout(() => {
toastEl.classList.remove('visible');
}, 4500);
}
function showWinOverlay() {
finalMovesEl.textContent = moves;
winOverlayEl.classList.add('visible');
}
function hideWinOverlay() {
winOverlayEl.classList.remove('visible');
}
function dealBoard(demoMode) {
let animalIndices = [];
for (let i = 0; i < 8; i++) {
animalIndices.push(i, i);
}
shuffle(animalIndices);
board = animalIndices.map((animalIdx, position) => ({
animalIndex: animalIdx,
state: 'down',
position: position
}));
moves = 0;
matchedPairs = 0;
flippedCards = [];
isLocked = false;
hideWinOverlay();
if (toastTimeout) clearTimeout(toastTimeout);
toastEl.classList.remove('visible');
if (demoMode) {
const remainingAnimal = Math.floor(Math.random() * 8);
board.forEach(card => {
if (card.animalIndex !== remainingAnimal) {
card.state = 'matched';
}
});
matchedPairs = 7;
}
movesEl.textContent = moves;
pairsLeftEl.textContent = 8 - matchedPairs;
renderBoard();
}
function preloadArt() {
const img = new Image();
img.onload = function() {
artLoadedFlag = true;
document.body.classList.add('art-loaded');
};
img.onerror = function() {
artLoadedFlag = false;
document.body.classList.add('art-missing');
};
img.src = ART_PATH;
}
newGameBtn.addEventListener('click', () => {
const demoMode = window.location.hash === '#demo';
dealBoard(demoMode);
});
toastEl.addEventListener('click', () => {
if (toastTimeout) clearTimeout(toastTimeout);
toastEl.classList.remove('visible');
});
winOverlayEl.addEventListener('click', () => {
const demoMode = window.location.hash === '#demo';
dealBoard(demoMode);
});
preloadArt();
const initialDemo = window.location.hash === '#demo';
dealBoard(initialDemo);
})();
</script>
</body>
</html>
{
"game": { "name": "TURN TWO CARDS" },
"sheet": {
"style": "Flat gouache painting on solid black background, warm earthy palette of terracotta, cream, ochre, and muted green, soft even studio lighting, fine ink outlines, subtle cross-hatching, vintage natural-history plate aesthetic, centered subject at uniform scale.",
"cells": [
{
"cell": 0,
"id": "axolotl",
"name": "Axolotl",
"role": "animal",
"prompt": "An axolotl with pink feathery external gills and a gentle smile, viewed from the side, four toes visible on front feet.",
"fact": "It regrows lost limbs, spinal cord, and even parts of its brain without forming scar tissue."
},
{
"cell": 1,
"id": "tardigrade",
"name": "Tardigrade",
"role": "animal",
"prompt": "A plump tardigrade with eight stubby clawed legs and a rounded segmented body, slightly translucent, seen in three-quarter view.",
"fact": "It can survive in the vacuum of space, extreme radiation, and being frozen for decades."
},
{
"cell": 2,
"id": "mantis-shrimp",
"name": "Mantis Shrimp",
"role": "animal",
"prompt": "A mantis shrimp with vivid rainbow-colored body and club-like front claws raised, side profile, antennae extended.",
"fact": "Its club-like claws strike with the speed of a bullet, creating cavitation bubbles that stun prey."
},
{
"cell": 3,
"id": "platypus",
"name": "Platypus",
"role": "animal",
"prompt": "A platypus with duck-like bill and webbed paws, rich brown fur, low swimming position, water-line perspective.",
"fact": "A venomous, egg-laying mammal that uses electrolocation to find prey underwater with its eyes shut."
},
{
"cell": 4,
"id": "narwhal",
"name": "Narwhal",
"role": "animal",
"prompt": "A narwhal with a long spiraled ivory tusk emerging from its head, mottled grey whale body, arctic whale profile.",
"fact": "Its spiral tusk is actually a tooth packed with nerve endings, thought to sense water conditions."
},
{
"cell": 5,
"id": "pangolin",
"name": "Pangolin",
"role": "animal",
"prompt": "A pangolin covered in overlapping brown keratin scales, tail curled forward, protective posture, long claws visible.",
"fact": "The only mammal covered in protective keratin scales, it rolls into a tight ball when threatened."
},
{
"cell": 6,
"id": "kakapo",
"name": "Kakapo",
"role": "animal",
"prompt": "A round kakapo with soft moss-green feathers, large dark eyes, short curved beak, perched on a low branch.",
"fact": "This flightless, nocturnal parrot can live over 90 years and has a musty, sweet scent."
},
{
"cell": 7,
"id": "okapi",
"name": "Okapi",
"role": "animal",
"prompt": "An okapi with deep brown body, white zebra-like stripes on its legs, long dark tongue extended, standing in profile.",
"fact": "The giraffe's only living relative, its striped legs camouflage it in dense rainforests."
},
{
"cell": 8,
"id": "back",
"name": "Card back",
"role": "back",
"prompt": "An ornate symmetrical pattern of interwoven animal paw prints and leaf motifs in cream and muted gold on black, radiating from the center."
}
]
}
}