程序代写 package dungeonmania.map;

package dungeonmania.map;

import java.util.ArrayList;
import java.util.HashMap;

Copyright By PowCoder代写 加微信 powcoder

import java.util.List;
import java.util.Map;
import java.util.PriorityQueue;
import java.util.stream.Collectors;

import dungeonmania.Game;
import dungeonmania.entities.Entity;
import dungeonmania.entities.Player;
import dungeonmania.entities.Portal;
import dungeonmania.entities.Switch;
import dungeonmania.entities.collectables.Bomb;
import dungeonmania.entities.enemies.Enemy;
import dungeonmania.entities.enemies.ZombieToastSpawner;
import dungeonmania.util.Direction;
import dungeonmania.util.Position;

public class GameMap {
private Game game;
private Map nodes = new HashMap<>();
private Player player;

* Initialise the game map
* 1. pair up portals
public void init() {
initPairPortals();
initRegisterMovables();
initRegisterSpawners();
initRegisterBombsAndSwitches();

private void initRegisterBombsAndSwitches() {
List bombs = getEntities(Bomb.class);
List switchs = getEntities(Switch.class);
for (Bomb b: bombs) {
for (Switch s: switchs) {
if (Position.isAdjacent(b.getPosition(), s.getPosition())) {
b.subscribe(s);
s.subscribe(b);

// Pair up portals if there’s any
private void initPairPortals() {
Map portalsMap = new HashMap<>();
nodes.forEach((k, v) -> {
v.getEntities()
.filter(Portal.class::isInstance)
.map(Portal.class::cast)
.forEach(portal -> {
String color = portal.getColor();
if (portalsMap.containsKey(color)) {
portal.bind(portalsMap.get(color));
portalsMap.put(color, portal);

private void initRegisterMovables() {
List enemies = getEntities(Enemy.class);
enemies.forEach(e -> {
game.register(() -> e.move(game), Game.AI_MOVEMENT, e.getId());

private void initRegisterSpawners() {
List zts = getEntities(ZombieToastSpawner.class);
zts.forEach(e -> {
game.register(() -> e.spawn(game), Game.AI_MOVEMENT, e.getId());
game.register(() -> game.getEntityFactory().spawnSpider(game), Game.AI_MOVEMENT, “zombieToastSpawner”);

public void moveTo(Entity entity, Position position) {
if (!canMoveTo(entity, position)) return;

triggerMovingAwayEvent(entity);
removeNode(entity);
entity.setPosition(position);
addEntity(entity);
triggerOverlapEvent(entity);

public void moveTo(Entity entity, Direction direction) {
if (!canMoveTo(entity, Position.translateBy(entity.getPosition(), direction))) return;
triggerMovingAwayEvent(entity);
removeNode(entity);
entity.translate(direction);
addEntity(entity);
triggerOverlapEvent(entity);

private void triggerMovingAwayEvent(Entity entity) {
List callbacks = new ArrayList<>();
getEntities(entity.getPosition()).forEach(e -> {
if (e != entity)
callbacks.add(() -> e.onMovedAway(this, entity));
callbacks.forEach(callback -> {
callback.run();

private void triggerOverlapEvent(Entity entity) {
List overlapCallbacks = new ArrayList<>();
getEntities(entity.getPosition()).forEach(e -> {
if (e != entity)
overlapCallbacks.add(() -> e.onOverlap(this, entity));
overlapCallbacks.forEach(callback -> {
callback.run();

public boolean canMoveTo(Entity entity, Position position) {
return !nodes.containsKey(position) || nodes.get(position).canMoveOnto(this, entity);

public Position dijkstraPathFind(Position src, Position dest, Entity entity) {
// if inputs are invalid, don’t move
if (!nodes.containsKey(src) || !nodes.containsKey(dest))
return src;

Map dist = new HashMap<>();
Map prev = new HashMap<>();
Map visited = new HashMap<>();

prev.put(src, null);
dist.put(src, 0);

PriorityQueue q = new PriorityQueue<>((x, y) ->
Integer.compare(dist.getOrDefault(x, Integer.MAX_VALUE), dist.getOrDefault(y, Integer.MAX_VALUE)));
q.add(src);

while (!q.isEmpty()) {
Position curr = q.poll();
if (curr.equals(dest) || dist.get(curr) > 200) break;
// check portal
if (nodes.containsKey(curr) && nodes.get(curr).getEntities().stream().anyMatch(Portal.class::isInstance)) {
Portal portal = nodes.get(curr).getEntities()
.filter(Portal.class::isInstance).map(Portal.class::cast)
.collect(Collectors.toList())
List teleportDest = portal.getDestPositions(this, entity);
teleportDest.stream()
.filter(p -> !visited.containsKey(p))
.forEach(p -> {
dist.put(p, dist.get(curr));
prev.put(p, prev.get(curr));
visited.put(curr, true);
List neighbours = curr.getCardinallyAdjacentPositions()
.filter(p -> !visited.containsKey(p))
.filter(p -> !nodes.containsKey(p) || nodes.get(p).canMoveOnto(this, entity))
.collect(Collectors.toList());

neighbours.forEach(n -> {
int newDist = dist.get(curr) + (nodes.containsKey(n) ? nodes.get(n).getWeight() : 1);
if (newDist < dist.getOrDefault(n, Integer.MAX_VALUE)) { q.remove(n); dist.put(n, newDist); prev.put(n, curr); Position ret = dest; if (prev.get(ret) == null || ret.equals(src)) return src; while (!prev.get(ret).equals(src)) { ret = prev.get(ret); return ret; public void removeNode(Entity entity) { Position p = entity.getPosition(); if (nodes.containsKey(p)) { nodes.get(p).removeEntity(entity); if (nodes.get(p).size() == 0) { nodes.remove(p); public void destroyEntity(Entity entity) { removeNode(entity); entity.onDestroy(this); public void addEntity(Entity entity) { addNode(new GraphNode(entity)); public void addNode(GraphNode node) { Position p = node.getPosition(); if (!nodes.containsKey(p)) nodes.put(p, node); GraphNode curr = nodes.get(p); curr.mergeNode(node); nodes.put(p, curr); public Entity getEntity(String id) { Entity res = null; for (Map.Entry entry : nodes.entrySet()) {
List es = entry.getValue().getEntities()
.filter(e -> e.getId().equals(id))
.collect(Collectors.toList());
if (es != null && es.size() > 0) {
res = es.get(0);
return res;

public List getEntities(Position p) {
GraphNode node = nodes.get(p);
return (node != null) ? node.getEntities() : new ArrayList<>();

public List getEntities() {
List entities = new ArrayList<>();
nodes.forEach((k, v) -> entities.addAll(v.getEntities()));
return entities;

public List getEntities(Class type) {
return getEntities().stream().filter(type::isInstance).map(type::cast).collect(Collectors.toList());

public long countEntities(Class type) {
return getEntities().stream().filter(type::isInstance).count();

public Player getPlayer() {
return player;

public void setPlayer(Player player) {
this.player = player;

public Game getGame() {
return game;

public void setGame(Game game) {
this.game = game;

程序代写 CS代考 加微信: powcoder QQ: 1823890830 Email: powcoder@163.com