Package net.sf.robocode.battle

Source Code of net.sf.robocode.battle.Battle$EnableRobotPaintCommand

/**
* Copyright (c) 2001-2014 Mathew A. Nelson and Robocode contributors
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://robocode.sourceforge.net/license/epl-v10.html
*/
package net.sf.robocode.battle;


import net.sf.robocode.battle.events.BattleEventDispatcher;
import net.sf.robocode.battle.peer.BulletPeer;
import net.sf.robocode.battle.peer.ContestantPeer;
import net.sf.robocode.battle.peer.RobotPeer;
import net.sf.robocode.battle.peer.TeamPeer;
import net.sf.robocode.battle.snapshot.TurnSnapshot;
import net.sf.robocode.host.ICpuManager;
import net.sf.robocode.host.IHostManager;
import net.sf.robocode.io.Logger;
import net.sf.robocode.io.RobocodeProperties;
import net.sf.robocode.repository.IRobotItem;
import net.sf.robocode.security.HiddenAccess;
import net.sf.robocode.settings.ISettingsManager;
import robocode.*;
import robocode.control.RandomFactory;
import robocode.control.RobotResults;
import robocode.control.RobotSetup;
import robocode.control.RobotSpecification;
import robocode.control.events.*;
import robocode.control.events.RoundEndedEvent;
import robocode.control.snapshot.BulletState;
import robocode.control.snapshot.ITurnSnapshot;

import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


/**
* The {@code Battle} class is used for controlling a battle.
*
* @author Mathew A. Nelson (original)
* @author Flemming N. Larsen (contributor)
* @author Luis Crespo (contributor)
* @author Robert D. Maupin (contributor)
* @author Titus Chen (contributor)
* @author Nathaniel Troutman (contributor)
* @author Julian Kent (contributor)
* @author Pavel Savara (contributor)
*/
public final class Battle extends BaseBattle {

  private static final int DEBUG_TURN_WAIT_MILLIS = 10 * 60 * 1000; // 10 seconds

  private final IHostManager hostManager;
  private final long cpuConstant;

  // Inactivity related items
  private int inactiveTurnCount;
  private double inactivityEnergy;

  // Turn skip related items
  private boolean parallelOn;
  private long millisWait;
  private int nanoWait;

  // Objects in the battle
  private int robotsCount;
  private List<RobotPeer> robots = new ArrayList<RobotPeer>();
  private List<ContestantPeer> contestants = new ArrayList<ContestantPeer>();
  private final List<BulletPeer> bullets = new CopyOnWriteArrayList<BulletPeer>();

  // Robot counters
  private int activeParticipants;
  private int activeSentries;

  // Death events
  private final List<RobotPeer> deathRobots = new CopyOnWriteArrayList<RobotPeer>();

  // Initial robot setups (if any)
  private RobotSetup[] initialRobotSetups;

  public Battle(ISettingsManager properties, IBattleManager battleManager, IHostManager hostManager, ICpuManager cpuManager, BattleEventDispatcher eventDispatcher) { // NO_UCD (unused code)
    super(
        properties, battleManager, eventDispatcher);
    this.hostManager = hostManager;
    this.cpuConstant = cpuManager.getCpuConstant();
  }

  void setup(RobotSpecification[] battlingRobotsList, BattleProperties battleProps, boolean paused) {
    isPaused = paused;
    battleRules = HiddenAccess.createRules(battleProps.getBattlefieldWidth(), battleProps.getBattlefieldHeight(),
        battleProps.getNumRounds(), battleProps.getGunCoolingRate(), battleProps.getInactivityTime(),
        battleProps.getHideEnemyNames(), battleProps.getSentryBorderSize());
    robotsCount = battlingRobotsList.length;
    computeInitialPositions(battleProps.getInitialPositions());
    createPeers(battlingRobotsList);
  }

