Page 1 of 1

Loop logic: Noise dissapation

Posted: Thu Jan 20, 2011 12:00 pm
by AdamRCarlson
EDIT: I re-read my post, and essentially it ended up being long and confusing. What I'm wondering, is if there's a way to set up a loop structure that has dynamic limits, and omits previous itteration's changes?



Let's say I have x and y coordinates set up as values on a really large grid, and I have a function noise($x, $y, $power).


when noise($x, $y, $power) is called, ideally it should assign $power to tile_noise_level where tile_x and tile_y are equal to $x and $y...

and then loop, but this time grab all adjacent tiles, meaning from $x-1, $y-1 to $x+1, $y+1 (excluding $x, $y as it's already been established) and apply ($power--;) to tile_noise_level to those...

and then loop from $x-2, $y-2 to $x+2, $y+2....

as long as ($power > 0).

I thought of somehow creating a collection of loops for as long as ($power > 0) :

Code: Select all


[0,0]

Code: Select all


[-1,-1]  [0,-1]  [+1,-1]
[-1,0]   [0,0]   [+1,0]
[-1,+1] [0,+1]  [+1, +1]

Code: Select all


[-2,-2]...


                    ...[+2,+2]


But I can't quite seem to wrap my head around how to do that dynamically with loops. And, that method also hits ground zero each itteration.

I guess what I'm looking for is an efficiant way to apply a reduced $power each itteration to outside surrounding tiles.

This is what I have now and I'll explain why I think it could be better:

Code: Select all


function noise($x, $y, $range){


	$counter_x = $x - $range;
	$counter_y = $y - $range;

	
	while($counter_x =< $x + $range){


		while($counter_y =< $y + $range){


			$current_string = "SELECT noise_level FROM map WHERE x ='" . $counter_x . "' AND y ='" . $counter_y . "'";
			$current_result = mysql_query($current_string);
			$current_data = mysql_fetch_array($current_result);



			$query_string = "UPDATE map SET noise_level ='" . $current_data["noise_level"] + 1 . "' WHERE x ='" . $coutner_x . "' AND y = '" . $counter_y . "'"; 
			$query_result = mysql_query($query_string);

			
			$counter_y++;

		}

	
		$counter_y = $y;
		$counter_x++;
		$range--;


	}
	


	

}
I think that writing to entries multiple times is redundant, and I'm looking for a better way to do it.


Any suggestions would be awesome, I've been on this for the past 3 hours so I've probably lost my ability to look at it objectivly. Any critisism is appreciated!

Re: Loop logic: Noise dissapation

Posted: Thu Jan 20, 2011 1:10 pm
by Jonah Bron
I think I understand what you're asking. But do you want to grow out like the first picture (attached) or the second?
grid2.jpg
grid2.jpg (6.97 KiB) Viewed 2897 times
grid1.jpg
grid1.jpg (4.06 KiB) Viewed 2897 times

Re: Loop logic: Noise dissapation

Posted: Thu Jan 20, 2011 1:22 pm
by AdamRCarlson
Like the first one. grid2.jpg

Re: Loop logic: Noise dissapation

Posted: Thu Jan 20, 2011 3:39 pm
by Jonah Bron
Okay, just working through the logic here. First, we have to look at the growing pattern.

[text]x + 0, y + 0
x + -1, y + -1
x + -1, y + 0
x + -1, y + 1
x + 0, y + -1
x + 0, y + 0
x + 0, y + 1
x + 1, y + -1
x + 1, y + 0
x + 1, y + 1
x + -2, y + -2
x + -2, y + -1
x + -2, y + 0
x + -2, y + 1
x + -2, y + 2
x + -1, y + -2
x + -1, y + -1
x + -1, y + 0
x + -1, y + 1
x + -1, y + 2
x + 0, y + -2
x + 0, y + -1
x + 0, y + 0
x + 0, y + 1
x + 0, y + 2
x + 1, y + -2
x + 1, y + -1
x + 1, y + 0
x + 1, y + 1
x + 1, y + 2
x + 2, y + -2
x + 2, y + -1
x + 2, y + 0
x + 2, y + 1
x + 2, y + 2[/text]
As you can see, it grows by (x + 2)^2. But, we only want to outline as we go out. So, we need to extract all tiles from our list that where both the x side and the y side are less than the absolute max.

[text]x + 0, y + 0
x + -1, y + -1
x + -1, y + 0
x + -1, y + 1
x + 0, y + -1
x + 0, y + 1
x + 1, y + -1
x + 1, y + 0
x + 1, y + 1
x + -2, y + -2
x + -2, y + -1
x + -2, y + 0
x + -2, y + 1
x + -2, y + 2
x + -1, y + -2
x + -1, y + 2
x + 0, y + -2
x + 0, y + 2
x + 1, y + -2
x + 1, y + 2
x + 2, y + -2
x + 2, y + -1
x + 2, y + 0
x + 2, y + 1
x + 2, y + 2[/text]

Are you beginning to see how it will work? Bummer, neither am I ;)

