Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

Matlab Problem structured array

  1. Apr 17, 2010 #1
    Not sure if anyone here is familiar with matlab programming. Im supposed to create a structured array (resembling a game board) that acts as a predator/prey simulator. The user needs to specify the size of the game board. Within the gameboard im supposed to represent a couple of different animals. Zebras, represented with a 'Z' should occupy 10% of the gameboard, giraffes represented with a 'G' occupy another 10%, hyenas represented with an 'H' occupy 5%, and there will be 1 lion represented with an 'L'. Unoccupied spaces will be represented with a hyphen.

    this is what i've come up with so far. I tried making the board filled with hyphens, and then replacing them by specifying different animals for random locations within the board. There might be an easier way to do this using vectorization and not for loops. Im also confused about how I should make each animal occupy random locations that amount to a certain percent of the gameboard. How can I do this randomly without having the same locations within the array specified twice? Once agian, vectorization might offer an easier means to doing this, im just not sure how.

    Any help you can offer will be greatly appreciated!!!

    function board = makeBoard(rows,cols)

    for rowIndex = 1:rows
    for colIndex = 1:cols
    board(rowIndex,colIndex).type = '-';
    end
    end

    %creates a structured array with hyphens at each location
     
  2. jcsd
  3. Apr 17, 2010 #2

    Mark44

    Staff: Mentor

    Your game board has rows * cols cells. This means that there should be .1 * rows * cols cells with zebras, the same number of giraffes, .05*rows*cols hyenas, and 1 lion.

    For example, if there are 30 rows and 40 columns (1200 cells), there should be 120 zebras, 120 giraffes, 60 hyenas, and 1 lion.

    One way to distribute the animals is to generate .25 * rows * cols random numbers in the range 1 through rows * cells. Using the example of a 30 row by 40 column board, you would generate 400 numbers in the range 1 through 1200. The first 120 of these you could distribute as zebras, the next 120 as giraffes, and the last 60 as hyenas. To make the explanation easier to understand, I'll continue using 30 rows and 40 columns. I'm saving the lion for last.

    Supposing that one of the random numbers generated was 723. This can be converted to row and col numbers by using the rem (short for remainder) function. rem(723, 30) gives the remainder after dividing 723 by 30, which is 3, and this will be the column number. If you subtract 3 from 723, you get 720, and 720 divided by 30 is 24, so an animal whose random number is 723 should be placed in row 24, column 3.

    Do that for all the animals except the lion. I don't think it's likely that you'll get a repeated random number, so this algorithm shouldn't end up with two animals at the same location, but I suppose it's possible, so you should check that where you put an animal has a '-' character in it. If it's some other character, you'll need to figure out some other place to put that animal.

    When you have all the zebras, giraffes, and hyenas in place, generate one more random number in the range 1 through rows * cols. Figure out as already described the cell of the array to put the lion. If there's already another animal there, generate another random number, and continue doing this until you get a cell that doesn't already have an animal in it.
     
  4. Apr 18, 2010 #3
    thanks for the great advice :smile:...

    I wrote out the code for the algorithm. My first for loop looks something like this...

    function board = makeBoard(rows,cols)

    for rowIndex = 1:rows
    for colIndex = 1:cols
    board(rowIndex,colIndex).type = '-';
    end
    end

    for index = 1:.1*rows*cols
    randomNumber = randi([1,rows*cols]);
    colNumber = rem(randomNumber,rows);
    rowNumber = abs(randomNumber - colNumber);
    board(rowNumber,colNumber).type = 'Z';
    end

    my only problem occurs when I run the code. A matlab error prompt appears reading...

    ??? Cell contents indices must be greater than 0

    Error in ==> makeBoard at 13
    board(rowNumber,colNumber).type = 'Z';

    I tried fixing this by adding the built in matlab absolute value command when subtracting my randomNumber by colNumber, but this didnt seem to help
     
  5. Apr 18, 2010 #4

    Mark44

    Staff: Mentor

    You might be having a problem with this line:
    randomNumber = randi([1,rows*cols]);
    I don't think this is the right syntax for this function, particularly the part with the thing in brackets.

    Also, before this line
    board(rowNumber,colNumber).type = 'Z';

    add some code to display the values of rowNumber and colNumber. One or both of these is not a positive integer.
     
  6. Apr 18, 2010 #5
    i think i got it to work correctly... heres my code...
    -----------------------------------------------------------
    function board = makeBoard(rows,cols)

    for rowIndex = 1:rows
    for colIndex = 1:cols
    board(rowIndex,colIndex).type = '-';
    end
    end

    for index = 1:.1*rows*cols
    randomNumber = randi([1,rows*cols]);
    colNumber = rem(randomNumber,rows);
    if (colNumber == 0)
    colNumber = colNumber + 1;
    end
    rowNumber = rem(randomNumber - colNumber,rows);
    if (rowNumber == 0)
    rowNumber = rowNumber + 1;
    end
    board(rowNumber,colNumber).type = 'Z';
    end

    for index = 1:.1*rows*cols
    randomNumber = randi([1,rows*cols]);
    colNumber = rem(randomNumber,rows);
    if (colNumber == 0)
    colNumber = colNumber + 1;
    end
    rowNumber = rem(randomNumber - colNumber,rows);
    if (rowNumber == 0)
    rowNumber = rowNumber + 1;
    end
    board(rowNumber,colNumber).type = 'G';
    end

    for index = 1:.05*rows*cols
    randomNumber = randi([1,rows*cols]);
    colNumber = rem(randomNumber,rows);
    if (colNumber == 0)
    colNumber = colNumber + 1;
    end
    rowNumber = rem(randomNumber - colNumber,rows);
    if (rowNumber == 0)
    rowNumber = rowNumber + 1;
    end
    board(rowNumber,colNumber).type = 'H';
    end

    randomNumber = randi([1,rows*cols]);
    colNumber = rem(randomNumber,rows);
    if (colNumber == 0)
    colNumber = colNumber + 1;
    end
    rowNumber = rem(randomNumber - colNumber,rows);
    if (rowNumber == 0)
    rowNumber = rowNumber + 1;
    end
    board(rowNumber,colNumber).type = 'L';
    end

    -----------------------------------------------------------

    My only problem now is when I run my test function, I keep getting an error prompt indicating that my board has improper dimensions.

    ------------------------------------------------------------
    function [] = test_makeBoard()
    board = makeBoard(10,10);
    err(size(board,1) ~= 10 || size(board,2) ~= 10,'board not created as 10x10');
    err(~isa(board,'struct'),'board is not a struct array');
    g=0;l=0;h=0;z=0;
    for ii=1:100
    board = makeBoard(10,10);
    b = [board.type];
    g=g+sum(b=='G');
    l=l+sum(b=='L');
    h=h+sum(b=='H');
    z=z+sum(b=='Z');
    end
    err(g/10000 < .05 || g/10000 > .15,sprintf('giraffes at %d percent of board',g/10000));
    err(z/10000 < .05 || z/10000 > .15,sprintf('zebras at %d percent of board',z/10000));
    err(h/10000 < .02 || h/10000 > .08,sprintf('hyenas at %d percent of board',h/10000));
    err(l ~= 100,'lions not one per board');
    end
    -----------------------------------------------------------

    any idea why i might be getting this error message. Im pretty sure it works because when I run fprintf(board.type) at the end of my program, it shows that I have a 10X10 struct type array
     
  7. Apr 18, 2010 #6

    Mark44

    Staff: Mentor

    From what I can tell, your board array is just an array, but you're treating it as if it were an array of structures. I can do this in C or C++, but I don't know matlab well enough to create an array whose elements are structures. The best I can do is to point you to the matlab documentation (if you don't already have it or have a link to it).
    Structures - http://www.mathworks.com/access/helpdesk/help/techdoc/ref/f16-42340.html#f16-53937 [Broken]

    I think what you might need to do is create a structure with all of the member names you plan to use, then create your board array, initializing each element in board with the structure.
    Here's a link to a doc page that might be helpful - http://www.mathworks.com/access/helpdesk/help/techdoc/matlab_oop/brd4btr.html [Broken]

    On the other hand, why do you have an array of structures? It appears to me that all you are putting in each cell is '-', 'Z', 'G', or 'L'. I don't see the need for the type member. You could just as well store these characters in your board array. I might be missing something here, that you are planning to have some other member value in each board element.
     
    Last edited by a moderator: May 4, 2017
Share this great discussion with others via Reddit, Google+, Twitter, or Facebook