=====================================================================
Column-to-Column SuperMove Calculation:
( number_of_free_cells + 1 ) * ( 2 ** ( number_of_empty_columns ) )
Note: If the destination is an empty column, then that column can not
be used in the above calculation.
=====================================================================
The above equation is what I have in my notes. I think you'll find it
listed elsewhere as well. Good luck!
"Super-super-move" is a new one on me. I suspect that it would violate
the move definitions of just about every other FreeCell game/solver.
Still, whose to say that you're wrong and they're right -- not me. As
long as you don't intend to share solutions with anyone else, then the
sky is the limit on what you implement. Otherwise, you'll need to treat
a super-super-move as a series of separate super-moves.
I ran across several, slightly different, versions of the FreeCell
dealing algorithm. Until recently, I just generated a control file for
input using a deal generator program from FC-Solver. That same generator
is also used by PatSolve. While trying to implement the algorithm into
my program, I ran into a problem where the random number generator from
Borland generated different random number sequences than those used in
MS FreeCell. It turned out that the source for the deal generator also
included the necessary random number generator. I will include the
source for the deal generator as an attachment. Hopefully, you won't
have any trouble adapting it for your use.
Note: The algorithm stores cards in row order, but the deal generator
program prints them in column order. Also, the first column is "saved"
for storing free cells and home cells. Don't get trapped by these
particulars when transferring the algorithm into your solver!
The "seed" is just a global variable that must be set to the deal number
before the random number generator is called for the first time. After
that, you never need to touch it. The particulars should be obvious from
the source code.
I don't use C++, but it's my understanding that it's straight-forward to
include C routines in a C++ program. My compiler uses the extension on
the filename to determine whether the source code is C/C++. Once it
generates the OBJ file and passes it to the linker, everything proceeds
normally to create an executable.
HELSER ERIC JOSEPH wrote:
> Right now I'm trying to get my (new and improved) program to implement
> supermoves, except I'm cheating. To determine if a huge jump is
> possible, the program uses this algorithm:
>
> Let F=number of available freecells
> Let C=number of available empty columns
> Longest card run moveable = (C*C+C)/2 + FC + F + 1
> Although this is probably the way it's supposed to be calculated, right?
>
> If the move is cool, the program just picks up the whole lot of cards
> and moves them over.
>
> What about super-super-moves that require the use of non-empty
> columns? Are those just treated as two or more separate moves? Right
> now I project that the biggest problem will be moving runs to empty
> columns. As for notation, my program's notation is going to look like
> a nightmare at best. (grin) Until I tell it how to translate. (And
> figure out for myself how it works!)
>
> Danny, you sound like the most likely to be able to answer this, but:
> how do you create the Microsoft deals using C++? I found the source
> somewhere, but I'm pretty sure it was solely for C, and I'm not
> familiar at all how seeding works. Could you point out where that file
> is, and possibly what kind of results to expect? This way I could use
> it in conjunction with my program to see how fast it solves the
> Microsoft 31999.
>
> How about that Kasparov v. X3D Fritz matchup? The two of 'em so far?
> That's what inspired me to start writing this program!
/*
make_microsoft_freecell_board.c - Program to generate the initial
board of Microsoft Freecell or Freecell Pro for input to
Freecell Solver.
Usage: make-microsoft-freecell-board [board-number] | fc-solve
Note: this program will generate the boards for Microsoft Freecell and
FC-Pro only if it is compiled with a Microsoft C compiler such as
Visual C++.
If you want to generate the code without those compilers use the
pi-make-microsoft-freecell-board program.
Based on the code by Jim Horne (who wrote the original Microsoft Freecell)
Modified By Shlomi Fish, 2000
Modified slightly by Danny A Jones, 2003
This code is under the public domain.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
static long seed;
typedef int CARD;
#define ACE 0 /* VALUE(card) */
#define DEUCE 1
#define VALUE(card) ((card) >> 2)
#define CLUB 0 /* SUIT(card) */
#define DIAMOND 1
#define HEART 2
#define SPADE 3
#define SUIT(card) ((card) & 3)
#define BLACK 0 /* COLOR(card) */
#define RED 1
#define COLOR(card) (SUIT(card) == DIAMOND || SUIT(card) == HEART)
#define MAXPOS 21
#define MAXCOL 9 /* includes top row as column 0 */
char * card_to_string(char * s, CARD card, int print_ts)
{
int suit = SUIT(card);
int v = VALUE(card)+1;
switch (v)
{
case 1: strcpy(s, "A" ); break;
case 10:
if (print_ts) strcpy(s, "T" );
else strcpy(s, "10"); break;
case 11: strcpy(s, "J" ); break;
case 12: strcpy(s, "Q" ); break;
case 13: strcpy(s, "K" ); break;
default:
sprintf(s, "%i", v);
}
switch (suit)
{
case CLUB: strcat(s, "C" ); break;
case DIAMOND: strcat(s, "D" ); break;
case HEART: strcat(s, "H" ); break;
case SPADE: strcat(s, "S" ); break;
}
return s;
}
int ms_rand( void )
{
seed = seed * 214013L + 2531011L;
return (seed >> 16) & 0x7fff;
}
int main(int argc, char * argv[])
{
CARD card[MAXCOL][MAXPOS]; /* current layout of cards, CARDs are ints */
int i, j; /* generic counters */
int wLeft = 52; /* cards left to be chosen in shuffle */
CARD deck[52]; /* deck of 52 unique cards */
int gamenumber;
int print_ts = 0;
int arg;
if (argc == 1) gamenumber = time(NULL);
else
{
arg = 1;
if (!strcmp(argv[arg], "-t"))
{
print_ts = 1;
arg++;
}
gamenumber = atoi(argv[arg]);
}
/* shuffle cards */
for (i = 0; i < 52; i++) /* put unique card in each deck loc. */
deck[i] = i;
seed = gamenumber;
for (i = 0; i < 52; i++)
{
j = ms_rand() % wLeft;
card[(i%8)+1][i/8] = deck[j];
deck[j] = deck[--wLeft];
}
{
int stack;
int c;
char card_string[10];
for (stack=1; stack<9; stack++ )
{
for (c=0; c < (6+(stack<5)); c++)
{
printf("%s",
card_to_string(card_string,card[stack][c],print_ts ) );
}
printf("%s", "\n");
}
}
return 0;
}
Received on Fri Nov 14 2003 - 00:08:59 IST