Loop logic: Noise dissapation

Not for 'how-to' coding questions but PHP theory instead, this forum is here for those of us who wish to learn about design aspects of programming with PHP.

Moderator: General Moderators

Post Reply
AdamRCarlson
Forum Newbie
Posts: 3
Joined: Thu Jan 20, 2011 9:26 am

Loop logic: Noise dissapation

Post 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!
User avatar
Jonah Bron
DevNet Master
Posts: 2764
Joined: Thu Mar 15, 2007 6:28 pm
Location: Redding, California

Re: Loop logic: Noise dissapation

Post 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 2899 times
grid1.jpg
grid1.jpg (4.06 KiB) Viewed 2899 times
AdamRCarlson
Forum Newbie
Posts: 3
Joined: Thu Jan 20, 2011 9:26 am

Re: Loop logic: Noise dissapation

Post by AdamRCarlson »

Like the first one. grid2.jpg
User avatar
Jonah Bron
DevNet Master
Posts: 2764
Joined: Thu Mar 15, 2007 6:28 pm
Location: Redding, California

Re: Loop logic: Noise dissapation

Post 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 ;)
User avatar
John Cartwright
Site Admin
Posts: 11470
Joined: Tue Dec 23, 2003 2:10 am
Location: Toronto
Contact:

Re: Loop logic: Noise dissapation

Post 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 :)
User avatar
Jonah Bron
DevNet Master
Posts: 2764
Joined: Thu Mar 15, 2007 6:28 pm
Location: Redding, California

Re: Loop logic: Noise dissapation

Post 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.
Last edited by Jonah Bron on Thu Jan 20, 2011 5:04 pm, edited 1 time in total.
User avatar
VladSun
DevNet Master
Posts: 4313
Joined: Wed Jun 27, 2007 9:44 am
Location: Sofia, Bulgaria

Re: Loop logic: Noise dissapation

Post 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
There are 10 types of people in this world, those who understand binary and those who don't
AdamRCarlson
Forum Newbie
Posts: 3
Joined: Thu Jan 20, 2011 9:26 am

Re: Loop logic: Noise dissapation

Post 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++;


	}
		

}
User avatar
Jonah Bron
DevNet Master
Posts: 2764
Joined: Thu Mar 15, 2007 6:28 pm
Location: Redding, California

Re: Loop logic: Noise dissapation

Post 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.
Post Reply