  private void createPeers(RobotSpecification[] battlingRobotsList) {
    // create teams
    Map<String, Integer> countedNames = new HashMap<String, Integer>();
    List<String> teams = new ArrayList<String>();
    List<String> teamDuplicates = new ArrayList<String>();
    List<Integer> robotDuplicates = new ArrayList<Integer>();

    // count duplicate robots, enumerate teams, enumerate team members
    for (RobotSpecification specification : battlingRobotsList) {
      final String name = ((IRobotItem) HiddenAccess.getFileSpecification(specification)).getUniqueFullClassNameWithVersion();

      if (countedNames.containsKey(name)) {
        int value = countedNames.get(name);

        countedNames.put(name, value == 1 ? 3 : value + 1);
      } else {
        countedNames.put(name, 1);
      }

      String teamFullName = HiddenAccess.getRobotTeamName(specification);

      if (teamFullName != null) {
        if (!teams.contains(teamFullName)) {
          teams.add(teamFullName);
          String teamName = teamFullName.substring(0, teamFullName.length() - 6);

          if (countedNames.containsKey(teamName)) {
            int value = countedNames.get(teamName);

            countedNames.put(teamName, value == 1 ? 3 : value + 1);
          } else {
            countedNames.put(teamName, 1);
          }
        }
      }
    }

    Map<String, List<String>> teamMembers = new HashMap<String, List<String>>();

    // name teams
    for (int i = teams.size() - 1; i >= 0; i--) {
      String teamFullName = teams.get(i);
      String name = teamFullName.substring(0, teamFullName.length() - 6);
      Integer order = countedNames.get(name);
      String newTeamName = name;

      if (order > 1) {
        newTeamName = name + " (" + (order - 1) + ")";
      }
      teamDuplicates.add(0, newTeamName);
      teamMembers.put(teamFullName, new ArrayList<String>());
      countedNames.put(name, order - 1);
    }

    // name robots
    for (int i = battlingRobotsList.length - 1; i >= 0; i--) {
      RobotSpecification specification = battlingRobotsList[i];
      String name = ((IRobotItem) HiddenAccess.getFileSpecification(specification)).getUniqueFullClassNameWithVersion();
      Integer order = countedNames.get(name);
      int duplicate = -1;

      String newName = name;

      if (order > 1) {
        duplicate = (order - 2);
        newName = name + " (" + (order - 1) + ")";
      }
      countedNames.put(name, (order - 1));
      robotDuplicates.add(0, duplicate);

      String teamFullName = HiddenAccess.getRobotTeamName(specification);

      if (teamFullName != null) {
        List<String> members = teamMembers.get(teamFullName);

        members.add(newName);
      }
    }

    // create teams
    Map<String, TeamPeer> namedTeams = new HashMap<String, TeamPeer>();

    // create robots
    for (int i = 0; i < battlingRobotsList.length; i++) {
      RobotSpecification specification = battlingRobotsList[i];
      TeamPeer team = null;

      String teamFullName = HiddenAccess.getRobotTeamName(specification);

      // The team index and robot index depends on current sizes of the contestant list and robot list
      int teamIndex = contestants.size();
      int robotIndex = robots.size();

      if (teamFullName != null) {
        if (!namedTeams.containsKey(teamFullName)) {
          String newTeamName = teamDuplicates.get(teams.indexOf(teamFullName));

          team = new TeamPeer(newTeamName, teamMembers.get(teamFullName), teamIndex);

          namedTeams.put(teamFullName, team);
          contestants.add(team);

        } else {
          team = namedTeams.get(teamFullName);
          if (team != null) {
            teamIndex = team.getTeamIndex();
          }
        }
      }
      Integer duplicate = robotDuplicates.get(i);
      RobotPeer robotPeer = new RobotPeer(this, hostManager, specification, duplicate, team, robotIndex);

      robots.add(robotPeer);
      if (team == null) {
        contestants.add(robotPeer);
      }
    }
  }

  public void registerDeathRobot(RobotPeer r) {
    deathRobots.add(r);
  }

  public BattleRules getBattleRules() {
    return battleRules;
  }

  public int getRobotsCount() {
    return robotsCount;
  }

