BJagger
BJagger

Reputation: 171

How to best iterate over diagonals of 2d array

I am writing a word search puzzle and I am wondering what will be the best approach for diagonally and anti-diagonally positioned catchphrases - as it is now I've implemented horizontal and vertical ones (each "type" of catchphrase is derived from a parent abstract catchphrase) and this is code searching for starting indexes of a word that will be placed vertically - if you have any hints about this implementation please give me your feedback as well :)

public List<Coordinate> findPossiblePositionsForWord(Character[][] grid) {
        List<Coordinate> result = new ArrayList<>();
        int consecutiveEmptyFields;
        final int wordLength = getWord().length();
        for (int column = 0; column < grid[0].length; column++) {
            consecutiveEmptyFields = 0;
            for (int row = grid.length - 1; row >= 0; row--) {
                if (grid[row][column] == null) {
                    consecutiveEmptyFields++;
                    if (consecutiveEmptyFields >= wordLength) {
                        result.add(new Coordinate(row, column));
                    }
                } else {
                    consecutiveEmptyFields = 0;
                }
            }
        }
        return result;
    }

The easiest way that I can think of is using two for loops: from 0 to x <= word.length and from 1 to y <= word.length - but maybe there is a better way: particularly using Java.

For further clarification: for catchphrases like this: "HOKUSPOKUS", "THIS", "GOOGLE", "STRESS", "TEST", "LENGTHY", "PARTLY" I will get result like (for example - it is random) this:

*****************************************
Catchprase successfully added!
Catchprase successfully added!
Catchprase successfully added!
Catchprase successfully added!
Catchprase successfully added!
Catchprase successfully added!
Catchprase successfully added!
*****************************************
G O O G L E _ _ _ H
_ _ _ _ _ _ T _ _ O
_ _ _ _ _ _ H _ _ K
_ _ _ _ _ _ I _ P U
_ _ _ _ _ _ S _ A S
L E N G T H Y _ R P
S T R E S S _ _ T O
_ _ _ _ _ _ _ _ L K
_ _ _ _ _ _ _ _ Y U
T E S T _ _ _ _ _ S

Process finished with exit code 0

Now I want to add catchphrases also diagonally

Upvotes: 1

Views: 178

Answers (1)

btilly
btilly

Reputation: 46389

I would suggest that instead of special casing each direction, you return a direction+start. Here is the basic idea that handles forwards, backwards, up, down, and both diagonals in either direction.

public List<Pair<Coordinate, Coordinate>> findPossiblePositionsForWord(Character[][] grid) {
    List<Pair<Coordinate, Coordinate>> result = new ArrayList<>();
    final int wordLength = getWord().length();
    for (int dirColumn : {-1, 0, 1}) {
        for (int dirRow : {-1, 0, 1}) {
            if (dirColumn == 0 && dirRow == 0) {
                continue;
            }
            for (
                int column = max(0, -dirColumn * wordLength);
                column < min(grid.length, grid.length + dirColumn*wordLength);
                column++
            ) {
                for (
                    int row = max(0, -dirRow * wordLength);
                    row < min(grid.length, grid.length + dirRow*wordLength);
                    row++
                ) {
                    // Test for whether the word can go here...
                    if (wordCanGoHere) {
                        result.add(
                            new Pair(
                                new Coordinate(row, column),
                                new Coordinate(dirRow, dirColumn)
                            )
                        );
                    }
                }
            }
        }
    }
    return result;
}

Upvotes: 1

Related Questions