Thread: Large 1D array -> Grid-like 2D array. HOW?

  1. #1
    Registered User
    Join Date
    Jun 2006
    Posts
    45

    Exclamation 1D array to 2D array conversion help!

    Hello.

    Im making a game for a certain community and I can load in these map levels. Each level is exactly 592 bytes -

    30x20 (30 chars to the right, 20 down) + end of line char and '\n' char. Oh but hte last line is the password for hte level so its only 4x20 if it wree gridded.

    Anyways, Im trying to grid it like that in a 2D array. My function:

    Code:
    void WorkWithMap() {
         for(i=0;i<19;i++) {
                           for(z=0;z<30;z++) {
                                             
                                             level[i][z]=map[i*z];
                                                                                 
                           }
         }
    }
    I dont WANT the password in there, so i didnt read up to 20 (hence i<19). This way doesnt work as when printing out, its all random and multiple characters where there is only one of in the file. So... Please help?

    I believe one reason is because if

    i=0

    and z=... say...

    z=23

    Than

    level[i][z] = map[ 0 * 23 ]

    thus resulting in map[0] through out the entire thing... Any way to make it work?
    Last edited by SG57; 11-05-2006 at 07:44 PM.

  2. #2
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    You're doing your math wrong. Your entire first row will be multiplied by zero. As will your entire first column. You need something like:
    Code:
    level[i][z] = map[ i + (z * 19) ];

    Quzah.
    Hope is the first step on the road to disappointment.

  3. #3
    Registered User
    Join Date
    Jun 2006
    Posts
    45
    Just tried it. Dont think it works as its now altered it sideways....

  4. #4
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Yep. So switch it around. Do you understand what it is you do to make a single dimension array act like a two dimensional one? You need to simulate each row and column. Therefore, you need to index each column. You need to also index each row.

    The column you're on is simply the column counter. Add that to your row. Your row is the length of each row, multiplied by your current row counter.


    Quzah.
    Hope is the first step on the road to disappointment.

  5. #5
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    When I was doing a program that needed to re-configure the dimensions of an array, it helped me a lot to change my variable names into row, col, and sqr, and keep a little drawing of an example of what I wanted (along with the math equation), right at hand, to glance at.

    You can't just use row and col variables on each side of the equation. You have to include the number of sqr's in each row:

    2d_array[row][col] = 1d_array[(row * sqrsInRow) + col]

    So if your 2D array is 30 sqr's wide:
    2d_array[5][4] = 1d_array[(5 * 30) + 4]

    Note: It helps to use maybe a border around the grid you want to show on your display. If you fill those border sqr's with a unique "border value" (maybe -9), then it just makes it easier to program, sometimes.

    I "forgot" there was a zero index to the array, and started using it at 1, not zero. Very helpful.
    So the next row also begins with the "one" column, 31 in your case.

    Also, (as you've done), make your board width a multiple of 10 Even though you don't need that much room, it makes using mod and such, much easier.

    Adak

  6. #6
    Registered User
    Join Date
    Jun 2006
    Posts
    45
    Im still having problems with it. I can get it to display like this:
    Code:
     ***
    * **
    ** *
    ***
    But not likes its supposed to:
    Code:
     ***
     ***
     ***
     ***
    Im using this code as Quzah's didnt get as close to what its supposed to be as this:
    Code:
    void WorkWithMap() {
         j=0;
         for(i=0;i<19;i++) {
                           for(z=0;z<30;z++) {
                                             level[i][z] = map[j]
                                             j++;
                           }
         }
    }
    Can someone confirm a working way to do this? I undrstand what you said and whatnot, but its just not working when i try.

  7. #7
    Registered User
    Join Date
    Jun 2004
    Posts
    201
    Quote Originally Posted by SG57
    Im using this code as Quzah's didnt get as close to what its supposed to be as this:
    uhm you expect people to spoon feed every line of code to you whenever you have a problem? How about try and think yourself, all the info you need is in the thread

  8. #8
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Quote Originally Posted by SG57
    Im still having problems with it. I can get it to display like this:
    Can someone confirm a working way to do this? I undrstand what you said and whatnot, but its just not working when i try.
    Perhaps because you're using end of line char's, and newline char's. They'll just goof it up, you need to get them out of there, or account for them in your arithmetic.

    Hint: get rid of them.

    My puzzle/game programs just about all use 2d and 1d arrays, and swap back and forth. There is no problem if you don't have extra char's in the array.

    Here's an example:

    Wheels is a 1D array. SATemp is a 2D array, and I'm transferring the SATemp data into the Wheels array:

    Wheels[r * 10 + c] = SATemp[r, c]

    Where r = row number, c = column number, and each row has 10 squares (this is from a Sudoku game). Wheels was an odometer graphic for solving the puzzle by brute force. SATemp was the Sudoku Array (Temp), the working array at that time.

    As you know, Sudoku standard puzzles just have 9 ssquares, but I have 10 sqr's in my array, and don't use the zero, 10, 20, 30, etc., sqr's for anything. They're not shown at all. The size just helps with the coding.


    Adak
    Last edited by Adak; 11-06-2006 at 01:38 AM.

  9. #9
    Registered User
    Join Date
    Jun 2006
    Posts
    45
    Laserve - If you re-read the foot note on my last post, i specifically said everything I try doesnt work - meaning ive tried multiple times with no success.

    Akak - Ive already tried that to no prevail. I had a if statement stating to not copy over every 31st character into the levels 2d array excluding 0 (the way i had it, it would multiply by 0 thus removing the first character). Im now going to experiment around until I get it. and yes im using this thread and everything posted in it as a reference (besides #7).

  10. #10
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    It works, guy! I use that code in my chess program, my Sudoku program, my minesweeper program, etc.

    It's just simple arithmetic, but you do need to ditch the extra char's - newlines, end of line markers, etc. At least until you get the basic one D to two D array changeover, working.

    Did you do that, yet?

    I'm just guessing here, but I'll bet money that you had your code to not transfer over certain char's into the new array - and THEN you forgot to subtract your array index number to account for that non-additional char. That's why you have 1 blank in the final array, every row or so.

    The reason it's frustrating is that you're telling the Wright brothers, that their flyer won't get off the ground. And we've already flown it in North Carolina, Paris, U.K., Germany, Ireland, etc.

    Your code snippet didn't include all the details needed to give you a more detailed answer for your particular program, but what I posted - definitely "flies".

    If you have another problem, then you need to post the code showing it, and describe it in more detail, please.

    Adak
    Last edited by Adak; 11-06-2006 at 01:55 AM.

  11. #11
    Registered User
    Join Date
    Jun 2006
    Posts
    45
    X(

    I know your right. Just about everyone here is more experienced in C than I... I just need to see a game's source that uses this method of transforming a 1D array into a 2D array. Either way, heres an overview of my situation.

    I load in a file AKA level. It must be 592 bytes in size (30x19 (map) + 1x4 (password)). Once loaded into a buffer called:

    map[592];

    I than seperate it into a more useable form via 2D array.

    level[19][30];

    So for every 30- characters I transfer over, I move down one element in the first []. Than later, i display the map via that 2D array. The only problem is its displaying like:

    Code:
     ***
    * **
    ** *
    Where as it should be displaying like:
    Code:
     ***
     ***
     ***
    Now, Ive come to believe the '\n' char at the end of each line is causing this little bug. so, in my for loop for transfering over, I didnt transfer over every 30th char from the map array thus removing the ending character. That didnt work, so I experimented by changing it to the every 31st char thinking my math was wrong or soemthing. Right now, that is this:
    Code:
         j=0;
         for(i=0;i<19;i++) {
                           for(z=0;z<30;z++) {
                                             if(j==31 || j==61 || j==91 || j==121 || j==151 || j==181 || j==211
                                                || j==241 || j==271 || j==301 || j==331 || j==361 || j==391 || j==421
                                                || j==451 || j==481 || j==511 || j==541 || j==571 || j==601) 
                                             { } else {
                                                         level[i][z] = map[j];
                                             }
                                             j++;
                           }
         }
    (The large amount of if j== statements are just to be positive im calculating right). That doesnt work, so now im here. Im going to experiment more as I have time. If you need any more info, ill supply it.

    I know im being a bother, im just stuck at this little predicament :-\ I know this isnt the best way as I should use ypur way, Adak, but this way has proved the closest to what i want route... Im willing to change if necessary.

  12. #12
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    SG, that code I posted was STRAIGHT out of a Sudoku game, and it's been solving EVERY standard puzzle correctly for months, now.

    Can the newlines and end of line char's be ignored with a simple if statement inside the transfer loop of data from one array to the other?

    Code:
    for (i = 0; i < (row * rowwidth + col); i++)  {
       value = 1D_array[i];
       if ((value != '\n) && (value != end of line char)) {
           row = i / 10;
           if (row < 1) row = 1;
           col = i % 10; 
           2D_array[row, col] = 1D_array[i]; 
       }
    }
    It's late and I'm punchy, but the above should give you some idea's.

    I'm off for some zzzz's. Good luck. I'll check back tomorrow. Still stuck, post or pm me, and show EXACTLY what is is that you have, and what it is that you want.

    A few rows of stars isn't too challenging.

    I believe if you change your variables from i, j, k, z, etc., and make them row, col, sqr, (or i for sqr if you're solid with that), you'll start to see how to do this. Maybe try it for just two rows, at first, then make it bigger.

    Adak
    Last edited by Adak; 11-06-2006 at 02:52 AM.

  13. #13
    Registered User
    Join Date
    Jun 2006
    Posts
    45
    lol the row of chars was an example, the first level is the following:
    Code:
    #####    ##    ##    #      #
    ##### ##### ##### ######## ##
    #####    ## #  ##    #### ###
    ######## ## ## ##### ### ####
    #####    ##    ##    ## #####
    #############################
    ######                 ######
    ######                 ######
    ######                 ######
    ######                 ######
    ######                 ######
    ######                 ######
    ######   #       #     ######
    ######F  #   # * # * S ######
    #############################
    ###########   ###############
    ############# ###############
    ############# ###############
    ###########     #############
    abc
    # = brick/wall/cieling/floor/ground/etc.
    ' ' = nothing/space/walk in/through
    * = block (moveable brick basically)
    F = finsih
    S = start/player position.

    I will now actually look deeply into your code you posted. I, too, am going to sleep very soon (school damn you 9th grade 8 AM bell). thanks for all your help thus far, Im positive Ive been a pain, but try to bare with me

  14. #14
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    offset=row*width+column

    Since this is more suited to C++ than C:

    Code:
    class CMap
    {
      WORD *m_pMap;
      WORD m_uWidth;
      WORD m_uMaxOffset;
    
      public:
       CMap():m_pMap(NULL),m_uWidth(0),m_uMaxOffset(0) { }
       virtual ~CMap(void) { delete [] m_pMap; }
    
       bool Create(int iWidth,int iHeight)
       {
          m_uMaxOffset=iWidth*iHeight;
          m_pMap=new WORD[m_uMaxOffset];
    
          if (!m_pMap) return true;
    
          m_iWidth=iWidth;
       }
    
       WORD GetValue(int iRow,int iCol,bool &bResult)
       {
          WORD uOffset=iRow*m_uWidth+iCol;
          if (uOffset>m_uMaxOffset) 
          {
             bResult=true;
             return 0xFFFF;
          }
          bResult=false;
          return m_pMap[uOffset];
       }
    
       bool SetValue(int iRow,int iCol,WORD uValue)
       {
         WORD uOffset=iRow*m_uWidth+iCol;
         if (uOffset>m_uMaxOffset) return true;
         m_pMap[uOffset]=uValue;
         return false;
       }
    };
    Convert to C and you have your map.
    Last edited by VirtualAce; 11-06-2006 at 05:08 AM.

  15. #15
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    The map you posted looks like it's 19x29, so assuming a newline character was read at the end of every line, maybe this would work:
    Code:
         j=0;
         for(i=0; i<19; i++) {
                           for (z=0; z<30; z++) {
                                             if (z != 29) {
                                                         level[i][z] = map[j];
                                             }
                                             j++;
                           }
         }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Array -> 2D array
    By Tupcia in forum C Programming
    Replies: 4
    Last Post: 05-16-2008, 02:29 AM
  2. passing/pointing to a 2d array
    By jamie85 in forum C Programming
    Replies: 7
    Last Post: 10-28-2005, 10:16 PM
  3. Copying from one 2d array to another....with a twist
    By Zildjian in forum C++ Programming
    Replies: 2
    Last Post: 10-24-2004, 07:39 PM
  4. Replies: 6
    Last Post: 10-21-2003, 09:57 PM
  5. Struct *** initialization
    By Saravanan in forum C Programming
    Replies: 20
    Last Post: 10-09-2003, 12:04 PM