  public boolean isDebugging() {
    return RobocodeProperties.isDebuggingOn();
  }

  public void addBullet(BulletPeer bullet) {
    bullets.add(bullet);
  }

  public void resetInactiveTurnCount(double energyLoss) {
    if (energyLoss < 0) {
      return;
    }
    inactivityEnergy += energyLoss;
    while (inactivityEnergy >= 10) {
      inactivityEnergy -= 10;
      inactiveTurnCount = 0;
    }
  }

  /**
   * Returns the number of active participants.
   *
   * @return the number of active participants.
   */
  public int countActiveParticipants() {
    return activeParticipants;
  }

  /**
   * Returns the number of active sentry robots.
   *
   * @return the number of active sentry robots.
   */
  public int countActiveSentries() {
    return activeSentries;
  }

  @Override
  public void cleanup() {

    if (contestants != null) {
      contestants.clear();
      contestants = null;
    }

    if (robots != null) {
      robots.clear();
      robots = null;
    }

    super.cleanup();

    battleManager = null;

    // Request garbage collecting
    for (int i = 4; i >= 0; i--) { // Make sure it is run
      System.gc();
    }
  }

  @Override
  protected void initializeBattle() {
    super.initializeBattle();

    parallelOn = System.getProperty("PARALLEL", "false").equals("true");
    if (parallelOn) {
      // how could robots share CPUs ?
      double parallelConstant = robots.size() / Runtime.getRuntime().availableProcessors();

      // four CPUs can't run two single threaded robot faster than two CPUs
      if (parallelConstant < 1) {
        parallelConstant = 1;
      }
      final long waitTime = (long) (cpuConstant * parallelConstant);

      millisWait = waitTime / 1000000;
      nanoWait = (int) (waitTime % 1000000);
    } else {
      millisWait = cpuConstant / 1000000;
      nanoWait = (int) (cpuConstant % 1000000);
    }
    if (nanoWait == 0) {
      nanoWait = 1;
    }
  }

  @Override
  protected void finalizeBattle() {
    eventDispatcher.onBattleFinished(new BattleFinishedEvent(isAborted()));

    if (!isAborted()) {
      eventDispatcher.onBattleCompleted(new BattleCompletedEvent(battleRules, computeBattleResults()));
    }

    for (RobotPeer robotPeer : robots) {
      robotPeer.cleanup();
    }
    hostManager.resetThreadManager();

    super.finalizeBattle();
  }

  @Override
  protected void preloadRound() {
    super.preloadRound();

    computeActiveRobots(); // Used for robotPeer.initializeRound()

    // At this point the unsafe loader thread will now set itself to wait for a notify

    for (RobotPeer robotPeer : robots) {
      robotPeer.initializeRound(robots, initialRobotSetups);
      robotPeer.println("=========================");
      robotPeer.println("Round " + (getRoundNum() + 1) + " of " + getNumRounds());
      robotPeer.println("=========================");
    }

    if (getRoundNum() == 0) {
      eventDispatcher.onBattleStarted(new BattleStartedEvent(battleRules, robots.size(), false));
      if (isPaused) {
        eventDispatcher.onBattlePaused(new BattlePausedEvent());
      }
    }

    computeActiveRobots(); // Used for RoundEnded check    hostManager.resetThreadManager();
  }

  @Override
  protected void initializeRound() {
    super.initializeRound();

    inactiveTurnCount = 0;

    // Start robots

    long waitMillis;
    int waitNanos;

    if (isDebugging()) {
      waitMillis = DEBUG_TURN_WAIT_MILLIS;
      waitNanos = 0;
    } else {
      long waitTime = Math.min(300 * cpuConstant, 10000000000L);

      waitMillis = waitTime / 1000000;
      waitNanos = (int) (waitTime % 1000000);
    }

    for (RobotPeer robotPeer : getRobotsAtRandom()) {
      robotPeer.startRound(waitMillis, waitNanos);
    }

    Logger.logMessage(""); // puts in a new-line in the log message

    final ITurnSnapshot snapshot = new TurnSnapshot(this, robots, bullets, false);

    eventDispatcher.onRoundStarted(new RoundStartedEvent(snapshot, getRoundNum()));
  }

