by date
slower day
slower day
| Name: | J Sears | |
|---|---|---|
| Date Posted: | Nov 20, 2006 | |
| Rating: | 3.0 out of 5 | |
| Public: | YES | |
| Comments: | YES | |
| RSS Feed: | or Subscribe with . | |
| Profile Page: | View profile page for J Sears |
Blog post
Well I did not get as much accomplished today as I had hoped. For starters I ended up rewriting my automatic card movement to the suit pile code. And once I had it written up the way I wanted something just wasn't working right, I reread the code a dozen times did find a couple tiny mistakes but they weren't the solution, I started adding echoes in to hunt down the problem, still couldn't figure out what it was and finally echoed out all of the values in an array I was working with through ever step of the function. The solution I finally came up with: I had a large misunderstanding on local vs global variables. I thought local just meant only used in that function. But apparently it also means when you leave that function and recall that function again those values are gone. Good to know. So I switched my array to global values and magically my code worked. That cost me a couple hours.
So after that I did some easy things, I added a timer to my game. That took about 3 minutes and worked perfect on first time around. I then began reading read write functions and how to use them and also researched FreeCell levels or games as most places write them but for ease of confusion I will call them levels. It seems that with the standard freecell game (there's many different variations) 99.999 and on are beatable games when created randomly. One site overly dedicated to the history of freecell showed a study done of the 1 million games on microsofts freecell which were randomly created I think he said 137 are not beatable. This was determined by people who are creating FreeCell solvers. From all the information I got on FreeCell solvers I am in no shape to write one, they are extremely complex and apparently a "perfect" one has not been created yet with all the efforts. If people who went to school for these kinds of things and have years of experience in them can't do it then I'm guessing I can't. There goes my AI in freecell idea. But the good that came of that is giving up on the idea of making sure all my games are winnable so I started on a randomizer to create levels.
The randomizer went together very easy with one snag, I tried to create a for loop that counted down instead of up and torque script seemed to hate that. So after many times of trying to figure out why my randomize function was not randomizing anything I switched that around and bang random. The way I set up a randomizer was to make an array of 52 spots 1 for each card, I entered the ImageData name of my cards as the information and I then had a for loop get a random number take the card in that random number and store it in card. Then I had a seperate value that was essential 51 - %i. that did 2 things set the limit for my random number and keep track of my spot in the array because how I did it was basically a shuffle, get random number take card from that spot and swap it with last spot in array and count down till all cards were moved.
Once I had that working good I created another function to read write the levels. Had a global variable of currentLevel which was for 1 thing. The first number to get written to the file so I can hopefully set up a read later when someone enters a game number to jump to the right spot and get the card order. I also had a variable to turn on and off the shuffler so I could get all the card spots out write to a file and then turn on the shuffler for a new level. I tested it by outputting 3 levels and it worked perfect.
Now my big challenge on this. First I only know of writeline which in my spot is annoying because it starts on next line everytime. since I am using a for loop to get the values out of the array that gives me 52 seperate lines instead of 1 line with all 52 in it. This is something I haven't found a solution to. Now I want to do 2 things. Create a read system that then loads in the level. And create a read system while making the levels to go through the previous levels and make sure it's not a repeat before writing it. These 2 tasks will share a lot of code so when I have one all figured out I will hopefully be close to the other. My over all plan with the levels is to do 2-3 million levels (want to at least be better then microsoft) that all have a game number. Then remove the level creation functions and hopefull have my read functions down and just focus on all the gui aspects.
To do list
read functions
housekeeping of some code (I currently decided that is at least 4 lines of code are shared by 2 or more
functions that I put them in their own function that might be excessive but I like the neatness)
Work on a way of checking if no possible moves remain and let player know game over (all freecells
have this)
Work on allowing player to move a column of successive cards (if you've played freecell you know what
I mean) this will mean adding a function to keep track of open spaces and columns and checking
when a player clicks if the stack is successive so this will be a bit of code
Add right click to see under cards, microsoft has this should be as simple as onRightMouseDown move
card to layer 0 onRightMouseUp move it back to it's old Layer.
that should keep me busy for a while and thanks for the help so far David
So after that I did some easy things, I added a timer to my game. That took about 3 minutes and worked perfect on first time around. I then began reading read write functions and how to use them and also researched FreeCell levels or games as most places write them but for ease of confusion I will call them levels. It seems that with the standard freecell game (there's many different variations) 99.999 and on are beatable games when created randomly. One site overly dedicated to the history of freecell showed a study done of the 1 million games on microsofts freecell which were randomly created I think he said 137 are not beatable. This was determined by people who are creating FreeCell solvers. From all the information I got on FreeCell solvers I am in no shape to write one, they are extremely complex and apparently a "perfect" one has not been created yet with all the efforts. If people who went to school for these kinds of things and have years of experience in them can't do it then I'm guessing I can't. There goes my AI in freecell idea. But the good that came of that is giving up on the idea of making sure all my games are winnable so I started on a randomizer to create levels.
The randomizer went together very easy with one snag, I tried to create a for loop that counted down instead of up and torque script seemed to hate that. So after many times of trying to figure out why my randomize function was not randomizing anything I switched that around and bang random. The way I set up a randomizer was to make an array of 52 spots 1 for each card, I entered the ImageData name of my cards as the information and I then had a for loop get a random number take the card in that random number and store it in card. Then I had a seperate value that was essential 51 - %i. that did 2 things set the limit for my random number and keep track of my spot in the array because how I did it was basically a shuffle, get random number take card from that spot and swap it with last spot in array and count down till all cards were moved.
Once I had that working good I created another function to read write the levels. Had a global variable of currentLevel which was for 1 thing. The first number to get written to the file so I can hopefully set up a read later when someone enters a game number to jump to the right spot and get the card order. I also had a variable to turn on and off the shuffler so I could get all the card spots out write to a file and then turn on the shuffler for a new level. I tested it by outputting 3 levels and it worked perfect.
Now my big challenge on this. First I only know of writeline which in my spot is annoying because it starts on next line everytime. since I am using a for loop to get the values out of the array that gives me 52 seperate lines instead of 1 line with all 52 in it. This is something I haven't found a solution to. Now I want to do 2 things. Create a read system that then loads in the level. And create a read system while making the levels to go through the previous levels and make sure it's not a repeat before writing it. These 2 tasks will share a lot of code so when I have one all figured out I will hopefully be close to the other. My over all plan with the levels is to do 2-3 million levels (want to at least be better then microsoft) that all have a game number. Then remove the level creation functions and hopefull have my read functions down and just focus on all the gui aspects.
To do list
read functions
housekeeping of some code (I currently decided that is at least 4 lines of code are shared by 2 or more
functions that I put them in their own function that might be excessive but I like the neatness)
Work on a way of checking if no possible moves remain and let player know game over (all freecells
have this)
Work on allowing player to move a column of successive cards (if you've played freecell you know what
I mean) this will mean adding a function to keep track of open spaces and columns and checking
when a player clicks if the stack is successive so this will be a bit of code
Add right click to see under cards, microsoft has this should be as simple as onRightMouseDown move
card to layer 0 onRightMouseUp move it back to it's old Layer.
that should keep me busy for a while and thanks for the help so far David
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 your own resources!| Allyn "Mr_Bloodworth" Mcelrath (Nov 20, 2006 at 21:59 GMT) |
| David Higgins (Nov 20, 2006 at 21:59 GMT) Resource Rating: 3 |
%string = '';
for(...)
{
%string = // ...
}
%fileObj.WriteLine(%string);
Also, you may look at the SimSet or SimGroup objects -- for example;
$CARD_TYPE_HEART = 0;
$CARD_TYPE_CLUB = 1;
$CARD_TYPE_DIAMOND = 2;
$CARD_TYPE_SPADE = 3;
// $CARD_VALUE_1 -> $CARD_VALUE_10 can be created, or just assumed Static ;)
// the $CARD_VALUE_J-A is useful in case statements
// to perform specific logic based on those cards, usually 1-10 are not
// special in any way, so there's no need to pre-define them for code readability
$CARD_VALUE_J = 11;
$CARD_VALUE_Q = 12;
$CARD_VALUE_K = 13;
$CARD_VALUE_A = 0; // Ace is first, or last? :)
datablock t2dSceneObjectDatablock(CardDataBlock)
{
size = "256 256";
//imageMap = someValidImageMapContainingYourCardImagesPreSorted
cardFace = $CARD_TYPE_HEART;
cardValue = $CARD_VALUE_A;
};
$cardDeck = new SimSet();
for(%x = 0; %x < 4; %x++)
{
for(%y = 0; %y < 14; %y++)
{
%card = new t2dSceneObject()
{
defaultConfig = CardDataBlock;
cardFace = %x;
cardValue = %y;
frame = %x * %y; // your image map should be sorted to perform this!
};
$cardDeck.add(%card);
}
}
// test script
echo("Test Script One: Ordered");
for(%x = 0; %x < $cardDeck.getCount(); %x++)
{
%card = $cardDeck.getObject(%x);
echo("Card: " @ %card.cardValue @ " -- FACE: " @ %card.cardFace);
}
// now to randomize the card deck
$cardDeckSorter = $cardDeck;
$cardDeck = new SimSet();
while($cardDeckSorter.getCount() > 0)
{
%card = $cardDeckSorter.getObject(getRandom(0, $cardDeckSorter.getCount()-1));
$cardDeck.add(%card);
$cardDeckSorter.remove(%card);
}
// test script
echo("\r\n\r\n");
echo("Test Script Two: Sorted");
for(%x = 0; %x < $cardDeck.getCount(); %x++)
{
%card = $cardDeck.getObject(%x);
echo("Card: " @ %card.cardValue @ " -- FACE: " @ %card.cardFace);
}
The code in that script, was saved to a cardSorter.cs file, and then simply exec()'d in the game.cs and executed -- there are two "test scripts" included, which show the way the card deck was after creation, and how it was after sorting.
The initial code, that create's the deck dynamically, does not need to be called ever again -- the deck can be randomized after being randomized, which would probably make the deck even more random --
The reason I used the SimSet and a datablock, was so that your card "array" could actually contain your actual card as well -- so if you fix up the datablock, and the %card = new t2dSceneObject() {}; block ... you can easily add your card graphic, etc -- otherwise, you can just use the code as is ...
If you don't attach the graphics and what not to the deck, then you can probably remove the datablock reference, and just create new t2dSceneObject's and add the cardFace and cardValue fields to it at creation --
| David Higgins (Nov 20, 2006 at 22:49 GMT) Resource Rating: 3 |
| David Higgins (Nov 20, 2006 at 23:13 GMT) Resource Rating: 3 |
| J Sears (Nov 20, 2006 at 23:19 GMT) |
@david I got cards from http://www.jfitz.com/cards/ but they're all individual cards so you'd have to combine them all if you want to make it easier that way, I've just been dealing with them seperated for now
I did end up using the string method (figured it out before I came back on to check this) worked out good I got the randomizer writing and check the previous lines all set up and let the machine go. It created I think 37000 unique games in 20 minutes before TGB crashed, the way I had it set up must have been leaving too much in memory, so I'll just add more games later. I seem to have the read file working fine too but here's my problem I'm using this
%card = new t2dSceneObject() {
scenegraph = t2dScene.SceneGraph;
imageMap = "n11";
frame = "0";
canSaveDynamicFields = "1";
position = "0 0";
Layer = %cardLayer;
MountInheritAttributes = "0";
cardValue = "1";
cardSuit = "1";
cardColor = "1";
};
%card.mount(%cardMount,0,0.5,0,false,false,false,false);to try and load each image and mount it to it's correct spot but it makes the object gives it an object number but when it goes to mount says error object is not in scene and I can't for the life of me figure out the problem
oh and for my game list file I didn't exec it in I just did OpenForRead and then since each game number is on a seperate line I just do %temp=%file.readline() and then keep a counter and when that counter hits the level number I have %level=%temp. Not sure if that's the best way to do it but seems to do ok
| J Sears (Nov 20, 2006 at 23:22 GMT) |
| David Higgins (Nov 21, 2006 at 00:56 GMT) Resource Rating: 3 |
as for the file stuff, not really sure -- I can look into the file objects in TGB and see what some alternatives are -- most file objects in other langauges have some form of 'seek' ability, which would be dramatically better then reading each line until you get to the one you want -- especially if you randomly generate 1,000,000 games -- just imagine waiting for 999,999 to load ;)
| David Higgins (Nov 21, 2006 at 01:11 GMT) Resource Rating: 3 |
J, are you a Pro or Indie licensee?
| J Sears (Nov 21, 2006 at 01:49 GMT) |
$levelNumber=50;
function createLevel()
{
%file= new FileObject();
%file.OpenForRead("~/data/levels/levels.cs");
for(%i=0;%i<$levelNumber;%i++)
%level=%file.readline();
//set array values to 0
for(%i=0;%i<8;%i++)
{
%columns[%i]=%i;
}
%objCount = t2dScene.getSceneObjectCount();
%objList = t2dScene.getSceneObjectList();
%columnCounter = 1;
//setup the starting 8 column markers, after those the cards themselves will be used
for(%i=0;%i<%objCount;%i++)
{
%obj= getWord(%objList, %i);
if(%obj.isColumn == %columnCounter)
{
%spot = %columnCounter - 1;
%columns[%spot] = %obj;
echo("this is the obj that should be in there now", %obj);
%columnCounter++;
echo(%columns[%spot], "this is the object in the column starting spot");
}
if(%columnCounter==9)
%i=%objCount;
}
%columnCounter = 0;
%layerCounter = 15;
%number = getWordCount(%level);
//let's mount those cards
for(%i=0;%i<%number;%i++)
{
for(%j=0;%j<%objCount;%j++)
{
%obj = getWord(%objList, %j);
%currentWord = getWord(%level, %i);
if(%obj.imageMap $= %currentWord)
{
%obj.Layer = %layerCounter;
%mountPoint = %columns[%columnCounter];
echo(%mountPoint, "this should be the same objects as above");
%obj.mount(%mountPoint,0,0.5,0,false,false,false,false);
%columns[%columnCounter]=%obj;
%columnCounter++;
if(%columnCounter==8)
{
%layerCounter--;
%columnCounter=0;
}
%j=%objCount;
}
}
}
}
I keep looking over it and just can't figure out why it would mount all the objects in the right spot and they're all layers 15 and up where the background is layer 31, and the background shows up. Never thought I'd pull that off. And all the objects are checked visible in the game builder.
Ya a seek would be good but for this operation a quick receive line loop shouldn't cause too much slow down, a more major game maybe.
| J Sears (Nov 21, 2006 at 02:02 GMT) |
| David Higgins (Nov 21, 2006 at 02:40 GMT) Resource Rating: 3 |
Scrambling some eggs and all of a sudden it's like "Ohhhhh ...." -- sucks when you run over to the computer to try it out and forget the foods still cooking :)
| J Sears (Nov 21, 2006 at 03:52 GMT) |
| Tank Dork (Nov 22, 2006 at 08:01 GMT) |
You and David might consider posting some of your finds as resources or a tutorial for the basics of starting a card game in TGB (the match game is only one.. and it is not alot of help). I plan on doing this when I get mine working but you guys are light years ahead of me it seems.
| David Higgins (Nov 22, 2006 at 12:38 GMT) Resource Rating: 3 |
You must be a member and be logged in to either append comments or rate this resource.


3.0 out of 5


