• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 323
  • Last Modified:

Finding Neighbor "cells"

Below is my code.  What I need to do is check each value in the array and see if that cell has exactly three neighboring cells that are also checked.  If that is the case then I need to keep this cell checked and move to the next value in the array and run the same test.  I've got the loop that shows me the value of each value in the array and it loops through.  I'm having a hard time figuring out the if statement to check to see if #1 the current cell is checked, and # if exactly three neighboring cells are also checked....
<?
$max_rows = 9;
$max_cols = 9;
 
 
if (isset($_POST['submit'])) {
  // $_POST['cb'] contains the array with selected checkboxes.
  $checked = $_POST['cb'];
        for ($y = 0; $y < $max_rows; $y++) {
                  for ($x = 0; $x < $max_cols; $x++) {
                                
                                // code modification here
                                echo ($y+1).",".($x+1)." is ";
                                echo ($checked[$y][$x] === 'check')?"checked<br>":"unchecked<br>";
                                
                                }
                  }
        }
 
?>
<form method='post'>
<?
 
for ($y = 0; $y < $max_rows; $y++) {
  for ($x = 0; $x < $max_cols; $x++) {
    echo "<input type='checkbox' name='cb[" . $y . "][" . $x. "]' value='check' ";
    if (isset($checked[$y][$x])) {
      echo "checked ";
    }
    echo "/>\n";
  }
  echo "<br />";
}
?>
 
<input type="submit" name="submit" />
</form>

Open in new window

0
cstormer
Asked:
cstormer
  • 3
  • 3
  • 2
  • +1
2 Solutions
 
BrianGEFF719Commented:
this is untested, but should get you on the right track

for($x=0;$x < $MAX;$x++)
{
 for($y=0;$y < $Y_MAX;$y++)
 {
     if($arr[$x][$y] == checked && 
              (
                    @$arr[$x - 1][$y] == checked ||
                    @$arr[$x + 1][$y] == checked ||
                    @$arr[$x][$y - 1] == checked ||
                    @$arr[$x][$y + 1] == checked
 
              )
         //ok...go ahead
                     
 }
}
0
 
cstormerAuthor Commented:
The problem with the above is that I think each cell has a possible 8 neighbors.

Top left, Top, Top Right, left, Right, Bottom Left, Bottom, Bottom Right

Also I can only move on if "three" of them are checked.. not all of them.  So I need a way count how many are checked and if it is more than 3, I actually uncheck the cell and if it is less than 3 I uncheck the cell... if it is exactly 3 I move on.
0
 
Steve BinkCommented:
In that case, you know that for cell x/y, you need to check the following:

(x-1)/(y-1)   (x)/(y-1)   (x+1)/(y-1)
(x-1)/(y)      no check   (x+1)/(y)
(x-1)/(y+1)  (x)/(y+1)  (x+1)/(y+1)

Using BrianGEFF719's code as a starting point:
for($x=0;$x < $MAX;$x++) {
  for($y=0;$y < $Y_MAX;$y++) {
    if ($arr[$x][$y] == checked) {
      $three_checks=0;
      for ($a=($x-1);$a<($x+2);$a++) { // $a will be the $x
        for ($b=($y-1);$b<($y+2);$b++) { // $b will be the $y
          if ($arr[$a][$b] == checked) { $three_checks++; }
        }
      }
      if $three_checks!=4) { 
        //uncheck the $arr[$x][$y]
        // use 4 because $arr[$x][$y] will be checked and included in the count
      }
    }
  }
}

Open in new window

0
Upgrade your Question Security!

Your question, your audience. Choose who sees your identity—and your question—with question security.

 
Beverley PortlockCommented:
Something that has not been mentioned is the effect of making updates to the array. If you change a value in the array because of the neighbouring cells then you can affect later tests. For example, consider the following rows (checked are shown as "x" and unchecked as "-") in the attached snippet. Consider the cell marked as 'o' which clearly has 3 neighbours and should be checked, but if you check it then the cell underneath marked '?' will be checked when you do it because it NOW has 3 neighbours.

What you need is two arrays - one for holding the values to check and an indentically sized one for setting/unsetting the checked values.


- - - x - - - 
- - - o - - -
- - x ? x - -

Open in new window

0
 
cstormerAuthor Commented:
Yes Bport,

Your 100% right... I was trying to figure out how I was going to deal with that issue... because I'm showing the revised grid on the screen after every cell is checked.
0
 
Steve BinkCommented:
You could take a count of which cells fail, then reset them after all the tests are done.  In that case, create a second array to mirror the $arr data.

Still, the recursive nature of your test will be problematic for you.  Can you explain a little more about what you're trying to do?  Maybe we can come up with a better strategy for you.
0
 
cstormerAuthor Commented:
I'm trying to duplicate this:

http://www.bitstorm.org/gameoflife/

using php and html checkboxes for the cells...
0
 
Steve BinkCommented:
That's exactly what I would do then.  Create a second array ($arr2) to hold the results of your testing.  Once all of the tests are complete, the second array becomes the real-time data.  Repeat from step 1.
0
 
Beverley PortlockCommented:
Try something along the outline shown in the attached snippet. I have not put your code in but the outline gives an idea of how to manage the arrays and so forth.
<?php
 
// Clear the array elements
//
function clearArray( & $arr ) {
    // some loops to set every array value to "unchecked"
}
 
 
// Load the initial configuration
//
function loadConfig( & $arr ) {
     // Code to do the loading
}
 
 
// Check for neighbours
//
function check( & $liveArray, & $resultsArray ) {
     //
     // Code here runs through the LIVE array and
     // checks for neighbours. The results are set
     // in the RESULTS array     
}
 
 
function showResults( $arr ) {
     // Code to "print" the array out
}
 
 
 
// ===== Main program =====
//
 
$arr1 = array();
$arr2 = array();
 
clearArray( $arr1 );
clearArray( $arr2 );
 
loadConfig( $arr1 );
 
// Do 10 generations
//
for ( $i=0; $i < 5; $i++ ) {
 
     showResults( $arr1 );
     check( $arr1, $arr2 );
     clearArray( $arr1 );
 
     showResults( $arr2 );
     check( $arr2, $arr1 );
     clearArray( $arr2 );
 
}
 
?>
 
If your "check" code does both set and unset then you could skip the "clearArray"s in the loop.
If it only sets values then you need to clear the arrays as shown

Open in new window

0

Featured Post

Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

  • 3
  • 3
  • 2
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now