  @Override
  protected void finalizeRound() {
    super.finalizeRound();

    for (RobotPeer robotPeer : robots) {
      robotPeer.waitForStop();
    }
    bullets.clear();

    eventDispatcher.onRoundEnded(new RoundEndedEvent(getRoundNum(), currentTime, totalTurns));
  }

  @Override
  protected void initializeTurn() {
    super.initializeTurn();

    eventDispatcher.onTurnStarted(new TurnStartedEvent());
  }

  @Override
  protected void runTurn() {
    super.runTurn();

    loadCommands();

    updateBullets();

    updateRobots();

    handleDeadRobots();

    if (isAborted() || oneTeamRemaining()) {
      shutdownTurn();
    }

    inactiveTurnCount++;

    computeActiveRobots();

    publishStatuses();

    // Robot time!
    wakeupRobots();
  }

  @Override
  protected void shutdownTurn() {
    if (endTimer == 0) {
      if (isAborted()) {
        for (RobotPeer robotPeer : getRobotsAtRandom()) {
          if (robotPeer.isAlive()) {
            robotPeer.println("SYSTEM: game aborted.");
          }
        }
      } else if (oneTeamRemaining()) {
        boolean leaderFirsts = false;
        TeamPeer winningTeam = null;

        robocode.RoundEndedEvent roundEndedEvent = new robocode.RoundEndedEvent(getRoundNum(), currentTime,
            totalTurns);

        for (RobotPeer robotPeer : getRobotsAtRandom()) {
          robotPeer.addEvent(roundEndedEvent);
          if (robotPeer.isAlive() && !robotPeer.isWinner() && !robotPeer.isSentryRobot()) {
            robotPeer.getRobotStatistics().scoreLastSurvivor();
            robotPeer.setWinner(true);
            robotPeer.println("SYSTEM: " + robotPeer.getNameForEvent(robotPeer) + " wins the round.");
            robotPeer.addEvent(new WinEvent());
            if (robotPeer.getTeamPeer() != null) {
              if (robotPeer.isTeamLeader()) {
                leaderFirsts = true;
              } else {
                winningTeam = robotPeer.getTeamPeer();
              }
            }
          }
          // Generate totals as round has ended, but first when the last scores has been calculated
          robotPeer.getRobotStatistics().generateTotals();
        }
        if (!leaderFirsts && winningTeam != null) {
          winningTeam.getTeamLeader().getRobotStatistics().scoreFirsts();
        }
      }
      if (isAborted() || isLastRound()) {
        List<RobotPeer> orderedRobots = new ArrayList<RobotPeer>(robots);
        Collections.sort(orderedRobots);
        Collections.reverse(orderedRobots);

        for (int rank = 0; rank < robots.size(); rank++) {
          RobotPeer robotPeer = orderedRobots.get(rank);
          robotPeer.getStatistics().setRank(rank + 1);
          BattleResults battleResults = robotPeer.getStatistics().getFinalResults();
          robotPeer.addEvent(new BattleEndedEvent(isAborted(), battleResults));
        }
      }
    }

    if (endTimer > 4 * TURNS_DISPLAYED_AFTER_ENDING) {
      for (RobotPeer robotPeer : robots) {
        robotPeer.setHalt(true);
      }
    }

    super.shutdownTurn();
  }

  @Override
  protected void finalizeTurn() {
    eventDispatcher.onTurnEnded(new TurnEndedEvent(new TurnSnapshot(this, robots, bullets, true)));

    super.finalizeTurn();
  }

  private BattleResults[] computeBattleResults() {
    ArrayList<BattleResults> results = new ArrayList<BattleResults>();
    for (int i = 0; i < contestants.size(); i++) {
      results.add(null);
    }
    for (int rank = 0; rank < contestants.size(); rank++) {
      ContestantPeer contestant = contestants.get(rank);
      contestant.getStatistics().setRank(rank + 1);
      BattleResults battleResults = contestant.getStatistics().getFinalResults();

      RobotSpecification robotSpec = null;
      if (contestant instanceof RobotPeer) {
        robotSpec = ((RobotPeer) contestant).getRobotSpecification();
      } else if (contestant instanceof TeamPeer) {
        robotSpec = ((TeamPeer) contestant).getTeamLeader().getRobotSpecification();
      }
      results.set(rank, new RobotResults(robotSpec, battleResults));
    }
    return results.toArray(new BattleResults[results.size()]);
  }

  /**
   * Returns a list of all robots in random order. This method is used to gain fair play in Robocode,
   * so that a robot placed before another robot in the list will not gain any benefit when the game
   * checks if a robot has won, is dead, etc.
   * This method was introduced as two equal robots like sample.RamFire got different scores even
   * though the code was exactly the same.
   *
   * @return a list of robot peers.
   */
  private List<RobotPeer> getRobotsAtRandom() {
    List<RobotPeer> shuffledList = new ArrayList<RobotPeer>(robots);

    Collections.shuffle(shuffledList, RandomFactory.getRandom());
    return shuffledList;
  }

  /**
   * Returns a list of all bullets in random order. This method is used to gain fair play in Robocode.
   *
   * @return a list of bullet peers.
   */
  private List<BulletPeer> getBulletsAtRandom() {
    List<BulletPeer> shuffledList = new ArrayList<BulletPeer>(bullets);

    Collections.shuffle(shuffledList, RandomFactory.getRandom());
    return shuffledList;
  }

  /**
   * Returns a list of all death robots in random order. This method is used to gain fair play in Robocode.
   *
   * @return a list of robot peers.
   */
  private List<RobotPeer> getDeathRobotsAtRandom() {
    List<RobotPeer> shuffledList = new ArrayList<RobotPeer>(deathRobots);

    Collections.shuffle(shuffledList, RandomFactory.getRandom());
    return shuffledList;
  }

  private void loadCommands() {
    // this will load commands, including bullets from last turn
    for (RobotPeer robotPeer : robots) {
      robotPeer.performLoadCommands();
    }
  }

  private void updateBullets() {
    for (BulletPeer bullet : getBulletsAtRandom()) {
      bullet.update(getRobotsAtRandom(), getBulletsAtRandom());
      if (bullet.getState() == BulletState.INACTIVE) {
        bullets.remove(bullet);
      }
    }
  }

  private void updateRobots() {
    boolean zap = (inactiveTurnCount > battleRules.getInactivityTime());

    final double zapEnergy = isAborted() ? 5 : zap ? .1 : 0;

    // Move all bots
    for (RobotPeer robotPeer : getRobotsAtRandom()) {
      robotPeer.performMove(getRobotsAtRandom(), zapEnergy);
    }

    // Scan after moved all
    for (RobotPeer robotPeer : getRobotsAtRandom()) {
      robotPeer.performScan(getRobotsAtRandom());
    }
  }

  private void handleDeadRobots() {

    for (RobotPeer deadRobot : getDeathRobotsAtRandom()) {
      // Compute scores for dead robots
      if (deadRobot.getTeamPeer() == null) {
        deadRobot.getRobotStatistics().scoreRobotDeath(getActiveContestantCount(deadRobot));
      } else {
        boolean teammatesalive = false;

        for (RobotPeer tm : robots) {
          if (tm.getTeamPeer() == deadRobot.getTeamPeer() && tm.isAlive()) {
            teammatesalive = true;
            break;
          }
        }
        if (!teammatesalive) {
          deadRobot.getRobotStatistics().scoreRobotDeath(getActiveContestantCount(deadRobot));
        }
      }

      // Publish death to live robots
      for (RobotPeer robotPeer : getRobotsAtRandom()) {
        if (robotPeer.isAlive()) {
          robotPeer.addEvent(new RobotDeathEvent(robotPeer.getNameForEvent(deadRobot)));

          if (robotPeer.getTeamPeer() == null || robotPeer.getTeamPeer() != deadRobot.getTeamPeer()) {
            robotPeer.getRobotStatistics().scoreSurvival();
          }
        }
      }
    }

    deathRobots.clear();
  }

