Solitaire *Work in progress*
by Johnathon · 11/28/2007 (6:12 pm) · 6 comments
I downloaded and messed with the Torque Game Builder demo and found that it was surprisingly easy to use. So I decided to see if I could get a simple game created during the 30 day trial. If I could accomplish that, then the engine would be worth purchasing it. I would even settle with an almost finished game, provided I felt I could get the game completed in a couple more weeks. Granted, I could not make something along the lines marble blast or bejewelled in 30 days with my current knowledge of TorqueScript, but I felt I could get a simple card\puzzle put together in that short amount of time.
So I set out to start work on GoFish, which quickly turned into Solitaire, and here I am now crunching away on Solitaire with 20 days left in my demo. I found a royalty free tileset of a deck of cards, cut them up and imported each image into TGB so I can position them on the screen and see where each card is going to end up at some point (as shown below).

I did this so I can layout the card table how I want it done, now that this is finished I can go about coding the game. The cards will be removed from the table when the game is ready to be tested and released, as the cards will be created during runtime(at least that's the plan at the moment).
The table is broke up into 'slots', and each slot will have an offset. Allowing me to do a %this.Move(%slotNumber, %offset) and have the card moved to where ever it needs to go (as illustrated below).

Slot 1 is where the 'winning' cards go. The Ace of Hearts is located at xx.xxx, and the remaining suites are placed at -12.000 offsets, which will be handled automatically through code.
To aquire the world position of each slot I simply cal my getSlot(%slot) method and pass to it the slot that I want coordinates for. It then returns them to me.
The offset code I am still working on and when it is finished I will post it up. The above code is pretty simple, but I wanted to show how I did it, incase anyone had any better idea's.
for now the game will be super simple, match the cards up in a traditional Solitaire game, but I was looking online and found rule sets for about 20 differant styles of Solitaire, so if I can get a basic game up and running, I will purchase the engine and incorporate differant rule sets that the player can choose from, along with differant back grounds and card styles.
The only thing that I'm concerned about is figuring out the following issue.
So I set out to start work on GoFish, which quickly turned into Solitaire, and here I am now crunching away on Solitaire with 20 days left in my demo. I found a royalty free tileset of a deck of cards, cut them up and imported each image into TGB so I can position them on the screen and see where each card is going to end up at some point (as shown below).

I did this so I can layout the card table how I want it done, now that this is finished I can go about coding the game. The cards will be removed from the table when the game is ready to be tested and released, as the cards will be created during runtime(at least that's the plan at the moment).
The table is broke up into 'slots', and each slot will have an offset. Allowing me to do a %this.Move(%slotNumber, %offset) and have the card moved to where ever it needs to go (as illustrated below).

Slot 1 is where the 'winning' cards go. The Ace of Hearts is located at xx.xxx, and the remaining suites are placed at -12.000 offsets, which will be handled automatically through code.
To aquire the world position of each slot I simply cal my getSlot(%slot) method and pass to it the slot that I want coordinates for. It then returns them to me.
//0 = Pile
//1 = Winning Slot (Very top)
//2 = Player Hand slot 0
//3 = player hand slot 1
//4 = player hand slot 2
//5 = player hand slot 3
//6 = player hand slot 4
//7 = player hand slot 5
function getSlot(%slot)
{
switch$ (%slot)
{
case "0":
%position = "-30.000 -19.000";
case "1":
%position = "4.000 -20.000";
case "2":
%position = "-26.000 -6.000";
case "3":
%position = "-14.000 -6.000";
case "4":
%position = "-2.000 -6.000";
case "5":
%position = "10.000 -6.000";
case "6":
%position = "22.000 -6.000";
case "7":
%position = "34.000 -6.000";
}
return %position;
}The offset code I am still working on and when it is finished I will post it up. The above code is pretty simple, but I wanted to show how I did it, incase anyone had any better idea's.
for now the game will be super simple, match the cards up in a traditional Solitaire game, but I was looking online and found rule sets for about 20 differant styles of Solitaire, so if I can get a basic game up and running, I will purchase the engine and incorporate differant rule sets that the player can choose from, along with differant back grounds and card styles.
The only thing that I'm concerned about is figuring out the following issue.
Click on 6 of Hearts, it gets selected. Click on 7 of clubs, move 6 of Hearts on topHow do I make sure that the two cards are of differant colored suite. This will take some messing with.
About the author
#2
11/29/2007 (4:21 pm)
Thanks, this is a good piece of code. I was also thinking about creating mount points and just mounting the cards into each mount point when needed. You think your approach is the better approach?
#3
Keep up the good work and good luck!
11/29/2007 (8:53 pm)
Hey, this is pretty good, Johnathon. I started working on a card game a while back. However, I never came up with a good solution for table locations aka slots. I did have a system in place, however, that allowed me to create any kind of decks I wanted. I could create custom decks for games besides solitaire that allowed only certain suits or cards in the deck.Keep up the good work and good luck!
#4
I don't think my approach is better, though. If it works, takes minimal coding and maintenance, and makes logical sense to you, any approach is good.
11/30/2007 (9:41 am)
I avoid mounting unless it logically makes sense. I don't find putting cards into piles the same as mountnig it to a pile and the card before it. My "down" piles (or tableau) are typically t2dSceneObjects that take up the whole column. It keeps track of how many cards are on it. That makes it easy to calculate where new cards should be. I then just use a moveTo for the moving cards and they look like they are linked together as they move over to the new pile.I don't think my approach is better, though. If it works, takes minimal coding and maintenance, and makes logical sense to you, any approach is good.
#5
12/10/2007 (5:42 am)
I for one would love to see some working code for a completed card game.. perferably something different than solitaire like Pitch or Rummy.. but even solitaire would be nice.
#6
12/10/2007 (3:41 pm)
Well, I ran into some issues and ran out of time with the demo before I could get it finished. i'm wanting to purchase the engine, but after looking at Stencyl I am going to hold off and see how that turns out and make my choice then. 
Associate William Lee Sims
Machine Code Games
If I have "slots" in my game, I tend to put t2dSceneObjects where I want the piles to be defined.
For example, I may
for( %i = 0; %i < 4; %i++ ) { %s = new t2dSceneObject() { sceneGraph = RenderGraph; }; %s.setGraphGroup( 2 ); %s.setSize( 72, 96 ); %s.setPosition( 52, 8 + 48 + 104 * %i ); %s.pile = %i; %s.suit = %i; $SOLITAURE::Slot[%i] = %s; }This sets where my 4 piles of cards go (what is your "Slot 1"). You'll notice a few things I do:
1) Set graph group to 2. When I do a mouse selection, I only look at BIT(2) in the graph group.
2) I pre-define the position so I can access it at any time (see further down).
3) I set the variable "pile" equal to the slot in the $SOLITAIRE::Slot array.
4) I set which suit will be at that slot (0 = Hearts, 1 = Diamonds, 2 = Spades, 3 = Clubs)
5) I make a global array of the scene objects to access anywhere in script.
Reasons:
1) I put the cards in graph group 1 to distinguish between selecting a card and selecting a pile.
2, 3, 4 & 5) I may want to right-click on a card to send it to the top 4 piles. I can send it to the correct spot by simply looking at the card's suit and accessing the correct pile in my global $SOLITAIRE::Slot array.
As for the cards, I set a variable on the sprite to set it's value and suit. Using my above example, it's trivial to determine the the suits are different colors (if you first selected suit 0 or 1, it has to go on a suit 2 or 3 and the other way around).
Good luck!