CrossWordFalcon:本地生成多语言填字游戏网格与线索
EtienneAb3d/CrossWordFalcon
CrossWordFalcon 可从网页直接生成带线索的填字游戏网格,支持法语、英语、德语、西班牙语、意大利语和葡萄牙语六种语言,网格尺寸 5×5 至 50×50,其中 30×30 以内可稳定运行。
CrossWordFalcon generates crossword grids, complete with clues, straight from a web page — in French, English, German, Spanish, Italian, or Portuguese. Pick a language, a size, and a difficulty level, and the app builds a full grid. You can also build a grid yourself instead: entirely by hand, or assisted by AI-powered tools that suggest words, definitions and titles, or finish the grid for you.
- Runs 100% locally — no cloud account, no AI subscription needed.
- Works on CPU or GPU — uses a graphics card automatically if you have one (including Apple Silicon Macs), and falls back to your CPU otherwise.
Try it online: a demo is running at https://falcon.cubaix.com/.
Features
Grid generation
- Six languages: French, English, German, Spanish, Italian, Portuguese.
- Bilingual grids: across words in one language, down words in another.
- Any size from 5×5 to 50×50, plus ready-made formats ("Préconfigurations"): grids up to 30×30 work reliably; 50×50 is still being fine-tuned.
- Three difficulty levels (Easy, Medium, Hard).
- Symmetric black-cell layouts: horizontal, vertical, diagonal, both ways, or rotation.
- Seven levels of computing effort for filling the grid automatically, from the quick "Flash" to the exhaustive "GridZilla".
- Themed grids: vocabulary and clues steered toward a subject you choose.
- "Challenge Words": force your own words into the grid.
Clues
- Clues written automatically by an AI language model, in the grid's language.
- Grounded in real dictionary definitions, grammar and example sentences.
- Short generated title for every grid.
- "Recompute": rewrite every clue of a grid, saved as a new version.
- Local AI model by default; optional cloud AI models (Mistral, Claude...) with automatic fallback to the local AI model.
Playing
- Playable grid in the browser, with keyboard or on-screen keyboard.
- "Check" and "Solution" buttons, without losing your answers.
- Zoom and sliders for large grids.
- Grid statistics: word count per length.
- Timer and progress saved under your nickname; resume anytime.
- Per-grid leaderboard (correct letters, then time).
- Shareable "Play" link for each grid.
Interactive mode (build a grid yourself)
- Place words one at a time ("Next") or by hand, undo step by step.
- Toggle black cells by hand, mirrored if the symmetry option is on.
- Word suggestions per slot, per crossing, by start or end.
- Warnings on letters that would block a crossing word.
- Highlighting of impossible, poor and set-aside slots.
- Letter statistics for every empty cell.
- "Clean": remove impossible zones automatically.
- "Finish the grid" / "Finish the zone": let the generator complete it.
- Suggested and automatic definitions, suggested titles.
- "Correct": fix spelling and grammar in a definition or title.
- Drafts saved automatically ("Créations"), publish to the Library.
- Reopen any Library grid, or any generation attempt, for editing.
Library and export
- Every grid stored in a shared Library, filterable by language and level.
- Player count per grid; "seen" tracking.
- PDF download (one or two A4 pages).
- Across Lite
.puzdownload. - SVG/PNG images of each published grid and its solution.
Tools
- Dictionary: same-root search, real definitions, AI-proposed definitions.
- Synonyms and theme-related words.
- Paraphraser: 5 rewordings of a sentence.
- Bilingual lookups side by side.
- One-click links to Perplexity, ChatGPT, Claude, Mistral and Euria.
- David FALCON: chat assistant for help and hints, without spoiling answers.
- Crossword news panel (RSS feeds and publishers' daily grids).
Interface and deployment
- Interface in six languages, following the chosen language.
- Nickname protected by a secret word.
- Online-user counter and CPU/GPU load meters.
- Runs entirely locally, on CPU or GPU (NVIDIA, Apple Silicon).
- Optional dual-GPU setup.
- Server available in Python or Java, interchangeable.
- Batch generator to pre-fill the Library.
- Command-line generator.
- Dictionaries rebuildable from their original sources.
What you need
- Python 3 installed on your computer (and, only for the optional Java
version of the server, Java 21 — installed by
./Install.sh). - A small local language model generates the clues by default, and needs no account or key — see Generating clues below for the (optional) cloud alternative.
Recommended hardware
The machine needs three things: processor cores to build the grids, a graphics card if you want good-quality clues written locally, and disk space if you turn on theme search ("Theme"/"Synonyms" buttons).
| Setup | Processor | Memory | Disk | Graphics card | Good for |
|---|---|---|---|---|---|
| Minimum | 4 cores | 8 GB | 20 GB SSD | none | Trying the app, or using a cloud AI model for the clues. The default small local model works but writes weaker clues, and large grids or the heaviest modes are slow. No theme search. |
| Recommended | 8 cores | 16 GB | 50 GB SSD | NVIDIA, 12 GB of video memory | Everything running locally for a few players at once: a 4B model for the clues and the chat, plus theme search. |
| Comfortable | 16 cores or more | 32 GB | 50 GB SSD | two NVIDIA cards, 12 GB each | Several players at once while the library is being pre-filled. The two cards can either run one larger model together (for example a 9B model split across both cards, for better clues and chat answers), or run two copies of a smaller model, one of them kept for the "Interactive" mode. |
The number of processor cores matters most for grid building: each core tries a different grid in parallel, so more cores find good grids sooner. Theme search alone takes about 17 GB of disk and 3 GB of memory. Rebuilding the dictionaries yourself (optional) needs about 25 GB more of disk.
Installation (one-time setup)
From a terminal, at the project root:
./Install.sh
This script prepares everything the app needs to run. Every dictionary the app uses already ships with the project; rebuilding them all from their original sources is optional and takes several hours per language:
data_builder/build_all.sh
Generating clues
First, create your own local settings file (this one is never sent to GitHub):
cp env_default.sh env.sh
By default, clues are generated by a language model that runs locally on your machine (no internet account needed). Start it once, in its own terminal:
pip install -r requirements-llama.txt # first time only (builds llama.cpp)
./run_llm.shThe first start downloads the model, which can take a while depending on your connection. It runs on a graphics card if you have one (including Apple Silicon Macs), and falls back to your CPU otherwise — slower, but it works. If it detects a graphics card that isn't being used yet, it rebuilds itself to enable it — a one-time, several-minute step that only happens once. On an NVIDIA card, this rebuild needs the full CUDA Toolkit installed, not just the graphics driver — if it's missing, the script says so and carries on with your CPU instead of getting stuck.
The default model (Qwen3.5-0.8B, ~1.6GB download) is deliberately small,
so a fresh checkout can generate clues end-to-end even on CPU alone,
without a long per-word wait — good for a first try, less so for actual
day-to-day use. env.sh lists several larger models, ordered smallest to
largest, each with a short note on its speed/quality trade-off — open it
and uncomment the block for whichever one fits your hardware and
patience, then restart run_llm.sh.
Want to force CPU even if you have a graphics card? Open env.sh and
uncomment LLAMA_FORCE_CPU=1 — useful if you'd rather keep the GPU free
for something else. Comment it out again (or remove it) to go back to
using the GPU.
Have two graphics cards? ./Install.sh detects this and can set up
two separate copies of the language model, one per card: one handles
grid generation (whether you start it yourself or via the automated
batch generator), the other handles everything interactive — the chat
assistant, the dictionary, the paraphraser, and the hands-on grid editor
— so the two never compete for the same card. Re-run ./Install.sh at
any time to turn this on or change which card does what.
Have a graphics card with at least 12GB of VRAM? The default model
favors speed, but a larger one — Qwen/Qwen3.8-27B, quantized to fit that
much VRAM — writes noticeably better clues, especially on trickier
grammatical cases (verb conjugations, plural/gender agreement), at the
cost of taking longer per word. To switch to it, open env.sh and follow
the commented instructions for Qwen3.8-27B (uncomment those four lines
instead of the default ones just above them), then restart run_llm.sh.
If you'd rather use a cloud service instead of running a model locally,
open env.sh at the project root and follow the commented instructions
there to switch to a cloud provider (e.g. Mistral, which offers a free API
key at console.mistral.ai). You can also
keep the local model for everything else and have only the clues and the
"Define" proposals written by another model — for example Claude, with an
API key from platform.claude.com: the
CLUE_LLM_* lines of env.sh explain how. If that service fails (usage
limit reached, network problem...), the local model takes over for five
minutes before the app tries it again. Either way, never
share env.sh or its contents — once you've put a real key in it, it holds
a personal secret, like a password.
Running the app
./run_Falcon.sh
Then open your browser at: http://127.0.0.1:3000
Other devices on the same network can also reach it — the script prints
the address to use for that when it finds one (something like
http://192.168.1.23:3000).
This script also takes care of cleanly stopping any version of the app that might already be running before starting a new one — feel free to rerun it as often as you like.
Prefer Java? The app's server side also exists in a Java version, which behaves exactly the same from the web page's point of view. Start it with:
./run_FalconJ.sh
It comes ready to run and only needs Java 21, which ./Install.sh installs
for you (along with Maven, used only if you modify the Java code itself).
./run_Falcon.sh and ./run_FalconJ.sh are interchangeable: each one
stops the other version before starting, so only one runs at a time, and
your grids, drafts and saved games are shared by both.
Pre-filling the library (optional)
If you want the Library to already contain a stock of grids, you can let the app generate a batch of them on its own, one at a time, in the background:
./run_Populate.sh start # 1000 grids, random language/level/size ./run_Populate.sh start --count 200 --language fr --difficulty easy ./run_Populate.sh status # is a batch running? show recent progress ./run_Populate.sh stop # stop it (finishes the current grid first, # or cancels it if that takes too long) ./run_Populate.sh restart --mode turbo # stop, then start again
The app (./run_Falcon.sh) must be running first. Each finished grid is
added to the Library automatically. The batch runs quietly in the
background and survives closing the terminal; its progress is written to
logs/populate.log. It also writes its own definitions one at a time
rather than several at once, so it never slows down other people using
the app at the same time. By default, each grid also gets a random theme
invented by the AI, so the Library ends up with real variety rather than
plain, unthemed grids — pass --no-theme to turn this off.
Using the app
On the page:
-
Choose a language (the interface itself switches to that language too), a width, a height (15×10 by default) — or pick a ready-made format in "Préconfigurations" (from the 6×6 "Ristretto noisette" to the 50×50 "Caffeteria"), which sets the size and black-cell rate in one click — and a difficulty level ("Easy" uses everyday vocabulary, "Hard" allows rarer words). For a bilingual grid — its across (horizontal) words in one language, its down (vertical) words in a different one — set the "Bilingue" / "Bilingual" field, right next to width and height, to a different language than the one you just chose; leaving it the same gives an ordinary, single-language grid. On a bilingual grid, definitions, dictionary lookups, and David FALCON's own hints all follow the language of the specific word they're about. The "Symmetry" menu, right of the black-cell rate, makes the black cells come in mirrored groups (horizontal, vertical, diagonal, both ways, or "Rotation" — four cells turned by quarter turns — for a square grid); every black cell the generator later adds, removes or moves follows the same symmetry (words in the way are removed first), so the finished grid stays symmetric.
-
Two optional fields sit right above the "Generate grid" button, both built the same way: type a word and click + (or just type a space, comma, or other punctuation right after it) to add it to the list shown below — click − next to a word to remove it. A "Theme" field steers the puzzle's vocabulary and clues toward a subject of your choice (leave it empty for an ordinary, unthemed grid). A "Challenge Words (customization)" field lets you force specific words into the finished grid before it's even built — the same feature Interactive mode's own "Challenge Words" box offers (see below), given priority over the theme and the ordinary dictionary when the grid is generated; the solver will even try to reshape the black-cell pattern itself to make room for one of these words (or a theme word, until 5 theme words are placed) when no slot of the right size already exists, and undoes that change whenever the word doesn't work out. After those two lists, the generator prefers words found in the language's official Scrabble word list (shipped in
data/scrabble/), shown in dark cyan in the preview grids and in Interactive mode. The Scrabble list is available in full at Medium and Hard, on top of the everyday vocabulary the chosen difficulty keeps; at Easy, only its words whose inflected forms are known are used. Once a language's usage scores are built (how common each word is, rated 0 to 5), the difficulty picks words by that score instead: Easy keeps the Scrabble words rated 3 and more (no proper nouns), Medium the words rated 2 and more (the Scrabble list, plus the most frequent everyday words missing from it), Hard every word. A word you list this way never shows up in the Library's own grid listing, since it's meant to stay a hidden answer to a spot you chose yourself. -
Click "Generate grid" (the button's own label follows your chosen language). A full grid with all its definitions can take anywhere from a few seconds to a couple of minutes, depending on its size — the status line above the grid keeps updating (building the grid, then writing each definition, including a running count of how many grid layouts have failed so far) so you can see it's still working, not stuck. While the grid layout is being searched for, a live preview shows up to 6 small snapshots of layouts tried so far; once a layout is found, the same preview switches to a single, letters-free view of that final grid for the rest of the process (optimizing it, then writing its definitions). Next to each snapshot's own stats, a small pencil button opens that exact attempt in Interactive mode, so you can take over by hand instead of waiting for the search to finish — this cancels the ongoing generation if it's still running. A gold medal in the left margin counts how many grids the search has successfully completed so far. When several are finished, the search stops before writing any definition and shows them all, best score first (the one the generator recommends framed in green; click "Voir" to see their letters): click the one you prefer, and its definitions are written. Without a choice within 10 minutes, the recommended grid is kept.
-
An empty grid appears on the right, with row and column numbers along its edges and a small number in the cells where each word starts, ready to be filled in. While you play, the generation settings are tucked away behind a single "Create a grid" button (the Library, Dictionary and other tool buttons stay visible) — click it to bring the full form back and start another grid. On the grid's left, zoom buttons (zoom in, zoom out, fit to window) make large grids readable: once zoomed in, sliders on the right of and below the grid move the view, while the row and column numbers stay visible (same in Interactive mode). Above the grid, a short generated title for the puzzle is shown, with the grid's difficulty next to it ("Difficulty: Medium"). Clues follow the usual crossword format: horizontal ("Horizontalement") clues appear to the left of the grid, grouped one line per row; vertical ("Verticalement") clues appear below, grouped one line per column, spanning the full width in two columns. Each line starts with its row or column number in bold, followed by each word's own number in parentheses; several words on the same line are chained together, for example:
3 (1) Petit mammifère domestique. — (5) Boisson chaude au petit-déjeuner.
Filling in the grid
Click a white cell to select it (it turns blue), then type letters on your keyboard:
- A letter fills the cell and moves the selection to the next cell in the current direction — set with Ctrl (see below) or the Across/Down buttons.
- An uppercase letter (Shift or Caps Lock) always moves the selection downwards — handy for typing a vertical word without changing the direction first.
- Pressing Ctrl flips between the horizontal and vertical direction — one tap each time, so you can switch without holding a key down.
- The arrow keys move the selection around the grid, skipping over black cells.
A clock next to the title starts with your first letter. Your letters and the clock are saved on the server under your nickname as you type: close the page, reopen the grid later from the Library or its link, and you pick up where you left off. The clock stops for good once every letter of the grid is right.
Clicking "Solution" on a grid you are playing under your nickname first asks for confirmation: once you have seen the solution, your score on that grid (percentage of correct letters and time) can no longer improve and stays as it was. Choose "Solution" to show it anyway, or "Keep playing" to go back to the grid.
At the top left of the grid, a statistics button shows how many words the grid holds for each length, longest first.
To the right of the grid, a ranking lists the 10 best players of that grid: first by how much of the grid they filled in correctly, then by the fastest time. Each line shows the rank, the nickname, the percentage of correct letters and the time. If you are not among the 10, your own rank is shown below them.
Two buttons above the grid help you check your progress:
- Solution reveals every letter of the finished grid; click it again to go back to your own answers (nothing you typed is lost).
- Check highlights what you've filled in so far: correct letters turn green, wrong ones turn red; click it again to return to the plain grid.
There is also a Definitions button that shows or hides the clue lists, and a Recompute button that rewrites all the clues for the grid you're looking at (the layout and answers stay the same). The recomputed grid replaces the one on screen and is saved as a new entry in the Library, with a version marker added to its title ("Graines" becomes "Graines (V2)", recomputing again gives "(V3)", and so on) — the grid you started from is left untouched.
Building a grid yourself (Interactive mode)
Pick "Interactive" in the Mode menu (above "Flash") and click "Generate grid". Instead of building the whole grid for you, the app gives you a black-cell layout with a single word placed and lets you do the rest by hand. The Dictionary panel opens automatically as soon as you enter this mode, so you can look up words while you fill in the grid:
- "Next" places one more word for you wherever it fits best, picked at random from among the best candidates for that spot — so undoing it and clicking again usually offers a different word; "Back" undoes the last change, one step at a time.
- You can click any cell and type a letter, press Space (or any punctuation key) to add or remove a black cell — mirrored according to the "Symmetry" menu — or Delete to clear a cell. Ctrl, or a second click on the selected cell, flips the horizontal/vertical direction the cursor moves in.
- A "Challenge Words" box beside the grid lets you list words you want to see in the finished puzzle: type one and click + (or just type a space or other punctuation right after it) to add it, or − next to a listed word to remove it. Any listed word that fits where you're currently looking shows up first, in green, whenever you ask the app for word suggestions. Within its own list, a word turns green once it's actually in the grid; clicking a word there drops it straight into the grid at the selected cell, replacing whatever letters or black cells were already in the way. "Next" also tries reshaping the black-cell layout itself — without ever disturbing a word you've already placed — to make room for a listed word with no matching-length gap anywhere yet, before falling back to its usual choices. It also avoids placing a listed word wherever doing so would leave a crossing word with no way to be completed — it tries another listed word or another spot first, and only places an ordinary word instead once none of them work.
- Once the grid is full, write a definition for each word (a "Suggest a definition" button asks the language model for a handful of ideas you can click through and pick from, "Correct" next to it fixes the typos, agreement mistakes, missing accents, missing spaces, a missing initial capital and a wrong word order in the definition you typed while keeping your wording, "Definitions" fills in one automatically for every valid word that still lacks one, "Recompute" rewrites the definitions of every valid word (after asking you to confirm when that replaces existing ones), and "Check" points you at any word still missing one), pick a title — "Suggest a title" offers up to 10 clickable ideas the same way, and its own "Correct" button fixes the title you typed — then click "Publish" — your creation goes into the Library, shown with your nickname and a "(Création)" tag. A "Save" button (left of "Publish", available at any point) keeps a draft in your "Créations" list without publishing it. If the "Theme" field (above "Generate grid") has something in it, both "Suggest" buttons lean their suggestions toward it; opening an existing themed grid for editing (see "Library" below) fills this field back in automatically from that grid's own theme. The same goes for the Challenge Words box: a grid generated (or published) with words listed there — whether typed on the main form before generating or added here — shows that same list again the moment it's reopened for editing.
- If you don't want to place every remaining word by hand, click "Finir la grille" at any point: it permanently locks every letter you've already placed and lets the automatic grid generator take over from there, filling in the rest (adding black cells where needed). It writes no definitions: yours are kept, and the "Definitions" button fills in the missing ones afterwards. The screen switches to the same live preview you'd see for an ordinary automatic generation, and your already-placed letters are shown framed in light green throughout.
Library
The "Library" button (always visible, top right of the form) opens a list of every grid you've ever generated on this server — its language, date, title, difficulty, size, and how many players have tried it, 20 per page, most recent first. A language filter lets you narrow the list to one language, or to "Bilingue" / "Bilingual" for every grid made of two languages, and a level filter narrows it to Easy, Medium, or Hard grids ("All levels" by default). Click a row to load that grid straight into the player, exactly as if it had just finished generating.
Each row also has a shareable "Play" link, an Export column with a PDF download of the empty grid (one A4 landscape page, sized so the grid and all its clues fit; for a grid with a side above 20 cells, two pages — the grid, then all the clues) and, next to it, a .puz download (the Across Lite format most crossword apps open), and a small pencil button that opens the grid in Interactive mode with all its letters and clues already filled in — handy for editing an existing grid. Opening one that way starts a fresh entry in your "Créations" list and never changes the stored grid. When you publish your edit, its row in the Library shows a note of which grid it came from — its title, author, and date — right under the new title.
If two people generate grids around the same time, each generation waits its turn in one of two short queues (one for building the grid itself, one for writing its definitions) so the machine isn't asked to do too much at once — the status line shows your place in line while you wait. While waiting, you can always browse and play a grid from the Library instead — yours will be added there automatically the moment it's ready.
Dictionary
The "Dictionnaire" / "Dictionary" button opens a small panel for looking words up in the chosen language:
- "Chercher" / "Search" lists every word with the same root as what
you typed (accents and case don't matter), each with its real
definitions and, when known, how common it is ("usage : X/5": 5 for
everyday vocabulary down to 0 for a practically unknown word). These
usage ratings also make grids favour everyday words; they are written
once per language by the local language model
(
data_builder/build_usage_scores.py fr— a long run, about a day for French). - "Synonymes" / "Synonyms" lists every word close in meaning to what you typed, most similar first, on one comma-separated line.
- "Thématique" / "Theme" does the same, but first asks the language
model to widen what you typed into a list of related keywords, so it
brings back a broader, theme-like vocabulary (a few seconds slower).
Both of these need two optional extra services running — a local
embedding server (
./run_embed.sh) and the Qdrant vector database (./Install_qdrant.shonce, then./run_qdrant.sh), with the word index built bypython -m data_builder.qdrant_populate --all. If any of that isn't set up, the button just shows a short "unavailable" message and everything else keeps working. - "Définir" / "Define" asks the language model for up to 10 definitions of what you typed.
- Five buttons with the logos of Perplexity, ChatGPT, Claude, Mistral and Euria open that assistant in a new tab, already asked to suggest crossword definitions for the word you typed and to explain all of its meanings. If the Thématique field of the creation form holds words, they are added to the request as a thematic hint.
If you're playing a bilingual grid (or you've picked two different languages in the generation form), the Dictionary's own language selector also offers a combined "<language 1>/<language 2>" option, selected by default in that case — pick it and every button above searches both languages at once, showing the two results side by side.
Paraphraser
Right next to "Dictionnaire" / "Dictionary" is a "Paraphraseur" / "Paraphraser" button: type a sentence, pick a language, and click "Paraphraser" / "Paraphrase" to get 5 alternative ways to say the same thing. Just like the Dictionary, a bilingual grid (or two different languages picked in the generation form) adds a combined language option and shows the 5 paraphrases for each language side by side. The same five assistant logos as in the Dictionary (Perplexity, ChatGPT, Claude, Mistral, Euria) open that assistant in a new tab, already asked for 5 paraphrases of your text.
Chatting with David FALCON
A small chat panel, open by default in the bottom-right corner of the page, lets you talk to David FALCON, an in-app assistant. Ask it how to use a feature of the page, or for a hint on the word you currently have selected in the grid — it can see the whole grid's clues and answers, and replies in whatever language you've chosen. It only answers questions about this app or about solving the current grid; for anything else, it will politely point you elsewhere. Click the small button in its title bar to collapse or reopen it.
Asking DevBot how grids are built
The page /DevBot.html (for instance http://127.0.0.1:3000/DevBot.html)
shows a second assistant, DevBot, on its own. It answers questions
about how the grid-generation algorithm works, from the project's
technical documentation only, and replies in your language (the one
chosen on the main page, otherwise your browser's). That documentation is
long: the language model serving the app needs a context window of about
45,000 tokens or more for DevBot to answer.
Going further
A technical document, for developers who want to understand or modify how the app works internally, will be added separately.
License
CrossWordFalcon is released under the MIT License — a permissive license that lets you use, copy, modify, and redistribute the software freely, for any purpose, as long as the copyright notice and the license text are kept in copies. The software is provided "as is", without warranty of any kind. See the LICENSE file for the full text.
来源:GitHub · github.com
