From dd05a6bd3e9317a698ad653e4e27cd1857997fb5 Mon Sep 17 00:00:00 2001 From: androidmage Date: Tue, 19 Jan 2016 14:09:39 -0500 Subject: [PATCH 1/2] Added swarming Swarm stays stationary --- RobotPlayer.java | 140 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 96 insertions(+), 44 deletions(-) diff --git a/RobotPlayer.java b/RobotPlayer.java index f6f0efd..1accb3d 100644 --- a/RobotPlayer.java +++ b/RobotPlayer.java @@ -51,18 +51,6 @@ public static void run(RobotController r){ Scout s = new RobotPlayer().new Scout(); s.run(); } - else if(selftype == RobotType.GUARD) { - Guard s = new RobotPlayer().new Guard(); - s.run(); - } - else if(selftype == RobotType.SOLDIER) { - Soldier s = new RobotPlayer().new Soldier(); - s.run(); - } - else if(selftype == RobotType.VIPER){ - Viper s = new RobotPlayer().new Viper(); - s.run(); - } else if(selftype == RobotType.TURRET){ Turret s = new RobotPlayer().new Turret(); s.run(); @@ -71,6 +59,10 @@ else if(selftype == RobotType.TTM){ TTM s = new RobotPlayer().new TTM(); s.run(); } + else if(selftype == RobotType.GUARD || selftype == RobotType.SOLDIER || selftype == RobotType.VIPER){ + Swarmer s = new RobotPlayer().new Swarmer(); + s.run(); + } } /** @@ -404,6 +396,64 @@ public void run() { } } + public class Swarmer{ + public MapLocation target; + public boolean goToTarget; + + public Swarmer(){ + target = null; + goToTarget = false; + } + + public void run(){ + while(true) { + try { + // Use Guard AI (move out) until there are enough soldiers ammassed around, then go towards enemy archon and attack + Signal[] signals = rc.emptySignalQueue(); + if (signals.length > 0) { + for (Signal s : signals) { + // receive a message containing enemy archon ID + if (s.getTeam() == ourTeam) { + FancyMessage f = FancyMessage.getFromRecievedSignal(s); + if(f.type == 2){ + int xPos = f.ints.first; + int yPos = f.ints.second; + target = new MapLocation(xPos, yPos); + goToTarget = true; + } + if(f.type == 3){ + goToTarget = false; + } + } + } + } + if(rc.isCoreReady()){ + if(goToTarget && rc.getLocation().distanceSquaredTo(target) > 25){ + RESOURCE_FUNCTIONS.BUG(target); + } + else{ + Direction random = RESOURCE_FUNCTIONS.chooseRandomDirection(); + if(rc.canMove(random)){ + rc.move(random); + } + } + } + if(rc.isWeaponReady()){ + RESOURCE_FUNCTIONS.attackWeakestEnemy(); + if(rc.isWeaponReady()){ + Direction rubbleDirection = RESOURCE_FUNCTIONS.clearRubbleForPath(target); + if(rubbleDirection != null){ + rc.clearRubble(rubbleDirection); + } + } + } + Clock.yield(); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + } /** * class Archon * @@ -411,18 +461,22 @@ public void run() { * */ private class Archon{ - - public boolean production; - public RobotType decision; + public MapLocation target; + public boolean goToTarget; + public boolean alpha; + /** * Constructor * */ public Archon(){ zombieRounds = rc.getZombieSpawnSchedule().getRounds(); - decision = null; - production = true; + target = null; + goToTarget = false; + if(rc.getLocation().equals(rc.getInitialArchonLocations(ourTeam)[0])){ + alpha = true; + } } /** @@ -442,36 +496,42 @@ public void run(){ System.out.println("type is " + x.type); if(x.isMessage){ if(x.type == 2){ + int xPos = x.ints.first; + int yPos = x.ints.second; + target = new MapLocation(xPos, yPos); + goToTarget = true; mostRecentEnemyArchonLocations.add(new Triple(0,new MapLocation(x.ints.first - 16000,x.ints.second - 16000),rc.getRoundNum())); } if(x.type == 3){ - production = false; - } - if(x.type == 4){ - production = true; + goToTarget = false; } } } } //If it can, always tries to build Scouts. if(rc.isCoreReady()){ + if(alpha && rc.getRoundNum() % 10 == 0){ + FancyMessage.sendMessage(2, rc.getLocation().x, rc.getLocation().y, 6400); + } + else if(alpha && rc.getRoundNum() > 10 && (rc.getRoundNum() - 5) % 10 == 0 && rc.getLocation().equals(target)){ + FancyMessage.sendMessage(3, 0, 0, 1000); + } + if(!alpha){ + if(goToTarget && rc.getLocation().distanceSquaredTo(target) > 2){ + RESOURCE_FUNCTIONS.BUG(target); + } + } MapLocation neutral = RESOURCE_FUNCTIONS.findAdjacentNeutralRobot(); if(neutral != null){ rc.activate(neutral); } - if(rc.getRoundNum() % 100 == 0){ - FancyMessage.sendMessage(1, 1, 1, 3); - } - if(decision == null){ - decision = RESOURCE_FUNCTIONS.chooseRobotType(); - } - if(rc.isCoreReady() && production){ - if(RESOURCE_FUNCTIONS.tryBuild(decision)){ //See function in RESOURCE_FUNCTIONS to know what it does + RobotType type = RESOURCE_FUNCTIONS.chooseRobotType(); + if(rc.isCoreReady()){ + if(RESOURCE_FUNCTIONS.tryBuild(type)){ //See function in RESOURCE_FUNCTIONS to know what it does //After building scout, waits a turn, then signals it the location, so it has a good idea of where base is //Also signals the scout which type to become FancyMessage.sendMessage(4, 0, 0, 6400); Clock.yield(); - decision = null; Triple scoutType = getScoutInitType(); //Check if near zombie round if (mostRecentEnemyArchonLocations.size() != 0 && RESOURCE_FUNCTIONS.isCloseToZombieSpawnRound()) { @@ -479,11 +539,8 @@ public void run(){ } FancyMessage.sendMessage(0,scoutType.first | scoutType.second,scoutType.third,3); } - else{ - FancyMessage.sendMessage(3, 0, 0, 6400); - } + } - movement(); } Clock.yield(); }catch(Exception e){ @@ -934,7 +991,7 @@ public static boolean moveAsFarAwayAsPossibleFrom(MapLocation epicenter) throws public static RobotType chooseRobotType() { for(int i: zombieRounds){ int currentRound = rc.getRoundNum(); - if(i-currentRound<=40 && i-currentRound>=0){ + if(i-currentRound<=20 && i-currentRound>=0){ return RobotType.SCOUT; } } @@ -945,17 +1002,9 @@ public static RobotType chooseRobotType() { return RobotType.SCOUT; } int fate = randall.nextInt(10); - if(fate < 4){ + if(fate > 1){ return RobotType.SOLDIER; } - if(fate == 9){ - return RobotType.SCOUT; - } - if(fate == 8){ - if(!RESOURCE_FUNCTIONS.zombiesNearby()){ - return RobotType.VIPER; - } - } return RobotType.GUARD; } /** @@ -1317,6 +1366,9 @@ public static MapLocation seekNearestPart(){ } return closest; } + public static Direction chooseRandomDirection(){ + return DIRECTIONS[randall.nextInt(DIRECTIONS.length)]; + } } From 7921a53758f2838197d6ee57a88919f1a8b8520b Mon Sep 17 00:00:00 2001 From: androidmage Date: Wed, 20 Jan 2016 23:47:56 -0500 Subject: [PATCH 2/2] Add Jack's code --- RobotPlayer.java | 195 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 142 insertions(+), 53 deletions(-) diff --git a/RobotPlayer.java b/RobotPlayer.java index 1accb3d..7c596c6 100644 --- a/RobotPlayer.java +++ b/RobotPlayer.java @@ -397,60 +397,148 @@ public void run() { } public class Swarmer{ - public MapLocation target; - public boolean goToTarget; + public static final double SWARM_RATIO = 4.0 / 3; //ratio of all spaces to robots + public MapLocation coreLocation; //location of archon + public MapLocation target; //location of hostile target [zombiedens, enemyarchons] + public int moveType; //type of movement: 0==movement around friendly archon, 1==movement towards "stepping stone target", 2==movement towards hostile target + public int targetID; + public boolean locked = false; public Swarmer(){ + coreLocation = null; target = null; - goToTarget = false; + moveType = 0; } public void run(){ while(true) { try { - // Use Guard AI (move out) until there are enough soldiers ammassed around, then go towards enemy archon and attack Signal[] signals = rc.emptySignalQueue(); - if (signals.length > 0) { - for (Signal s : signals) { - // receive a message containing enemy archon ID - if (s.getTeam() == ourTeam) { - FancyMessage f = FancyMessage.getFromRecievedSignal(s); - if(f.type == 2){ - int xPos = f.ints.first; - int yPos = f.ints.second; - target = new MapLocation(xPos, yPos); - goToTarget = true; - } - if(f.type == 3){ - goToTarget = false; + for(int i = 0; i < signals.length; i++){ + if(signals[i].getTeam() == ourTeam){ + FancyMessage s = FancyMessage.getFromRecievedSignal(signals[i]); + if(s.isMessage){ + if(s.type == 0){ //Type 0: give our bots location of archon + coreLocation = s.senderLocation; + }else if(s.type == 1){ //Type 1: give our bots a "stepping stone" location + if(moveType == 0 && !locked){ //ignored if we already have a target, or if in locked mode + moveType = 1; + target = new MapLocation(s.ints.first,s.ints.second); + } + }else if(s.type == 2){ //Type 2: force robots back into regular swarming + locked = true; + moveType = 0; + }else if(s.type == 3){ //Type 3: if in forced swarming, brings back to regular behavior + locked = false; } } } } + if(moveType != 2 && rc.isWeaponReady()){ + RESOURCE_FUNCTIONS.attackWeakestEnemy(); + } if(rc.isCoreReady()){ - if(goToTarget && rc.getLocation().distanceSquaredTo(target) > 25){ - RESOURCE_FUNCTIONS.BUG(target); + if(moveType == 0 && coreLocation != null){ + int startDir = randall.nextInt(8); + int[] tryOrder = new int[]{0,1,-1,2,-2,3,-3,4}; + double swarmRadius = RESOURCE_FUNCTIONS.getGoodSwarmRadius(); + MapLocation current = rc.getLocation(); + boolean hasMoved = false; + int minInd = -1; + int minDistance = -1; + for(int i = 0; i < tryOrder.length && !hasMoved; i++){ + MapLocation moveTo = current.add(RESOURCE_FUNCTIONS.intToDir(startDir + tryOrder[i])); + int distance = moveTo.distanceSquaredTo(coreLocation); + if(distance > 2 && distance < (int)(swarmRadius + 1) && rc.canMove(current.directionTo(moveTo))){ + rc.move(current.directionTo(moveTo)); + hasMoved = true; + } + if(rc.canMove(RESOURCE_FUNCTIONS.intToDir(startDir + tryOrder[i]))){ + int newdist = current.add(RESOURCE_FUNCTIONS.intToDir(startDir + tryOrder[i])).distanceSquaredTo(coreLocation); + if(minInd == -1 || newdist < minDistance){ + minInd = i; + minDistance = newdist; + } + } + } + if(!hasMoved && minInd != -1){ + rc.move(RESOURCE_FUNCTIONS.intToDir(startDir + tryOrder[minInd])); + } + if(!locked){ + RobotInfo[] enemiesInSight = rc.senseHostileRobots(rc.getLocation(),rc.getType().sensorRadiusSquared); + for(int i = 0; i < enemiesInSight.length; i++){ + if(enemiesInSight[i].type == RobotType.ARCHON || enemiesInSight[i].type == RobotType.ZOMBIEDEN){ + target = enemiesInSight[i].location; + targetID = enemiesInSight[i].ID; + moveType = 2; + rc.broadcastSignal((int)(rc.getLocation().distanceSquaredTo(coreLocation) * 1.1)); + } + } + } } - else{ - Direction random = RESOURCE_FUNCTIONS.chooseRandomDirection(); - if(rc.canMove(random)){ - rc.move(random); + if(moveType == 1){ + int startDir = randall.nextInt(8); + int[] tryOrder = new int[]{0,1,-1,2,-2,3,-3,4}; + int minInd = -1; + int minDistance = -1; + MapLocation current = rc.getLocation(); + for(int i = 0; i < tryOrder.length; i++){ + if(rc.canMove(RESOURCE_FUNCTIONS.intToDir(startDir + tryOrder[i]))){ + int newdist = current.add(RESOURCE_FUNCTIONS.intToDir(startDir + tryOrder[i])).distanceSquaredTo(target); + if(minInd == -1 || newdist < minDistance){ + minInd = i; + minDistance = newdist; + } + } + } + if(minInd != -1){ + rc.move(RESOURCE_FUNCTIONS.intToDir(startDir + tryOrder[minInd])); + } + RobotInfo[] enemiesInSight = rc.senseHostileRobots(rc.getLocation(),rc.getType().sensorRadiusSquared); + for(int i = 0; i < enemiesInSight.length; i++){ + if(enemiesInSight[i].type == RobotType.ARCHON || enemiesInSight[i].type == RobotType.ZOMBIEDEN){ + target = enemiesInSight[i].location; + targetID = enemiesInSight[i].ID; + moveType = 2; + rc.broadcastSignal((int)(rc.getLocation().distanceSquaredTo(coreLocation) * 1.1)); + } } } - } - if(rc.isWeaponReady()){ - RESOURCE_FUNCTIONS.attackWeakestEnemy(); - if(rc.isWeaponReady()){ - Direction rubbleDirection = RESOURCE_FUNCTIONS.clearRubbleForPath(target); - if(rubbleDirection != null){ - rc.clearRubble(rubbleDirection); + if(moveType == 2){ + if(rc.canSenseRobot(targetID)){ + RobotInfo rr = rc.senseRobot(targetID); + target = rr.location; + if(rc.isWeaponReady() && rc.canAttackLocation(target)){ + rc.attackLocation(target); + } + }else{ + target = null; + targetID = -1; + moveType = 0; + } + int startDir = randall.nextInt(8); + int[] tryOrder = new int[]{0,1,-1,2,-2,3,-3,4}; + int minInd = -1; + int minDistance = -1; + MapLocation current = rc.getLocation(); + for(int i = 0; i < tryOrder.length && target != null; i++){ + if(rc.canMove(RESOURCE_FUNCTIONS.intToDir(startDir + tryOrder[i]))){ + int newdist = current.add(RESOURCE_FUNCTIONS.intToDir(startDir + tryOrder[i])).distanceSquaredTo(target); + if(minInd == -1 || newdist < minDistance){ + minInd = i; + minDistance = newdist; + } + } + } + if(minInd != -1 && rc.isCoreReady()){ + rc.move(RESOURCE_FUNCTIONS.intToDir(startDir + tryOrder[minInd])); } } } - Clock.yield(); } catch (Exception e) { e.printStackTrace(); } + Clock.yield(); } } } @@ -476,6 +564,9 @@ public Archon(){ goToTarget = false; if(rc.getLocation().equals(rc.getInitialArchonLocations(ourTeam)[0])){ alpha = true; + }else{ + target = rc.getInitialArchonLocations(ourTeam)[0]; + goToTarget = true; } } @@ -493,28 +584,16 @@ public void run(){ for(int i = 0; i < signals.length; i++){ if(signals[i].getTeam() == ourTeam){ FancyMessage x = FancyMessage.getFromRecievedSignal(signals[i]); - System.out.println("type is " + x.type); - if(x.isMessage){ - if(x.type == 2){ - int xPos = x.ints.first; - int yPos = x.ints.second; - target = new MapLocation(xPos, yPos); - goToTarget = true; - mostRecentEnemyArchonLocations.add(new Triple(0,new MapLocation(x.ints.first - 16000,x.ints.second - 16000),rc.getRoundNum())); - } - if(x.type == 3){ - goToTarget = false; - } + if(!x.isMessage){ + FancyMessage.sendMessage(1,x.senderLocation.x,x.senderLocation.y,(int)(RESOURCE_FUNCTIONS.getGoodSwarmRadius() * 1.1)); + break; } } } //If it can, always tries to build Scouts. if(rc.isCoreReady()){ if(alpha && rc.getRoundNum() % 10 == 0){ - FancyMessage.sendMessage(2, rc.getLocation().x, rc.getLocation().y, 6400); - } - else if(alpha && rc.getRoundNum() > 10 && (rc.getRoundNum() - 5) % 10 == 0 && rc.getLocation().equals(target)){ - FancyMessage.sendMessage(3, 0, 0, 1000); + FancyMessage.sendMessage(0,0,0,(int)(RESOURCE_FUNCTIONS.getGoodSwarmRadius() * 1.1)); } if(!alpha){ if(goToTarget && rc.getLocation().distanceSquaredTo(target) > 2){ @@ -530,14 +609,14 @@ else if(alpha && rc.getRoundNum() > 10 && (rc.getRoundNum() - 5) % 10 == 0 && rc if(RESOURCE_FUNCTIONS.tryBuild(type)){ //See function in RESOURCE_FUNCTIONS to know what it does //After building scout, waits a turn, then signals it the location, so it has a good idea of where base is //Also signals the scout which type to become - FancyMessage.sendMessage(4, 0, 0, 6400); - Clock.yield(); - Triple scoutType = getScoutInitType(); + //FancyMessage.sendMessage(4, 0, 0, 6400); + //Clock.yield(); + /*Triple scoutType = getScoutInitType(); //Check if near zombie round if (mostRecentEnemyArchonLocations.size() != 0 && RESOURCE_FUNCTIONS.isCloseToZombieSpawnRound()) { scoutType = getScoutHerdingType(); } - FancyMessage.sendMessage(0,scoutType.first | scoutType.second,scoutType.third,3); + FancyMessage.sendMessage(0,scoutType.first | scoutType.second,scoutType.third,3);*/ } } @@ -780,6 +859,15 @@ public boolean wiggle(MapLocation target) throws GameActionException{ */ public static class RESOURCE_FUNCTIONS{ + public static double getGoodSwarmRadius(){ + int numRobots = rc.getRobotCount(); + double radius = Math.sqrt((Swarmer.SWARM_RATIO * numRobots) / (2 * Math.PI)); + if(radius >= 5){ + return radius; + } + return 5; + } + /** * Direction intToDir * @@ -989,7 +1077,7 @@ public static boolean moveAsFarAwayAsPossibleFrom(MapLocation epicenter) throws * @return RobotType that will be produced */ public static RobotType chooseRobotType() { - for(int i: zombieRounds){ + /*for(int i: zombieRounds){ int currentRound = rc.getRoundNum(); if(i-currentRound<=20 && i-currentRound>=0){ return RobotType.SCOUT; @@ -1005,7 +1093,8 @@ public static RobotType chooseRobotType() { if(fate > 1){ return RobotType.SOLDIER; } - return RobotType.GUARD; + return RobotType.GUARD;*/ + return RobotType.SOLDIER; } /** * boolean almostSurrounded