Solved

Put Freecell Cards into Excel or Access

Posted on 2001-08-19
12
1,174 Views
Last Modified: 2008-02-01
Hi

I am planning to write a program to play freecell.

It is possible to start a freecell game and then put the starting data into Excel or into an array manually....but what I would like to do is take the starting cards on the screen and put them into an Excel sheet or an Access table directly from the screen with VB code or whatever
Office type technique .

This is a real challange well worth 200 points.

leo
0
Comment
Question by:leojl
  • 5
  • 4
  • 3
12 Comments
 
LVL 2

Expert Comment

by:TrueDrake
Comment Utility
Hi,
You could use cards.dll :
http://home.computer.net/~mheller/cards.html

Enjoy
0
 
LVL 2

Expert Comment

by:TrueDrake
Comment Utility
Hi again,

Here's a link for cards32.dll
http://rookscape.com/vbgaming/tutU.php

Enjoy
0
 
LVL 3

Author Comment

by:leojl
Comment Utility
hi
thanks for the input.
I did not know about those dll's
and they could be of interest to me
to use in the future.

however the dll's do not answer my question.

I wish to start a new game of freecell which will
put on my screen 8 columns of cards. Then I wish to
use an identifier for each card and put that identifier
into an Excel cell for each column.

I have choosen to designate cards as 1 through 13
with ace=1, then 2=2 ... 10=10 etc and then
jack=11, queen=12 and king=13.
spades=1,clubs=2,hearts=3 diamonds=4

Then use a decimal point between card value and suit
so that ,for example, a jack of diamonds would be
identified as 11.4  and a 5 of clubs as 5.2 etc.

This is completely arbitrary and I am open to suggestion
if there is already a standard... in fact my brief look
at the sites provided suggest that there must be a similar
identifier technique for the dll's.

So the task at hand is to have a computerized technique
to look at the 8 columns of cards at the start of a
freecell game and put the identifier for each card into
a corresponding cell in an Excel sheet.

leo



0
 
LVL 2

Expert Comment

by:TrueDrake
Comment Utility
Hi,

You'll have to make your own Freecell game and place the data in Excel. You'll have to make a table of all the cards in the deck and randomly select cards that will be referenced in your grid.

Enjoy
0
 
LVL 1

Expert Comment

by:garethd
Comment Utility
Hi Leojl,

Here is some VBA code which will generate a deal in Freecell format onto a Excel worksheet called "Sheet1". The Randomized deal sequence is based on the same formula used to generate the actual Freecell deals and it generates numbers between 0 and 51 representing the cards. This is also how the cards are represented in CARDS/CARDS32.DLL , I believe.

The actual Freecell randomized deals are seeded with the game number as in this example but here the deal is different because the randomizer in VB (Access as well i think) returns a decimal value between 0 and 1 whereas the C compiler RAND() function returns an integer.

If you have access to a c compiler to create your own call to the RAND() function or you know how to access a C function from VB you could replace the line that reads:
j = Int(Rnd() * (cardsleft - 1))

with call to C routine as follows:

j = Rand() mod cardsleft

and your deals should come out the same as Freecell.

However, from your post I don't think you really need to generate the same deals as Freecell to create your own version of the game!

If you want to keep your designation for cards you can change the code but I like the simplicity of the 0 thru 51 personally.

Additionally for further coding purposes you might want to store the deal in an array as well as or instead of putting on the spreadsheet.

Info on the original algorithm by Jim Horne can be found at http://members.aol.com/wgreview/mshuffle.txt

If you want to contact me directly please e-mail to
garethd@yahoo.com



Here is the VBA Subroutine, hope this helps


Public Sub gen_deal(GameNumber As Integer)


        Dim deck(0 To 51) As Integer
        Dim i, j, col, row, cardsleft As Integer
           
'Load 0 thru 51 to array representing deck of cards

        For i = 0 To 51
           deck(i) = i
        Next
 
' Set the Active Excel sheet to receive the deal

        Worksheets("Sheet1").Activate

' Keep Count of Cards that Haven't yet been dealt
        cardsleft = 52
       
' Seed the randomizer with Game Number

        Rnd (-1) ' Reset Randomizer
        Randomize (GameNumber) 'Seed it

' Deal the Cards

    For i = 0 To 51
            ' Get next Random Number. and ensure it is
            'between 1 and number of cards left
                         
        j = Int(Rnd() * (cardsleft - 1))
        col = (i Mod 8) + 1
        row = Int((i / 8)) + 1
   
       Worksheets("Sheet1").Cells(row, col).Value = deck(j)
       cardsleft = cardsleft - 1
      deck(j) = deck(cardsleft) 'fill spot used by lastcard
    Next
   
End Sub
0
 
LVL 3

Author Comment

by:leojl
Comment Utility
hi all,

thanks for the input...i have been too busy to
really study the comments. my question is really
if I start a freecell game...such as game #68
, which is currently unsolved by us,  how can I get
the starting cards for game #68 and put them into my VB6 program.

Excel is not a problem....the question is to somehow
sweep across the monitor and detect card identifiers.