  private void publishStatuses() {
    for (RobotPeer robotPeer : robots) {
      robotPeer.publishStatus(currentTime);
    }
  }

  private void computeActiveRobots() {
    int countActiveParticipants = 0;
    int countActiveSentries = 0;

    for (RobotPeer robot : robots) {
      if (robot.isAlive()) { // robot must be alive in order to be active
        if (robot.isSentryRobot()) {
          countActiveSentries++;
        } else {
          countActiveParticipants++;
        }
      }
    }
    this.activeParticipants = countActiveParticipants;
    this.activeSentries = countActiveSentries;
  }

  private void wakeupRobots() {
    // Wake up all robot threads
    final List<RobotPeer> robotsAtRandom = getRobotsAtRandom();

    if (parallelOn) {
      wakeupParallel(robotsAtRandom);
    } else {
      wakeupSerial(robotsAtRandom);
    }
  }

  private void wakeupSerial(List<RobotPeer> robotsAtRandom) {
    for (RobotPeer robotPeer : robotsAtRandom) {
      if (robotPeer.isRunning()) {
        // This call blocks until the robot's thread actually wakes up.
        robotPeer.waitWakeup();

        if (robotPeer.isAlive()) {
          if (isDebugging() || robotPeer.isPaintEnabled()) {
            robotPeer.waitSleeping(DEBUG_TURN_WAIT_MILLIS, 1);
          } else if (currentTime == 1) {
            robotPeer.waitSleeping(millisWait * 10, 1);
          } else {
            robotPeer.waitSleeping(millisWait, nanoWait);
          }
        }
      }
    }
  }

  private void wakeupParallel(List<RobotPeer> robotsAtRandom) {
    for (RobotPeer robotPeer : robotsAtRandom) {
      if (robotPeer.isRunning()) {
        // This call blocks until the robot's thread actually wakes up.
        robotPeer.waitWakeup();
      }
    }
    for (RobotPeer robotPeer : robotsAtRandom) {
      if (robotPeer.isRunning() && robotPeer.isAlive()) {
        if (isDebugging() || robotPeer.isPaintEnabled()) {
          robotPeer.waitSleeping(DEBUG_TURN_WAIT_MILLIS, 1);
        } else if (currentTime == 1) {
          robotPeer.waitSleeping(millisWait * 10, 1);
        } else {
          robotPeer.waitSleeping(millisWait, nanoWait);
        }
      }
    }
  }

  private int getActiveContestantCount(RobotPeer peer) {
    int count = 0;

    for (ContestantPeer c : contestants) {
      if (c instanceof RobotPeer) {
        RobotPeer robot = (RobotPeer) c;
        if (!robot.isSentryRobot() && robot.isAlive()) {
          count++;
        }
      } else if (c instanceof TeamPeer && c != peer.getTeamPeer()) {
        for (RobotPeer robot: (TeamPeer) c) {
          if (!robot.isSentryRobot() && robot.isAlive()) {
            count++;
            break;
          }
        }
      }
    }
    return count;
  }

