Improves getNeighbours greatly
This commit is contained in:
parent
6a21332877
commit
d4c7d08df7
@ -91,7 +91,7 @@ public interface ILocation extends IPosition {
|
||||
* Find the grid cells between this location (exclusive) and another location
|
||||
* (inclusive).
|
||||
*
|
||||
* This is will be a list of length {@link #gridDistanceTo(other)}, containing
|
||||
* This is a list of length {@link #gridDistanceTo(other)}, containing
|
||||
* the cells that a chess queen would visit when moving to <code>other</code>.
|
||||
* <p>
|
||||
* Computes the maximum of the horizontal and the vertical distance. For
|
||||
|
@ -26,7 +26,7 @@ public class Girl implements INonPlayer {
|
||||
private int attack;
|
||||
private int defence;
|
||||
private int visibility;
|
||||
private Backpack<IItem> backpack = new Backpack<>();
|
||||
private Backpack backpack = new Backpack();
|
||||
private static final Random random = new Random();
|
||||
private List<Class<?>> validItems;
|
||||
|
||||
|
@ -397,7 +397,9 @@ public class Game implements IGame {
|
||||
}
|
||||
|
||||
public void draw() {
|
||||
map.draw(painter, printer);
|
||||
//map.draw(painter, printer);
|
||||
GameMap aMap = (GameMap) map;
|
||||
aMap.drawVisible(painter, printer, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -471,20 +473,17 @@ public class Game implements IGame {
|
||||
@Override
|
||||
public List<ILocation> getVisible() {
|
||||
List<ILocation> neighbours = map.getNeighbourhood(currentLocation, currentActor.getVision());
|
||||
List<ILocation> valid = new ArrayList<>();
|
||||
List<ILocation> invalid = new ArrayList<>();
|
||||
for (ILocation neighbour : neighbours) {
|
||||
boolean blocked = false;
|
||||
for (ILocation tile : currentLocation.gridLineTo(neighbour)) {
|
||||
if (map.hasWall(tile)) {
|
||||
blocked = true;
|
||||
invalid.add(neighbour);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!blocked) {
|
||||
valid.add(neighbour);
|
||||
}
|
||||
}
|
||||
return valid;
|
||||
neighbours.removeAll(invalid);
|
||||
return neighbours;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -6,15 +6,15 @@ import inf101.v18.rogue101.objects.IItem;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class Backpack<T extends IItem> implements IContainer {
|
||||
public class Backpack implements IContainer {
|
||||
/**
|
||||
* A list containing everything in the backpack.
|
||||
*/
|
||||
private List<T> content = new ArrayList<>();
|
||||
private List<IItem> content = new ArrayList<>();
|
||||
/**
|
||||
* The maximum amount of items allowed in a single backpack.
|
||||
*/
|
||||
private final int MAX_SIZE = 5;
|
||||
private final int MAX_SIZE = 50;
|
||||
|
||||
@Override
|
||||
public int getCurrentHealth() {
|
||||
@ -57,7 +57,11 @@ public class Backpack<T extends IItem> implements IContainer {
|
||||
* @return
|
||||
*/
|
||||
public int size() {
|
||||
return content.size();
|
||||
int totalSize = 0;
|
||||
for (IItem item : content) {
|
||||
totalSize += item.getSize();
|
||||
}
|
||||
return totalSize;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -75,8 +79,8 @@ public class Backpack<T extends IItem> implements IContainer {
|
||||
* @param item The item to add
|
||||
* @return
|
||||
*/
|
||||
public boolean add(T item) {
|
||||
if (content.size() < MAX_SIZE) {
|
||||
public boolean add(IItem item) {
|
||||
if (size() < MAX_SIZE) {
|
||||
content.add(item);
|
||||
return true;
|
||||
} else {
|
||||
@ -99,7 +103,7 @@ public class Backpack<T extends IItem> implements IContainer {
|
||||
* @param i The index of an element
|
||||
* @return An object of type T
|
||||
*/
|
||||
public T get(int i) {
|
||||
public IItem get(int i) {
|
||||
return content.get(i);
|
||||
}
|
||||
|
||||
@ -108,18 +112,12 @@ public class Backpack<T extends IItem> implements IContainer {
|
||||
*
|
||||
* @return A list of T
|
||||
*/
|
||||
public List<T> getContent() {
|
||||
public List<IItem> getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFull() {
|
||||
return content.size() >= MAX_SIZE;
|
||||
}
|
||||
|
||||
//This shows as an error, but is necessary to compile.
|
||||
@Override
|
||||
public int compareTo(Object o) {
|
||||
return compareTo((IItem)o);
|
||||
return size() >= MAX_SIZE;
|
||||
}
|
||||
}
|
||||
|
@ -3,9 +3,12 @@ package inf101.v18.rogue101.items;
|
||||
import inf101.v18.rogue101.game.IGame;
|
||||
import inf101.v18.rogue101.objects.IItem;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class Chest implements IContainer {
|
||||
private List<IItem> container = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public IItem get(int i) {
|
||||
return null;
|
||||
@ -38,12 +41,12 @@ public class Chest implements IContainer {
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return null;
|
||||
return "Chest";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSize() {
|
||||
return 100;
|
||||
return 10000;
|
||||
}
|
||||
|
||||
public String getPrintSymbol() {
|
||||
|
@ -1,14 +1,10 @@
|
||||
package inf101.v18.rogue101.items;
|
||||
|
||||
import inf101.v18.rogue101.objects.IItem;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A container for storing anything extending IItem.
|
||||
*
|
||||
* @param <T> The item type to store
|
||||
*/
|
||||
public interface IContainer<T extends IItem> extends IItem {
|
||||
public interface IContainer extends IItem {
|
||||
/**
|
||||
* Retrieves an item from a container in index i
|
||||
*
|
||||
@ -23,7 +19,7 @@ public interface IContainer<T extends IItem> extends IItem {
|
||||
*
|
||||
* @return A list of Objects extending IItem
|
||||
*/
|
||||
List<T> getContent();
|
||||
List<IItem> getContent();
|
||||
|
||||
/**
|
||||
* Checks if we can add anything at all to the container.
|
||||
|
@ -11,10 +11,12 @@ import inf101.v18.grid.IMultiGrid;
|
||||
import inf101.v18.grid.MultiGrid;
|
||||
import inf101.v18.rogue101.Main;
|
||||
import inf101.v18.rogue101.examples.Carrot;
|
||||
import inf101.v18.rogue101.game.IGame;
|
||||
import inf101.v18.rogue101.game.IllegalMoveException;
|
||||
import inf101.v18.rogue101.items.Manga;
|
||||
import inf101.v18.rogue101.objects.IActor;
|
||||
import inf101.v18.rogue101.objects.IItem;
|
||||
import inf101.v18.rogue101.objects.IPlayer;
|
||||
import inf101.v18.rogue101.objects.Wall;
|
||||
import javafx.scene.canvas.GraphicsContext;
|
||||
|
||||
@ -117,7 +119,7 @@ public class GameMap implements IGameMap {
|
||||
try {
|
||||
for (ILocation loc : cells) {
|
||||
List<IItem> list = grid.get(loc);
|
||||
String sym = " ";
|
||||
String sym = ".";
|
||||
if (!list.isEmpty()) {
|
||||
if (Main.MAP_DRAW_ONLY_DIRTY_CELLS) {
|
||||
ctx.clearRect(loc.getX() * w, loc.getY() * h, w, h);
|
||||
@ -141,6 +143,88 @@ public class GameMap implements IGameMap {
|
||||
dirtyLocs.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws only the tiles visible to the player.
|
||||
*
|
||||
* @param painter
|
||||
* @param printer
|
||||
* @param game
|
||||
*/
|
||||
public void drawVisible(ITurtle painter, Printer printer, IGame game) {
|
||||
Iterable<ILocation> cells;
|
||||
if (Main.MAP_DRAW_ONLY_DIRTY_CELLS) {
|
||||
if (dirtyLocs.isEmpty())
|
||||
return;
|
||||
else
|
||||
cells = dirtyLocs;
|
||||
} else {
|
||||
cells = grid.locations();
|
||||
painter.as(GraphicsContext.class).clearRect(0, 0, getWidth() * printer.getCharWidth(),
|
||||
getHeight() * printer.getCharHeight());
|
||||
printer.clearRegion(1, 1, getWidth(), getHeight());
|
||||
}
|
||||
GraphicsContext ctx = painter.as(GraphicsContext.class);
|
||||
double h = printer.getCharHeight();
|
||||
double w = printer.getCharWidth();
|
||||
if (Main.MAP_AUTO_SCALE_ITEM_DRAW) {
|
||||
ctx.save();
|
||||
ctx.scale(w / h, 1.0);
|
||||
w = h;
|
||||
}
|
||||
try {
|
||||
IPlayer player = null;
|
||||
ILocation playerPos = null;
|
||||
for (ILocation loc : cells) {
|
||||
printer.printAt(loc.getX() + 1, loc.getY() + 1, " ");
|
||||
if (this.hasActors(loc) && this.getActors(loc).get(0) instanceof IPlayer) {
|
||||
player = (IPlayer) this.getActors(loc).get(0);
|
||||
playerPos = loc;
|
||||
}
|
||||
}
|
||||
List<ILocation> positions = getVisible(getNeighbourhood(playerPos,player.getVision()), playerPos);
|
||||
positions.add(playerPos);
|
||||
for (ILocation loc : positions) {
|
||||
List<IItem> list = grid.get(loc);
|
||||
String sym = ".";
|
||||
if (!list.isEmpty()) {
|
||||
if (Main.MAP_DRAW_ONLY_DIRTY_CELLS) {
|
||||
ctx.clearRect(loc.getX() * w, loc.getY() * h, w, h);
|
||||
// ctx.fillRect(loc.getX() * w, loc.getY() * h, w, h);
|
||||
}
|
||||
painter.save();
|
||||
painter.jumpTo((loc.getX() + 0.5) * w, (loc.getY() + 0.5) * h);
|
||||
boolean dontPrint = list.get(0).draw(painter, w, h);
|
||||
painter.restore();
|
||||
if (!dontPrint) {
|
||||
sym = list.get(0).getPrintSymbol();
|
||||
}
|
||||
}
|
||||
printer.printAt(loc.getX() + 1, loc.getY() + 1, sym);
|
||||
}
|
||||
} finally {
|
||||
if (Main.MAP_AUTO_SCALE_ITEM_DRAW) {
|
||||
ctx.restore();
|
||||
}
|
||||
}
|
||||
dirtyLocs.clear();
|
||||
}
|
||||
|
||||
private List<ILocation> getVisible(List<ILocation> neighbours, ILocation loc) {
|
||||
List<ILocation> invalid = new ArrayList<>();
|
||||
for (ILocation neighbour : neighbours) {
|
||||
if (!hasWall(neighbour)) {
|
||||
for (ILocation tile : loc.gridLineTo(neighbour)) {
|
||||
if (hasWall(tile)) {
|
||||
invalid.add(neighbour);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
neighbours.removeAll(invalid);
|
||||
return neighbours;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<IActor> getActors(ILocation loc) {
|
||||
List<IActor> items = new ArrayList<>();
|
||||
@ -263,105 +347,32 @@ public class GameMap implements IGameMap {
|
||||
} else if (dist == 0) {
|
||||
return new ArrayList<>(); // empty!
|
||||
}
|
||||
|
||||
List<ILocation> locations = new ArrayList<>();
|
||||
for (int i = 1; i <= dist; i++) {
|
||||
ILocation current = loc;
|
||||
boolean blockedNorth = false, blockedSouth = false, blockedWest = false, blockedEast = false;
|
||||
for (int j = 0; j < i; j++) { //Checks if we reach out of bounds in the North or West direction.
|
||||
if (current.canGo(GridDirection.NORTHWEST)) {
|
||||
current = current.go(GridDirection.NORTHWEST);
|
||||
} else if (current.canGo(GridDirection.WEST)) {
|
||||
current = current.go(GridDirection.WEST);
|
||||
blockedNorth = true;
|
||||
} else if (current.canGo(GridDirection.NORTH)) {
|
||||
current = current.go(GridDirection.NORTH);
|
||||
blockedWest = true;
|
||||
} else {
|
||||
blockedNorth = true;
|
||||
blockedWest = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
current = loc;
|
||||
for (int j = 0; j < i; j++) { //Checks if we reach out of bounds in the South or East direction.
|
||||
if (current.canGo(GridDirection.SOUTHEAST)) {
|
||||
current = current.go(GridDirection.SOUTHEAST);
|
||||
} else if (current.canGo(GridDirection.EAST)) {
|
||||
current = current.go(GridDirection.EAST);
|
||||
blockedSouth = true;
|
||||
} else if (current.canGo(GridDirection.SOUTH)) {
|
||||
current = current.go(GridDirection.SOUTH);
|
||||
blockedEast = true;
|
||||
} else {
|
||||
blockedSouth = true;
|
||||
blockedEast = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!blockedNorth && !blockedEast && !blockedWest && !blockedSouth) { //If nothing is blocked, get the top and bottom.
|
||||
current = goTo(loc, GridDirection.NORTHWEST, i);
|
||||
addLoc(locations, current, GridDirection.EAST, i * 2 + 1);
|
||||
current = goTo(loc, GridDirection.SOUTHWEST, i);
|
||||
addLoc(locations, current, GridDirection.EAST, i * 2 + 1);
|
||||
} else if (blockedNorth && !blockedEast && !blockedWest) { //If top is blocked, get bottom.
|
||||
current = goTo(loc, GridDirection.EAST, i);
|
||||
addLoc(locations, current, GridDirection.SOUTH, i + 1);
|
||||
current = goTo(loc, GridDirection.WEST, i);
|
||||
addLoc(locations, current, GridDirection.SOUTH, i + 1);
|
||||
} else if (blockedSouth && !blockedEast && !blockedWest) { //If bottom is blocked, get top.
|
||||
current = goTo(loc, GridDirection.EAST, i);
|
||||
addLoc(locations, current, GridDirection.NORTH, i + 1);
|
||||
current = goTo(loc, GridDirection.WEST, i);
|
||||
addLoc(locations, current, GridDirection.NORTH, i + 1);
|
||||
}
|
||||
if (blockedNorth && !blockedEast) { //Get sides if we have collided with top or bottom.
|
||||
current = goTo(loc, GridDirection.EAST, i);
|
||||
addLoc(locations, current, GridDirection.SOUTH, i + 1);
|
||||
} else if (blockedNorth && !blockedWest) {
|
||||
current = goTo(loc, GridDirection.WEST, i);
|
||||
addLoc(locations, current, GridDirection.SOUTH, i + 1);
|
||||
} else if (blockedSouth && !blockedEast) {
|
||||
current = goTo(loc, GridDirection.EAST, i);
|
||||
addLoc(locations, current, GridDirection.NORTH, i + 1);
|
||||
} else if (blockedSouth && !blockedWest) {
|
||||
current = goTo(loc, GridDirection.WEST, i);
|
||||
addLoc(locations, current, GridDirection.NORTH, i + 1);
|
||||
}
|
||||
if (!blockedNorth && !blockedSouth && !blockedWest) { //Get east sides.
|
||||
current = goTo(loc, GridDirection.NORTHWEST, i);
|
||||
current = current.go(GridDirection.SOUTH);
|
||||
addLoc(locations, current, GridDirection.SOUTH, i * 2 - 1);
|
||||
} else if (blockedNorth && blockedWest) {
|
||||
current = goTo(loc, GridDirection.SOUTH, i);
|
||||
addLoc(locations, current, GridDirection.EAST, i);
|
||||
} else if (blockedSouth && blockedWest) {
|
||||
current = goTo(loc, GridDirection.NORTH, i);
|
||||
addLoc(locations, current, GridDirection.EAST, i);
|
||||
} else if (blockedWest) {
|
||||
current = goTo(loc, GridDirection.NORTH, i);
|
||||
addLoc(locations, current, GridDirection.EAST, i + 1);
|
||||
current = goTo(loc, GridDirection.SOUTH, i);
|
||||
addLoc(locations, current, GridDirection.EAST, i + 1);
|
||||
}
|
||||
if (!blockedNorth && !blockedSouth && !blockedEast) { //Get west sides.
|
||||
current = goTo(loc, GridDirection.NORTHEAST, i);
|
||||
current = current.go(GridDirection.SOUTH);
|
||||
addLoc(locations, current, GridDirection.SOUTH, i * 2 - 1);
|
||||
} else if (blockedNorth && blockedEast) {
|
||||
current = goTo(loc, GridDirection.SOUTH, i);
|
||||
addLoc(locations, current, GridDirection.WEST, i);
|
||||
} else if (blockedSouth && blockedEast) {
|
||||
current = goTo(loc, GridDirection.NORTH, i);
|
||||
addLoc(locations, current, GridDirection.WEST, i);
|
||||
} else if (blockedEast) {
|
||||
current = goTo(loc, GridDirection.NORTH, i);
|
||||
addLoc(locations, current, GridDirection.WEST, i + 1);
|
||||
current = goTo(loc, GridDirection.SOUTH, i);
|
||||
addLoc(locations, current, GridDirection.WEST, i + 1);
|
||||
}
|
||||
}
|
||||
return locations;
|
||||
List<ILocation> neighbours = new ArrayList<>();
|
||||
int startX = loc.getX();
|
||||
int startY = loc.getY();
|
||||
for (int i = 1; i <= dist; i++) {
|
||||
int leftX = startX - i;
|
||||
int rightX = startX + i;
|
||||
int topY = startY - i;
|
||||
int bottomY = startY + i;
|
||||
for (int x = leftX; x <= rightX; x++) {
|
||||
if (grid.isValid(x, topY)) {
|
||||
neighbours.add(getLocation(x, topY));
|
||||
}
|
||||
if (grid.isValid(x, bottomY)) {
|
||||
neighbours.add(getLocation(x, bottomY));
|
||||
}
|
||||
}
|
||||
for (int y = topY; y <= bottomY; y++) {
|
||||
if (grid.isValid(leftX, y)) {
|
||||
neighbours.add(getLocation(leftX, y));
|
||||
}
|
||||
if (grid.isValid(rightX, y)) {
|
||||
neighbours.add(getLocation(rightX, y));
|
||||
}
|
||||
}
|
||||
}
|
||||
return neighbours;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -14,7 +14,7 @@
|
||||
# # #
|
||||
# G #
|
||||
# G #
|
||||
# #
|
||||
# c #
|
||||
# #
|
||||
# #
|
||||
# G #
|
||||
|
@ -13,7 +13,7 @@ import java.util.List;
|
||||
|
||||
public class Player implements IPlayer {
|
||||
private int hp = getMaxHealth();
|
||||
private final Backpack<IItem> equipped = new Backpack<>();
|
||||
private final Backpack equipped = new Backpack();
|
||||
// True if the player wants to pick up something using the digit keys
|
||||
private boolean dropping = false;
|
||||
// True if the player wants to drop something using the digit keys
|
||||
@ -158,7 +158,7 @@ public class Player implements IPlayer {
|
||||
* @param i The wanted index
|
||||
*/
|
||||
private void pickUp(IGame game, int i) {
|
||||
if (equipped.size() < 5) {
|
||||
if (!equipped.isFull()) {
|
||||
List<IItem> items = game.getLocalItems();
|
||||
if (items.size() >= i) {
|
||||
IItem pickedUp = game.pickUp(items.get(i));
|
||||
@ -204,7 +204,9 @@ public class Player implements IPlayer {
|
||||
List<String> items = new ArrayList<>();
|
||||
for (IItem item : equipped.getContent()) {
|
||||
String name = item.getName();
|
||||
items.add(firstCharToUpper(name));
|
||||
if (name != null) {
|
||||
items.add(firstCharToUpper(name));
|
||||
}
|
||||
}
|
||||
//TODO: Add item bonuses to visible stats.
|
||||
game.formatStatus("HP: %d/%d ATK: %d DEF: %s DMG: %s INV: %s", hp, getMaxHealth(), getAttack(), getDefence(), getDamage(), String.join(",", items));
|
||||
@ -300,4 +302,10 @@ public class Player implements IPlayer {
|
||||
}
|
||||
return amount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getVision() {
|
||||
//TODO: Increase vision based on equipped items
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user