views:

74

answers:

3

Basically, I'm creating a puzzle where you can swap pieces. And I want to make sure that when swapping 2 elements, the selection is valid.

Since the puzzle is only 9 pieces (3x3), I am currently using the code:

  function valid_selection(p1, p2) {
   if (p1 == 1 && (p2 == 2 || p2 == 4)) return true;
   if (p1 == 2 && (p2 == 1 || p2 == 3 || p2 == 5)) return true;
   if (p1 == 3 && (p2 == 2 || p2 == 6)) return true;
   if (p1 == 4 && (p2 == 1 || p2 == 5 || p2 == 7)) return true;
   if (p1 == 5 && (p2 == 2 || p2 == 4 || p2 == 6 || p2 == 8)) return true;
   if (p1 == 6 && (p2 == 3 || p2 == 5 || p2 == 9)) return true;
   if (p1 == 7 && (p2 == 4 || p2 == 8)) return true;
   if (p1 == 8 && (p2 == 5 || p2 == 7 || p2 == 9)) return true;
   if (p1 == 9 && (p2 == 6 || p2 == 8)) return true;

   return false;
  }

But, can I do this programatically? Anyone know of such an algorithm?

Any help is appreciated.

+1  A: 

Assuming your matrix has positions like so:

1 2 3
4 5 6
7 8 9

You should be able to do the following:

if ( abs(p2-p1) == 3 // test for vertical connectedness
        || ( abs(p2-p1) == 1 // test for horizontal connectedness
        && ( p1+p2 != 7 && p1+p2 != 13) ) ) // except for edge cases (3,4 and 6,7)
    return true;
Fragsworth
That's exactly how my matrix is, and it doesn't work properly.Example:let p1=4and p2=3It shouldn't match as p2 is in the top right corner (p1 is in the middle left), but it passes the if test.
google
Edit, nvm just noticed your edit. Ill give this a go.
google
Nope, this fails on p1=2, p2=5 when it should match,Also fails on: p1=5,p2=8
google
I don't know why it would fail, if you look at the code - clearly it will return true on 2,5 and 5,8. Check to make sure your braces are correct.
Fragsworth
Oops, my bad. It does work indeed. Just one more question, what is so special about 7 and 13, and how did you derive that? Cheers for your help.
google
Horizontal connectedness is if p1 and p2 are 1 apart, except for in positions (3,4) and (6,7). So you can add p1+p2 to check if they are in these positions - and you exclude them. There is a more general approach (You can use the width of the matrix to find these instead) but this is small enough that it doesn't matter.
Fragsworth
A: 

You could also convert each piece on the grid into coordinate form.

ie:

1 is (0,0), 2 is (0,1), 3 is (0,2), 4 is (1,0), etc

So, given that the coordinate of p1 is (x_p1, y_p1) and p2 is (x_p2, y_p2) then your function would return true if:

( abs(x_p2 - x_p1) + abs(y_p2 - y_p1) ) == 1

I think...? Haven't actually tried it.

And this should work regardless of grid size.

Knobby
A: 

Assuming this is JavaScript:

var N = 3;  // size of matrix

var x1 = p1 % N, y1 = Math.floor(p1 / N);
var x2 = p2 % N, y2 = Math.floor(p2 / N);

return (x1 == x2 && Math.abs(y2 - y1) == 1) ||
       (y1 == y2 && Math.abs(x2 - x1) == 1);
Jason Orendorff