  private void computeInitialPositions(String initialPositions) {
    initialRobotSetups = null;

    if (initialPositions == null || initialPositions.trim().length() == 0) {
      return;
    }

    List<String> positions = new ArrayList<String>();

    Pattern pattern = Pattern.compile("([^,(]*[(][^)]*[)])?[^,]*,?");
    Matcher matcher = pattern.matcher(initialPositions);

    while (matcher.find()) {
      String pos = matcher.group();
      if (pos.length() > 0) {
        positions.add(pos);
      }
    }
    if (positions.size() == 0) {
      return;
    }

    initialRobotSetups = new RobotSetup[positions.size()];

    String[] coords;
    double x, y, heading;

    for (int i = 0; i < positions.size(); i++) {
      coords = positions.get(i).split(",");

      Random random = RandomFactory.getRandom();

      x = RobotPeer.WIDTH + random.nextDouble() * (battleRules.getBattlefieldWidth() - 2 * RobotPeer.WIDTH);
      y = RobotPeer.HEIGHT + random.nextDouble() * (battleRules.getBattlefieldHeight() - 2 * RobotPeer.HEIGHT);
      heading = 2 * Math.PI * random.nextDouble();

      int len = coords.length;

      if (len >= 1 && coords[0].trim().length() > 0) {
        try {
          x = Double.parseDouble(coords[0].replaceAll("[^0-9.]", ""));
        } catch (NumberFormatException ignore) {// Could be the '?', which is fine
        }
        if (len >= 2 && coords[1].trim().length() > 0) {
          try {
            y = Double.parseDouble(coords[1].replaceAll("[^0-9.]", ""));
          } catch (NumberFormatException ignore) {// Could be the '?', which is fine
          }
          if (len >= 3 && coords[2].trim().length() > 0) {
            try {
              heading = Math.toRadians(Double.parseDouble(coords[2].replaceAll("[^0-9.]", "")));
            } catch (NumberFormatException ignore) {// Could be the '?', which is fine
            }
          }
        }
      }
      initialRobotSetups[i] = new RobotSetup(x, y, heading);
    }
  }

  private boolean oneTeamRemaining() {
    if (countActiveParticipants() <= 1) {
      return true;
    }

    boolean found = false;
    TeamPeer currentTeam = null;

    for (RobotPeer currentRobot : robots) {
      if (currentRobot.isAlive()) {
        if (!found) {
          found = true;
          currentTeam = currentRobot.getTeamPeer();
        } else {
          if (currentTeam == null && currentRobot.getTeamPeer() == null) {
            return false;
          }
          if (currentTeam != currentRobot.getTeamPeer()) {
            return false;
          }
        }
      }
    }
    return true;
  }

  // --------------------------------------------------------------------------
  // Processing and maintaining robot and battle controls
  // --------------------------------------------------------------------------

  void killRobot(int robotIndex) {
    sendCommand(new KillRobotCommand(robotIndex));
  }

  public void setPaintEnabled(int robotIndex, boolean enable) {
    sendCommand(new EnableRobotPaintCommand(robotIndex, enable));
  }

  void setSGPaintEnabled(int robotIndex, boolean enable) {
    sendCommand(new EnableRobotSGPaintCommand(robotIndex, enable));
  }

  void sendInteractiveEvent(Event e) {
    sendCommand(new SendInteractiveEventCommand(e));
  }

  private class KillRobotCommand extends RobotCommand {
    KillRobotCommand(int robotIndex) {
      super(robotIndex);
    }

    public void execute() {
      robots.get(robotIndex).kill();
    }
  }


  private class EnableRobotPaintCommand extends RobotCommand {
    final boolean enablePaint;

    EnableRobotPaintCommand(int robotIndex, boolean enablePaint) {
      super(robotIndex);
      this.enablePaint = enablePaint;
    }

    public void execute() {
      robots.get(robotIndex).setPaintEnabled(enablePaint);
    }
  }


  private class EnableRobotSGPaintCommand extends RobotCommand {
    final boolean enableSGPaint;

    EnableRobotSGPaintCommand(int robotIndex, boolean enableSGPaint) {
      super(robotIndex);
      this.enableSGPaint = enableSGPaint;
    }

    public void execute() {
      robots.get(robotIndex).setSGPaintEnabled(enableSGPaint);
    }
  }


  private class SendInteractiveEventCommand extends Command {
    public final Event event;

    SendInteractiveEventCommand(Event event) {
      this.event = event;
    }

    public void execute() {
      for (RobotPeer robotPeer : robots) {
        if (robotPeer.isInteractiveRobot()) {
          robotPeer.addEvent(event);
        }
      }
    }
  }
}
TOP

Related Classes of net.sf.robocode.battle.Battle$EnableRobotPaintCommand

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.