On Mon, 17 Nov 2003, HELSER ERIC JOSEPH wrote:
> Man, I'm having the hardest time ever on this program. I think I have
> three or four versions of this program written, each one a modification
> of previous types just so I didn't have to start over if I screwed up
> too badly.
>
Do you use a Version Control system? I can highly recommend Subversion:
http://subversion.tigris.org/
> In Michael Mann's solver, and most others I downloaded, the program is
> usually extremely lengthy. Do you guys think it is possible to write a
> solver that works correctly using only about 200-400 lines, and no
The first version of Freecell Solver was about 1000 lines. Of course, many
lines were "wasted" on having complex meta-moves which I thought were
necessary instead of atomic moves. So I suppose you can write a solver at
about less. In C++ with STL it would be a bit easier, because you have
some data structures that can serve as a state collection.
I also think there was a lot of duplicate code in checking for a state's
existence and adding it to the states collection.
> external files (other than necessary includes)? I think I only had about
> a handful of functions, too. I'm not sure why you'd need multple .c
> files and extra .h files to include...
>
Freecell Solver is divided into modules and each module implements a
certain class or subcomponent. The added complexity is for a reason, but
it is not required for implementing a basic solver.
> Apparently C++ won't let me create arrays inside of structs for some
> stupid reason...
>
It should allow arrays inside of classes. Maybe you should ask at a C++
forum. I'm not a C++ STL expert.
Regards,
Shlomi Fish
>
> -----Original Message-----
> From: Danny A Jones <dajones_at_inreach.com>
> To: fc-solve-discuss_at_yahoogroups.com
> Date: Fri, 14 Nov 2003 17:17:07 -0800
> Subject: Re: Strategies for coding a solver
>
> Something must have been lost in my comments about using C code in a C++
> program. Borland handles it just fine.
>
> There are three (primary) solvers available to my knowledge: FcPro26,
> FreeCell Solver 2.8.6, and PatSolve 3.0.
>
> FcPro26 is an interactive Windows FreeCell game with three solvers
> included. I highly recommend checking it out. Its web page contains URLs
> to the other solver sites as well.
> http://www.rrhistorical.com/rrdata/Fcpro65/
>
> FreeCell Solver 2.8.6 is a command-line solver. It has a wealth of
> configuration options to control how the solver runs. It used a separate
> program to generate a deal and "pipe" it into the program. It produces
> several output formats.
>
> PatSolve 3.0 is another command-line solver that uses the same program
> as FreeCell Solver 2.8.6 to "pipe" a deal into the solver. Its output is
> non-standard. I wrote a program to translate the output and count the
> direct moves generated. I recently used PatSolve 3.0 to search for deals
> that required lengthy solutions. It wasn't a perfect search, but it
> produced many hits that proved useful. It took weeks to complete a
> search of the MS-1M deals!!!
>
> Both FreeCell Solver 2.8.6 and PatSolve 3.0 include direct and auto
> moves in their solutions. Depending on the solver used, FcPRo26 may (or
> may not) include auto moves in the solutions it produces.
>
> None of the above solvers were designed to find an optional solution
> path. However, they do have an "optimize" feature that looks for better
> solutions than in default mode. They do an excellent job of solving
> deals in a very short amount of time!!! This is very important when
> you're playing interactively or searching a range of deals to see if
> they can be solved.
>
> If a solver takes one second to solve a deal, then it'll take: 1) almost
> 9 hours to solve the original MS-32K deals, 2) almost 11.6 days to solve
> the (expanded) MS-1M deals, and 3) almost 272.2 years to solve the
> 8,589,934,591 deals allowed in FcPro26. I point this out because there
> are two solvers that aren't yet available but do search for an optimal
> solution path -- mine and that of WKRfresno. Both of which take minutes
> to find an optimal solution to a deal.
>
> My command-line, atomic move solver produces (near-)optimal solutions
> for any deal, but it currently takes 3-4 minutes to solve a deal. I'm
> working on improving its performance, but it'll never be a speed demon.
> Its output contains only direct moves and is formatted for input to FcPro26.
>
> WKRfresno has a "sequence move" solver that also takes several minutes
> to produce an optimal solution for a deal. To my knowledge, he is
> currently using it to search the MS-32K deals for those with the
> shortest number of moves possible in their solutions. (Deal #11853 can
> be solved in 21 atomic moves and 19 sequence moves.)
>
> Bottom Line: I don't know of any way to accurately rate the MS deals
> because the solvers with speed don't find optimal path solutions ... and
> the solvers that find optimal path solutions would take a millennium to
> do the job.
>
> I can't help you with your C++ code. I took a one-week C++ course
> several years back, but never ended up programming with it.
>
> HELSER ERIC JOSEPH wrote:
>
> > C and C++ are generally the same. I guess I couldn't use that code
> > since I'm using Borland C++. Borland's fun.
> >
> > Anyway, are there any solvers that determine the most efficient method
> > of solving a deal, as in fewest number of manual moves (not including
> > the final cascade or any sub-moves of super/meta-moves)? I could do
> > that and come up with a rating system for all MS games. That would be
> > really really fun.
> >
> > Can you help me with some code in my program? I think I got everything
> > I need written out, but I'm having some trouble with classes.
> > Forunately (sarcasm) for me, my second year C++ class was taught by a
> > handful of Word documents. I didn't understand a thing from them. Not
> > to mention it's been about two years since then and I have never used
> > a class in a program.
> >
> > class column
> > {
> > public: //everything is public
> > apvector <int> c; //array of integers
> > column();
> > };
> > column::column() //constructor thing
> > {
> > c.resize(0); //resizes c to zero elements initially
> > }
> >
> > I want to be able to make arrays of type "column". Column is just a
> > generic array of ints, where the integers are the cards. In the
> > program, I tell the program to create an array
> >
> > apvector <column> tbl(8);
> >
> > (I don't know if you guys are familiar with apvector, but if you
> > don't, it's a type of 1D array.) Ideally, this makes eight empty
> > columns for me. Now I could be able to say
> >
> > tbl[column_number].c[card_number]
> >
> > and be able to call up some integer. For example, if all this worked
> > out and MS game #1 was loaded into the program, saying tbl[0].c[0]
> > would return the value 111, or JD. tbl[0].c[1] would be KD,
> > tbl[7].c[5], 10C...
> >
> > I keep getting the error "Undefined symbol c". What did I screw up
> > this time? Probably something elementary, given what I know about
> > classes. (I know, well, "Jack")
> >
> > -----Original Message-----
> > From: Danny A Jones <dajones_at_inreach.com>
> > To: fc-solve-discuss_at_yahoogroups.com
> > Date: Fri, 14 Nov 2003 00:08:53 -0800
> > Subject: Re: Strategies for coding a solver
> >
> > /*
> > 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;
> > }
> >
> >
> >
> > Yahoo! Groups Sponsor
> > ADVERTISEMENT
> > <http://rd.yahoo.com/SIG=12ck0qvqe/M=243273.4156324.5364586.1261774/D=egroupweb/S=1705006497:HM/EXP=1068932479/A=1750744/R=0/*http://servedby.advertising.com/click/site=552006/bnum=1068846079668789>
> >
> >
> >
> > To unsubscribe from this group, send an email to:
> > fc-solve-discuss-unsubscribe_at_yahoogroups.com
> >
> >
> >
> > Your use of Yahoo! Groups is subject to the Yahoo! Terms of Service
> > <http://docs.yahoo.com/info/terms/>.
>
>
>
>
>
>
> To unsubscribe from this group, send an email to:
> fc-solve-discuss-unsubscribe_at_yahoogroups.com
>
>
>
> Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/
>
>
----------------------------------------------------------------------
Shlomi Fish shlomif_at_vipe.technion.ac.il
Home Page:
http://t2.technion.ac.il/~shlomif/
An apple a day will keep a doctor away. Two apples a day will keep two
doctors away.
Falk Fish
Received on Mon Nov 17 2003 - 22:15:37 IST