Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
package com.almasb.fxgl.core.collection.grid;

import com.almasb.fxgl.core.math.FXGLMath;
import static com.almasb.fxgl.core.collection.grid.NeighborFilteringOption.*;

import java.lang.reflect.Array;
import java.util.ArrayList;
Expand All @@ -15,7 +16,6 @@
import java.util.Random;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
* @param <T> cell type
Expand Down Expand Up @@ -98,7 +98,6 @@ public final int getCellHeight() {
return cellHeight;
}


/**
* Checks if given (x,y) is within the bounds of the grid,
* i.e. get(x, y) won't return OOB.
Expand All @@ -124,18 +123,37 @@ public final List<T> getCells() {
}

/**
* Note: returned cells are in the grid (i.e. bounds are checked).
* Diagonal cells are not included.
* Note: returned cells are in the grid (i.e. bounds are checked). (defaulted to 4 directions)
* The order is left, up, right, down.
*
* @return a new list of neighboring cells to given (x, y)
*/
public final List<T> getNeighbors(int x, int y) {
return getNeighbors(x, y, FOUR_DIRECTIONS);
}

/**
* Note: returned cells are in the grid (i.e. bounds are checked).
* NeighborFilteringOption allow filtering based on desired # of directions
* The order is left, up, right, down. + "Optionally" up-left, up-right, down-left, down-right
*
* @return a new list of neighboring cells to given (x, y)
*/
public final List<T> getNeighbors(int x, int y, NeighborFilteringOption neighborFilteringOption) {
List<T> result = new ArrayList<>();
getLeft(x, y).ifPresent(result::add);
getUp(x, y).ifPresent(result::add);
getRight(x, y).ifPresent(result::add);
getDown(x, y).ifPresent(result::add);

// Include "Corner" neighbors when eight directions
if(neighborFilteringOption.is(EIGHT_DIRECTIONS)) {
getUpLeft(x, y).ifPresent(result::add);
getUpRight(x, y).ifPresent(result::add);
getDownLeft(x, y).ifPresent(result::add);
getDownRight(x, y).ifPresent(result::add);
}

return result;
}

Expand Down Expand Up @@ -171,6 +189,22 @@ public final Optional<T> getDown(Cell cell) {
return getDown(cell.getX(), cell.getY());
}

public final Optional<T> getUpRight(Cell cell) {
return getUpRight(cell.getX(), cell.getY());
}

public final Optional<T> getUpLeft(Cell cell) {
return getUpLeft(cell.getX(), cell.getY());
}

public final Optional<T> getDownRight(Cell cell) {
return getDownRight(cell.getX(), cell.getY());
}

public final Optional<T> getDownLeft(Cell cell) {
return getDownLeft(cell.getX(), cell.getY());
}

public final Optional<T> getRight(int x, int y) {
return getOptional(x + 1, y);
}
Expand All @@ -187,6 +221,23 @@ public final Optional<T> getDown(int x, int y) {
return getOptional(x, y + 1);
}

public final Optional<T> getUpRight(int x, int y) {
return getOptional(x + 1, y - 1);
}

public final Optional<T> getUpLeft(int x, int y) {
return getOptional(x - 1, y - 1);
}

public final Optional<T> getDownRight(int x, int y) {
return getOptional(x + 1, y + 1);
}

public final Optional<T> getDownLeft(int x, int y) {
return getOptional(x - 1, y + 1);
}


/**
* @param x pixel coord x
* @param y pixel coord y
Expand Down Expand Up @@ -248,7 +299,7 @@ public final Optional<T> getRandomCell(Predicate<T> predicate) {
public final Optional<T> getRandomCell(Random random, Predicate<T> predicate) {
List<T> filtered = getCells().stream()
.filter(predicate)
.collect(Collectors.toList());
.toList();

if (filtered.isEmpty())
return Optional.empty();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* FXGL - JavaFX Game Library. The MIT License (MIT).
* Copyright (c) AlmasB ([email protected]).
* See LICENSE for details.
*/

package com.almasb.fxgl.core.collection.grid;


