Skip to content

Commit

Permalink
Removed Dijsktra algo and tweaked A*
Browse files Browse the repository at this point in the history
  • Loading branch information
David52920 committed Feb 2, 2021
1 parent 9c37aa0 commit 098f003
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 197 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ public void tick() {
if(turnTime == (finalTurnTime - 10) && !context.getPlayerManager().listBots().isEmpty()) {
context.getPlayerManager().AILogic();
}
if(turnTime == (finalTurnTime - 30) && !context.getPlayerManager().listBots().isEmpty()) {
if(turnTime == (finalTurnTime - 50) && !context.getPlayerManager().listBots().isEmpty()) {
try {
for (Player p : context.getPlayerManager().listBots()) {
context.getPlayerManager().sendMoveBar(p);
Expand Down
10 changes: 5 additions & 5 deletions server/src/com/benberi/cadesim/server/model/player/Player.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import com.benberi.cadesim.server.model.cade.Team;
import com.benberi.cadesim.server.model.cade.map.BlockadeMap;
import com.benberi.cadesim.server.model.cade.map.flag.Flag;
import com.benberi.cadesim.server.model.player.ai.util.AStarNode;
import com.benberi.cadesim.server.model.player.ai.util.MoveState;
import com.benberi.cadesim.server.model.player.ai.util.NPC_Type;
import com.benberi.cadesim.server.model.player.collision.PlayerCollisionStorage;
Expand Down Expand Up @@ -147,7 +148,7 @@ public void setFirstEntry(boolean firstEntry) {
private boolean enteredSafeLandside = false; // reason why
private boolean enteredSafeOceanside = false; // "

private List<MoveState> path;
private List<AStarNode> path;
private Position goal;

/**
Expand Down Expand Up @@ -593,7 +594,6 @@ public void respawn(int[] customPosition, VesselFace customFace, float customDam
respawnOnLandside(false, customPosition, customFace, customDamage, shouldSpawnFullCannons);
} else {
context.getPlayerManager().serverBroadcastMessage(this.getName() + " was sunk!");

// after sink, return control after x turns
this.setTurnsUntilControl(context.getPlayerManager().getRespawnDelay());
if (getTurnsUntilControl() > 0)
Expand All @@ -604,7 +604,7 @@ public void respawn(int[] customPosition, VesselFace customFace, float customDam
" turns after sinking"
);
}

context.getPlayerManager().resetPlayerFlags(this); // reset flags that are stuck
// sunk, 'respawn' on land side with new ship
vessel.resetDamageAndBilge();
respawnOnLandside(true, customPosition, customFace, customDamage, shouldSpawnFullCannons);
Expand Down Expand Up @@ -1097,7 +1097,7 @@ public void setType(NPC_Type typeValue) {
type = typeValue;
}

public void setPath(List<MoveState> path) {
public void setPath(List<AStarNode> path) {
this.path = path;

}
Expand All @@ -1106,7 +1106,7 @@ public void clearPath() {
if(this.path != null) this.path.clear();
}

public List<MoveState> getPath() {
public List<AStarNode> getPath() {
return this.path;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import com.benberi.cadesim.server.model.player.ai.NPC_Type2;
import com.benberi.cadesim.server.model.player.ai.NPC_Type3;
import com.benberi.cadesim.server.model.player.ai.NPC_Type4;
import com.benberi.cadesim.server.model.player.ai.util.Dijsktra;
import com.benberi.cadesim.server.model.player.ai.util.AStarSearch;
import com.benberi.cadesim.server.model.player.ai.util.NPC_Type;
import com.benberi.cadesim.server.model.player.collision.CollisionCalculator;
import com.benberi.cadesim.server.model.player.domain.JobbersQuality;
Expand Down Expand Up @@ -129,7 +129,7 @@ public class PlayerManager {
* random number generator
*/
Random randomGenerator = new Random();
protected Dijsktra algorithm;
protected AStarSearch algorithm;
/**
* restart conditions
*/
Expand Down Expand Up @@ -269,7 +269,7 @@ public void setGameEnded(boolean gameEnded) {
public PlayerManager(ServerContext context) {
this.context = context;
this.collision = new CollisionCalculator(context, this);
this.algorithm = new Dijsktra(context);
this.algorithm = new AStarSearch(context);
resetTemporarySettings();
}

Expand Down Expand Up @@ -1272,8 +1272,14 @@ public void resetPlayerFlags() {
* Wrapper to reset specific players flags
*/
public void resetPlayerFlags(Player player) {
for(Player pl : listRegisteredPlayers()) {
if(pl == player) player.getFlags().clear();
if(player.isBot()) {
for(Player pl : listBots()) {
if(pl == player) player.getFlags().clear();
}
}else {
for(Player pl : listRegisteredPlayers()) {
if(pl == player) player.getFlags().clear();
}
}
}

Expand Down Expand Up @@ -1934,7 +1940,8 @@ public void setTeam(Player pl, int value) {
sendTeamInfo();
AILogic();
for(Player bot : listBots()) {
bot.setDestination(getMaxTilePoints(bot));
bot.setDestination(getMaxTilePoints(bot));
resetPlayerFlags(bot);
}
}
}
Expand Down Expand Up @@ -2197,7 +2204,7 @@ else if (message.startsWith("/bug")) {
}
}

public Dijsktra getAlgorithm() {
public AStarSearch getAlgorithm() {
return algorithm;
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
package com.benberi.cadesim.server.model.player.ai.util;

import java.util.ArrayList;
import java.util.List;

import com.benberi.cadesim.server.ServerContext;
import com.benberi.cadesim.server.model.player.Player;
import com.benberi.cadesim.server.model.player.move.MoveType;
import com.benberi.cadesim.server.model.player.vessel.VesselFace;
import com.benberi.cadesim.server.util.Position;
Expand All @@ -8,58 +13,85 @@
* Class used as a state/nodes in A* algorithm
*/
public class AStarNode {

List<AStarNode> neighbors = new ArrayList<AStarNode>();
public Position position;
public VesselFace face;
public MoveType move;
public AStarNode parent;
public double fCost, gCost, hCost;
public int time;
public int step;

public AStarNode(Position position, VesselFace face, MoveType move, AStarNode parent, double gCost, double hCost) {
public AStarNode(Position position, VesselFace face, MoveType move, AStarNode parent, double gCost, double hCost, int step) {
this.position = position;
this.face = face;
this.move = move;
this.parent = parent;
this.gCost = gCost;
this.hCost = hCost;
this.fCost = this.gCost + this.hCost;
this.step = step;
}
/*
* Node if no move is placed
*/
public AStarNode MoveNone() {
return new AStarNode(position.copy(), face, MoveType.NONE, this, 0, 0);
return new AStarNode(position.copy(), face, MoveType.NONE, this, 0, 0, step + 1);
}
/*
* Node if move forward from current position
*/
public AStarNode MoveForward() {
return new AStarNode(position.copy().add(Position.Forward(face)), face, MoveType.FORWARD, this, 0, 0);
return new AStarNode(position.copy().add(Position.Forward(face)), face, MoveType.FORWARD, this, 0, 0, step + 1);
}
/*
* Node if move left from current position
*/
public AStarNode MoveLeft() {
return new AStarNode(position.copy().add(Position.Left(face)), face.getPrev(), MoveType.LEFT, this, 0, 0);
return new AStarNode(position.copy().add(Position.Left(face)), face.getPrev(), MoveType.LEFT, this, 0, 0, step + 1);
}
/*
* Node if turn in place (left of current position) - used for obstacles
*/
public AStarNode TurnLeft() {
return new AStarNode(position.copy(), face.getPrev(), MoveType.LEFT, this, 0, 0);
return new AStarNode(position.copy(), face.getPrev(), MoveType.LEFT, this, 0, 0, step + 1);
}
/*
* Node if move right from current position
*/
public AStarNode MoveRight() {
return new AStarNode(position.copy().add(Position.Right(face)), face.getNext(), MoveType.RIGHT, this, 0, 0);
return new AStarNode(position.copy().add(Position.Right(face)), face.getNext(), MoveType.RIGHT, this, 0, 0, step + 1);
}
/*
* Node if turn in place (right of current position) - used for obstacles
*/
public AStarNode TurnRight() {
return new AStarNode(position.copy(), face.getNext(), MoveType.RIGHT, this, 0, 0);
return new AStarNode(position.copy(), face.getNext(), MoveType.RIGHT, this, 0, 0, step + 1);
}

public void addNeighbors(ServerContext context, Player start) {
neighbors.add(this.MoveNone());
if(context.getMap().isRock(this.MoveForward().position.getX(), this.MoveForward().position.getY(), start)) {
neighbors.add(this.TurnLeft()); // turn in place
neighbors.add(this.TurnRight());
}else {
neighbors.add(this.MoveForward());
if(context.getMap().isRock(this.MoveLeft().position.getX(), this.MoveLeft().position.getY(), start)) {
neighbors.add(this.TurnLeft()); // turn in place
neighbors.add(this.TurnRight());
}else {
neighbors.add(this.MoveLeft());
}
if(context.getMap().isRock(this.MoveRight().position.getX(), this.MoveRight().position.getY(), start)) {
neighbors.add(this.TurnLeft()); // turn in place
neighbors.add(this.TurnRight());
}else {
neighbors.add(this.MoveRight());
}
}
}

public List<AStarNode> getNeighbors(){
return this.neighbors;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,12 @@ public int compare(AStarNode n0, AStarNode n1) {
public List<AStarNode> findPath(Player bot, Position goal){
openList = new ArrayList<AStarNode>();
closedList = new ArrayList<AStarNode>();
List<AStarNode> neighbors = new ArrayList<AStarNode>();
int leftAmount = bot.getMoveTokens().countLeftMoves();
int forwardAmount = bot.getMoveTokens().countForwardMoves();
int rightAmount = bot.getMoveTokens().countRightMoves();
AStarNode current = new AStarNode(bot, bot.getFace(), MoveType.NONE, null, 0, bot.distance(goal));
AStarNode current = new AStarNode(bot, bot.getFace(), MoveType.NONE, null, 0, bot.distance(goal), 0);
openList.add(current);
while(openList.size() > 0) {
while(!openList.isEmpty()) {
Collections.sort(openList, nodeSorter);
current = openList.get(0);
if(current.position.equals(goal)) { // if goal node found
Expand All @@ -60,63 +59,40 @@ public List<AStarNode> findPath(Player bot, Position goal){
openList.clear();
closedList.clear();
Collections.reverse(path);
if(path.size() > 3 && bot.getVessel().has3Moves()) {
path = path.subList(0, 3);
}else if(path.size() > 4 && !(bot.getVessel().has3Moves())) {
path = path.subList(0, 4);
}
return path;
}
if(current.step > 200)break;
openList.remove(current);
closedList.add(current);
//add specific neighbors
neighbors.add(current.MoveNone());
if(context.getMap().isRock(current.MoveForward().position.getX(), current.MoveForward().position.getY(), bot)) {
neighbors.add(current.TurnLeft()); // turn in place
neighbors.add(current.TurnRight());
}else {
neighbors.add(current.MoveForward());
if(context.getMap().isRock(current.MoveLeft().position.getX(), current.MoveLeft().position.getY(), bot)) {
neighbors.add(current.TurnLeft()); // turn in place
neighbors.add(current.TurnRight());
}else {
neighbors.add(current.MoveLeft());
}
if(context.getMap().isRock(current.MoveRight().position.getX(), current.MoveRight().position.getY(), bot)) {
neighbors.add(current.TurnLeft()); // turn in place
neighbors.add(current.TurnRight());
}else {
neighbors.add(current.MoveRight());
}
}
for(AStarNode neighborNode : neighbors) {
if(context.getMap().isOutOfBounds(neighborNode.position.getX(), neighborNode.position.getY()))continue;
current.addNeighbors(context, bot);
for(AStarNode neighbor : current.getNeighbors()) {
if(context.getMap().isOutOfBounds(neighbor.position.getX(), neighbor.position.getY()))continue;
//skip if out of particular move
if((leftAmount == 0 && neighborNode.move == MoveType.LEFT) ||
(rightAmount == 0 && neighborNode.move == MoveType.RIGHT) ||
(forwardAmount == 0 && neighborNode.move == MoveType.FORWARD)) {
if((leftAmount == 0 && neighbor.move == MoveType.LEFT) ||
(rightAmount == 0 && neighbor.move == MoveType.RIGHT) ||
(forwardAmount == 0 && neighbor.move == MoveType.FORWARD)) {
continue;
}
// Compute the cost to get *to* the action tile.
double costToReach = current.position.distance(neighborNode.position);
double costToReach = current.position.distance(neighbor.position);

if(neighborNode.move == MoveType.FORWARD) costToReach += 0.2;
if(current.position.equals(neighborNode.position) && neighborNode.move != MoveType.NONE) costToReach += 0.8; // when ship is trapped by rock
int at = context.getMap().getTile(neighborNode.position.getX(), neighborNode.position.getY());
if(neighbor.move == MoveType.FORWARD) costToReach += 0.5;
if(current.position.equals(neighbor.position) && neighbor.move != MoveType.NONE) costToReach += 0.8; // when ship is trapped by rock
int at = context.getMap().getTile(neighbor.position.getX(), neighbor.position.getY());
if(context.getMap().isWind(at)){ // special action tiles
neighborNode.position = context.getMap().getNextActionTilePositionForTile(neighborNode.position, at);
costToReach += getActionCost(neighborNode, at);
neighbor.position = context.getMap().getNextActionTilePositionForTile(neighbor.position, at);
costToReach += getActionCost(neighbor, at);
}
if(context.getMap().isWhirlpool(at)) {
neighborNode.position = context.getMap().getFinalActionTilePosition(at, neighborNode.position, 0);
neighborNode.face = neighborNode.face.getNext();
costToReach += getActionCost(neighborNode, at);
neighbor.position = context.getMap().getFinalActionTilePosition(at, neighbor.position, 0);
neighbor.face = neighbor.face.getNext();
costToReach += getActionCost(neighbor, at);
}
AStarNode node = new AStarNode(neighborNode.position, neighborNode.face,neighborNode.move, current, current.gCost + costToReach, heuristicDistance(neighborNode.position,goal));
if(positionInList(closedList, neighborNode.position) && current.gCost >= node.gCost)continue;
if(!positionInList(openList, neighborNode.position) || current.gCost < node.gCost) openList.add(node);
AStarNode node = new AStarNode(neighbor.position, neighbor.face,neighbor.move, current, current.gCost + costToReach, heuristicDistance(neighbor.position,goal), neighbor.step);
if(positionInList(closedList, neighbor.position) && current.gCost >= node.gCost)continue;
if(!positionInList(openList, neighbor.position) || current.gCost < node.gCost) openList.add(node);
}
neighbors.clear(); // clear neighbors after iterating.
}
closedList.clear();
return null;
Expand Down
Loading

0 comments on commit 098f003

Please sign in to comment.