Ident by 0 thru 51 is ok if you provide the rule to go
from an integer to a specific card.
leo
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 1

Expert Comment

by:garethd
Comment Utility
Hi Leojl,

Why do this complicated process of interfacing to a program that was not designed for such?

The cards are generated by the simple (public domain)algorithm that I sent earlier. This code I posted is a VB version of that exact same code used by Freecell which can be found at

http://members.aol.com/wgreview/mshuffle.txt

This article was provided by the original auther of Freecell.


This algorithm uses a "Game Number" as the seed to a randomize routine to randomly generate the numbers 0 thru 51 representing your cards.

The only proviso for the VB code version (as I noted) is that the Rnd function in VB is different than the Rand function in C which is what Freecell uses.

This means that though the result is a genuine freecell deal it will differ from the same "Game Number" in Freecell.

It is now clear that rather than writing a Freecell program you are going to write a Freecell solver program.

Therefore you really need the same deal as the corresponding "Game number" in Freecell.

What remains to be done is:
Replace the one (1) line of code in the VB version with a call to the C routine rand() instead of the VB routine rnd(). Then seeding the routine with the "game number" will result in the exact same deal as Freecell.


The question is: what is the best way to use a C function in a VB program ? Maybe the whole thing should be done in C ?

Good Luck
0
 
LVL 3

Author Comment

by:leojl
Comment Utility
hi again,

I am going to be out of town for a few days, but I
am not ignoring this question.....

If I could create the same cards with the game number as the random number seed that would indeed give me what I need ..... I will study your inputs while I am at the
campground.

I am quite good in Visual Basic. I recently bought Visual
C++ 6.0 , but I am just starting to learn C++ so there
will be some study to do something as complicated as getting the cards for freecell.

leo
0
 
LVL 1

Accepted Solution

by:
garethd earned 200 total points
Comment Utility
Hi Leo,

Didn't like leaving my previous comment up in the air but unfortunately my C/C++ knowledge does not extend to writing DLL's......so here is a workable (maybe not ultra elegent) solution.

The solution is in 2 parts:

Part 1: Use a C program based on the original authors (Jim Horne) C routine to generate the card numbers to a file. (see code below)

This program accepts 2 parameters 1) GameNumber as String and 2) FilePath\FileName as a string

The created file is a Comma Delimetered (CSV) format that Excel can read, The default file is created in the same folder that you put the program in. (default file name is "@FreeCell@GameNumber")

===========================================================================================================
Part 2. A simple Vis.Basic sub to call the C routine and then read in the values from the newly created file the end result of this routine is an array of integers 7 rows by 8 columns representing the deal layout

===========================================================================================================

The Cards are represented by the numbers 0 thru 51 and can be defined as follows:

            Club      Diam      Heart      Spade

Ace            0      1      2      3  
Two            4      5      6      7
Three            8      9      10      11
Four            12      13      14      15
Five            16      17      18      19
Six            20      21      22      23
Seven            24      25      26      27
Eight            28      29      30      31
Nine            32      33      34      35
Ten            36      37      38      39
Jack            40      41      42      43
Queen            44      45      46      47
King            48      49      50      51

This means that the card SUIT can be determined by the formula (CardValue Mod 4) with 0=Clubs, 1=Diamonds, 2=Hearts, 3=Clubs

The actual card can be determinined by the formula ((CardValue/4) +1) to return a number between 1 and 13 with 1 the Ace and 13 the King

I am not certain why Jim Horne didnt alternate the suits so that a MOD 2 would have indicated Red or Black !!!!

===========================================================================================================

