Skip to content

Instantly share code, notes, and snippets.

@Jumplion
Last active May 10, 2017 19:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Jumplion/d7f361ffe35e2b1940b452b47fce8dfb to your computer and use it in GitHub Desktop.
Save Jumplion/d7f361ffe35e2b1940b452b47fce8dfb to your computer and use it in GitHub Desktop.
AI Project Agent code.
/*
* Tomer Braff
* May 10, 2017
* txb130030Agent
*
* This is the code for my own Agent for an AI class project.
* An applet runs that displays an NxN sized arena where two teams, Red and Green, are placed
* on opposite sides of eachother. Each team has a team base and a team flag on the far left/right
* sides of the arena. Agents can only do certain actions: Move North, South, East, West, Place a Bomb, or do Nothing.
* The agents must interface with code that was provided to me in the class. All the code in this file
* was created with those limitations, which were the following:
*
* LIMITATIONS
*
* Agents can only see what is directly north, south, east, and west of their current position.
* AgentEnvironment provided functions to see what is directly north/south/east/west (NSEW) of the agent's
* current position, as well as if an enemy/base/friend/etc... was in the general NSEW direction.
* AgentAction is a class that provides the integer representations of certain actions an Agent can take
* As limited by the environment, an Agent can only do one of these moves: Move NSEW, Plant a Bomb, or do nothing
* Agents do not know their locations and cannot access the arena except by AgentEnvironment functions.
*
* Because of these limitations and more, I had to create several methods of having the Agents know where they are
* in the map, whether they've respawned, what general direction they should go in, etc...
*
* Comments in the code should provide insight as to what I needed to create for the Agents and how it is used.
*
* The main portion of code is that to figure out which direction to go in next. As the Agent moves around
* the environment they build up a 10x10 map and take note of which nodes are obstacles, enemies, etc...
* Then the Agent takes their current position and uses the A* search algorithm to find a path to the enemy or
* team base (depending on if they have the flag or not) and they go in that direction.
*
*
*/
package ctf.agent;
import java.util.*;
import ctf.common.*;
// Enum of the various types of obstacles that can occur in the environment.
// The Nodes on the map the agents use all indicate what type of Node they are
enum ObsType
{
Null(-1), None(0), Obstacle(1), Friend(2), Foe(3), TeamFlag(4), EnemFlag(5), TeamBase(6), EnemBase(7);
private int value;
private ObsType(int val){
this.value = val;
}
}
// A Wrapper Key Object
// Source:
// https://stackoverflow.com/questions/14677993/how-to-create-a-hashmap-with-two-keys-key-pair-value
// For the HashMap that contains X and Y coordinates since HashMaps can't contain two keys for a value.
// This way I can just do Map<Key, Node> and to get a specific value I do map.get(new Key(x,y)) instead
// of doing a roundabout, convoluted way of, say, having a Map with they Key being the X coordinate
// and a value of another Map has a Key being the Y value with a value of the environment state.
// ( Map<int xCoordinate, Map<int yCoordinate>> )
class Key
{
private final int x;
private final int y;
public Key(int x, int y) {
this.x = x;
this.y = y;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Key)) return false;
Key key = (Key) o;
return x == key.x && y == key.y;
}
@Override
public int hashCode() {
int result = x;
result = 31 * result + y;
return result;
}
}
// Class that populates the map
//
class Node
{
public double value = -1; // Heuristic value for nodes in A* search
public Node prevNode = null; // Used to keep track of the path back to the root node when searching
public ObsType type = ObsType.Null; // The type of obstacle this node is (none, obstacle, team base, etc...)
public int xCoord = -10000; // X Coordinate of the Node in the map
public int yCoord = -10000; // Y Coordinate of the Node in the map
// Constructors
Node()
{
type = ObsType.Null;
}
Node(ObsType t, int x, int y)
{
type = t;
SetXY(x,y);
}
Node(ObsType t, int x, int y, double val)
{
type = t;
SetXY(x,y);
value = val;
}
// Sets the X and Y coordinates
public void SetXY(int x, int y)
{
xCoord = x;
yCoord = y;
}
// Compares the X,Y coordinate values of this node to the pass node
public boolean CompareXY(Node n)
{
return (xCoord == n.xCoord && yCoord == n.yCoord);
}
// Creates a string representation of the X and Y coordinates
public String XY()
{
return "X: " + xCoord + ", Y: " + yCoord;
}
// Returns a Key object created from the Node's X,Y coordinates
public Key getKey()
{
return new Key(xCoord, yCoord);
}
// Gets the Node that is North/South/East/West from the this Node
// NSEW goes - 0:North, 1:South, 2:East, 3:West
// Possibly could be easier with an enum for NSEW?
public Key GetNSEWKey(int NSEW)
{
switch(NSEW){
case 0:
return new Key(xCoord, yCoord+1);
case 1:
return new Key(xCoord, yCoord-1);
case 2:
return new Key(xCoord+1, yCoord);
case 3:
return new Key(xCoord-1, yCoord);
}
return new Key(xCoord, yCoord+1);
}
// Distance formulas to certain nodes, mostly used to determine value heuristic
public double Distance(Node other)
{
return Math.sqrt(Math.pow(other.xCoord - xCoord, 2) - Math.pow(other.yCoord - yCoord, 2));
}
public double Distance(int x, int y)
{
return Math.sqrt(Math.pow(x - xCoord, 2) - Math.pow(y - yCoord, 2));
}
}
// Main Agent code
public class txb130030Agent extends Agent
{
// A static HashMap that all txb130030Agent's have access to
// This map contains Nodes with a Key (from the Key class) as a key value (new Key(x,y)).
// The map is updated continually as Agents traverse the environment, making note of which
// nodes are obstacles and which nodes aren't.
public static Map<Key, Node> map = new HashMap<Key, Node>();
// The X and Y positions the Agent is currently in
int xPos = 0, yPos = 0;
// The Nodes that contain the Enemy/Team bases respectively
public static Node enemyBase = null, teamBase = null;
// The current node the Agent is on as well as the initial node they spawned at
Node currentNode = null, spawnNode = null;
// If the Agent first spawned at the top left/right or bottom left/right corner of the arena
public boolean botLeftAgent = false, botRightAgent = false, topLeftAgent = false, topRightAgent = false;
// Obstacle Types of NSEW, as well as if the team/enemy bases are NSEW of the Agent
ObsType nType, sType, eType, wType;
boolean nBase, sBase, eBase, wBase;
boolean nBaseEnem, sBaseEnem, eBaseEnem, wBaseEnem;
public int ID = 0;
public static int numAgents = 0;
// Couldn't use constructors like I wanted to, had to use a boolean flag to indicate if the Agent was created yet
public boolean initialized = false;
public static List<Agent> agents = new ArrayList<Agent>();
public boolean IsDefender()
{
return ID == 0;
}
// Couldn't use a constructor for the project, so I used a boolean to switch off when initialized
public void Initialize()
{
initialized = true;
ID = numAgents;
numAgents++;
// Determines if an agent will go for the enemy flag or "defend" the team base
if(numAgents % 2 != 0)
map.clear();
agents.add(this);
// Initialize a 10x10 map
if(map.isEmpty())
for(int x=-1; x<=10; x++)
for(int y=-1; y<=10; y++)
{
// Border obstacle
if(x == -1 || x == 10 || y == -1 || y == 10)
map.put(new Key(x,y), new Node(ObsType.Obstacle, x, y));
else
map.put(new Key(x,y), new Node(ObsType.None, x, y));
}
// If this Agent started in the bottom/top corner on the left/right side
// This is done by seeing if the enemy base is either North or South of the agent, and either East or West of the agent
if(nBaseEnem && wBaseEnem)
{
botRightAgent = true;
currentNode = spawnNode = map.get(new Key(9,0));
xPos = 9;
yPos = 0;
map.get(new Key(9,4)).type = ObsType.TeamBase;
map.get(new Key(0,4)).type = ObsType.EnemBase;
teamBase = map.get(new Key(9,4));
enemyBase = map.get(new Key(0,4));
}
else if(sBaseEnem && wBaseEnem)
{
topRightAgent = true;
currentNode = spawnNode = map.get(new Key(9,9));
xPos = 9;
yPos = 9;
map.get(new Key(9,4)).type = ObsType.TeamBase;
map.get(new Key(0,4)).type = ObsType.EnemBase;
teamBase = map.get(new Key(9,4));
enemyBase = map.get(new Key(0,4));
}
else if(nBaseEnem && eBaseEnem)
{
botLeftAgent = true;
currentNode = spawnNode = map.get(new Key(0,0));
xPos = 0;
yPos = 0;
map.get(new Key(0,4)).type = ObsType.TeamBase;
map.get(new Key(9,4)).type = ObsType.EnemBase;
teamBase = map.get(new Key(0,4));
enemyBase = map.get(new Key(9,4));
}
else
{
topLeftAgent = true;
currentNode = spawnNode = map.get(new Key(0,9));
xPos = 0;
yPos = 9;
map.get(new Key(0,4)).type = ObsType.TeamBase;
map.get(new Key(9,4)).type = ObsType.EnemBase;
teamBase = map.get(new Key(0,4));
enemyBase = map.get(new Key(9,4));
}
// Create heuristic values for the nodes
for(int x=0; x<9; x++)
for(int y=0; y<9; y++)
map.get(new Key(x,y)).value = enemyBase.Distance(map.get(new Key(x,y)));
}
// Check if the Agent has respawned to its original location
// This is needed because if an Agent contacts an enemy they are repositioned, not reinstantiated.
// Therefore, the Agent needs to check if it is in the same state as it's original spawning position
public void CheckIfRespawned()
{
// If the base is directly north/south of the agent
// Reset the currentNode to be the agent's spawn node
// Each statement asks if the agent is a top right/left or bottom right/left agent.
// Then it checks if the situation now is the same as if it had spawned.
// For example, if the Agent initially spawned at the bottom right corner, then we
// need to check if the enemy base is NorthEast of the Agent, AND we need the team
// base to be DIRECTLY North of the agent and NEITHER East or West of the Agent.
// We also check if the Southern Node is an obstacle as that determines if it is a corner.
// (No obstacles can be on the far east/west sides of the arena, and when we initialized the map
// we made the outside borders impenetrable obstacles)
// If all of that is true, then the Agent has respawned, so let's do what we need to do.
if(botRightAgent && nBaseEnem && wBaseEnem && nBase && !wBase && !eBase && sType == ObsType.Obstacle)
{
currentNode = map.get(spawnNode.getKey());
xPos = spawnNode.xCoord;
yPos = spawnNode.yCoord;
}
else if(topRightAgent && sBaseEnem && wBaseEnem && sBase && !wBase && !eBase && nType == ObsType.Obstacle)
{
currentNode = map.get(spawnNode.getKey());
xPos = spawnNode.xCoord;
yPos = spawnNode.yCoord;
}
else if(botLeftAgent && nBaseEnem && eBaseEnem && nBase && !wBase && !eBase && sType == ObsType.Obstacle)
{
currentNode = map.get(spawnNode.getKey());
xPos = spawnNode.xCoord;
yPos = spawnNode.yCoord;
}
else if(topLeftAgent && sBaseEnem && eBaseEnem && nBase && !wBase && !eBase && nType == ObsType.Obstacle)
{
currentNode = map.get(spawnNode.getKey());
xPos = spawnNode.xCoord;
yPos = spawnNode.yCoord;
}
}
public int getMove(AgentEnvironment env)
{
// Clamp the X and Y positions of the Agent
if(xPos > 9)
xPos = 9;
if(xPos < 0)
xPos = 0;
if(yPos > 9)
yPos = 9;
if(yPos < 0)
yPos = 0;
// Check the obstacle types of the NSEW nodes
nType = CheckType(env, 0);
sType = CheckType(env, 1);
eType = CheckType(env, 2);
wType = CheckType(env, 3);
// Check if the team base is in the general NSEW direction of the Agent
nBase = env.isBaseNorth(AgentEnvironment.OUR_TEAM, false);
sBase = env.isBaseSouth(AgentEnvironment.OUR_TEAM, false);
eBase = env.isBaseEast(AgentEnvironment.OUR_TEAM, false);
wBase = env.isBaseWest(AgentEnvironment.OUR_TEAM, false);
// Check if the Enemy base is in the general NSEW direction of the Agent
nBaseEnem = env.isBaseNorth(AgentEnvironment.ENEMY_TEAM, false);
sBaseEnem = env.isBaseSouth(AgentEnvironment.ENEMY_TEAM, false);
eBaseEnem = env.isBaseEast(AgentEnvironment.ENEMY_TEAM, false);
wBaseEnem = env.isBaseWest(AgentEnvironment.ENEMY_TEAM, false);
// Initialize the Agent if they haven't been already.
if(!initialized)
Initialize();
// Check if the agent has respawned
if(!env.hasFlag())
CheckIfRespawned();
// Checks if the team/enemy flag (depending on the situation) is directly NSEW of the Agent
// This is so we don't go through all the searching just for a simple direction
int foundFlagDir = UpdateCurrentNode(nType, sType, eType, wType, env.hasFlag());
// Is this agent a "defender"? If not, just do the normal algorithm
if(IsDefender())
{
// If the enemy team has our flag, go towards the enemy base
// Otherwise, just go to the team base
if(env.hasFlag(AgentEnvironment.ENEMY_TEAM))
return GetNextAction(currentNode, enemyBase);
else
return GetNextAction(currentNode, teamBase);
}
else
{
// If the agent doesn't have the flag, go towards the predicted enemy base
if( !env.hasFlag() )
{
// If we had found the flag earlier, move up to that flag
if(foundFlagDir > -1)
{
switch(foundFlagDir){
case AgentAction.MOVE_NORTH:
xPos++;
break;
case AgentAction.MOVE_SOUTH:
xPos--;
break;
case AgentAction.MOVE_EAST:
yPos++;
break;
case AgentAction.MOVE_WEST:
yPos--;
break;
}
return foundFlagDir;
}
else
return GetNextAction(currentNode, enemyBase);
}
else
return GetNextAction(currentNode, teamBase);
}
}
// A* Search
// Will start at the root, search through the nodes for a potential path to the goal
// Once it gets a path, returns the action that will take it to the next node on that path
private int GetNextAction(Node root, Node goal)
{
// Keep track of the nodes we've already been to
List<Key> expanded = new ArrayList<Key>();
Queue<Node> Q = new LinkedList<Node>();
root.prevNode = null;
Q.add(root);
// So long as the Queue is not empty, keep searching
while (!Q.isEmpty())
{
// Take the next node in the queue
Node n = Q.peek();
Q.remove();
// Have we reached the goal? Let's go the direction the next node wants us to go in
if (n.CompareXY(goal))
return ReturnAction(root, n);
// Otherwise, have we already visited this node? Don't bother if we have
if(!expanded.contains(n.getKey()))
{
expanded.add(n.getKey());
List<Node> children = new ArrayList<Node>();
// Go through NSEW children nodes. If a node is null, an obstacle, or an Enemy, don't add to the list.
Node nNode = map.get(n.GetNSEWKey(0));
Node sNode = map.get(n.GetNSEWKey(1));
Node eNode = map.get(n.GetNSEWKey(2));
Node wNode = map.get(n.GetNSEWKey(3));
if(nNode != null && !expanded.contains(nNode.getKey()) && nNode.type != ObsType.Obstacle && nNode.type != ObsType.Foe)
{
nNode.prevNode = n;
children.add(nNode);
}
if(sNode != null && !expanded.contains(sNode.getKey()) && sNode.type != ObsType.Obstacle && sNode.type != ObsType.Foe)
{
sNode.prevNode = n;
children.add(sNode);
}
if(eNode != null && !expanded.contains(eNode.getKey()) && eNode.type != ObsType.Obstacle && eNode.type != ObsType.Foe)
{
eNode.prevNode = n;
children.add(eNode);
}
if(wNode != null && !expanded.contains(wNode.getKey()) && wNode.type != ObsType.Obstacle && wNode.type != ObsType.Foe)
{
wNode.prevNode = n;
children.add(wNode);
}
//children = SortChildren(children, team);
// Add the children to the queue if there are any
for (int i = 0; i < children.size(); i++)
Q.add(children.get(i));
}
}
// If we went through all of that and somehow didn't find a path, then something is wrong with the map
// An agent probably listed a node as an obstacle by mistake, blocking off half of the map
// Let's clear the map and reinitialize it. Not the most ideal way, but it works
map.clear();
for(int x=-1; x<=10; x++)
for(int y=-1; y<=10; y++)
{
// Border obstacle
if(x == -1 || x == 10 || y == -1 || y == 10)
map.put(new Key(x,y), new Node(ObsType.Obstacle, x, y));
else
map.put(new Key(x,y), new Node(ObsType.None, x, y));
}
return -1;
}
// Return the integer value of the next action we should take
public int ReturnAction(Node root, Node n)
{
Node checkNode = n;
// Go up the node's prevNode values until it hits the root node.
// This will let us see what the next direction should be
while (checkNode.prevNode != null)
{
if(checkNode.prevNode.CompareXY(root))
break;
checkNode = checkNode.prevNode;
}
int action = 0;
// Check this next node with the root's NSEW nodes and see which direction it should go.
// Probably could be done so that the nodes keep track of which direction the prevNode came from.
if(map.get(root.GetNSEWKey(0)) == map.get(checkNode.getKey()))
{
yPos++;
action = AgentAction.MOVE_NORTH;
}
else if(map.get(root.GetNSEWKey(1)) == map.get(checkNode.getKey()))
{
yPos--;
action = AgentAction.MOVE_SOUTH;
}
else if(map.get(root.GetNSEWKey(2)) == map.get(checkNode.getKey()))
{
xPos++;
action = AgentAction.MOVE_EAST;
}
else if(map.get(root.GetNSEWKey(3)) == map.get(checkNode.getKey()))
{
xPos--;
action = AgentAction.MOVE_WEST;
}
else
action = AgentAction.DO_NOTHING;
return action;
}
// Sorts the nodes from least to greaatest depending on the passed boolean
public List<Node> SortChildren(List<Node> l, boolean asc)
{
List<Node> list = l;
Node min;
for (int x=0; x < list.size(); x++)
{
min = list.get(x);
int loc = x;
for (int k = x + 1; k < list.size(); k++)
{
if (asc && min.value > list.get(k).value)
{
min = list.get(k);
loc = k;
}
else if (!asc && min.value < list.get(k).value)
{
min = list.get(k);
loc = k;
}
}
Node temp, temp2;
temp = list.get(x);
temp2 = list.get(loc);
list.remove(x);
list.add(x, temp2);
list.remove(loc);
list.add(loc, temp);
}
return list;
}
// Updates the current node the Agent is on.
// Updates the NSEW nodes of the current node the Agent is on.
private int UpdateCurrentNode(ObsType n, ObsType s, ObsType e, ObsType w, boolean hasFlag)
{
currentNode = map.get(new Key(xPos, yPos));
Node nNode = map.get(new Key(xPos, yPos+1));
Node sNode = map.get(new Key(xPos, yPos-1));
Node eNode = map.get(new Key(xPos+1, yPos));
Node wNode = map.get(new Key(xPos-1, yPos));
// We check if the retrieved node is null just in case.
// Otherwise, we update the node type UNLESS it is an Obstacle (there can't magically be no obstacle anymore)
if(nNode == null)
nNode = new Node(n, xPos, yPos+1, enemyBase.Distance(xPos, yPos+1));
else if(nNode.type != ObsType.Obstacle)
nNode.type = n;
if(sNode == null)
sNode = new Node(s, xPos, yPos-1, enemyBase.Distance(xPos, yPos-1));
else if(sNode.type != ObsType.Obstacle)
sNode.type = s;
if(eNode == null)
eNode = new Node(e, xPos+1, yPos, enemyBase.Distance(xPos+1, yPos));
else if(eNode.type != ObsType.Obstacle)
eNode.type = e;
if(wNode == null)
wNode = new Node(w, xPos-1, yPos, enemyBase.Distance(xPos-1, yPos));
else if(wNode.type != ObsType.Obstacle)
wNode.type = w;
// Put the
map.put(currentNode.getKey(), currentNode);
map.put(nNode.getKey(), nNode);
map.put(sNode.getKey(), sNode);
map.put(eNode.getKey(), eNode);
map.put(wNode.getKey(), wNode);
// This is to check if any of the NSEW nodes that we just updated are actually the
// enemy or team bases. Used to bypass searaching if we can just go immediately to the flag
// Should probably decouple this from the function, but it works for now.
if(!hasFlag)
{
if(nNode.type == ObsType.EnemFlag || nNode.type == ObsType.EnemBase)
return AgentAction.MOVE_NORTH;
if(sNode.type == ObsType.EnemFlag || sNode.type == ObsType.EnemBase)
return AgentAction.MOVE_SOUTH;
if(eNode.type == ObsType.EnemFlag || eNode.type == ObsType.EnemBase)
return AgentAction.MOVE_EAST;
if(wNode.type == ObsType.EnemFlag || wNode.type == ObsType.EnemBase)
return AgentAction.MOVE_WEST;
else
return -100;
}
// Otherwise, if we do have the flag, return if our own base is within reach
else
{
if(nNode.type == ObsType.TeamFlag || nNode.type == ObsType.TeamBase)
return AgentAction.MOVE_NORTH;
if(sNode.type == ObsType.TeamFlag || sNode.type == ObsType.TeamBase)
return AgentAction.MOVE_SOUTH;
if(eNode.type == ObsType.TeamFlag || eNode.type == ObsType.TeamBase)
return AgentAction.MOVE_EAST;
if(wNode.type == ObsType.TeamFlag || wNode.type == ObsType.TeamBase)
return AgentAction.MOVE_WEST;
else
return -100;
}
}
// Checks what type the NSEW node is from the current position using the AgentEnvironment
// NSEW tells us in what direction relative to the Agent the node we're checking is
// 0:N, 1:S, 2:E, 3:W
private ObsType CheckType(AgentEnvironment env, int NSEW)
{
if(checkAgentAdjacent(env, NSEW, false))
return ObsType.Friend;
if(checkAgentAdjacent(env, NSEW, true))
return ObsType.Foe;
if(checkFlagAdjacent(env, NSEW, false))
return ObsType.TeamFlag;
if(checkFlagAdjacent(env, NSEW, true))
return ObsType.EnemFlag;
if(checkBaseAdjacent(env, NSEW, false))
return ObsType.TeamBase;
if(checkBaseAdjacent(env, NSEW, true))
return ObsType.EnemBase;
if(checkObsAdjacent(env, NSEW))
return ObsType.Obstacle;
return ObsType.None;
}
// Checks if there is an Agent (either friend or enemy) adjacent to the current position
// NSEW tells us in what direction relative to the Agent the node we're checking is
// 0:N, 1:S, 2:E, 3:W
private boolean checkAgentAdjacent(AgentEnvironment e, int NSEW, boolean enemTeam)
{
if(enemTeam){
switch(NSEW){
case 0:
return e.isAgentNorth(AgentEnvironment.ENEMY_TEAM, true);
case 1:
return e.isAgentSouth(AgentEnvironment.ENEMY_TEAM, true);
case 2:
return e.isAgentEast(AgentEnvironment.ENEMY_TEAM, true);
case 3:
return e.isAgentWest(AgentEnvironment.ENEMY_TEAM, true);
}
}
else{
switch(NSEW){
case 0:
return e.isAgentNorth(AgentEnvironment.OUR_TEAM, true);
case 1:
return e.isAgentSouth(AgentEnvironment.OUR_TEAM, true);
case 2:
return e.isAgentEast(AgentEnvironment.OUR_TEAM, true);
case 3:
return e.isAgentWest(AgentEnvironment.OUR_TEAM, true);
}
}
return enemTeam;
}
// Checks if there is a Flag (enemy or team) adjacent to the Agent
// NSEW tells us in what direction relative to the Agent the node we're checking is
// 0:N, 1:S, 2:E, 3:W
private boolean checkFlagAdjacent(AgentEnvironment e, int NSEW, boolean enemTeam)
{
if(enemTeam){
switch(NSEW){
case 0:
return e.isFlagNorth(AgentEnvironment.ENEMY_TEAM, true);
case 1:
return e.isFlagSouth(AgentEnvironment.ENEMY_TEAM, true);
case 2:
return e.isFlagEast(AgentEnvironment.ENEMY_TEAM, true);
case 3:
return e.isFlagWest(AgentEnvironment.ENEMY_TEAM, true);
}
}
else{
switch(NSEW){
case 0:
return e.isFlagNorth(AgentEnvironment.OUR_TEAM, true);
case 1:
return e.isFlagSouth(AgentEnvironment.OUR_TEAM, true);
case 2:
return e.isFlagEast(AgentEnvironment.OUR_TEAM, true);
case 3:
return e.isFlagWest(AgentEnvironment.OUR_TEAM, true);
}
}
return false;
}
// Checks if there is an obstacle directly adjacent to the Agent
// NSEW tells us in what direction relative to the Agent the node we're checking is
// 0:N, 1:S, 2:E, 3:W
private boolean checkObsAdjacent(AgentEnvironment e, int NSEW)
{
switch(NSEW){
case 0:
return e.isObstacleNorthImmediate();
case 1:
return e.isObstacleSouthImmediate();
case 2:
return e.isObstacleEastImmediate();
case 3:
return e.isObstacleWestImmediate();
}
return false;
}
// Checks if there is a base (enemy or team) directly aadjacent to the agent
// NSEW tells us in what direction relative to the Agent the node we're checking is
// 0:N, 1:S, 2:E, 3:W
private boolean checkBaseAdjacent(AgentEnvironment e, int NSEW, boolean enemTeam)
{
if(enemTeam){
switch(NSEW){
case 0:
return e.isBaseNorth(AgentEnvironment.ENEMY_TEAM, true);
case 1:
return e.isBaseSouth(AgentEnvironment.ENEMY_TEAM, true);
case 2:
return e.isBaseEast(AgentEnvironment.ENEMY_TEAM, true);
case 3:
return e.isBaseWest(AgentEnvironment.ENEMY_TEAM, true);
}
}
else{
switch(NSEW){
case 0:
return e.isBaseNorth(AgentEnvironment.OUR_TEAM, true);
case 1:
return e.isBaseSouth(AgentEnvironment.OUR_TEAM, true);
case 2:
return e.isBaseEast(AgentEnvironment.OUR_TEAM, true);
case 3:
return e.isBaseWest(AgentEnvironment.OUR_TEAM, true);
}
}
return enemTeam;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment