Chess, algorithm to find last location moving diagonally

2.1k views Asked by At

This may be a little hard to explain without a picture but, I am in the process of checking to see if the king is in check. To do so, I am starting at the king's location and going up, left, down, right, then all the diagonal patterns.

To simplify my code, I have a path checker method which takes in a starting location and ending location and returns true if there are any threats to the king in that path. So, I am calling this method like:

board.incheckPath(kingLocation, new Location(8, kingY))

This would check from the king to the top row, same column. I have a similar statement for left, down, and right.

The problem is I am trying to use the same fashion for the diagonal patterns, and I can't figure out a simple algorithm to figure out where the last location is. If you are higher than you are to the right, then if you go up and right diagonally, you're going to hit the top row before you hit the right most column. I figured out the algorithm for that location is:

if x > y { row = 8; column = 8-(x-y) } else { row = 8-(x-y); column = 8; }

Because where you land at is going to be the difference between x and y away from either the top row or right column. But I cannot figure out what the result would be for going up and left, down and left, or down and right.

3

There are 3 answers

2
Boris Brodski On BEST ANSWER

Suppose, you coordinates are

/|\ y
 |              col8
 +---+ ... +---+---+
 |   |     |   |   | <- row 8
 +---+ ... +---+---+
 |   |     |   |   | 
 +---+ ... +---+---+
 ...............
 +---+ ... +---+---+
 |   |     |   |   | <- row 1
 +---+ ... +---+---+--->
                       x

Extending your solution it will looks like

// Up right
if (y > x) { row = 8; column = 8-(y-x) } else { row = 8-(x-y); column = 8; }

// Down left
if (x > y) { row = 1; column = 1+(x-y) } else { row = 1+(y-x); column = 1; }

// Up left
if (9-x < y) { row = 8; column = x+y-8 } else { row = x+y-1; column = 1; }

// Down right
if (9-x > y) { row = 1; column = x+y-1 } else { row = x+y-8; column = 8; }
1
Boris Brodski On

I would suggest, that you define a path in another more suitable way:

 int pathDeltas[][] = {
     {1, 0}, {0, 1}, {-1, 0}, {0, -1}, // Up, down, left, right
     {1, 1}, {-1, 1}, {1, -1}, {-1, -1}, // diagonal paths
 };

Then you can start from the kind position and adds deltas to x and y coordinates until you hit 1 or 8 value. Also you could calculate the knight paths like this:

int knightDeltas[][] {{1, 2}, {2, 1}, {-1, 2}, {-2, 1},
                     {1, -2}, {2, -1}, {-1, -2}, {-2, -1}};
0
jweil On

to M Cliatt, 2013, number of bishop diagonal steps from square defined by (R,C) (where R and C are from [1..8]) in each direction until you hit the wall on 8x8 board

NE = Min(8 - R, 8 - C)
NW = Min(8 - R, C - 1)
SE = Min(R - 1, 8 - C)
SW = Min(R - 1, C - 1)

a moment's reflection on the board shows these split along the diagonals (NE, SW split this way) and anti-diagonals (NW, SE)...e.g. for NE above diagonal 8-R branch is always chosen and below diagonal the 8-C branch is always chosen. They are equal on the diagonal.

So last element of ray in NE direction starting on squares above diagonal from (R,C) = (R + 8-R, C + 8-R)

btw - thinking about this in the context of bishop legal moves obstruction (at the moment)...interested in where you ended up on your problem