Help with grid algorithm

Godot Version

4.3

Question

I need help writing an algorithm that finds the closest number up or down to a parameter that is divisible evenly by 16 but not 32

I believe you can use binary operators.

func is_16_not_32(input: int) -> bool:
    # any 1-8 place is not divisable by 16
    var div_16: bool = input & 0b01111 == 0
    # similarly, a 16ths place means not divisable by 32
    var not_32: bool = input & 0b10000 != 0
    return div_16 and not_32

Sorry this only deduces if it is a valid number.

A similar binary operating function would have a strange rounding behavior if that is okay.

func make_grid_16_not_32(input: int) -> int:
    var div_16: int = input & 0b01111
    var no_16: int = input ^ div_16

    var no_32: int = no_16 | 0b10000
    return no_32

Basically i am spawning rooms and they end up not aligned to my tilemap. I need to snap the x position to the closest 16 but not 32 if it has an odd length and 32 if its even same for the Y.

I got close using snapped but you cant use it independently on the x and y and it doesnt account for 32 also being a multiple of 16.

1 Like

Then you can use the first part of that function for everything, and the second part for your extra conditions.

if length & 0b1 == 0: # even
    pos.x = make_grid_16(pos.x)
else: # odd
    pos.x = make_grid_16_not_32(pos.x)

I ended up coming up with this. it works but I can’t help but feel like I could do the same in less code it just seems like a lot for a relatively trivial function.

public static Vector2I GridSnap(Vector2I position, int width, int height, int cellSize)
    {
        int newX = int.MinValue;
        int newY = int.MinValue;

        if (width / cellSize % 2 != 0) {
            for (int upX = position.X; upX < position.X + cellSize; upX++) {
                if (upX % (cellSize / 2) == 0 && upX % cellSize != 0) {
                    newX = upX;
                    break;
                }
            }
            for (int downX = position.X; downX > position.X - cellSize; downX--) {
                if (downX % (cellSize / 2) == 0 && downX % cellSize != 0) {
                    if (newX - position.X > position.X - downX) {
                        newX = downX;
                        break;
                    }
                }
            }
        }
        else {
            for (int upX = position.X; upX < position.X + cellSize; upX++) {
                if (upX % cellSize == 0) {
                    newX = upX;
                    break;
                }
            }
            for (int downX = position.X; downX > position.X - cellSize; downX--) {
                if (downX % cellSize == 0) {
                    if (newX - position.X > position.X - downX) {
                        newX = downX;
                        break;
                    }
                }
            }
        }
        if (height / cellSize % 2 != 0) {
            for (int upY = position.Y; upY < position.Y + cellSize; upY++) {
                if (upY % (cellSize / 2) == 0 && upY % cellSize != 0) {
                    newY = upY;
                    break;
                }
            }
            for (int downY = position.Y; downY > position.Y - cellSize; downY--) {
                if (downY % (cellSize / 2) == 0 && downY % cellSize != 0) {
                    if (position.Y - newY > downY - position.Y) {
                        newY = downY;
                        break;
                    }
                }
            }
        }
        else {
            for (int upY = position.Y; upY < position.Y + cellSize; upY++) {
                if (upY % cellSize == 0) {
                    newY = upY;
                    break;
                }
            }
            for (int downY = position.Y; downY > position.Y - cellSize; downY--) {
                if (downY % cellSize == 0 ) {
                    if (newY - position.Y > position.Y - downY) {
                        newY = downY;
                        break;
                    }
                }
            }
        }
        return new Vector2I(newX,newY);
    }

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.