Advertisement
Guest User

Untitled

a guest
Apr 19th, 2018
65
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 17.17 KB | None | 0 0
  1.  
  2.  
  3. package ctf.agent; import static java.lang.System.out; import ctf.common.AgentAction; import ctf.common.AgentEnvironment; import java.awt.Point; import java.util.ArrayList; import java.util.LinkedList; import java.util.Random; import java.util.Collections; public class srs140430Agent extends Agent {     Random rand = new Random();     final int unvisited = 0;     final int empty = 1;     final int obstacle = 2;     final int mybase = 3;     final int theirbase = 4;     final int bfsvisited = 5;     final int mine = 6;         class Board {   int size;   int[][] b;  Point mybasepoint;  Point theirbasepoint;   Board(int size, boolean left) {         this.size = size;       b = new int[size][size];        for (int i = 0; i < size; i++) {        b[0][i] = empty;        b[size - 1][i] = empty;         }       if (left) {         b[0][(size - 1) / 2] = mybase;      mybasepoint = new Point(0, (size - 1) / 2);         b[size - 1][(size - 1) / 2] = theirbase;        theirbasepoint = new Point(size - 1, (size - 1) / 2);       } else {        b[size - 1][(size - 1) / 2] = mybase;       mybasepoint = new Point(size - 1, (size - 1) / 2);      b[0][(size - 1) / 2] = theirbase;       theirbasepoint = new Point(0, (size - 1) / 2);      }   }   public boolean reachable(Point target, Point from){         return target == from || getPath(from, target).size() != 1;     }       public LinkedList<Point> getPath(Point from, Point to) {        int[][] visited = new int[size][size];      int[][] cum_cost = new int[size][size];         for (int i = 0; i < size; i++)      for (int j = 0; j < size; j++) cum_cost[i][j] = Integer.MAX_VALUE / 2;      for (int i = 0; i < size; i++) for (int j = 0; j < size; j++) visited[i][j] = b[i][j];      Point[][] pred = new Point[size][size];         LinkedList<Point> Q = new LinkedList<Point>();      visited[from.x][from.y] = bfsvisited;       cum_cost[from.x][from.y] = 0;       pred[from.x][from.y] = null;        Q.add(from);        while (!Q.isEmpty()) {      Point min_p = Q.peek();         int min_cost = cum_cost[min_p.x][min_p.y] + distance(min_p, to);        for (Point p : Q) {             int cost = cum_cost[p.x][p.y] + distance(p, to);            if (cost < min_cost) {          min_p = p;          min_cost = cost;            }       }       if (min_p.equals(to)) break;        Q.remove(min_p);        visited[min_p.x][min_p.y] = bfsvisited;         ArrayList<Point> neighbors = neighbors(min_p);      for (Point neighbor : neighbors) {          if (!Q.contains(neighbor) && visited[neighbor.x][neighbor.y] == empty) Q.add(neighbor);             int new_cost = cum_cost[min_p.x][min_p.y] + 1 + distance(min_p, to);            int old_cost = cum_cost[neighbor.x][neighbor.y] + distance(neighbor, to);           if (new_cost < old_cost) {          cum_cost[neighbor.x][neighbor.y] = cum_cost[min_p.x][min_p.y] + 1;          pred[neighbor.x][neighbor.y] = min_p;           }       }       }       LinkedList<Point> path = new LinkedList<>();        Point p = to;       while (p != null) {         path.push(p);       p = pred[p.x][p.y];         }       return path;    }   public int n_discovered(){      int n = 0;      for(int i = 0; i < size; i++)       for(int j = 0 ; j < size;j++)           if(b[i][j] != unvisited)            n+=1;       return n;   }       public int evalPoint(Point point, Point current, Point goal) {      //TODO: avoid unvisited nodes with lots of barriers around them         int dist_pg = distance(point, goal);        int dist_pc = getPath(current, point).size();       int pg_weight = Math.min(n_discovered()/size*size + 1/2, 1);                // count number of unvisited nodes near target node;        int unvisited_neighbors = 0;        int obstacles_nearby = 0;       int radius = 1;         int radius_obstacle = 2;        for (int i = -radius; i <= radius; i++) {       for (int j = -radius; j <= radius; j++) {           int neighborx = point.x + i;            int neighbory = point.y + j;            if (neighborx >= size || neighbory >= size) continue;           if (neighborx < 0 || neighbory < 0) continue;           if (b[neighborx][neighbory] == unvisited) unvisited_neighbors += 1;         }       }       for (int i = -radius_obstacle; i <= radius_obstacle; i++) {         for (int j = -radius_obstacle; j <= radius_obstacle; j++) {             int neighborx = point.x + i;            int neighbory = point.y + j;            if (neighborx >= size || neighbory >= size) continue;           if (neighborx < 0 || neighbory < 0) continue;           if (b[neighborx][neighbory] == obstacle) obstacles_nearby += 1;         }       }               return dist_pc + dist_pg/2 + obstacles_nearby;  }   public ArrayList<Point> getReachableUnvisited(Point from) {         int[][] visited = new int[size][size];      for (int i = 0; i < size; i++) for (int j = 0; j < size; j++) visited[i][j] = b[i][j];      LinkedList<Point> Q = new LinkedList<Point>();      ArrayList<Point> reachable = new ArrayList<Point>();        visited[from.x][from.y] = bfsvisited;       Q.add(from);        while (!Q.isEmpty()) {      Point p = Q.pop();      visited[p.x][p.y] = bfsvisited;         ArrayList<Point> neighbors = neighbors(p);      for (Point neighbor : neighbors) {          if (visited[neighbor.x][neighbor.y] == unvisited) {             reachable.add(neighbor);            visited[neighbor.x][neighbor.y] = bfsvisited;           }           if (visited[neighbor.x][neighbor.y] == empty && !Q.contains(neighbor)) Q.add(neighbor);         }       }       return reachable;   }   public ArrayList<Point> neighbors(Point p) {        int x = p.x;        int y = p.y;        ArrayList<Point> neighborz = new ArrayList<>();         if (x - 1 >= 0) neighborz.add(new Point(x - 1, y));         if (x + 1 < size) neighborz.add(new Point(x + 1, y));       if (y - 1 >= 0) neighborz.add(new Point(x, y - 1));         if (y + 1 < size) neighborz.add(new Point(x, y + 1));       return neighborz;   }   public String toString() {      StringBuilder s = new StringBuilder();      for (int i = size - 1; i >= 0; i--) {       for (int j = 0; j < size; j++) {            s.append(b[j][i]);          s.append(' ');      }       s.append('\n');         }       return s.toString();    }     }     static int distance(Point p1, Point p2) {   return Math.abs(p1.x - p2.x) + Math.abs(p1.y - p2.y);     }     static int n_agents = 0;     static Board board;     static int size = 0;     static boolean doneSizing = false;     static int turn = 0;     static srs140430Agent oddAgent;     static srs140430Agent evenAgent;     boolean topAgent, bottomAgent;     boolean leftTeam, rightTeam;     boolean determineSize = false;     boolean newGame = true;     int id;     Point coord;     Point prev;     Point goal;     LinkedList<Point> path;     LinkedList<Boolean> memory = new LinkedList<>();         public srs140430Agent() {   n_agents += 1;  id = n_agents;  board = null;   size = 2;   doneSizing = false;     turn = 0;   if (id % 2 == 0) evenAgent = this;  else oddAgent = this;     }     public int getMove(AgentEnvironment env) {  if (newGame) newGameSetup(env);     if (bottomAgent) turn += 1;     if(memory != null){         if (leftTeam)       memory.add(env.isObstacleEastImmediate());      if (rightTeam)      memory.add(env.isObstacleWestImmediate());  }   if (determineSize) return investigateSize(env);         if (coord == null) {        out.println("COORD IS NULL");       if (env.isBaseSouth(0, true)) coord = new Point(homeColumn(), (board.size - 1) / 2 + 1);        else coord = new Point(homeColumn(), (board.size - 1) / 2 - 1);     }   if(memory != null){         int x = coord.x;        if(leftTeam)        x += 1;         else        x -= 1;         if(topAgent){       for(int y = size - 1; y >= coord.y; y--){           if(memory.poll())           board.b[x][y] = obstacle;           else            board.b[x][y] = empty;      }       }       else{       for(int y = 0; y <= coord.y; y++){          if(memory.poll())           board.b[x][y] = obstacle;           else            board.b[x][y] = empty;      }           }       memory = null;  }       out.println("*************");   if (topAgent) {         out.println("Top Agent's Move:");   }   if (bottomAgent) {      out.println("Bottom Agent's Move:");    }   checkIfReset(env);  checkForObstacles(env);     int move = -1;  if(!env.hasFlag() && attackFlagBearer(env) != AgentAction.DO_NOTHING){      out.println("Attacking Flag");      move = attackFlagBearer(env);       prev = coord;       coord = newCoord(move);         return move;    }   if(topAgent && env.hasFlag(AgentEnvironment.ENEMY_TEAM)){       ArrayList<Point> neighbors = board.neighbors(coord);        int[][] eval = new int[board.size][board.size];         for(int i =0; i < board.size; i ++){        for(int j = 0; j < board.size; j++){            if(i > coord.x){            if(env.isFlagEast(AgentEnvironment.OUR_TEAM, false))               eval[i][j] += 5;             }           if(i < coord.x){            if(env.isFlagWest(AgentEnvironment.OUR_TEAM, false))               eval[i][j] += 5;             }           if(j > coord.y){            if(env.isFlagNorth(AgentEnvironment.OUR_TEAM, false))              eval[i][j] += 5;             }           if(j < coord.y){            if(env.isFlagSouth(AgentEnvironment.OUR_TEAM, false))              eval[i][j] += 5;             }           if(getOtherAgent().coord.x == i && getOtherAgent().coord.y == j)            eval[i][j] -= 500;      }       }       Collections.shuffle(neighbors);         Point best = null;      int val = -1;       for(Point p: neighbors){        if(eval[p.x][p.y] > val){           best = p;           val = eval[p.x][p.y];       }       }       move = actionFromPoints(coord, best);       prev = coord;       coord = newCoord(move);                 System.out.printf("PANIC, CURR = %s, TARGET = %s, %d\n", coord, best, val);                 return move;    }       move = computeNextMove(env);    if (isBlocked(move, env)){      move = rand.nextInt(4);         if (isBlocked(move, env))       move = rand.nextInt(4);     }           if (isBlocked(move, env))       move = AgentAction.DO_NOTHING;      prev = coord;   coord = newCoord(move);     return move;     }     int attackFlagBearer(AgentEnvironment env){  if(!env.hasFlag(AgentEnvironment.ENEMY_TEAM)){      return AgentAction.DO_NOTHING;  }       if(env.isFlagEast(AgentEnvironment.OUR_TEAM, true)){        out.println("ENEMY FLAGBEARER IS ADJACENT!");       return AgentAction.MOVE_EAST;   }   if(env.isFlagWest(AgentEnvironment.OUR_TEAM, true)){        out.println("ENEMY FLAGBEARER IS ADJACENT!");       return AgentAction.MOVE_WEST;   }   if(env.isFlagNorth(AgentEnvironment.OUR_TEAM, true)){       out.println("ENEMY FLAGBEARER IS ADJACENT!");       return AgentAction.MOVE_NORTH;  }   if(env.isFlagSouth(AgentEnvironment.OUR_TEAM, true)){       out.println("ENEMY FLAGBEARER IS ADJACENT!");       return AgentAction.MOVE_SOUTH;  }       return AgentAction.DO_NOTHING;     }         void setGoal(AgentEnvironment env){    if (bottomAgent && goal == null) goal = board.theirbasepoint;   if (topAgent && goal == null) goal = new Point(board.mybasepoint.x, board.mybasepoint.y - 1);   if (env.hasFlag()){         goal = board.mybasepoint;       path = null;    }   if(goal == board.mybasepoint && !env.hasFlag()){        goal = board.theirbasepoint;        path = null;    }   if(topAgent && goal.equals(coord)){         int ydiff = board.mybasepoint.y - coord.y;      goal = new Point(board.mybasepoint.x, board.mybasepoint.y + ydiff);     }     }     int computeNextMove(AgentEnvironment env) {     setGoal(env);   if(path != null){       Point target = path.peekLast();           if(board.b[target.x][target.y] != unvisited){         out.println("TARGET IS ALREAD VISITED");        path = null;        }       else if (coord.equals(path.peek())) {       out.println("FOLLOWING PATH");      path.pop();         if(!path.isEmpty())             return actionFromPoints(coord, path.peek());        else            path = null;        }       else        path = null;    }   //recompute path    if (path == null) {         out.println("COMPUTING PATH TO NEW TARGET");        int min_cost = Integer.MAX_VALUE;       Point target = null;        if(!board.reachable(goal, coord)){      for (Point p : board.getReachableUnvisited(coord)) {            if (board.evalPoint(p, coord, goal) < min_cost){ target = p;            min_cost = board.evalPoint(p, coord, goal);             }       }       }       else{       out.println("GOAL IS REACHABLE");       if(topAgent)            target = goal;      else if(!env.hasFlag()){            if(rand.nextDouble() < 0.25){           for (Point p : board.getReachableUnvisited(coord)) {                if (board.evalPoint(p, coord, goal) < min_cost){ target = p;                min_cost = board.evalPoint(p, coord, goal);                 }           }           }else{          target = goal;          }               }       else{           target = goal;      }       }       out.printf("NEW TARGET: %s%n",target);      path = board.getPath(coord, target);    }   out.printf("%s %s%n", coord, path);     if(topAgent){       if(env.isAgentNorth(AgentEnvironment.ENEMY_TEAM, true))         return AgentAction.MOVE_NORTH;      if(env.isAgentSouth(AgentEnvironment.ENEMY_TEAM, true))         return AgentAction.MOVE_SOUTH;      if(env.isAgentWest(AgentEnvironment.ENEMY_TEAM, true))      return AgentAction.MOVE_WEST;       if(env.isAgentEast(AgentEnvironment.ENEMY_TEAM, true))      return AgentAction.MOVE_EAST;   }       if(path.isEmpty())      return AgentAction.DO_NOTHING;      if (coord.equals(path.peek())) {        out.println("FOLLOWING PATH");      path.pop();         if(!path.isEmpty())         return actionFromPoints(coord, path.peek());        else        path = null;    }   out.println("RETURNING RANDOM");    return rand.nextInt(4);     }         int actionFromPoints(Point from, Point to) {  assert from != null;    assert to != null;  int diffx = to.x - from.x;  int diffy = to.y - from.y;  switch (diffx) {    case 1:         return AgentAction.MOVE_EAST;   case -1:        return AgentAction.MOVE_WEST;   }   switch (diffy) {    case 1:         return AgentAction.MOVE_NORTH;  case -1:        return AgentAction.MOVE_SOUTH;  }   return AgentAction.DO_NOTHING;     }     int xOffset(int move) {    switch (move) {     case AgentAction.MOVE_EAST:         return 1;   case AgentAction.MOVE_WEST:         return -1;  default:        return 0;   }     }     int yOffset(int move) {     switch (move) {     case AgentAction.MOVE_NORTH:        return 1;   case AgentAction.MOVE_SOUTH:        return -1;  default:        return 0;   }     }     Point newCoord(int move) {  return new Point(coord.x + xOffset(move), coord.y + yOffset(move));     }     boolean isBlocked(int move, AgentEnvironment env) {   if(move == AgentAction.DO_NOTHING)      return false;   srs140430Agent other = getOtherAgent();     assert other != this;   Point temp = newCoord(move);    if (temp.equals(other.coord)) return true;      switch (move) {     case AgentAction.MOVE_EAST:         if(env.hasFlag() && env.isAgentEast(AgentEnvironment.ENEMY_TEAM, true))         return true;        assert (temp.equals(other.coord)) == env.isAgentEast(AgentEnvironment.OUR_TEAM, true);      return env.isObstacleEastImmediate() || (env.isFlagEast(AgentEnvironment.OUR_TEAM, true) && !env.hasFlag());    case AgentAction.MOVE_WEST:         if(env.hasFlag() && env.isAgentWest(AgentEnvironment.ENEMY_TEAM, true))         return true;        assert (temp.equals(other.coord)) == env.isAgentWest(AgentEnvironment.OUR_TEAM, true);      return env.isObstacleWestImmediate() || (env.isFlagWest(AgentEnvironment.OUR_TEAM, true) && !env.hasFlag());    case AgentAction.MOVE_NORTH:        if(env.hasFlag() && env.isAgentNorth(AgentEnvironment.ENEMY_TEAM, true))        return true;        assert (temp.equals(other.coord)) == env.isAgentNorth(AgentEnvironment.OUR_TEAM, true);         return env.isObstacleNorthImmediate() || (env.isFlagNorth(AgentEnvironment.OUR_TEAM, true) && !env.hasFlag());  case AgentAction.MOVE_SOUTH:        if(env.hasFlag() && env.isAgentSouth(AgentEnvironment.ENEMY_TEAM, true))        return true;        assert (temp.equals(other.coord)) == env.isAgentSouth(AgentEnvironment.OUR_TEAM, true);         return env.isObstacleSouthImmediate() || (env.isFlagSouth(AgentEnvironment.OUR_TEAM, true) && !env.hasFlag());  case AgentAction.DO_NOTHING:        return false;   }   assert false;   return true;     }     void checkForObstacles(AgentEnvironment env) {   if (coord.x - 1 >= 0) {         boolean obst = env.isObstacleWestImmediate();       int val = obst ? obstacle : empty;      if (board.b[coord.x - 1][coord.y] == unvisited) board.b[coord.x - 1][coord.y] = val;    }   if (coord.x + 1 < size) {       boolean obst = env.isObstacleEastImmediate();       int val = obst ? obstacle : empty;      if (board.b[coord.x + 1][coord.y] == unvisited) board.b[coord.x + 1][coord.y] = val;    }   if (coord.y - 1 >= 0) {         boolean obst = env.isObstacleSouthImmediate();      int val = obst ? obstacle : empty;      if (board.b[coord.x][coord.y - 1] == unvisited) board.b[coord.x][coord.y - 1] = val;    }   if (coord.y + 1 < size) {       boolean obst = env.isObstacleNorthImmediate();      int val = obst ? obstacle : empty;      if (board.b[coord.x][coord.y + 1] == unvisited) board.b[coord.x][coord.y + 1] = val;    }     }     void checkIfReset(AgentEnvironment env) {   if (onHomeColumn(env)) {        if (topAgent && env.isObstacleNorthImmediate())         coord = new Point(homeColumn(), board.size - 1);        else if (bottomAgent && env.isObstacleSouthImmediate()) coord = new Point(homeColumn(), 0);     }     }     void newGameSetup(AgentEnvironment env) {   if (env.isObstacleSouthImmediate()) bottomAgent = true;     else topAgent = true;   leftTeam = env.isBaseEast(1, false);    rightTeam = !leftTeam;  newGame = false;    determineSize = true;     }     int investigateSize(AgentEnvironment env) {     if (topAgent && !env.isFlagSouth(0, true)) {        size += 1;      return AgentAction.MOVE_SOUTH;  }   if (bottomAgent && !env.isFlagNorth(0, true)) {         size += 1;      return AgentAction.MOVE_NORTH;  }   if (!doneSizing) {      doneSizing = true;      determineSize = false;      return AgentAction.DO_NOTHING;  }   determineSize = false;  size += 1;  board = new Board(size, leftTeam);  return AgentAction.DO_NOTHING;     }     boolean onHomeColumn(AgentEnvironment env) {   if (leftTeam) return !env.isBaseWest(0, false);     return !env.isBaseEast(0, false);     }     srs140430Agent getOtherAgent() {    if (id % 2 == 0) return oddAgent;   else return evenAgent;     }     int homeColumn() {     return leftTeam ? 0 : board.size - 1;     } }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement