3
\$\begingroup\$

I'm implementing engine tools for my hex board game and this one is becoming messy. I want to get a list of all the positions that a cone of size N would have, given "caster" origin X,Y and origin in X0, Y0 taking direction into account. So far I have been able to get a size one cone using a "simple pattern" approach, but it doesn't translate well for N-sized cones.

This is the original cone

enter image description here

and the code

public PositionArray getArcAdjacents(int originx, int originy, int targetx, int targety,
        int range) {
    final FloatPair direction = this.getDirectionVector(originx, originy, targetx, targety);
    final PositionArray highlights = new PositionArray(gameMap);
    highlights.add(new Pair(targetx, targety));
    int offset = 0;
    if ((targetx % 2) == 0) {
        offset = 1;
    }
    if (direction.x > 0) {
        if (direction.y >= 0) {
            highlights.add(new Pair(targetx - 1, (targety + 1) - offset));
            highlights.add(new Pair(targetx, targety - 1));
        } else {
            highlights.add(new Pair(targetx, targety + 1));
            highlights.add(new Pair(targetx - 1, targety - offset));
        }
    } else if (direction.x < 0) {
        if (direction.y >= 0) {
            highlights.add(new Pair(targetx + 1, (targety + 1) - offset));
            highlights.add(new Pair(targetx, targety - 1));
        } else {
            highlights.add(new Pair(targetx + 1, targety - offset));
            highlights.add(new Pair(targetx, targety + 1));
        }
    } else {
        if (direction.y > 0) {
            highlights.add(new Pair(targetx + 1, targety - offset));
            highlights.add(new Pair(targetx - 1, targety - offset));
        } else if (direction.y < 0) {
            highlights.add(new Pair(targetx + 1, (targety + 1) - offset));
            highlights.add(new Pair(targetx - 1, (targety + 1) - offset));
        }
    }
    return highlights;
}
\$\endgroup\$
2
  • 1
    \$\begingroup\$ What type of coord system are you using? \$\endgroup\$ – mobo Jun 12 '13 at 16:15
  • 1
    \$\begingroup\$ Odd-q with 0,0 on the bottom left. \$\endgroup\$ – MLProgrammer-CiM Jun 12 '13 at 19:19
2
\$\begingroup\$

I could fix it with a bit of algorithmics:

public PositionArray getArcRange(int originx, int originy, int targetx, int targety, int range) {
    if (range < 0) {
        range = 0;
    }
    final PositionArray open = new PositionArray(gameMap);
    final PositionArray closed = new PositionArray(gameMap);
    final FloatPair direction = this.getDirectionVector(targetx, targety, originx, originy);
    closed.add(new Pair(targetx, targety));
    while (closed.size > 0) {
        final Pair position = closed.removeIndex(0);
        if (!open.contains(position, false)
                && (this.getDistance(targetx, targety, position.x, position.y) <= range)) {
            closed.addAll(this.getArcAdjacents(position, direction));
            open.add(position);
        }
    }
    open.removeIndex(0);
    return open;
}

private PositionArray getArcAdjacents(Pair target, FloatPair direction) {
    final PositionArray highlights = new PositionArray(gameMap);
    int offset = 0;
    if ((target.x % 2) == 0) {
        offset = 1;
    }
    if (direction.x > 0) {
        if (direction.y >= 0) {
            highlights.add(new Pair(target.x - 1, (target.y + 1) - offset));
            highlights.add(new Pair(target.x, target.y - 1));
        } else {
            highlights.add(new Pair(target.x, target.y + 1));
            highlights.add(new Pair(target.x - 1, target.y - offset));
        }
    } else if (direction.x < 0) {
        if (direction.y >= 0) {
            highlights.add(new Pair(target.x + 1, (target.y + 1) - offset));
            highlights.add(new Pair(target.x, target.y - 1));
        } else {
            highlights.add(new Pair(target.x + 1, target.y - offset));
            highlights.add(new Pair(target.x, target.y + 1));
        }
    } else {
        if (direction.y > 0) {
            highlights.add(new Pair(target.x + 1, target.y - offset));
            highlights.add(new Pair(target.x - 1, target.y - offset));
        } else if (direction.y < 0) {
            highlights.add(new Pair(target.x + 1, (target.y + 1) - offset));
            highlights.add(new Pair(target.x - 1, (target.y + 1) - offset));
        }
    }
    return highlights;
}

Result: Cones!

Beware of the trap, my PositionArray doesn't allow duplicates or positions outside the board.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.