Previous Blog Next Blog
Prev/Next Blog
by date

furthering FreeCell

furthering FreeCell
Name:J Sears 
Date Posted:Nov 18, 2006
Rating:3.0 out of 5
Public:YES
Comments:YES
RSS Feed:GarageGames Blog feedor Subscribe with .
Profile Page:View profile page for J Sears

Blog post
Well I decided to use this blog as a good reference of my progress. Considering I started this with very little knowledge I think I'm movng at a good speed, I did have some c/c++ self training but never on a big scale just the basics.
Today I tested my theory that it would be just as fast to lay out all the freecell levels in the game builder if I had all the cards set up in rows out of the camera view with all settings possible set up including link points. So I spent a lot of time with a ruler and my screen to get the link points in exact same spot on each card and that part actually turned out good. So with everything set up I decided to see how long it would take to build a level, all I had to do was click mount and drag and let go of each card since all mounts were set up, change each cards layer appropriate to it's spot in the column and change the bottom row dynamic values of isSelectable and isMountable to 1. This took significantly longer then I had planned. Took almost 5 minutes which with practice and a routine might at absolute best get down to 3 minutes. This is too long, and here's why I calculated how long it would take to enter 1 million levels (microsofts original release freecell had 1 mil, new free cell programs have insane amounts) if it took me a minute a level to type or click. that worked out to just under 2 years straight typing. So that sucks and obviously 3 minutes a level is much worse. So I will try to get a good way of doing it in script after my failed attempts to create something simple that way before so we'll see.

I figure the people who make freecell games must have a computer program figure out possible levels and record them in a certain way so all the person does is take that file and plug it in, maybe I can figure that out for now I'll just do 100 levels.

After spending all that time on a failed theory (the ruler method for link points on 52 objects was not fast) I worked on some other aspects of the game.
Made gui for recording number of moves
Fixed rules in the mouse folder that allowed double clicking a card to increase the move count (didn't
affect the rules of the card movement just the move count)
Made gui for number of cards remaining (cards not in the suit stacks)
Am very close to finishing up the code for automatically moving a card into the suit piles if the only cards
that could be placed on it are in their suit piles and it's the next highest card for it's own suit pile

Future steps for probably Sunday won't have time tomorrow
Organize some of the code currently in mouse.cs into functions in freecell.cs and have mouse call them
A Check to see if game is won
Save game in progress to load automatically on game launch
Add timer till game won
Save timer and moves per game number if best scores

Further Future
"Table" graphcis instead of blue background screen I have set up
Better graphics for my moves cards left and soon to be timer GUI
Figure out how to save top scores to online database that all players can access
See if I can figure out how to make an AI that plays the freecell game.

Well thanks for reading if anyone is

Recent Blog Posts
List:01/25/08 - persistance is rewarding
08/28/07 - My thoughts, and my farewell
05/23/07 - some progress on cards
04/23/07 - teaching my computer to play cards
01/03/07 - I'm not dead
12/06/06 - time to learn networking
12/05/06 - back on a decent pace
12/04/06 - back at it

Submit ResourceSubmit your own resources!

David Higgins   (Nov 19, 2006 at 07:23 GMT)   Resource Rating: 3
@J, to help with the link points, as the cards will always have the same link points, you could create a CardDataBlock which contains your link points, default size and position, as well as your dynamic field properties as well.

This way, when you drag/drop the card in Level Builder, all you have to do is assign it to the CardDataBlock you created and then snap it to the mount you wish to use -- no need to use a ruler anymore, yay!

If your unsure of how to create the link points through code, there's a really fun trick I love using -- take one card, place it in Level Builder, set it up the way you want it, all your properties, etc.

Save the level -- for simplicity, make sure the card is the only thing in the level.

Once the level is saved, navigate to the games/projectName/data/levels directory and open the level.t2d file with a text editor (I prefer Torsion). You'll notice the code for the t2dStaticSprite is in this file -- now copy that code out, should look something like this;


new t2dStaticSprite(yourCardNameIfYouGaveItOne)
{
size = "256 256";
position = "0 0";
linkPoints = "0 1 2 3 4 5";
};


That's some really quick pseudo-code for ya :)

Now, alter the code just slightly in the new script file, make it look something like this:


new datablock t2dSceneObjectDataBlock(CardDataBlock)
{
size = "256 256";
position = "-500 0"; // places the card HIGH, out of default level view
linkPoints = "0 1 2 3 4 5";
someCustomAttributeThatDeterminesCardState = 0; // yay for dynamic fields
};


Now, save this file in your gameScripts directory, open your game.cs and exec('~/script.cs") it.

Close TGB, re-open it, and you'll notice that the CardDataBlock is now available as an option when you create t2dSceneObject's in the level -- when you select it, the Level Builder automatically assigns the default values you created.

Now, this was a rather quick and dirty intro to datablocks, but if you search TDN and the forums, you'll find much more useful write-ups on datablocks.


Also, for the 1 million games -- last time i played freecell, the card layout was the same, the only thing that really differed was the fact that the cards in the stack were not always the same -- which is most likely where your 1 million games comes from, I assume? (Not a big solitaire player)

You could very easily create an array through script, each element of the array would contain a reference to one of your cards -- then write a random sort algorithm, or use someone elses if you can find one (may have to do some C++/C#/Java/Whatever to TorqueScript conversion) and viola, you have a random level generater ... with no need to physically save anything other then a single level, which would act as your "playing field" (background with card snaps and deck mounts).

David Higgins   (Nov 19, 2006 at 07:25 GMT)   Resource Rating: 3
oh btw -- keep up the .plan posting, sounds like your making great progress and learning along the way.

g'luck with the game, can't wait to try a demo/beta if and when one becomes available.

J Sears   (Nov 19, 2006 at 19:07 GMT)
great tip on the link points, I knew youc ould create them in script but never thought of putting them in the datablock. And the tip for getting the datablock info is very clever, wish I would have thought of that :-)

The problem with random generator (although I plan to make a few different types of solitaire games in one game and some can use that) is the fact that FreeCell was made where all levels have a solution, if you make it randomly generated no more guarantee of being beatable. That's where my problem comes in, I figure someone who designed the game orginally probably came up with a level generator system that made all the levels beatable.

David Higgins   (Nov 19, 2006 at 19:25 GMT)   Resource Rating: 3
@J,

There's actually quite a few ideas that could simplify your level creation --

For something like this, where you are trying to create array stacks of beatable games, you'd actually gain performance and disk space by not creating your levels in level builder as the amount of added information and data that level builder adds to the mix is not necessary --

You could create a custom file format, such as something like:

1 11 K Q J 2 1 1 2 1 5 4 3 ....

Where each word is a card, and each line is a "game" ... and then use the file i/o operations in torquescript to open the file, load a random game, and parse the card locations -- where the first card mention goes in spot 1, then spot 2, etc, etc ...

You could then easily populate the game file by hand with notepad, or write a program in a more likely technology such as .NET or Python, or VB or something to help you populate the game file faster -- perhaps even have a random game generator that determines the game is beatable, and then generates the game file from those games.

J Sears   (Nov 19, 2006 at 23:07 GMT)
I had been thinking of a way to work with a simple file to read the information and create the level, just hadn't learned enough about reading and writing files yet to figure that out. And in order for me to be able to make an AI program first that could run through a game real fast to determine if it is beatable. So I still have a lot to work on.

David Higgins   (Nov 20, 2006 at 01:52 GMT)   Resource Rating: 3
@J, Feel free to ask any questions you need to ask --

Tank Dork   (Nov 20, 2006 at 10:24 GMT)
I have been tinkering with a card game idea in TGB also and up till I saw this blog I haven't seen any real infomation around on it.. your freecell style will use a less random deal.. but mine just needs a random shuffling.. I have contemplated writing the dealer in C++ and integrating it.. but I can't help but think that TGB can handle it script wise alot easier. Can anyone point me or other "card gamers" in the right direction.. would a scripted array accessed by a getRandom(number of possible cards decremented each hand) work in torque script?

Edit: spelling
Edited on Nov 20, 2006 10:25 GMT

David Higgins   (Nov 20, 2006 at 16:15 GMT)   Resource Rating: 3
@Tank, if you really wanted to simulate a card deck, you'd randomly sort the deck then access the top or bottom card from there.

You must be a member and be logged in to either append comments or rate this resource.