You mentioned that you have the Visual C which is what I used to create the program as a "WIN32 Console" "Empty project" ( to eliminate all that complicated C++ stuff that I don't understand). However I could e-mail the executable if you wish.


Hope this is what u are looking for

Good Luck


Garethd

===================================================================================

Part 1 C Program by Jim Thorne with a few modifications by GarethD


#include <stdio.h>                // garethd
#include <stdlib.h>
#include <string.h>                        // garethd

int main(int argc, char* argv[])
{

#define     MAXPOS         21
#define     MAXCOL          9    // includes top row as column 0
int    card[MAXCOL][MAXPOS];    // current layout of cards, CARDs are



    int  i, j;                // generic counters
    int  col, pos;
    int  wLeft = 52;          // cards left to be chosen in shuffle
    int deck[52];            // deck of 52 unique cards

//--------------------------------------------------------------------            
// GarethD Definitions
int GameNumber ;
char   FileName[256];
char  GameNumberChar[9];
int FileOK;
FILE *ptrFileName;

strcpy(GameNumberChar,"1");            // Default to Game 1
//--------------------------------------------------------------------
// GarethD Code to      
// Resolve the Game Number and File names AND CREATE THE FILE      
      if (argc > 1) strcpy(GameNumberChar,argv[1]);

      GameNumber = atoi(GameNumberChar);

      if (argc > 2)
            strcpy(FileName, argv[2]);
            else
            
            {
                  strcpy(FileName,"@FreeCell@");
                   strcat(FileName,GameNumberChar);
                   strcat(FileName,".CSV");
            }

      FileOK = 0;
      if ( (ptrFileName = fopen( FileName, "w" )) != NULL) FileOK = 1;

      printf("[FreeCell Game # %d]\n",GameNumber);
      if (FileOK == 1)
      fprintf(ptrFileName,"[FreeCell Game # %d]\n",GameNumber);
//--------------------------------------------------------------------      
      
wLeft = 52;
    for (col = 0; col < MAXCOL; col++)          // clear the deck
        for (pos = 0; pos < MAXPOS; pos++)
            card[col][pos] = 0;
            
    /* shuffle cards */

    for (i = 0; i < 52; i++)      // put unique card in each deck loc.
        deck[i] = i;

    srand(GameNumber);            // gamenumber is seed for rand()

       

    for (i = 0; i < 52; i++)
    {
        j = rand() % wLeft;
        card[(i%8)+1][i/8] = deck[j];
            

//--------------------------------------------------------------------
// GarethD Code to      
// Print the results to the Window and to the named File
            printf("%00d,",deck[j]);                              // GarethD
            if (FileOK == 1) fprintf(ptrFileName,"%00d,",deck[j]); // GarethD

       
            
            if (i % 8 == 7)                                    // GarethD
            {                                                // GarethD
                  printf("\n") ;                              // GarethD
                  if (FileOK == 1) fprintf(ptrFileName,"\n");      // GarethD
            }
//--------------------------------------------------------------------
            
            deck[j] = deck[--wLeft];
            
    }
            
//--------------------------------------------------------------------
// GarethD to Close File      
      printf("\n\n") ;                                          // GarethD
      if (FileOK == 1)  fclose( ptrFileName);                        // GarethD
//--------------------------------------------------------------------
      

      return 0;
}

===================================================================================
Part 2 Visual Basic Code

Sub GetDeal(gamenumber As Integer, FileName As String)

Dim Cards(7, 8) As Integer
Dim GameHeader As String
Dim inchar As String

' Call C routine to generate the deal

returnCode = Shell("c:\FreeCellDeal.exe " & gamenumber & " " & FileName, 6)

' Read the Deal File into Cards Array

Open FileName For Input As #1
COL = 0
ROW = 0

Line Input #1, Header  ' Read 1st line into header.

'---------------------------------------------------------
Do While Not EOF(1)   ' Loop until end of file.

   
inchar = Input(1, #1)
   If (inchar = ",") Then
        If (COL Mod 8) = 0 Then
            ROW = ROW + 1
            COL = 1
        Else
            COL = COL + 1
        End If
    Cards(ROW, COL) = CInt(Number)
    Number = ""
  Else
  Number = Number & inchar
 
  End If
 
Loop
'---------------------------------------------------------

Close #1



End Sub
0
 
LVL 3

Author Comment

by:leojl
Comment Utility
hello all

thanks much for the input.

I have not had time to actually apply the ideas so far.
I will be interested in the difference between random
numbers from C/C++ vs VB.   VB random numbers from rnd
are indeed random 0<rnd<1 (or are 0 or 1  possible?)  .
But VB rnd does NOT restart the same string of random
numbers when you try to randomize with the same seed.
The only way that I know to get the same sequence of random numbers from VB is to do randomize (start seed)
at the very start of a program.

sincerely ... leo
0
 
LVL 1

Expert Comment

by:garethd
Comment Utility
See my earlier comment, where I posted a deal generation routine in VB. As noted, this will NOT produce the same random sequence as C compiler that Freecell uses, but it does produce a legitimate deal. The use of the rnd(-1) in this routine will always reset the randomizer. Without this the randomizer users the previously returned random number as the next seed regardless of what you use in the rnd() function or randomize function.

The rnd() in VB and the RAND() in C are totally different beasts and will never produce the same set of random number no matter what you seed with.

VB returns a decimal number betweeen 0.000000 and 0.999999
which means you multiply by your upper boundary (in this case 52)to get what you want
whereas C returns an integer between 1 and 32,267 (or something close to this) which means you use MOD with your upper boundary



Hope this helps

Garethd

0
 
LVL 3

Author Comment

by:leojl
Comment Utility
I thank all for input..
I am going out of town again
so will accept this input and
evaluate it later..
sincerely .. leo
0

Featured Post

Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

How many times recently have you prepared a presentation or emailed a document to a client and you have found that they have older versions of MS Office and they can not open the file you have prepared.  Although most visitors to this site are exper…
Using Word 2013, I was experiencing some incredible lag when typing.  Here's what worked for me....
Learn how to make your own table of contents in Microsoft Word using paragraph styles and the automatic table of contents tool. We'll be using the paragraph styles in Word’s Home toolbar to help you create a table of contents. Type out your initial …
Polish reports in Access so they look terrific. Take yourself to another level. Equations, Back Color, Alternate Back Color. Write easy VBA Code. Tighten space to use less pages. Launch report from a menu, considering criteria only when it is filled…

771 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now