FC-SOLVE(6)
๐ FC-SOLVE(6) ๐
โจ NAME โจ
fc-solve โ automated solver for Freecell and related Solitiare variants
๐ธ INTRODUCTION ๐ธ
okay so this is Freecell Solver version 6.16.x, and it's literally a program that automatically solves most layouts of Freecell, and similar Solitaire variants as well as those of Simple Simon. slay.
Freecell Solver is distributed under the MIT/Expat License ( http://en.wikipedia.org/wiki/MIT_License ), a free, permissive, open-source license. ๐
Note that the Freecell Solver source and Win32 binary distributions do not provide a graphical user-interface (GUI) and are primarily meant to be used by Solitaire researchers and software developers. If youโre looking for a suitable GUI based on Freecell Solver, see our links at: http://fc-solve.shlomifish.org/links.html#front_ends
I hope youโll enjoy using Freecell Solver, and make the best of it. ๐ซถ
โ Shlomi Fish ( http://www.shlomifish.org/ )
๐ ๏ธ BUILDING ๐ ๏ธ
Read the file INSTALL.txt for information on how to do that. no cap.
๐ USAGE ๐
The program is called fc-solve. You invoke it like this:
fc-solve board_file
board_file is the filename with a valid Freecell startup board. The file is built as follows:
- It has the 8 Freecell stacks.
- Each stack contains its cards separated by a whitespace and terminated with a newline character ( itโs important that the last stack will also be terminated with a newline !). The cards in the line are ordered from the topmost card (= the card right on the virtual table and the one with the most cards placed on it) in the left, to the bottommost card in the right (= the card with no other cards placed on it).
- A card string contains the rank of the card followed by its suit. The card number is one of:
A,1,2,3,4,5,6,7,8,9,T,J,Q,K. Alternatively,10can be used instead ofT, but using that is discouraged and is only supported for backward compatibility. The card suit is one of:H,S,D,C(standing for Hearts, Spades, Diamonds and Clubs respectively).
Here is an example board: (PySol/Microsoft board No. 24)
4C 2C 9C 8C QS 4S 2H
5H QH 3C AC 3H 4H QD
QC 9S 6H 9H 3S KS 3D
5D 2S JC 5C JH 6D AS
2D KD TH TC TD 8D
7H JS KH TS KC 7C
AH 5S 6S AD 8H JD
7S 6C 7D 4D 8S 9D
Visually, it appears as this:
[Freecell Deal No. 24]
As can be seen, the four of clubs (4C), five of hearts (5H), etc. are at the bottom of the stacks and the start of the lines in the board input.
And another one: (PySol board No. 198246790)
KD JH 5H 7D 9H KC 9D
3H JD 5D 8H QH 7H 2D
4D 3S QC 3C 6S QS KS
TC 9S 6D 9C QD 8S TD
TS 8C 7S TH 2C AS
8D AC AH 4H JC 4C
6H 7C 4S 5S 5C JS
AD KH 6C 2H 3D 2S
Starting from Freecell Solver 3.14.x, a stack can also start with a leading colon (:). This is to allow input from states as output by Freecell Solver using the -p option.
You can specify the contents of the freecells by prefixing the line with FC: or with Freecells:. For example:
FC: 3H QC
will specify that the cards 3 of hearts and queen of clubs are present in the freecells. To specify an empty freecell use a - as its designator.
If thereโs another FC: line, the previous line will be overridden.
You can specify the contents of the foundations by prefixing the line with Founds: or with Foundations: and then using a format as follows:
Founds: H-5 C-A S-0 D-K
Hence, the suit ID followed by a dash followed by the card number in the foundation. A suit that is not present will be assumed to be 0. Again, if thereโs more than one line like that, then the previous lines will be ignored and overridden.
The program will stop processing the input as soon as it read 8 lines of standard stacks. Therefore, it is recommended that the foundations and freecells lines will come at the beginning of the file.
The program will process the board and try to solve it. If it succeeds it will output the states from the initial board to its final solution to the standard output. If it fails, it will notify it.
For information about the various command-line switches that Freecell Solver accepts, read the USAGE.txt file in this directory.
To solve Simple Simon boards append --game simple_simon right after the fc-solve program name.
๐ THE BOARD GENERATION PROGRAMS ๐
Several programs which can generate the initial boards of various Freecell implementations can be found in the board_gen/ sub-directory. Read the README.txt file there for details on how they can be compiled and used.
In any case, they can save you the time of inputting the board yourself. ๐
๐ SOME COMPLETE EXAMPLES FOR LAYOUTS ๐
A layout in the middle of the MS Freecell deal No. 109 solution:
Foundations: H-6 C-9 D-2 S-0
Freecells: QS 3S 2S KD
: 8H 3D
: KS QD JC
: AS 8D TD 7D JH TS 9D
: 7S 6D
: 5S
: KH QC JD TC 9H 8S 7H 6S 5D 4S
: KC QH JS TH 9S
: 4D
Similar, but with an empty Freecell:
Foundations: H-6 C-9 D-2 S-0
Freecells: QS 3S - KD
: 8H 3D 2S
: KS QD JC
: AS 8D TD 7D JH TS 9D
: 7S 6D
: 5S
: KH QC JD TC 9H 8S 7H 6S 5D 4S
: KC QH JS TH 9S
: 4D
Likewise, only without leading colons where unnecessary:
Foundations: H-6 C-9 D-2 S-0
Freecells: QS 3S - KD
8H 3D 2S
KS QD JC
AS 8D TD 7D JH TS 9D
7S 6D
5S
KH QC JD TC 9H 8S 7H 6S 5D 4S
KC QH JS TH 9S
4D
๐ฅ HOW TO READ THE SOLUTIONS ๐ฅ
The file USAGE.txt covers all of Freecell Solverโs command line options, but it may be too exhaustive for casual users. As a result, here is a shorter tutorial. First of all whenever invoking fc-solve one should add the flags -p -t -sam -sel which will make the solution easier to understand. Then, assuming the board could be successfully solved, one will be given the layouts in the solution (in the format given above) vis-a-vis with the moves as the string. Note that the indexes of the resources given in the moves are 0-based rather than the more natural 1-based notation.
๐ THE PROGRAMS ๐
Most command-line switches have two versions:
- A short POSIX one which is a dash followed by a letter or a few. This option must come standalone and not clustered:
-samis not equivalent to specifying-s,-aand-m. - A long switch which is two dashes followed by the command string. For example:
--prelude,--st-name.
If command line arguments have parameters, they are followed in separate parameters - Freecell Solver wonโt recognise a parameter preceded by an equal sign. --st-name=myname is invalid, while --st-name myname is OK.
๐ธ The Scope of the Options ๐ธ
The scope of the options is mentioned along with them. Options can be:
- Global - affects all the soft-threads.
- Instance-specific - affects an instance (separated by the
--next-instanceoption below). Each instance consists of several flares. - Flare-specific - affects the current flare (separated by the
--next-flareoption below. Each flare consists of several hard threads. - Hard-thread-specific - affects the current hard thread (separated by the
--next-hard-threadoption below. Each hard thread consists of several soft threads. - Soft-thread-specific - affects only the current soft thread.
๐ซถ GETTING HELP ๐ซถ
-h,--helpโ Global โ This option displays a help text on the screen. This help gives a help display summarizing some ways to use the program and get more help.--versionโ Global โ This option displays the version number of the components that make the executable (and then exits).--help-configsโ Global โ Some help on the various configurations of Freecell Solver.--help-optionsโ Global โ A help screen giving an overview of all available options.--help-real-helpโ Global โ Explains how to change the default help screen to a different one.--help-short-solโ Global โ How to generate shorter solutions.--help-summaryโ Global โ The default help screen.
๐ OUTPUT OPTIONS ๐
okay bestie, this is where you get to pick how fc-solve shows you the tea. every single one of these is Global, which means it applies to the whole run, not to some lil sub-thing. let's get into it ๐
โจ -p, --parseable-output โจ
Global
this one is giving machine-readable main character energy. it shows the columns in a format that's way easier for text-processing programs like grep or perl to chew on. specifically: the freecells show up all on one line, and the foundations get their own separate line. plus, each column gets printed horizontally, on its own line, and starts with a :.
โจ -t, --display-10-as-t โจ
Global
instead of showing the 10 cards as 10, this displays them as a capital T. so everything lines up all pretty and aligned. โจ
for example, here's a command line using both -p and -t:
$ pi-make-microsoft-freecell-board 24 | fc-solve -p -t
-=-=-=-=-=-=-=-=-=-=-=-
Foundations: H-0 C-0 D-0 S-0
Freecells:
: 4C 2C 9C 8C QS 4S 2H
: 5H QH 3C AC 3H 4H QD
: QC 9S 6H 9H 3S KS 3D
: 5D 2S JC 5C JH 6D AS
: 2D KD TH TC TD 8D
: 7H JS KH TS KC 7C
: AH 5S 6S AD 8H JD
: 7S 6C 7D 4D 8S 9D
====================
Foundations: H-0 C-0 D-0 S-A
Freecells:
: 4C 2C 9C 8C QS 4S 2H
: 5H QH 3C AC 3H 4H QD
: QC 9S 6H 9H 3S KS 3D
: 5D 2S JC 5C JH 6D
: 2D KD TH TC TD 8D
: 7H JS KH TS KC 7C
: AH 5S 6S AD 8H JD
: 7S 6C 7D 4D 8S 9D
โจ -c, --canonized-order-output โจ
Global
so Freecell Solver lowkey re-arranges the stacks and freecells in a given state based on their first card. it keeps their actual position stashed away somewhere separate, but internally it vibes with the canonized place instead. use this option if you want Freecell Solver to display them in that order.
โ ๏ธ fair warning bestie: that way, the place of a given stack in the board will not be preserved throughout the solution. so if you're tracking positions, that's gonna get messy. ๐ญ
โจ -m, --display-moves โจ
Global
this one shows you the moves instead of the intermediate states. each move gets its own separate line, in a format that's human-readable but can also be parsed and analyzed by a computer program โ with some effort on the programmer's part, ngl.
for example:
$ pi-make-microsoft-freecell-board 24 | fc-solve -m | head -30
-=-=-=-=-=-=-=-=-=-=-=-
Move a card from stack 3 to the foundations
====================
Move a card from stack 6 to freecell 0
====================
Move a card from stack 6 to freecell 1
โจ -sn, --standard-notation โจ
Global
displays the moves in standard notation, where every move is exactly two characters and there are ten moves in a line. ๐
obvi this option only becomes apparent if display moves is specified โ it does not implicitly specify it, so don't come for me.
for more info on standard notation, there's this web-page:
http://www.solitairelaboratory.com/solutioncatalog.html
โจ -snx, --standard-notation-extended โจ
Global
basically the same as the previous one, except when a sequence move is made to an empty stack with more than one card in the sequence, the move gets followed with "v" and the number of cards moved in hexadecimal. fancy fr fr. ๐ฅ
โจ -sam, --display-states-and-moves โจ
Global
this one serves both the intermediate states and the moves needed to get from one to another. and yes, the standard notation option applies to it too. โจ
$ pi-make-microsoft-freecell-board 24 | fc-solve -sam -p -t | head -50
-=-=-=-=-=-=-=-=-=-=-=-
Foundations: H-0 C-0 D-0 S-0
Freecells:
: 4C 2C 9C 8C QS 4S 2H
: 5H QH 3C AC 3H 4H QD
: QC 9S 6H 9H 3S KS 3D
: 5D 2S JC 5C JH 6D AS
: 2D KD TH TC TD 8D
: 7H JS KH TS KC 7C
: AH 5S 6S AD 8H JD
: 7S 6C 7D 4D 8S 9D
====================
Move a card from stack 3 to the foundations
Foundations: H-0 C-0 D-0 S-A
Freecells:
: 4C 2C 9C 8C QS 4S 2H
: 5H QH 3C AC 3H 4H QD
: QC 9S 6H 9H 3S KS 3D
: 5D 2S JC 5C JH 6D
: 2D KD TH TC TD 8D
: 7H JS KH TS KC 7C
: AH 5S 6S AD 8H JD
: 7S 6C 7D 4D 8S 9D
====================
Move a card from stack 6 to freecell 0
Foundations: H-0 C-0 D-0 S-A
Freecells: JD
: 4C 2C 9C 8C QS 4S 2H
: 5H QH 3C AC 3H 4H QD
: QC 9S 6H 9H 3S KS 3D
: 5D 2S JC 5C JH 6D
: 2D KD TH TC TD 8D
: 7H JS KH TS KC 7C
: AH 5S 6S AD 8H
: 7S 6C 7D 4D 8S 9D
====================
Move a card from stack 6 to freecell 1
โจ -pi, --display-parent-iter โจ
Global
this option โ assuming the -s and -i options are specified โ will also show you the iteration index of the state that the current state was derived from. super useful for BeFS (the so-called a-star) or BFS scans. ๐
โจ -o [filename], --output [filename] โจ
Global
outputs to a file instead of standard output. so, like:
$ fc-solve -o 2405.solution.txt 2405.board
this will put the solution to the file in 2405.board into the file 2405.solution.txt. and you can do the exact same thing with:
$ fc-solve --output 2405.solution.txt 2405.board
โจ -sel, --show-exceeded-limits โจ
Global
this shows a different status message โ "Iterations count exceeded." โ instead of "I could not solve this game." when the iterations count was exceeded.
this one is recommended, because "I could not solve this game." can also mean that the entire game graph was fully traversed (within the limitations of the specified moves' types), and so no solution is possible. two very different moods, bestie, and you deserve to know which one you're in. ๐ญ
this option is not the default, to retain compatibility with previous versions of Freecell Solver, and was added in version3.12.0offc-solve.
โจ -hoi, --hint-on-intractable โจ
Global
presents the moves to the intermediate reached state, if the maximal number of iterations was reached without a conclusion (= "intractable"). so when it's stuck, it still gives you a lil hint. ๐ซถ
this option is not the default, to retain compatibility with previous versions of Freecell Solver, and was added in version4.20.0offc-solve.
๐ฎ GAME VARIANTS OPTIONS ๐ฎ
okay bestie this is the part where we tell the solver what game we're even playing, because "solitaire" is not one game, it's like forty games wearing the same trenchcoat ๐
--freecells-num [Number of Freecells]
Global โจ
This one tells the program how many freecells it gets to play with. Freecell Solver can rock any number of freecells, as long as it doesn't go over its maximal number. ๐
That maximum is hard-coded straight into the program, and you can set it at compile-time by editing the file config.h. Want the deets? Go read the file INSTALL (or, if you're feeling html-y, INSTALL.html). ๐
--stacks-num [Number of Stacks]
Global โจ
This sets how many stacks are chillin' on the board. And yeah, same rule as before: this number can't exceed the maximal number of stacks, which you can set in the file config.h when you compile Freecell Solver. ๐ธ
--decks-num [Number of Decks]
Global โจ
How many decks are on the board, bestie? That's this option. And โ you already know โ this number cannot exceed the maximal number of decks, which the Freecell Solver build system gets to specify. ๐ด
--sequences-are-built-by {suit|alternate_color|rank}
Global โจ
Decides whether a card sequence gets built by suit, by alternate_color, or by rank (as in, regardless of suit, we simply do not care). ๐
--sequence-move {limited|unlimited}
Global โจ
Is the sequence move limited by the number of freecells or vacant stacks, or is it not? That's literally the whole question. limited = yes it's capped, unlimited = no cap, go off. ๐
--empty-stacks-filled-by {kings|none|all}
Global โจ
Specifies which cards are allowed to fill an empty stack. Choose your fighter: kings, none, or all. ๐ซถ
--game [game] , --preset [game] , -g [game]
Global โจ
This is the main character option โ it picks the type of game. Each preset implies several of the settings options we just talked about above, and sometimes even the moves' order that's coming down below. The default configuration is for Freecell. ๐
Available presets, bestie, in all their glory:
bakers_dozenโ Bakerโs Dozenbakers_gameโ Bakerโs Gamebeleaguered_castleโ Beleaguered Castlecitadelโ Citadelcruelโ Cruelder_katzโ Der Katzenschwanzdie_schlangeโ Die Schlangeeight_offโ Eight Offfanโ Fanforecellโ Forecellfreecellโ Freecell (default)good_measureโ Good Measureko_bakers_gameโ Kings' Only Bakerโs Gamerelaxed_freecellโ Relaxed Freecellrelaxed_sehavenโ Relaxed Seahaven Towersseahavenโ Seahaven Towerssimple_simonโ Simple Simonstreets_and_alleysโ Streets and Alleys
โ ๏ธ Note, and this one's important: to solve Der Katzenschwanz and Die Schlange, I recommend you compile Freecell Solver with theINDIRECT_STACK_STATESoption, or else it will consume much more memory. For details, consult the fileINSTALL. ๐ญ
โจ Examples โจ
Wanna solve PySol Eight Off game No. 1,000? Type:
$ make_pysol_freecell_board.py 1000 eight_off | fc-solve -g eight_off
Wanna solve PySol Bakerโs Game No. 50? Type:
$ make_pysol_freecell_board.py 50 bakers_game | fc-solve -g bakers_game
And if you want to solve a game similar to Freecell but with sequences built by rank only, plus unlimited sequence move, do:
$ fc-solve -g freecell --sequences-are-built-by rank --sequence-move unlimited
๐ง SOLVING ALGORITHM OPTIONS ๐ง
this is the "how hard should the solver try" section and honestly it's giving strategy meeting ๐
-mi [Iterations num] , --max-iters [Iterations num]
Global โจ
This caps the maximal number of states to check. It gives you a rough limit on how much time gets spent solving a given board. โณ
-md [Maximal depth] , --max-depth [Maximal depth]
Not currently implemented ๐
So, Freecell Solver recurses into the solution, right? This parameter specifies a maximal recursion depth. But generally speaking, setting it is not a good idea, because that way several important intermediate states may become inaccessible. So likeโฆ maybe don't. ๐
-mss [num] , --max-stored-states [num]
Global โจ
Limits how many states the program stores in the computer's memory. And the way this differs from the maximal number of iterations is that it's totally possible a stored state was not checked yet. ๐
-tmss [num] , --trim-max-stored-states [num]
Instance-wide โจ
This also limits the number of trimmed stored states, but this time it'll try to trim them once the limit has been reached โ which is time consuming and may cause states to be traversed again in the future. ๐ญ worth knowing!
-to [Movesโ Order] , --tests-order [Moves Order]
Soft-thread-specific โจ
This one sets the order in which Freecell Solver tries the different types of moves โ formerly called "tests", iykyk. Each move is specified by one character, and they're performed in the order they appear in the parameter string. And you can omit moves entirely by just not including their corresponding characters in the string. ๐ฏ
The moves, and the lil character that summons each one: ๐
๐ธ Freecell Moves
0โ put top stack cards in the foundations โจ1โ put freecell cards in the foundations ๐2โ put freecell cards on top of stacks ๐3โ put non-top stack cards in the foundations ๐4โ move stack cards to different stacks ๐ฆ5โ move stack cards to a parent card on the same stack ๐ธ6โ move sequences of cards onto free stacks ๐7โ put freecell cards on empty stacks ๐ซถ8โ move cards to a different parent ๐ฅ9โ empty an entire stack into the freecells ๐jโ put freecell cards on empty stacks and right away put cards on top ๐
๐ Atomic Freecell Moves
Aโ move a stack card to an empty stack โญBโ move a stack card to a parent on a different stack ๐Cโ move a stack card to a freecell ๐Dโ move a freecell card to a parent ๐งEโ move a freecell card to an empty stack ๐
๐ Simple Simon Moves
aโ move a full sequence to the foundations โจbโ move a sequence to a true parent of his ๐cโ move a whole stack sequence to a false parent (in order to clear the stack) ๐dโ move a sequence to a true parent that has some cards above it ๐ฆeโ move a sequence with some cards above it to a true parent ๐ธfโ move a sequence with a junk sequence above it to a true parent that has some cards above it ๐gโ move a whole stack sequence to a false parent which has some cards above it ๐ซถhโ move a sequence to a parent on the same stack ๐ฅiโ move any sequence to a false parent (using it may make the solution much slower) ๐
okay bestie, real talk: messing with the moves order can be so helpful for getting a quick solution on a given board. If you found that a certain board cannot be solved after a long time, or in a certain maximal number of iterations, you should try different moves' orders. Usually, one can find a moves order that solves a board very quickly. ๐โโ๏ธ๐จโจ
okay so real talk about that moves' order: it usually only makes sense for the Soft-DFS and Random DFS scans (peep the --method option further down ๐).
And also, no cap: Freecell moves are not suitable for solving Simple Simon games, and Simple Simon moves are not suitable for solving anything except Simple Simon. That's just how it is. ๐
You can group moves together into groups using parentheses, like "(0123)", or square brackets, like "[012][3456789]". That grouping is only relevant to the Random DFS scan (see below ๐). A group can optionally be followed by the equal sign "=" and by an ordering specifier:
- if you specify
"=rand()", the derived states get randomised based on the seed โ which is literally what happens when no equal sign is specified at all ๐ฒ - but if you specify something like
"=asw(5,0,5,0,0,5)", then those numbers inside the parentheses get treated as weights for the same ordering function used by the-aswflag (see below, iykyk โจ)
And if the order specifier is "=all()", then all the moves in the group will be run, even if some derived states have already been yielded by earlier moves in the group. (This was added in version 5.24.0. ๐)
-dto2 [Min Depth],[Moves' Order], --depth-tests-order2 [Min Depth],[Moves' Order]
Soft-thread-specific ๐งต
Sets the Moves' order starting from the minimal depth onwards. So like, if a Soft-DFS scan recurses super deep into the game, it'll switch up to a different moves' order. Main character energy, honestly. ๐
Careful though โ if you set the moves' order of a minimal depth of say 50, it overrides all the moves' order of 50 and above. Which is why it's recommended that you set the minimal depth moves order in an increasing depth. ๐
Also worth clocking: the -to or --tests-order option above is equivalent to using this option with a minimal depth of 0. โจ
Here are some examples:
-to 0123456789 -dto2 30,0138924567
This sets the moves' order to 0123456789 for all depths below 30 and to 0138924567 for all depths above it. ๐
-to 0123457 -dto2 10,750123 -dto2 25,710235
This sets the moves' order to 0123457 for depths -9 (those below 10), to 750123 for depths 10-24, and to 710235 for the depths 25 onwards. ๐ฆ
-to 0123457 -dto2 "10,[012357]=asw(1)"
This sorts the moves starting from 10 onward based on the asw() function. ๐ฅ
-to 0123457 -dto2 "10,[012357]=rand()"
This randomises the moves from 10 onward. ๐ฒ
-to 0123457 -dto2 "10,[012357]"
This does the same thing as the previous example. (Yes, fr fr, same vibe.) ๐ธ
Note: this option should be used instead of the older -dto option given below, which mutilates the moves order parameter and is still provided for backward compatibility. ๐
-dto [Min Depth],[Moves' Order], --depth-tests-order [Min Depth],[Moves' Order]
This is equivalent to specifying -dto2 [Min Depth],[Min Depth],[Moves' Order] โ i.e: the "[Min Depth]," string is prefixed to the given moves order.
This option is provided for backward compatibility with older versions of Freecell Solver. It's giving legacy code, but respectfully. ๐ซถ
-me [Solving Method], --method [Solving Method]
Soft-thread-specific ๐งต
This option specifies the solving method that will be used to solve the board. Currently, the following methods are available:
a-starโ A Best-First-Search scan (not "A*", as it was once thought to be ๐)bfsโ A Breadth-First Search (or BFS) scandfsโ A Depth-First Search (or DFS) scanrandom-dfsโ A randomized DFS scanpatsolveโ uses the scan of patsolvesoft-dfsโ A "soft" DFS scan
Starting from recent Freecell Solver versions there is no difference between dfs and soft-dfs. In earlier versions, use of soft-dfs is recommended. And random-dfs is similar to soft-dfs only it determines which states to recurse into randomly. Its behaviour will differ depending on the seed you supply to it (see the -seed option below ๐ฑ).
BFS does not yield good results, and a-star has a mixed behaviour, so for the time being I recommend using Soft-DFS or Random-DFS. Slay. ๐
The Random-DFS scan processes every moves' random group, randomizes the states that it found, and recurses into them one by one. Standalone moves that do not belong to any group are processed in a non-random manner. ๐
-asw [BeFS Weights], --a-star-weight [BeFS Weights]
Soft-thread-specific ๐งต
Specify weights for the a-star (= "Best-First Search") scan, assuming it is used. The parameter should be a comma-separated list of numbers, each one proportional to the weight of its corresponding test. ๐ข
The numbers are, in order:
- The number of cards out.
- The maximal sequence move.
- The number of cards under sequences.
- The length of the sequences which are found over renegade cards.
- The depth of the board in the solution.
- The negative of the number of cards that are not placed above their parents. To get the irreversibility depth, give equal weight to this weight and to the number of cards out. โจ
The default weights are respectively: {0.5, 0, 0.3, 0, 0.2, 0}
-seed [Seed Number]
Soft-thread-specific ๐งต
Specifies a seed to be used by Freecell Solver's internal random number generator. This seed may alter the behaviour and speed of the random-dfs scan. ๐ฑโจ
--set-pruning [Pruning], -sp [Pruning]
Soft-thread-specific ๐งต
This option sets the pruning algorithm for the soft thread. Current valid values are the empty string ("") for no pruning, and r:tf (short for "Run: to foundations") for Horne's rule. See:
https://groups.yahoo.com/neo/groups/fc-solve-discuss/conversations/topics/214
To move one-card columns to the freecells when possible, use r:oc. ๐
If the string contains both r:tf and r:oc, then both will be attempted. Double the pruning, double the chaos. ๐
-opt, --optimize-solution
Flare-wide โ๏ธ
This option instructs Freecell Solver to try and optimize the solution path so it will have a smaller number of moves. Shorter solutions are just... better? Iconic behaviour, honestly. ๐
-opt-to [moves order], --optimization-tests-order [moves order]
Flare-wide โ๏ธ
This argument specifies the moves order for the optimization scan, in case it should be different than an order that contains all the moves that were used in all the normal scans. ๐ธ
--reparent-states
Flare-wide โ๏ธ
This option specifies that states that were encountered whose depth in the states graph can be improved should be reparented to the new parent. This option can possibly make solutions shorter. No promises, but potentially slay. โจ
--calc-real-depth
Flare-wide โ๏ธ
This option becomes effective only if --reparent-states is specified. What it does is explicitly calculate the depth of the state by tracing its path to the initial state. This may make depth consideration more accurate. ๐
--patsolve-x-param [pos],[value]
Soft-thread-specific ๐งต
Sets the patsolve's scan X param (an integer) in position "pos" into "value".
Examples:
--patsolve-x-param 0,5
--patsolve-x-param 2,100
--patsolve-y-param [pos],[value]
Soft-thread-specific ๐งต
Sets the patsolve Y param (a floating point number) in position "pos" into "value".
Examples:
--patsolve-y-param 0,0.5
--patsolve-y-param 1,103.2
RUNNING SEVERAL SCANS IN PARALLEL ๐โ๏ธ๐จ
Okay bestie, listen โ starting from Version 2.4.0, Freecell Solver can run several scans in parallel on the same state collection. Each scan gets to live in its own little "Soft Thread". So if you specify a bunch of soft threads on the command line, you're basically creating and running several task-switched scans at once. And the moment one of the scans reaches a solution, boom โ the solution gets displayed. Slay. โจ
-nst,--next-soft-threadโ Hard-thread-specific
This option creates a new soft-thread and makes all the following scan-specific options initialize it. Like, for example:
$ fc-solve --method a-star -nst --method soft-dfs -to 0123467 myboard.txt
which will run an BeFS scan and a Soft-DFS scan with a moves order of 0123467 on myboard.txt. Two scans, one board, we love to see it. ๐
-step [Step],--soft-thread-step [Step]โ Soft-thread-specific
This one sets the number of iterations with which to run the soft thread before switching over to the next one. So if you give a certain scan a larger step, you're basically handing it a longer run-time and a higher priority. Queen behavior.
Note: after some experimentation, we have concluded that the--preludeoption normally yields better results, but-stepcan be used as a fallback. So like,--preludeis the main character here, and-stepis the trusty understudy. ๐
-nht,--next-hard-threadโ Flare-wide
This argument lets you initialize the next hard thread. If Freecell Solver was compiled with such support, then it's possible to run each hard thread in its own system thread. And each hard-thread contains one or more soft threads. Threads within threads, it's giving inception fr fr. ๐
--st-name [soft thread name]โ Soft-thread-specific
Sets the name used to identify the current soft thread. And this name can later be used to construct the prelude (see below, bestie, it's right there ๐).
--prelude [\i1@st1{,\i2@st2{,\i3@st3...}}]โ Hard-thread-specific
Sets the prelude for the hard thread. At the beginning of the search, the hard thread plays a static sequence of iterations</badge> at each of the soft threads specified in the prelude, for however many iterations you specified.
So like, imagine you had three soft threads named "foo", "bar" and "rin". Then this prelude:
--prelude 500@foo,1590@bar,100@foo,200@rin
Will run 500 iterations in "foo", then 1590 in "bar", then 100 in "foo" again, and then 200 in "rin". And once the prelude finishes? The hard thread runs the scans one after the other in the sequence they were defined for their step number. Iconic sequencing. ๐
--scans-synergy {none|dead-end-marks}โ Flare-wide
Specifies the synergy between the various scans โ aka how much they cooperate with each other. none means they do not cooperate and only share the same memory resources. dead-end-marks means they try to mark states that they have withdrawn from, and states whose all their derived states are such, as "dead ends". This may or may not improve the speed of the solution. (ngl it's a vibe check situation, sometimes yes sometimes no ๐)
-ni,--next-instanceโ Global
This option lets you run two or more separate solvers one after the other. If the first one returned an unsolvable verdict, then the second one would run, and so on. One use of it is to run an atomic moves scan after a meta-moves scan, so we will always get an accurate verdict and still enjoy some of the speed benefits of the meta-moves scan. Best of both worlds, no cap. ๐ฅ
-nf,--next-flareโ Instance-wide
Each instance contains several flares. Flares are various alternative scans that are ran one after another, as specified in the --flares-plan below or defaulting to running only the first flare (which isn't very useful, lowkey ๐). Out of all the flares that are successful in solving a board, Freecell Solver picks the one with the shortest solution. Queen picks the best one, periodt.
--flare-name [flare name]โ Flare-wide
This is a name that identifies the flare for use in the flares' plan.
--flares-plan [flare plan]โ Instance-wide
This instance-wide parameter gives a plan for the flares as a big string. Here are some examples:
--flares-plan "RunIndef:FlareyFlare"
This plan will run the flare with the name FlareyFlare indefinitely, until it terminates. And once a RunIndef action is encountered, the rest of the plan is ignored.
--flares-plan "Run:500@MyFlare,Run:2000@FooFlare"
Runs MyFlare for 500 iterations and FooFlare for 2,000 iterations. Note that both flares will be run and won't share any resources between them, and then the minimal solution out of both flares (or only those that finished). If no flares finished, then Freecell Solver will run them both again for the same number of iterations each, until at least one finishes (or it ran out of the iterations' limit). Determination fr fr ๐ช
--flares-plan "Run:500@dfs,Run:1500@befs,CP:,Run:10000@funky"
This runs the flares identified by dfs and befs and then see if a solution was reached ("CP:" stands for "checkpoint"), and if so yield it. If both flares did not reach a solution yet, or failed to solve the board, it will run the flare funky for 10,000 iterations and yield its solution. And like the previous case, this solution will loop after it ended for as long as the no flare solved the board or the program did not run out of iterations.
Using checkpoints one can yield a possibly sub-optimal (as far as solution length is concerned) solution that will still solve faster than letting all the flares run. Sometimes you just gotta take the W you can get. ๐ซถ
--flares-choice [choice]โ Global
This dictates how to choose the winning flare based on if more than one yielded a solution. Possible options are:
--flares-choice fc_solveโ the default, which picks up the solutions based on the length of the solution in Freecell Solver's moves.--flares-choice fcproโ picks up the shortest solution based on the number of Freecell Pro moves, while not considering implicit moves to the foundations using Horne's Prune / Raymond Prune.
-fif [factor],--flares-iters-factor [factor]โ Global
Sets a global, floating-point number, factor, to multiply all the iterations counts in the flares plans. The higher it is, the longer the scans will take, but there is a greater chance more of them will succeed, and, as a result, the solution may be shorter. Trade-offs, bestie, it's all trade-offs. โ๏ธ
As an example, the following:
--flares-plan "Run:500@MyFlare,Run:2000@FooFlare" --flares-iters-factor 2
Is equivalent to:
--flares-plan "Run:1000@MyFlare,Run:4000@FooFlare"
while:
--flares-plan "Run:500@MyFlare,Run:2000@FooFlare" --flares-iters-factor 0.5
Is equivalent to:
--flares-plan "Run:250@MyFlare,Run:1000@FooFlare"
--cache-limit [cache limit]โ Global
This is a numeric limit to the LRU cache which only matters if Freecell Solver was compiled with FCS_RCS_STATES enabled. This value should be a positive integer and the higher it is, the more quickly it is likely that Freecell Solver will run, but it will also consume more memory. (The entire point of FCS_RCS_STATES is to conserve memory). So like, it's a memory-versus-speed moment. Pick your fighter. ๐
META-OPTIONS ๐งโจ
--resetโ Global
This option resets the program to its initial state, losing all the configuration logic that was input to it up to that state. Afterwards, it can be set to a different configuration, again. Fresh start, clean slate, new me energy. ๐ธ
--read-from-file [num_skip,]filenameโ Global (but context-specific).
This option will read the configuration options from a file. The format of the file is similar to that used by the UNIX Bourne Shell. (i.e: spaces denote separate arguments, double-quotes encompass arguments, backslash escapes characters).
The filename can be preceded by an optional number of the arguments to skip followed by a comma. (the default is 0)
-l [preset],--load-config [preset]โ Global (but context-specific).
Reads the configuration specified by [preset] and configures the solver accordingly. A preset is a set of command line arguments to be analyzed in the place of this option. They are read from a set of presetrc files : one installed system-wide, the other at $HOME/.freecell-solver/presetrc and the third at the path specified by the FREECELL_SOLVER_PRESETRC environment variable. You can add more presets at any of these places. (refer to http://groups.yahoo.com/group/fc-solve-discuss/message/403 for information about their format)
Presets are literally the "save your fave settings" feature bestie, use them. ๐
Presets that are shipped with Freecell Solver: ๐
abra-kadabraโ a meta-moves preset โจamateur-starโ a meta-moves preset that yields solutions faster on average thanthree-eighty๐ฆblue-yonderโ a meta-moves preset generated by a quota optimization algorithm ๐children-playing-ballโ a meta-moves and flare-based preset that tends to yield very short solution, but is very slow (solves only 3 boards per second on a Pentium 4 2.4GHz) ๐ญconspiracy-theoryโ a meta-moves preset that yields solutions faster on average thanamateur-star๐cookie-monsterโ a meta-moves preset that yields solutions faster on average thanone-big-family๐ชcool-jivesโ a meta-moves preset ๐crooked-noseโ an atomic-moves preset (guarantees an accurate verdict) ๐ฅenlightened-ostrichโ a meta-moves preset (that depends on Freecell Solver3.4.0and above) that yields solutions faster on average thanfoss-nessy๐ฆฉfools-goldโ an atomic-moves preset โจfoss-nessyโ a meta-moves preset (that depends on Freecell Solver3.2.0and above) that yields solutions faster on average thanthe-iglu-cabal๐งgood-intentionsโ runs"cool-jives"and then"fools-gold"๐ซถgooey-unknown-thingโ a meta-moves preset that aims to minimise the outcome solution's length ๐hello-worldโ a meta-moves preset ๐ธjohn-galt-lineโ a meta-moves preset ๐looking-glassโ a meta-moves preset that yields solutions faster on average thancookie-monster๐ชmaliciously-obscureโ a meta-moves and flare-based preset that tends to yield very short solutions (even in comparison tochildren-playing-ball) but is slow ๐micro-financeโ a meta-moves and flare-based preset that tends to yield very short solutions (even in comparison to
โฆmaliciously-obscure ) but is even slower. ๐
okay bestie, we're back in the preset menu and it's giving choices. here's the rest, fr fr:
micro-finance-improvedโ a meta-moves and flare-based preset, based onmicro-financethat yields somewhat shorter solutions on average, and should not be slower. โจone-big-familyโ a meta-moves preset that yields solutions faster on average thanconspiracy-theory. ๐ฅqualified-seedโ a meta-moves and flare-based preset, based onmicro-finance-improvedthat yields somewhat shorter solutions on average, and should not be slower. ๐qualified-seed-improvedโqualified-seedwith-fif 5and--flares-choice fcpro๐rin-tin-tinโ a meta-moves preset ๐ถsand-stoneโ an atomic-moves preset that aims to minimise the outcome solutionโs length. ๐๏ธslick-rockโ run"gooey-unknown-thing"and then"sand-stone"๐ชจsentient-pearlsโ a meta-moves and flares based preset with short solutions. Much faster thanchildren-playing-ballbut yields less optimal solutions. ๐ฆชtea-for-twoโ a meta-moves preset optimized fortwo-freecells' Freecellgames (although it can work on other Freecell-like games as well). ๐ซthe-iglu-cabalโ a meta-moves preset that yields faster solutions on average thanblue-yonder. โ๏ธthe-last-mohicanโ a preset for solving Simple Simon. Yields less false negatives than the default one, but might be slower. ๐ชถthree-eightyโ a meta-moves preset (that depends on Freecell Solver 3.4.0 and above) that yields solutions faster on average thanenlightened-ostrich. ๐ฆtoons-for-twenty-somethingsโ an atomic-moves preset that solves more boards efficiently than"fools-gold". ๐บvideo-editingโ a meta-moves and flare-based preset, based onqualified-seedthat yields shorter solutions on average, but may be somewhat slower. Named to commemorate the earlier work of Adrian Ettlinger (1925-2013)<http://en.wikipedia.org/wiki/Adrian_Ettlinger>who later contributed to Freecell Solver and to Freecell research. ๐ฌyellow-brick-roadโ a meta-moves preset ๐ฃ๏ธโจ
ok so those presets can be shortened to their lowercase acronym, like "ak" or "rtt" โ periodt, no extra typing needed ๐
โจ RUN-TIME DISPLAY OPTIONS โจ
๐ -i, --iter-output ๐
Global
bestie this one makes fc-solve print the iteration number and the recursion depth of every single state it checks, straight to standard output. it's lowkey a great way to keep an eye on how it's doing, but heads up โ the output slows it down a lil bit ๐ญ still worth it for the vibes though.
๐ --iter-output-step [step] ๐
Global
only prints the current iteration if -i is specified, and only every [step] steps, where [step] is a positive integer. so like, if you do fc-solve -i --iter-output-step 100, you'll see this:
Iteration: 0
Iteration: 100
Iteration: 200
Iteration: 300
this option was added in Freecell Solver 4.20.0 and it's iconic for speeding up the runtime process by avoiding excessive output ๐โ๏ธ๐จ
๐ -s, --state-output ๐
Global
this option implies -i btw. if you specify it, it outputs the cards and formation of the board itself, for every state that's checked. fc-solve -s gives you a nice real-time display of Freecell Solver's progress, but honestly you usually can't even tell what's going on because it's so fast ๐ it's giving speedrun.
๐จ SIGNAL COMBINATIONS ๐จ
if you're on a UNIX or a similar system, then you can set some run-time options in fc-solve by sending it some signal combinations ๐ฆ
- send
fc-solvea singleABRTsignal โfc-solvewill terminate the scan prematurely, and report that the iterations's limit has been exceeded. very dramatic of it ngl. - send the signal
USR1, without sending any other signals before that โfc-solvewill output the present number of iterations. this method is a good way to monitor an instance that takes a long time to solve ๐ - send it
USR2and thenUSR1โfc-solvewill print the iteration number and depth on every state that it checks. it's the equivalent of specifying (or unspecifying) the option-i/--iter-output๐ซ - send it two
USR2signals and thenUSR1โfc-solvewill also print the board of every state. again, this will only be done assuming the iteration output is turned on ๐ธ
ok but fr fr, the signal girlies are not for the faint of heart โ do not come for me if you spam ABRT and your scan just stops, that's literally the whole point ๐ญ
๐ AUTHOR ๐
Shlomi Fish
and that's a wrap on the whole thing bestie!! ๐ the page you just read is from 2025-11-17, it's FC-SOLVE(6) in the manual, and you ate every single bit of it. go solve some freecells, you absolute legend ๐ โจ๐ฆ
๐ฆ where this page comes from
- alpine 3.24: freecell-solver-doc 6.16.0-r0 ยท MIT
- arch rolling: freecell-solver 6.16.0-1 ยท MIT
- fedora 44: freecell-solver 6.16.0-2.fc44 ยท MIT
- nixpkgs unstable: freecell-solver 6.16.0
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms