From ac8f2210baa396770aca799666865b37660cb4d0 Mon Sep 17 00:00:00 2001 From: Marcus Date: Mon, 20 Jan 2025 20:00:18 +1300 Subject: [PATCH] Soldier logic & Mopper logic micros done-ish --- java/src/s2/Mopper.java | 119 +++++++++++++++++++++++-------- java/src/s2/Soldier.java | 16 +++++ java/src/s2/Tower.java | 5 +- java/src/s2/TowerEngager.java | 127 ++++++++++++++++++++++++++++++++++ 4 files changed, 238 insertions(+), 29 deletions(-) create mode 100644 java/src/s2/TowerEngager.java diff --git a/java/src/s2/Mopper.java b/java/src/s2/Mopper.java index 2e11511..826c82e 100644 --- a/java/src/s2/Mopper.java +++ b/java/src/s2/Mopper.java @@ -8,64 +8,96 @@ public class Mopper implements GenericRobotContoller { RobotController rc; Pathing pathing_engine; - public Mopper(RobotController handler) throws GameActionException{ + public Mopper(RobotController handler) throws GameActionException { rc = handler; pathing_engine = new Pathing(handler); } - public void run() throws GameActionException{ + public void run() throws GameActionException { System.out.println("Starting mopper logic..."); - + + MapInfo currentTile = rc.senseMapInfo(rc.getLocation()); + if (currentTile.getPaint() != null && currentTile.getPaint().isEnemy() && rc.canAttack(rc.getLocation())) { + System.out.println("Attacking enemy paint under itself.OVERRIDE.########################################"); + rc.attack(rc.getLocation(), false); // Use primary paint color + return; // Exit this turn after attacking the square under itself + } + + // Reset variables + Direction bestDirection = null; // Redeclared here - causing the error + int maxEnemiesInDirection = 0; // Redeclared here - causing the error + // Define all possible directions Direction[] directions = Direction.values(); - - // Initialize variables to track the best direction - Direction bestDirection = null; - int maxEnemiesInDirection = 0; - + // Get the mopper's current location MapLocation curLoc = rc.getLocation(); - + // Scan for all enemies within the circle of radius 2 * sqrt(2) RobotInfo[] nearbyEnemies = rc.senseNearbyRobots(curLoc, 8, rc.getTeam().opponent()); - + // Count enemies in each direction based on their relative position for (Direction dir : directions) { int enemyCount = 0; - + for (RobotInfo enemy : nearbyEnemies) { MapLocation enemyLoc = enemy.getLocation(); - + // Check if the enemy lies in the swing range for the current direction - if (isInSwingRange(curLoc, enemyLoc, dir)) { + if (rc.isActionReady() && isInSwingRange(curLoc, enemyLoc, dir)) { + enemyCount++; } } - - System.out.println("Direction: " + dir + ", Enemies: " + enemyCount); - // Update the best direction if this one has more enemies if (enemyCount > maxEnemiesInDirection) { maxEnemiesInDirection = enemyCount; bestDirection = dir; } } - - // Perform the mop swing in the best direction if enemies are found + if (bestDirection != null && maxEnemiesInDirection > 0) { - - rc.mopSwing(bestDirection); + // Check if the robot can perform the mop swing + if (rc.isActionReady() && rc.canMopSwing(bestDirection)) { + rc.mopSwing(bestDirection); + } else { + // Handle invalid swing or cooldown + if (!rc.canMopSwing(bestDirection)) { + System.out.println("Mop swing skipped: Can't swing in direction " + bestDirection); + } else { + System.out.println("Mop swing skipped: Action cooldown not expired."); + } + // Pass onto the else block or fallback + } } else { - + bestDirection = findEnemyPaintDirection(curLoc, directions); + + if (bestDirection != null) { + if (rc.isActionReady()) { // Check if the robot is ready to act + System.out.println("Clearing enemy paint in direction: " + bestDirection); + + // Declare and reset targetLoc + MapLocation targetLoc = null; + + // Calculate the target location based on the best direction + targetLoc = curLoc.add(bestDirection); + + // Check if attack is possible and perform the attack + if (rc.canAttack(targetLoc)) { + rc.attack(targetLoc, false); // Use primary paint color to clear the tile + } + } else { + System.out.println("Attack skipped: Action cooldown not expired."); + } + } else { + pathing_engine.Move(); + } } - - // If no enemies to mop swing, move randomly - pathing_engine.Move(); // Try to paint beneath us as we walk to avoid paint penalties - MapInfo currentTile = rc.senseMapInfo(rc.getLocation()); + currentTile = rc.senseMapInfo(rc.getLocation()); if (!currentTile.getPaint().isAlly() && rc.canAttack(rc.getLocation())) { - rc.attack(rc.getLocation()); + rc.attack(rc.getLocation(), false); // Use primary paint color } } @@ -73,7 +105,7 @@ private boolean isInSwingRange(MapLocation mopperLoc, MapLocation targetLoc, Dir // Get the relative position of the target int dx = targetLoc.x - mopperLoc.x; int dy = targetLoc.y - mopperLoc.y; - + // Check based on direction and relative positions switch (swingDir) { case NORTH: @@ -88,4 +120,37 @@ private boolean isInSwingRange(MapLocation mopperLoc, MapLocation targetLoc, Dir return false; } } + + private Direction findEnemyPaintDirection(MapLocation curLoc, Direction[] directions) throws GameActionException { + Direction bestDirection = null; + int maxEnemyPaintCount = 0; + + // Check each direction for enemy paint + for (Direction dir : directions) { + int enemyPaintCount = 0; + + // Scan adjacent tiles in the direction + MapLocation targetLoc = curLoc.add(dir); + + // Ensure the target location is on the map + if (rc.onTheMap(targetLoc)) { + MapInfo targetTile = rc.senseMapInfo(targetLoc); + + // Count tiles with enemy paint + if (targetTile.getPaint() != null && targetTile.getPaint().isEnemy() && targetTile.isPassable()) { + enemyPaintCount++; + } + + + // Update the best direction if this one has more enemy paint + if (enemyPaintCount > maxEnemyPaintCount) { + maxEnemyPaintCount = enemyPaintCount; + bestDirection = dir; + } + } + } + + return bestDirection; + } } + diff --git a/java/src/s2/Soldier.java b/java/src/s2/Soldier.java index 1122949..f9aef9c 100644 --- a/java/src/s2/Soldier.java +++ b/java/src/s2/Soldier.java @@ -13,15 +13,30 @@ public class Soldier implements GenericRobotContoller { Pathing pathing_engine; boolean buildPaintTowerNext = false; + private TowerEngager towerEngager; // Declare TowerEngager instance + MapLocation currentLocation; public Soldier(RobotController handler) throws GameActionException { rc = handler; pathing_engine = new Pathing(handler); SRP_pattern = rc.getResourcePattern(); + towerEngager = new TowerEngager(handler); // Initialize TowerEngager } public void run() throws GameActionException { + + //START OF SOLDIER TOWER PRODDING CODE####################################################################### + //towerEngager.engageEnemyTower(); + + if (towerEngager.engageEnemyTower()) { + return; // Skip further logic and end the turn if tower engagement was successful + } + + //END OF SOLDIER TOWER PRODDING CODE####################################################################### + + + //get our current location at the start of each run currentLocation = rc.getLocation(); if (shouldBuildSRP()) { @@ -166,6 +181,7 @@ private boolean shouldBuildSRP() throws GameActionException{ return true; } + private void buildSRP() throws GameActionException{ isBuildingSRP = true; MapInfo[] key_squares = rc.senseNearbyMapInfos(8); diff --git a/java/src/s2/Tower.java b/java/src/s2/Tower.java index 817b87b..de653d8 100644 --- a/java/src/s2/Tower.java +++ b/java/src/s2/Tower.java @@ -64,7 +64,7 @@ public void run() throws GameActionException { if (spawn_count[rtype] >= target_count[rtype]) { rtype++; } - if (rtype == 2) { + if (rtype > 2) { rtype = 0; spawn_count[0] = 0; spawn_count[1] = 0; @@ -74,11 +74,12 @@ public void run() throws GameActionException { if (chipCount > 10_000) { target_count[0] = 5; target_count[1] = 2; + target_count[2] = 1; } if (chipCount < 650) { target_count[0] = 3; target_count[1] = 1; - // target_count[2] = 1; + target_count[2] = 1; } // Attack logic for Tower diff --git a/java/src/s2/TowerEngager.java b/java/src/s2/TowerEngager.java new file mode 100644 index 0000000..8a20134 --- /dev/null +++ b/java/src/s2/TowerEngager.java @@ -0,0 +1,127 @@ +//Includes attacking Logic and Sequence. + +package s2; + +import java.util.HashSet; + +import battlecode.common.*; +//import s2.generics.GenericFunc; + +//import java.util.Random; + + +public class TowerEngager { + + + HashSet enemyLocations = new HashSet(); + + + RobotController rc; + + public TowerEngager(RobotController handler) { + this.rc = handler; + } + + public boolean engageEnemyTower() throws GameActionException { + //System.out.println("Running tower engagement logic..."); + + // Sense nearby map info in a certain radius + MapInfo[] nearbyMapInfo = rc.senseNearbyMapInfos(-1); + + MapLocation enemyTowerLocation = null; + + // Identify the location of an enemy tower + int minDistance = Integer.MAX_VALUE; // Initialize with a large value + for (MapInfo mapInfo : nearbyMapInfo) { + if (mapInfo.hasRuin()) { + RobotInfo robot = rc.senseRobotAtLocation(mapInfo.getMapLocation()); + if (robot != null && robot.getTeam() != rc.getTeam()) { + int currentDistance = rc.getLocation().distanceSquaredTo(mapInfo.getMapLocation()); + if (currentDistance < minDistance) { + System.out.println("We found something Boss! A tower?"); + minDistance = currentDistance; // Update the minimum distance + enemyTowerLocation = mapInfo.getMapLocation(); // Update the closest tower + } + } + } + + } + + // Add the closest tower to the HashSet if one was found + if (enemyTowerLocation != null) { + enemyLocations.add(enemyTowerLocation); + } + + + if (enemyTowerLocation == null) { + //System.out.println("No enemy tower detected in range."); + return false; // Exit the function if no enemy tower is found + } + + System.out.println("Enemy tower detected at: " + enemyTowerLocation); + + // Check if the enemy tower is already a ruin + if (enemyLocations.contains(enemyTowerLocation) && rc.senseRobotAtLocation(enemyTowerLocation) == null) { + System.out.println("Enemy tower has been destroyed (turned into a ruin)."); + enemyLocations.remove(enemyTowerLocation); // Remove the tower's location from the HashSet + return false; // Exit as there is no active enemy tower at this location + } + + + // Get the current robot's location + MapLocation currentLocation = rc.getLocation(); + + // Calculate a direction towards the enemy tower + Direction towardsTower = currentLocation.directionTo(enemyTowerLocation); + + // Move one step towards the enemy tower if possible + // Check if the robot is outside the tower's attack range but can still see it + System.out.println("Debug Before Cooldown Check: Movement=" + rc.getMovementCooldownTurns() + ", Action=" + rc.getActionCooldownTurns()); + if (rc.getMovementCooldownTurns() > 0 || rc.getActionCooldownTurns() > 0) { //IMPORTANT RUNNING WITH 0 IS OPTIMAL BUT SHOUDL TWEAK LATER + System.out.println("Movement cooldown: " + rc.getMovementCooldownTurns()); + System.out.println("Cooldowns too high, skipping engagement. Action cooldown is:" + rc.getActionCooldownTurns()); + return true; + } + + + if (currentLocation.distanceSquaredTo(enemyTowerLocation) > 9 && + currentLocation.distanceSquaredTo(enemyTowerLocation) <= 16 && + rc.getMovementCooldownTurns() == 0 && rc.getActionCooldownTurns() == 0) { + if (rc.canMove(towardsTower)) { + rc.move(towardsTower); + System.out.println("Moved towards enemy tower at: " + enemyTowerLocation); + + //Attacking sequence added here: + // Attack the tower after moving closer + if (rc.canAttack(enemyTowerLocation)) { + rc.attack(enemyTowerLocation); // Attack the tower + System.out.println("Attacked enemy tower after moving closer: " + enemyTowerLocation); + } + + return true; // Exit after taking one step + } + } + + // If the robot is within the tower's attack range, move one step away + if (currentLocation.distanceSquaredTo(enemyTowerLocation) <= 9) { + Direction awayFromTower = enemyTowerLocation.directionTo(currentLocation); + if (rc.canMove(awayFromTower)) { + + //Attack before leaving sequence here: + + if (rc.canAttack(enemyTowerLocation)) { + rc.attack(enemyTowerLocation); // Attack the tower + System.out.println("Attacked enemy tower before retreating: " + enemyTowerLocation); + } + + rc.move(awayFromTower); + System.out.println("Moved away from enemy tower to avoid attack."); + return true; // Move away from the tower successfully + } + } + + return false; + + } +} +