AI memory match game cards: 8 pairs, one style, deck built in code

Make a memory-match deck with the image API: eight subjects in one style via a reference image, then duplicate, shuffle and lay out the deck in Pillow.

5 min readSume
All posts

A memory-match deck needs eight different pictures in one visual style, each one used twice, plus a single card back. Generate the eight pictures once with the image API, pass the first approved picture as input_references to keep the style, and let code do the rest: duplicate every picture, shuffle, and lay the sheet out in Pillow. The model never has to draw the same animal twice, which is where decks usually look inconsistent.

Pairs have to be pixel-identical to be fair, so duplicating the file is the correct move. Asking a model for two copies produces two near-misses, and a child will spot the difference. This recipe uses a reference for style and code for exact pairs.

Eight subjects, one style anchor

Approve one picture first and call it the anchor. Then request the other seven with the anchor as a reference and a prompt that changes only the subject. GPT Image 2.5 accepts up to 16 references, so there is room to add a second anchor if the style drifts (Sume Image API docs).

Ask for a square image with a plain background and bold shapes, so each picture sits inside a card with room for a border. Keep the style words identical across calls and change only the subject word.

import os, requests

H = {"Authorization": f"Bearer {os.environ['SUME_API_KEY']}"}
STYLE = "flat children's book illustration, thick outline, soft colors, plain cream background, no text"

def card(subject, anchor_url=None):
    body = {"model": "openai/gpt-image-2.5", "aspect_ratio": "1:1", "quality": "medium",
            "prompt": f"{subject}, centered. {STYLE}"}
    if anchor_url:
        body["input_references"] = [{"type": "image_url", "image_url": {"url": anchor_url}}]
        body["prompt"] = f"Same style as the reference image. {body['prompt']}"
    r = requests.post("https://api.sume.com/v1/images", headers=H, json=body, timeout=120)
    r.raise_for_status()
    if r.status_code == 202:
        raise RuntimeError("queued: poll the job status_url")
    return r.json()["data"][0]["url"]

anchor = card("a smiling red fox")
print("anchor:", anchor)
print([card(s, anchor) for s in ("a sleepy owl", "a green frog", "a blue whale")])

Duplicate, shuffle, lay out

Once you have eight files, the deck is a data problem. Double the list, shuffle with a fixed seed so you can reproduce a layout, and paste the tiles into a 4 by 4 grid. A card back is drawn once in code: a solid colour with a simple border, which stays crisp at any print size.

The demo below fabricates eight coloured tiles so it runs without the generated files; point paths at your downloads for the real deck.

import random
from PIL import Image, ImageDraw

def deck_sheet(paths, out, cell=256, cols=4, seed=7):
    tiles = [Image.open(p).convert("RGB").resize((cell, cell)) for p in paths] * 2
    random.Random(seed).shuffle(tiles)
    rows = len(tiles) // cols
    sheet = Image.new("RGB", (cols * cell, rows * cell), "white")
    for i, t in enumerate(tiles):
        sheet.paste(t, ((i % cols) * cell, (i // cols) * cell))
    sheet.save(out)
    back = Image.new("RGB", (cell, cell), "#2f5d8a")
    ImageDraw.Draw(back).rectangle([12, 12, cell - 13, cell - 13], outline="#f4e3b2", width=6)
    back.save("card-back.png")
    return sheet.size

if __name__ == "__main__":
    paths = []
    for i in range(8):
        Image.new("RGB", (300, 300), (30 * i, 255 - 25 * i, 90 + 10 * i)).save(f"t{i}.png")
        paths.append(f"t{i}.png")
    print(deck_sheet(paths, "deck.png"))

Checks before you print

Hold the eight pictures side by side and make sure no two could be confused at card size. A fox and a red dog will be, so choose subjects that differ in shape and colour. Print one test sheet before ordering a deck.

For keeping a style across a set of images, see one anchor icon, then references. For a sheet of variants from a single call, see the contact sheet recipe.

Sources

Related posts

More in Use cases

All Use cases posts

Written by Sume