/**
* Define Movement Directions
*
* @author Jean-Rene Lavoie ([email protected])
*/
public enum NeighborFilteringOption {

FOUR_DIRECTIONS, EIGHT_DIRECTIONS;

public boolean is(NeighborFilteringOption... neighborFilteringOptions) {
for(NeighborFilteringOption neighborFilteringOption : neighborFilteringOptions) {
if(neighborFilteringOption.equals(this)) {
return true;
}
}
return false;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,15 @@ public void testGetNeighbors() {
assertThat(grid.getNeighbors(3, GRID_SIZE - 1), containsInAnyOrder(grid.get(3, GRID_SIZE - 2), grid.get(2, GRID_SIZE - 1), grid.get(4, GRID_SIZE - 1)));
}

@Test
public void testGetNeighborsEightDirections() {
assertThat(grid.getNeighbors( 3,3, NeighborFilteringOption.EIGHT_DIRECTIONS), containsInAnyOrder(
grid.get(2, 2), grid.get(2, 3), grid.get(2, 4),
grid.get(3, 2), grid.get(3, 4), // Doesn't contain 3, 3 (self)
grid.get(4, 2), grid.get(4, 3), grid.get(4, 4)
));
}

@Test
public void testGetRandomCell() {
for (int i = 0; i < 50; i++) {
Expand All @@ -165,7 +174,7 @@ public void testRandomCell() {
}

@Test
public void testDirections() {
public void testFourDirections() {

// right cell

Expand Down Expand Up @@ -209,6 +218,58 @@ public void testDirections() {
assertThat(grid.getDown(grid.get(1, GRID_SIZE - 1)).isPresent(), is(false));
}

@Test
public void testEightDirections() {
// up right cell
Optional<MockCell> upRightCell = grid.getUpRight(grid.get(1, 1));

assertThat(upRightCell.isPresent(), is(true));
assertThat(upRightCell.get().getX(), is(2));
assertThat(upRightCell.get().getY(), is(0));

assertThat(grid.getUpRight(grid.get(0, 0)).isPresent(), is(false));
assertThat(grid.getUpRight(grid.get(0, GRID_SIZE-1)).isPresent(), is(true));
assertThat(grid.getUpRight(grid.get(GRID_SIZE-1, 0)).isPresent(), is(false));
assertThat(grid.getUpRight(grid.get(GRID_SIZE-1, GRID_SIZE-1)).isPresent(), is(false));

// up left Cell
Optional<MockCell> upLeftCell = grid.getUpLeft(grid.get(1, 1));

assertThat(upLeftCell.isPresent(), is(true));
assertThat(upLeftCell.get().getX(), is(0));
assertThat(upLeftCell.get().getY(), is(0));

assertThat(grid.getUpLeft(grid.get(0, 0)).isPresent(), is(false));
assertThat(grid.getUpLeft(grid.get(0, GRID_SIZE-1)).isPresent(), is(false));
assertThat(grid.getUpLeft(grid.get(GRID_SIZE-1, 0)).isPresent(), is(false));
assertThat(grid.getUpLeft(grid.get(GRID_SIZE-1, GRID_SIZE-1)).isPresent(), is(true));

// down right Cell
Optional<MockCell> downRightCell = grid.getDownRight(grid.get(1, 1));

assertThat(downRightCell.isPresent(), is(true));
assertThat(downRightCell.get().getX(), is(2));
assertThat(downRightCell.get().getY(), is(2));

assertThat(grid.getDownRight(grid.get(0, 0)).isPresent(), is(true));
assertThat(grid.getDownRight(grid.get(0, GRID_SIZE-1)).isPresent(), is(false));
assertThat(grid.getDownRight(grid.get(GRID_SIZE-1, 0)).isPresent(), is(false));
assertThat(grid.getDownRight(grid.get(GRID_SIZE-1, GRID_SIZE-1)).isPresent(), is(false));

// down left cell
Optional<MockCell> downLeftCell = grid.getDownLeft(grid.get(1, 1));

assertThat(downLeftCell.isPresent(), is(true));
assertThat(downLeftCell.get().getX(), is(0));
assertThat(downLeftCell.get().getY(), is(2));

assertThat(grid.getDownLeft(grid.get(0, 0)).isPresent(), is(false));
assertThat(grid.getDownLeft(grid.get(0, GRID_SIZE-1)).isPresent(), is(false));
assertThat(grid.getDownLeft(grid.get(GRID_SIZE-1, 0)).isPresent(), is(true));
assertThat(grid.getDownLeft(grid.get(GRID_SIZE-1, GRID_SIZE-1)).isPresent(), is(false));
}


public static class MockCell extends Cell {

public MockCell(int x, int y) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* FXGL - JavaFX Game Library. The MIT License (MIT).
* Copyright (c) AlmasB ([email protected]).
* See LICENSE for details.
*/

package com.almasb.fxgl.core.collection.grid;

import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.*;

public class NeighborFilteringOptionTest {

@Test
public void testIs() {
assertTrue(NeighborFilteringOption.FOUR_DIRECTIONS.is(NeighborFilteringOption.FOUR_DIRECTIONS));
assertFalse(NeighborFilteringOption.EIGHT_DIRECTIONS.is(NeighborFilteringOption.FOUR_DIRECTIONS));
}

}