D.Slatk Posted August 3, 2005 Posted August 3, 2005 Okay, been a while since I've posted. Anyways, lately I have been thinking about something I have been wanting to do but have got stuck on this part. My idea involves a grid. In the grid, each little cell contains something, maybe in image, who knows. This grid of course would have to be displayed to the web browser in one of different forms but that doesn't really matter here. Now here comes the hard part. I want to be able to store the grid in a single variable. Something that could look like this: >xxxxxxxxTxB xxxTxxxxxxB xxxxxxTxxxB xxTxxxxxxxB xxxxxxxxTxB xxxxxxxxTxB xxxTxxxxxxB xxxxxxTxxxB xxTxxxxxxxB xxxxxxxxTx That's a 10x10 grid. I need to find a way to have php scan that variable, and do something depending on the certain letter it sees. Say for every "x" it sees, it needs to make a green cell and for every "T" it sees, it needs to make a brown tile. And for every "B" it sees, it starts a new row. Is there any function that I can use in order to scan it and perform an action depending on what letter it encounters? There might be a really simple way to do this I haven't been able to find, or I'll need to define my own function to do it. >.< Quote
surefire Posted August 4, 2005 Posted August 4, 2005 (I may be missing some of your meaning... but here goes) I'd use an array. That's not technically a variable, but sounds like the tool to use. If you need the array in a variable, serialize() the array. Quote
D.Slatk Posted August 4, 2005 Author Posted August 4, 2005 (edited) I have started using arrays but it's quite inconvenient. x.x Here is what I have so far: >// Store the map into the variable... $area1 = 'x x x x x x x x x x x x x x x x x x x x x x x x x x x x x xB x x x x x x x x x x x x x x x x x x x x x x x x x x x x x xB x x x x x x x x x x x x x x x x x x x x x x x x x x x x x xB x x x x x x x x x x x x x x x x x x x x x x x x x x x x x xB x x x x x x x x x x x x x x x x x x x x x x x x x x x x x xB x x x x x x x x x x x x x x x x x x x x x x x x x x x x x xB x x x x x x x x x x x x x x x x x x x x x x x x x x x x x xB x x x x x x x x x x x x x x x x x x x x x x x x x x x x x xB x x x x x x x x x x x x x x x x x x x x x x x x x x x x x xB x x x x x x x x x x x x x x x x x x x x x x x x x x x x x xB x x x x x x x x x x x x x x x x x x x x x x x x x x x x x xB x x x x x x x x x x x x x x x x x x x x x x x x x x x x x xB x x x x x x x x x x x x x x x x x x x x x x x x x x x x x xB x x x x x x x x x x x x x x x x x x x x x x x x x x x x x xB x x x x x x x x x x x x x x x x x x x x x x x x x x x x x xB x x x x x x x x x x x x x x x x x x x x x x x x x x x x x xB x x x x x x x x x x x x x x x x x x x x x x x x x x x x x xB x x x x x x x x x x x x x x x x x x x x x x x x x x x x x xB x x x x x x x x x x x x x x x x x x x x x x x x x x x x x xB x x x x x x x x x x x x x x x x x x x x x x x x x x x x x xB x x x x x x x x x x x x x x x x x x x x x x x x x x x x x xB x x x x x x x x x x x x x x x x x x x x x x x x x x x x x xB x x x x x x x x x x x x x x x x x x x x x x x x x x x x x xB x x x x x x x x x x x x x x x x x x x x x x x x x x x x x xB x x x x x x x x x x x x x x x x x x x x x x x x x x x x x xB x x x x x x x x x x x x x x x x x x x x x x x x x x x x x xB x x x x x x x x x x x x x x x x x x x x x x x x x x x x x xB x x x x x x x x x x x x x x x x x x x x x x x x x x x x x xB x x x x x x x x x x x x x x x x x x x x x x x x x x x x x xB x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x'; // Get it all on one one line... $area1 = explode ("\n", $area1); $area1 = implode ('', $area1); // Explode the string to store the rows into an array... $area1 = explode ('B', $area1); // Explode again to store each character into a nested array... for ($i = 0; $i < 30; $i++) { $area1[$i] = explode (' ', $area1[$i]); } From there I could recall any one of the x's by using $area[row][column]. I have run into another problem. I need it to be $area[column][row], heh... Sorry about all the questions, I only know the basics of php. Also a couple other minor things... I'm not sure or not if there's a function to put a variable all on one line or not... Edited August 4, 2005 by D.Slatk Quote
surefire Posted August 4, 2005 Posted August 4, 2005 You've described the tree, can you give me a view of the forest? What's the big picture thing you're trying to accomplish? Quote
D.Slatk Posted August 4, 2005 Author Posted August 4, 2005 (edited) Okay I managed to get something done. Sorry for not being very clear. I'm trying to have a big "map" of letters that are used to output a table. Each letter represents something in the table, whether it's a cell with a certain color or a </tr><tr> to start a new row. One problem I was having was when I was trying to explode that string so I could each each letter into its own array. I couldn't just explode with '' (explode things that have nothing between them), which I was trying to do to accomplish that. So I looked at php.net and after a bit of looking found a function called chunk_split()! So I used that to place a colon after every letter, then used substr() to take off the last colon, and then exploded it by the colon so each letter was in it's own key as I wanted. Here is the working code: >echo '<html><head><title>Test</title><style type="text/css"><!-- body,table {font-size:11px;} --></style></head><body>'; // Store the map into the variable... $area1 = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxLxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxLLxxxLLLxxxxxxxxxxx xxxxxxxLLxxLxxxxxxLLxxxxxxxxxxxx xxxxxxLLLxxxxLLxxxxxxLLLLLxxxxxx xxxxxxxxxxxxxxxxxxLLLLLLLLLLxxxx xxxLLLLLLLLLLLLLLLLLLLLLLLLLLxxx xxLLLLLLLLLLLLLLLLLLLLLLLLLLLLxx xxLLLLLLLLLLLLLLLLLLLLLLLLLLLLxx xxxLLLLLLLLLLLLLLLLLLLLLLLLLLLxx xxxxLLLLLLLLLLLLLLLLLLLLLLLLLLxx xxxLLLLLLLLLLLLLLLLLLLLLLLLLLLxx xxLLLLLLLLLLLLLLLLLLLLLLLLLLLLxx xLLLLLLLLLLLLLLLLLLLLLLLLLLLLLxx xLLLLLLLLLLLLLLLLLLLLLLLLLLLLLxx xLLLLLLLLLLLLLLLLLLLLLLLLLLLLxxx xLLLLLLLLLLLxxxxxxxLxLLLLLxxxxxx xLLLLLLLLLxxxxxxxxxxxxxxxxxxxxxx xLLLLLLLxxxxxxxxxxxxxxxxxxxxxxxx xLLLLLLLxxxxxxxxxxxxxxxxxxxxxxxx xLLLLLLLLLxxxxxxxxxxxxxxxxxxxxxx xxLLLLLLLLLLLLLLLLLLLLxxxxxxxxxx xxxLLLLLLLLLLLLLLLLLLLLxxxxxxxxx xxxxLLLLLLLLLLLLLLLLLLLLxxxxxxxx xxxxxLLLLLLLLLLLLLLLLLLLLxxxxxxx xxxxxxLLLLLLLLLLLLLLLLLLLxxxxxxx xxxxxxxLLLLLLLLLLLLLLLLLxxxxxxxx xxLLxxxxxxxxxxxxxxLLLxxxxxxxxxxx xxxxxxxLLLxxxLxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'; // Separate the letters with a colon... $area1 = chunk_split($area1, 1, ':'); $area1 = substr ($area1, 0, (strlen($area1)-1)); // Put each tile into a key of the array... $area1 = explode (':', $area1); // Generate the table and it's tiles depending on the contents of each key... echo '<table border="0" cellpadding="0" cellspacing="0" align="center"><tr>'; for ($i = 0; isset($area1[$i]); $i++) { switch ($area1[$i]) { case 'x': echo '<td width="16" height="16" bgcolor="#89CBF3"> </td>'; break; case 'L': echo '<td width="16" height="16" bgcolor="#19CF00"> </td>'; break; case "\n": echo '</tr><tr>'; break; default: echo '<td width="16" height="16" bgcolor="#FFFFFF"> </td>'; } } echo '</tr></table>'; echo '</body></html>'; You can see it in action at http://test.talonz.com/enginetest.php However I am still looking for ways to make the script more clean. Thanks for telling me about the serialize() function, that way it'd be easy to store this into a mysql record. Okay, and the big forest thing. I want to be able to have a very large map. In order to reduce speeds of requests to the table I'd have several maps, with each record having some way of identifying where it is in relationship to the other maps. Then the big goal is I want to be able to recall say a 10x10 area for starters anywhere on that big map (all of the records put together forms the big map)... It's confusing I think but right now I just want to make sure I can get those records stored and recalled in a nice clean way. Edited August 4, 2005 by D.Slatk Quote
jpepper Posted August 5, 2005 Posted August 5, 2005 If I understand you correctly you want the states in a single string so that you can easily store the states in a database. If you want to access the strings states directly without exploding the string into an array just use the string index operator $str = "hello"; echo $str{0}; // outputs 'h' echo $str{1}; // outputs 'e' since your array is 10,10 you would have a string of length 100. to calculate the 1d index from a 2d co-ordinate you just do the following: $rowLength = 10; $numRows = 10; $stringIndex = ($rowIndex * $rowLength) + $colIndex; echo $str{$stringIndex}; so if you want to access the character in the string at row 0, column 5.. $stringIndex would be (0 * 10) + 5 = 5. Row 2 at column 3 would be (2 * 10) + 3 = 23; hope this helps Quote
D.Slatk Posted August 5, 2005 Author Posted August 5, 2005 (edited) That is a very good idea, thanks! One thing before I try it though, I looked for documentation on php.net so I could find more information out about it but couldn't find any... Do you have a link to it there? edit Nevermind, foud some, it was way down though: http://us2.php.net/manual/en/language.types.string.php Going to go try it now. edit Yay, works. All I had to do was take out the code that converted the string into an array, and then replace each instance if $area1[$i] with $area1{$1}. Any more ideas on how to make this run faster / make the code more clean would be greatly appreciated! http://test.talonz.com/enginetest.php <- Ignore the trees, was testing something. Edited August 5, 2005 by D.Slatk Quote
jpepper Posted August 5, 2005 Posted August 5, 2005 Glad to help. Sorry.. I cant think of any way to make it faster. Depending on your application you might be able to cache the output table if page requests for the same info are common, but I don't know how dynamic your data is. Quote
D.Slatk Posted August 5, 2005 Author Posted August 5, 2005 hehe, That's okay. My next step is probably going to have to be to store several areas (smaller map chunks of the big map) in a database and somehow assign attributes to organize how they should be arranged on the big map as a whole. I think I am going to use an area id for the primary key, two numbers for the area location (x and y), then the map string for that area. I'd need to write a function that requests a portion of the map depending on for numbers (x1, y1, x2, y2) and those four numbers being two "global" coordinates. An area's global coordinates are determined by the area location. That is the best idea I can think of in order to reduce stress. See I could just make one HUGE map, but since when people request, they only request (normally) a 21x21 chunk of it, that creates a lot of stress on the server. They'd be requesting a huge data entry and only using just a small portion of it. With my idea in the first paragraph, they'll only be request up to four max areas at a time which is stitched together to show them the portion they're supposed to see. This is all just theorizing. No idea how I'll get it done but all you need is an ambition. If anybody has any other ideas that would work better, prove to be less stress on the server, or make the output'ed source code smaller again please share! hehe. Quote
carbonize Posted August 6, 2005 Posted August 6, 2005 (edited) Just off the top of my head you could just do a replace on the string. (Sorry if this got mentioned before but I only scanned the thread). >function generate_map($str) { $str = str_replace('x', '<td class="g1"> </td>', $str); $str = str_replace('T', '<td class="g2"> </td>', $str); $str = str_replace('L', '<td class="w1"> </td>', $str); $str = str_replace("\n", "</tr>\n<tr>\n", $str); return $str; } Or use preg_replace. Could even make an array of each letter and what it represents then use a foreach loop. >$tiles = array('x' => '<td class="g1"> </td>', 'T' => '<td class="g2"> </td>', '\n' => '</tr>\n<tr>\n'); foreach ($tiles as $key => $value) { str_replace($key, $value, $mapstring); } Edited August 6, 2005 by carbonize Quote
D.Slatk Posted August 6, 2005 Author Posted August 6, 2005 That's a really cool function, but it's very hard to get actual things inside of the cells such as the trees that are in the link... it is more easy for me to output the map piece by piece (td by td, and run conditionals to check if they need the images inside and if so then place them) until they all put together the actual map... Quote
jpepper Posted August 8, 2005 Posted August 8, 2005 Sounds like you are on the correct track using a 2d primary key as coords. Personally I think I would use a multi keyed primary id being the upper left hand coordinates of the system. If you keep the x,y separate you should be able to do queries in ranges. IE: all maps with x coordinates < b but greater than a and with y coordiants > c but less then d. You may even play around with letting some client side scripting display the actual data and grab just the map string from the site. This could let you do fast scrolling around your map without refreshing the page. JP Quote
D.Slatk Posted August 8, 2005 Author Posted August 8, 2005 Hehe, I am not actually using a primary key as the coords. Each "area" would have its own primary key of course, but it'd just be its id. Rather, each area has an identification associated with it, mainly its coords with all the other areas. Say you have 9 areas that are put next to eachother to form the large map. >[Area 0x0] [Area 0x1] [Area 0x2] [Area 1x0] [Area 1x1] [Area 1x2] [Area 2x0] [Area 2x1] [Area 2x2] That's how they'd be next to eachother on the actual map. To calculate the global top-left coordinate of an area, that'd be done depending on the sizes of the areas. Right now I'm thinking each size will be 32x32, but that isn't final yet. So the top left of area 1x2 would be (32, 64). So basically the top-left global coords of an area are based on the area coords... Because if I need to edit it, I can, but I can't edit a primary key. Quote
jpepper Posted August 9, 2005 Posted August 9, 2005 I believe you are mistaken about not being able to modify a primary key. At least using mysql you can. Primary keys just have to be unique. Since presumably you would have no overlapping areas in your db, you should be able to guarantee uniqueness without an additional id. The following does work as long as 1,1 is not already in the db. CREATE TABLE `test` ( `x` int(10) unsigned NOT NULL default '0', `y` int(10) unsigned NOT NULL default '0', `data` varchar(255) NOT NULL default '', PRIMARY KEY (`x`,`y`) ) TYPE=MyISAM COMMENT='test'; INSERT INTO `test` VALUES (1, 2, 'testdata'); UPDATE `test` SET `y` = '1' WHERE `x` =1 AND `y` =2; Quote
D.Slatk Posted August 9, 2005 Author Posted August 9, 2005 Oh okay, I see what you mean there, now. I didn't know that you could assign primary keys to two columns! Changin will work unless I need to use foreign keys, which I don't think I would need to do yet, really. This should save a column for several tables, thanks. By the way, if you try to change the value of a primary key into a value that already exists in the column, will it bring up an error? Quote
jpepper Posted August 9, 2005 Posted August 9, 2005 Changin will work unless I need to use foreign keys You can still do it, you just need a 2 field foreign key. By the way, if you try to change the value of a primary key into a value that already exists in the column, will it bring up an error? Yes it will throw error #1062 - Duplicate entry BTW what is the acutal purpose of your app. How is it going to be used? (If you don't mind me asking) Quote
D.Slatk Posted August 10, 2005 Author Posted August 10, 2005 (edited) You can still do it, you just need a 2 field foreign key.Yes it will throw error #1062 - Duplicate entry BTW what is the acutal purpose of your app. How is it going to be used? (If you don't mind me asking) <{POST_SNAPBACK}> Wow that really adds a lot more possibilities than I had imagined, making a primary key depend on two columns' values. Okay good about the error thing, when the php interfaces with the database I'll get caught if I'm doing anything stupid! You certainly know a lot about about mysql. Thanks for all the help by the way. I'll post why I'm building it in the morning as it will take some time to type up. It is a bit late here in california. Edited August 10, 2005 by D.Slatk Quote
D.Slatk Posted August 11, 2005 Author Posted August 11, 2005 (edited) Okay, basically I am trying to build the first steps of a game. I've got an idea and so i'm going with it. Since it involves things on a visual map, I think that's where I need to start. Each tile on the map has certain things associated with it. Maybe you'll run into a monster, maybe you'll get teleported to a different location, maybe it'll trigger a conversation with a computer-controlled character. I have most of the details of how to get it done, I just need to keep reading this book and then actually write the rest of the code for it. If you are interested in how the tables are going to be structured feel free to PM me and I'll give you more details! Edited August 11, 2005 by D.Slatk Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.