Re: Loop logic: Noise dissapation

Posted: Thu Jan 20, 2011 3:46 pm
by John Cartwright
Thanks for frying my brain with this logic problem. Now I'll be trying to solve this forever, so one of you genius figure this out quickly please :)

Re: Loop logic: Noise dissapation

Posted: Thu Jan 20, 2011 3:57 pm
by Jonah Bron
@John with pleasure.

Code: Select all

// a two-dimensional array holding the power level grid
$world = array(
    array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
    array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
    array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
    array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
    array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
    array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
    array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
    array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
    array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
    array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
);

function bomb($x, $y, $strength) {
    global $world;

    $step = 0;
    
    while ($strength > 0) {
        for ($ymod = -$step; $ymod <= $step; $ymod++) {
            for ($xmod = -$step; $xmod <= $step; $xmod++) {
                if (abs($xmod) == $step || abs($ymod) == $step) {
                    $world[$y + $ymod][$x + $xmod] = $strength;
                }
            }
        }
        $step++;
        $strength--;
    }
}
Untested. No, I'm not advocating the use of global variables.

Edit: realized that you're making database calls. Modified slightly for performance improvement.

Re: Loop logic: Noise dissapation

Posted: Thu Jan 20, 2011 4:15 pm
by VladSun
It's some kind of image processing you want to apply. It's some kind of low pass filter - probably plain LP filter, Gaussian filter or median filter.
i think you know it's name so telling it would help :)

http://en.wikipedia.org/wiki/Low-pass_filter
http://en.wikipedia.org/wiki/Gaussian_blur
http://en.wikipedia.org/wiki/Median_filter

Re: Loop logic: Noise dissapation

Posted: Thu Jan 20, 2011 4:19 pm
by AdamRCarlson
Jonah Bron wrote:@John with pleasure.

Code: Select all

// a two-dimensional array holding the power level grid
$world = array(
    array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
    array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
    array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
    array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
    array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
    array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
    array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
    array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
    array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
    array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
);

function bomb($x, $y, $strength) {
    global $world;

    $step = 0;
    
    while ($step <= $strength) {
        for ($ymod = -$step; $ymod <= $step; $ymod++) {
            for ($xmod = -$step; $xmod <= $step; $xmod++) {
                $world[$y + $ymod][$x + $xmod]++;
            }
        }
        $step++;
    }
}
Untested. No, I'm not advocating the use of global variables.

Unfortunately, we're dealing with a grid that's going to be roughly 1000 x 1000 so I don't know if I want to even look at that array in code... like ever... hehe. Other than that, here's what I've come up with:

I realized that it's as simple as determining the distance from ground zero to wherever you're loop is currently trying to effect.

This will probably work :)

Code: Select all


function noise($x, $y, $range){


	$low_x = $x - $range;
	$low_y = $y - $range;
	$high_x = $x + $range;
	$high_y = $y + $range;

	$x_counter = $low_x;
	$y_counter = $low_y;


	while($x_counter < $high_x){


		while($y_counter < $high_y){


			
			$distance_to_center = max(abs($x - $x_counter), abs($y - $y_counter));

			
	
			$query_string = "SELECT noise_level FROM map WHERE tile_x = '$x_counter' AND tile_y = '$y_counter'";
			$query_result = mysql_query($query_string);
			$query_data = mysql_fetch_row($query_result);


			$query_string = "UPDATE map SET noise_level = '" . (($range - $distance_to_center) + $query_data[0]) . "' WHERE tile_x = '$x_counter' AND tile_y = '$y_counter'";				 
				

			$query_result = mysql_query($query_string);

			$y_counter++;

		}

		
		$y_counter = $low_y;
		$x_counter++;


	}
		

}

Re: Loop logic: Noise dissapation

Posted: Thu Jan 20, 2011 4:59 pm
by Jonah Bron
I didn't mean for you to use it exactly like that. The idea was for you to remove the array code (which acts as a placeholder), and put in your database code.