Skip to content

Commit

Permalink
Updated AI to use A* algorithm
Browse files Browse the repository at this point in the history
  • Loading branch information
David52920 committed Jan 7, 2021
1 parent 91bf0b9 commit 2bce840
Show file tree
Hide file tree
Showing 12 changed files with 270 additions and 89 deletions.
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ allprojects {
version = '1.0'
ext {
appName = "Cadesim"
gdxVersion = '1.9.12'
gdxVersion = '1.9.13'
roboVMVersion = '2.3.11'
box2DLightsVersion = '1.5'
ashleyVersion = '1.7.3'
Expand Down
40 changes: 0 additions & 40 deletions server/src/com/benberi/cadesim/server/model/player/NPC_Type4.java

This file was deleted.

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.NPC_Type;
import com.benberi.cadesim.server.model.player.collision.PlayerCollisionStorage;
import com.benberi.cadesim.server.model.player.domain.JobbersQuality;
import com.benberi.cadesim.server.model.player.domain.MoveGenerator;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@
import com.benberi.cadesim.server.model.cade.Team;
import com.benberi.cadesim.server.model.cade.map.flag.Flag;
import com.benberi.cadesim.server.model.player.Vote.VOTE_RESULT;
import com.benberi.cadesim.server.model.player.ai.NPC_Type1;
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.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;
import com.benberi.cadesim.server.model.player.domain.PlayerLoginRequest;
Expand Down Expand Up @@ -124,6 +130,7 @@ public class PlayerManager {
* random number generator
*/
Random randomGenerator = new Random();
protected AStarSearch algorithm;
/**
* restart conditions
*/
Expand All @@ -145,7 +152,7 @@ public class PlayerManager {
private String disengageBehavior;
@SuppressWarnings("unused")
private String chatChannel = "global";

/**
* helper method to split string into parts
* https://stackoverflow.com/a/3760193
Expand Down Expand Up @@ -263,6 +270,7 @@ public void setGameEnded(boolean gameEnded) {
public PlayerManager(ServerContext context) {
this.context = context;
this.collision = new CollisionCalculator(context, this);
this.algorithm = new AStarSearch(context);
resetTemporarySettings();
}

Expand Down Expand Up @@ -1789,6 +1797,24 @@ public void getMaxTilePoints(Player player) {
System.out.println(sortedMap.values()); // position of tile (x,y)
}

public void respawnAI() {
for(Player p : listBots()) {
p.setTeam(getBotTeam());
}
for(Player p : listBots()) {
if(listRegisteredPlayers().get(0).getTeam() == Team.ATTACKER) {
p.respawnOnLandside(true);
}else {
p.respawnOnLandside(false);
}
}
for(Player p : listRegisteredPlayers()) {
if(!p.isBot()) {
p.getPackets().sendPlayers();
}
}
}

public void spawnAI() {
removeAI();
int playerListSize = listRegisteredPlayers().size();
Expand All @@ -1799,22 +1825,11 @@ public void spawnAI() {
for (int i =0; i < playerListSize ; i++) {
createBot(NPC_Type.TYPE4, randomBotName(), listRegisteredPlayers().get(0).getVessel().getID(), getBotTeam(), null, getBotFace(), 0.0f);
}
createBot(NPC_Type.TYPE3, randomBotName(), 0, getBotTeam(), null, getBotFace(), 0.0f);
createBot(NPC_Type.TYPE1, randomBotName(), 1, getBotTeam(), null, getBotFace(), 0.0f);
createBot(NPC_Type.TYPE2, randomBotName(), 2, getBotTeam(), null, getBotFace(), 0.0f);
createBot(NPC_Type.TYPE3, randomBotName(), 8, getBotTeam(), null, getBotFace(), 0.0f);
for(Player p : listBots()) {
if(listRegisteredPlayers().get(0).getTeam() == Team.ATTACKER) {
p.respawnOnLandside(true);
}else {
p.respawnOnLandside(false);
}
}
for(Player p : listRegisteredPlayers()) {
if(!p.isBot()) {
p.getPackets().sendPlayers();
}
}
// createBot(NPC_Type.TYPE3, randomBotName(), 0, getBotTeam(), null, getBotFace(), 0.0f);
// createBot(NPC_Type.TYPE1, randomBotName(), 1, getBotTeam(), null, getBotFace(), 0.0f);
// createBot(NPC_Type.TYPE2, randomBotName(), 2, getBotTeam(), null, getBotFace(), 0.0f);
// createBot(NPC_Type.TYPE3, randomBotName(), 8, getBotTeam(), null, getBotFace(), 0.0f);
respawnAI();
return;

case "medium":
Expand All @@ -1824,18 +1839,7 @@ public void spawnAI() {
createBot(NPC_Type.TYPE1, randomBotName(), 2, getBotTeam(), null, getBotFace(), 0.0f);
createBot(NPC_Type.TYPE2, randomBotName(), 3, getBotTeam(), null, getBotFace(), 0.0f);
createBot(NPC_Type.TYPE3, randomBotName(), 4, getBotTeam(), null, getBotFace(), 0.0f);
for(Player p : listBots()) {
if(listRegisteredPlayers().get(0).getTeam() == Team.ATTACKER) {
p.respawnOnLandside(true);
}else {
p.respawnOnLandside(false);
}
}
for(Player p : listRegisteredPlayers()) {
if(!p.isBot()) {
p.getPackets().sendPlayers();
}
}
respawnAI();
return;
case "hard":
for (int i =0; i < playerListSize * 2 ; i++) {
Expand All @@ -1846,18 +1850,7 @@ public void spawnAI() {
createBot(NPC_Type.TYPE2, randomBotName(), 2, getBotTeam(), null, getBotFace(), 0.0f);
createBot(NPC_Type.TYPE3, randomBotName(), 8, getBotTeam(), null, getBotFace(), 0.0f);
createBot(NPC_Type.TYPE3, randomBotName(), 8, getBotTeam(), null, getBotFace(), 0.0f);
for(Player p : listBots()) {
if(listRegisteredPlayers().get(0).getTeam() == Team.ATTACKER) {
p.respawnOnLandside(true);
}else {
p.respawnOnLandside(false);
}
}
for(Player p : listRegisteredPlayers()) {
if(!p.isBot()) {
p.getPackets().sendPlayers();
}
}
respawnAI();
return;
default:
return;
Expand Down Expand Up @@ -1924,7 +1917,8 @@ public void setTeam(Player pl, int value) {
Team afterTeam = pl.getTeam();
sendTeamInfo();
if(beforeTeam != afterTeam) {
spawnAI();
respawnAI();
sendTeamInfo();
}
}

Expand Down Expand Up @@ -2185,4 +2179,8 @@ else if (message.startsWith("/bug")) {
}
}
}

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

import com.benberi.cadesim.server.ServerContext;
import com.benberi.cadesim.server.model.player.Player;
import com.benberi.cadesim.server.model.player.ai.util.NPC_Type;
import com.benberi.cadesim.server.model.player.move.MoveType;

import io.netty.channel.Channel;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.benberi.cadesim.server.model.player;
package com.benberi.cadesim.server.model.player.ai;

import com.benberi.cadesim.server.ServerContext;
import com.benberi.cadesim.server.model.player.Player;
import com.benberi.cadesim.server.model.player.ai.util.NPC_Type;
import com.benberi.cadesim.server.model.player.move.MoveType;

import io.netty.channel.Channel;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.benberi.cadesim.server.model.player;
package com.benberi.cadesim.server.model.player.ai;

import com.benberi.cadesim.server.ServerContext;
import com.benberi.cadesim.server.model.player.Player;
import com.benberi.cadesim.server.model.player.ai.util.NPC_Type;
import com.benberi.cadesim.server.model.player.move.MoveType;

import io.netty.channel.Channel;
Expand Down
119 changes: 119 additions & 0 deletions server/src/com/benberi/cadesim/server/model/player/ai/NPC_Type4.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
package com.benberi.cadesim.server.model.player.ai;

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.ai.util.AStarNode;
import com.benberi.cadesim.server.model.player.ai.util.NPC_Type;
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;

import io.netty.channel.Channel;

/*
* AI Logic - chaser type (goes after player)
* Priority - shooting, flag points
*/
public class NPC_Type4 extends Player {
@SuppressWarnings("unused")
private ServerContext context;
private List<AStarNode> path = null;

public NPC_Type4(ServerContext ctx, Channel c) {
super(ctx,c);
context = ctx;
super.setBot(true);
super.set(-1, -1); // not spawned
super.setType(NPC_Type.TYPE4);
}

@Override
public void calculateRoute() {
Position destination = new Position(3,3); // replace with cluster
if(this.equals(destination)) {
return;
}
path = context.getPlayerManager().getAlgorithm().findPath(this, destination);
VesselFace face = getFace();
if(path != null) {
if(path.size() > 0) {
int numberOfMoves = getVessel().has3Moves() ? 3 : 4;
Position currentPosition = this.copy();
for(int slot = 0; slot <= numberOfMoves; slot++) { //moves to enter
int positionIndex = (path.size() - 1) - (slot); //subtract slot to allow multiple moves
if(positionIndex < 0 || path.size() < slot) { // make sure it doesn't count too far
return;
}
Position pos = path.get(positionIndex).position;
Position left = MoveType.LEFT.getFinalPosition(currentPosition, face);
Position right = MoveType.RIGHT.getFinalPosition(currentPosition, face);
Position forward = MoveType.FORWARD.getFinalPosition(currentPosition, face);
if(left.equals(pos)) {
currentPosition.add(left.getX() - getX(), left.getY() - getY());
getMoves().setMove(slot, MoveType.LEFT);
switch(face) {
case NORTH:
face = VesselFace.WEST;
break;
case SOUTH:
face = VesselFace.EAST;
break;
case WEST:
face = VesselFace.SOUTH;
break;
case EAST:
face = VesselFace.NORTH;
break;
}
}else if(right.equals(pos)) {
currentPosition.add(right.getX() - getX(), right.getY() - getY());
getMoves().setMove(slot, MoveType.RIGHT);
switch(face) {
case NORTH:
face = VesselFace.EAST;
break;
case SOUTH:
face = VesselFace.WEST;
break;
case WEST:
face = VesselFace.NORTH;
break;
case EAST:
face = VesselFace.SOUTH;
break;
}
}else if(forward.equals(pos)){
currentPosition.add(forward.getX() - getX(), forward.getY() - getY());
getMoves().setMove(slot, MoveType.FORWARD);
switch(face) {
case NORTH:
face = VesselFace.NORTH;
break;
case SOUTH:
face = VesselFace.SOUTH;
break;
case WEST:
face = VesselFace.WEST;
break;
case EAST:
face = VesselFace.EAST;
break;
}
}
}
}
}
}

@Override
public void performLogic() {
calculateRoute();
}

@Override
public NPC_Type getType() {
return type;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.benberi.cadesim.server.model.player.ai.util;

import com.benberi.cadesim.server.model.player.vessel.VesselFace;
import com.benberi.cadesim.server.util.Position;

public class AStarNode {

public Position position;
public VesselFace face;
public AStarNode parent;
public double fCost, gCost, hCost;

public AStarNode(Position position, AStarNode parent, double gCost, double hCost) {
this.position = position;
this.parent = parent;
this.gCost = gCost;
this.hCost = hCost;
this.fCost = this.gCost + this.hCost;
}

}
Loading

0 comments on commit 2bce840

Please sign in to comment.