Spaces:
Sleeping
Sleeping
|
Download README.md from tejasashinde/flip-card-component: direct link, hf CLI and curl.
- Browser
- Download file 4.75 kB
-
https://huggingface.co/spaces/tejasashinde/flip-card-component/resolve/main/README.md
- Command line
-
hf download hf://spaces/tejasashinde/flip-card-component/README.md
-
curl -L -o README.md https://huggingface.co/spaces/tejasashinde/flip-card-component/resolve/main/README.md
4.75 kB
| title: Flip Card Component | |
| emoji: π΄ | |
| colorFrom: blue | |
| colorTo: indigo | |
| sdk: gradio | |
| sdk_version: 6.18.0 | |
| python_version: '3.13' | |
| app_file: app.py | |
| pinned: true | |
| license: apache-2.0 | |
| short_description: Card matching game with emoji pairs and 3D card flips | |
| # π΄ Flip Card | |
| A custom **Gradio HTML component** for a memory matching card game. | |
| Flip cards, find matching emoji pairs, use presets, add custom emojis, and track completed games. | |
| Inspired by [MatchWise](https://huggingface.co/spaces/build-small-hackathon/MatchWise). The original prototype was expanded into a reusable application and now includes a custom HTML component for improved interactivity and integration. | |
| --- | |
| ## Features | |
| * Built with `gr.HTML` | |
| * Smooth 3D card flip animation | |
| * Match and wrong-pair feedback | |
| * Preset and custom emoji input | |
| * Responsive grid up to 4Γ4 | |
| * Result output through `props.value` | |
| * Game history display | |
| --- | |
| ## Files Structure | |
| ```text | |
| . | |
| βββ app.py # Demo Gradio app | |
| βββ flip_card.py # Reusable FlipCard component | |
| βββ requirements.txt | |
| βββ README.md | |
| ``` | |
| --- | |
| ## Install and Run | |
| ```bash | |
| pip install -r requirements.txt | |
| python app.py | |
| ``` | |
| Then open `http://127.0.0.1:7860` in your browser. | |
| --- | |
| ## Quick Start | |
| ```python | |
| import gradio as gr | |
| from flip_card import FlipCard | |
| with gr.Blocks() as demo: | |
| game = FlipCard() | |
| result = gr.Textbox(label="Result") | |
| game.change( | |
| fn=lambda value: value or "", | |
| inputs=game, | |
| outputs=result, | |
| ) | |
| demo.launch() | |
| ``` | |
| --- | |
| ## Usage with Presets, Custom Emojis, and History | |
| ```python | |
| import gradio as gr | |
| from flip_card import DEFAULT_EMOJIS, PRESETS, FlipCard, update_flip_card | |
| def on_win(result: str | None, history: list[str] | None): | |
| if not result: | |
| return "", "", history or [] | |
| history = (history or []) + [result] | |
| history_text = "\n".join( | |
| f"{i}. {item}" | |
| for i, item in enumerate(reversed(history[-10:]), start=1) | |
| ) | |
| return result, history_text, history | |
| def change_preset(name: str): | |
| emojis = PRESETS.get(name, DEFAULT_EMOJIS).copy() | |
| return ( | |
| update_flip_card(emojis=emojis), | |
| emojis, | |
| ",".join(emojis), | |
| "", | |
| ) | |
| def parse_emojis(text: str | None): | |
| emojis = [item.strip() for item in (text or "").split(",") if item.strip()] | |
| emojis = list(dict.fromkeys(emojis)) | |
| return emojis[:8] if len(emojis) >= 2 else DEFAULT_EMOJIS.copy() | |
| def apply_custom(text: str | None): | |
| emojis = parse_emojis(text) | |
| return update_flip_card(emojis=emojis), emojis, "" | |
| def new_game(emojis: list[str] | None): | |
| return update_flip_card(emojis=emojis or DEFAULT_EMOJIS.copy()), "" | |
| with gr.Blocks() as demo: | |
| game = FlipCard() | |
| result = gr.Textbox(label="Result", interactive=False) | |
| history_box = gr.Textbox(label="Game History", lines=6, interactive=False) | |
| preset = gr.Dropdown( | |
| label="Preset", | |
| choices=list(PRESETS.keys()), | |
| value="Fruits", | |
| ) | |
| custom = gr.Textbox( | |
| label="Custom Emojis", | |
| value="π,π", | |
| placeholder="Example: πΆ,π±,π¦,πΌ", | |
| ) | |
| apply_btn = gr.Button("Apply Custom Emojis") | |
| new_btn = gr.Button("New Shuffled Game") | |
| current_emojis = gr.State(DEFAULT_EMOJIS.copy()) | |
| history = gr.State([]) | |
| game.change( | |
| fn=on_win, | |
| inputs=[game, history], | |
| outputs=[result, history_box, history], | |
| ) | |
| preset.change( | |
| fn=change_preset, | |
| inputs=preset, | |
| outputs=[game, current_emojis, custom, result], | |
| ) | |
| apply_btn.click( | |
| fn=apply_custom, | |
| inputs=custom, | |
| outputs=[game, current_emojis, result], | |
| ) | |
| new_btn.click( | |
| fn=new_game, | |
| inputs=current_emojis, | |
| outputs=[game, result], | |
| ) | |
| demo.launch() | |
| ``` | |
| --- | |
| ## Component API | |
| ```python | |
| FlipCard( | |
| value=None, | |
| emojis=None, | |
| cards=None, | |
| cards_json=None, | |
| grid_cols=None, | |
| game_id=None, | |
| **kwargs | |
| ) | |
| ``` | |
| ### Parameters | |
| * `value`: Final winning message. | |
| * `emojis`: List of emojis used to create matching pairs. | |
| * `cards`: Pre-built shuffled card list. | |
| * `cards_json`: Internal JSON card state. | |
| * `grid_cols`: Number of grid columns. | |
| * `game_id`: Unique id used to reset frontend state. | |
| --- | |
| ## Presets | |
| ```python | |
| from flip_card import PRESETS | |
| ``` | |
| Available presets: | |
| * `Fruits` | |
| * `Animals` | |
| * `Space` | |
| * `Food` | |
| * `Nature` | |
| * `Challenge` | |
| --- | |
| ## Updating the Component | |
| Use `update_flip_card()` when changing cards from an event handler. | |
| ```python | |
| from flip_card import update_flip_card | |
| def change_game(): | |
| return update_flip_card(emojis=["πΆ", "π±", "π¦", "πΌ"]) | |
| ``` | |
| Do not return a new `FlipCard()` instance from event handlers. | |
| --- | |
| ## License | |
| MIT |