AIHardCapital.java :  » Game » Risk_1.0.9.8 » risk » engine » ai » Java Open Source

Java Open Source » Game » Risk_1.0.9.8 
Risk_1.0.9.8 » risk » engine » ai » AIHardCapital.java
//  Group D

package risk.engine.ai;

import risk.engine.*;
import risk.engine.core.*;

import java.util.*;

/**
 * <p> Class for AIHardPlayer </p>
 * @author SE Group D
 */

public class AIHardCapital extends AIHard {

  public String getPlaceArmies() {

    String output;

        if ( game.NoEmptyCountries()==false ) {

      Continent[] cont = game.getContinents();

      /* ai attempts to gain control of a continent during initial placement */

      int territorynum = 0;
      int check = -1;
      String name=null;
      int val = -1;

      for (int i=0; i<cont.length; i++) {
          Vector ct = new Vector();
          Continent co = cont[i];
          ct = co.getTerritoriesContained();

          for (int j=0; j<ct.size(); j++) {
              if ( ((Country)ct.elementAt(j)).getOwner() == player ) { territorynum++; }
          }

          if (check <= territorynum) {
        check = territorynum;
        val = i;
          }
          territorynum = 0;
      }

      /* ..pick country from that continent */
      boolean picked = false;
      if (check > 0) {
          Continent co = cont[val];
          Vector ct = co.getTerritoriesContained();

          for (int j=0; j<ct.size(); j++) {
        if ( ((Country)ct.elementAt(j)).getOwner() == null )  {
            name=((Country)ct.elementAt(j)).getColor()+"";
            picked = true;
            break;
        }
          }
      }

      if (picked == false) {
          Continent co = cont[val];
          Vector ct = co.getTerritoriesContained();

          for (int j=0; j<ct.size(); j++) {
        if ( ((Country)ct.elementAt(j)).getOwner() == null )  {
            name=((Country)ct.elementAt(j)).getColor()+"";

            Vector v = ((Country)ct.elementAt(j)).getNeighbours();
            for (int k=0; k<ct.size(); k++) {
          if (((Country)v.elementAt(k)).getOwner() != player) {
              name=((Country)ct.elementAt(j)).getColor()+"";
              break;
          }
            }
        }
          }
      }

      String str = expandBase(player.getTerritoriesOwned());
      if( str != null )
                            name = str;

                        String s = blockOpponent(player);
                        if( s != null )
                            name = s;

            if (name == null)
          output = "autoplace";

            else
          output = "placearmies " + name +" 1";
        }
        else {

      Vector pt = player.getTerritoriesOwned();

      String name=null;
      Country capital = player.getCapital();
      if (capital == null)
          capital = findCapital();

      for (int a=0; a< pt.size() ; a++) {

          if ( ownsNeighbours( (Country)pt.elementAt(a)) == false && ((Country)pt.elementAt(a)).getArmies() <= 11 ) {
                                name=((Country)pt.elementAt(a)).getColor()+"";
                                break;
                            }

                if ( name != null ) { break; }

      }

      String st = attackCapital();
      if( st != null ) 
                            name = st;

                        String s = keepBlocking(player);
                        if( s != null ) 
                            name = s;

                        String f = freeContinent(player);
                        if( f != null ) 
                            name = f;

      String str = reinforceBase(capital);
      if (str != null)
          name = str;

        if (name == null)
          name = findAttackableTerritory(player);
        
      if ( name == null ) 
          output = "placearmies " + ((Country)pt.elementAt(0)).getColor() +" "+player.getExtraArmies();

//Removed so that it will add armies one at a time, thus reinforcing the base until it has enough defense
//at which time it will place in other territories as well.  Re-added so that it would not take forever
//for the computer to place armies. Re-removed after seeing that the time is neglibile.
        else if (game.getSetup() ) 
          output = "placearmies " + name +" "+player.getExtraArmies();

        else
          output = "placearmies " + name +" 1";
        }

    return output;

  }


  public String getAttack() {

    String output=null;
    boolean attackFromCap = player.getCapital().getArmies() > addEnemies(player.getCapital())*2+5; 
        boolean chosen = false;
        Continent[] cont = game.getContinents();
    Vector t = player.getTerritoriesOwned();
    Vector n;
    Vector options = new Vector();
        for (int a=0; a< t.size(); a++) {
            if ( ((Country)t.elementAt(a)).getArmies() > 1 ) {
          if ( (Country)t.elementAt(a) != player.getCapital() ||
            attackFromCap ) {
        n = ((Country)t.elementAt(a)).getNeighbours();

        /* attack ratio set to 50% of attack force */

        int ratio = ((Country)t.elementAt(a)).getArmies();
        for (int b=0; b< n.size() ; b++) {
            if ( ((Country)n.elementAt(b)).getOwner() != player && ((Country)n.elementAt(b)).getArmies() + (ratio / 2) < ratio) {
          //output= "attack " + ((Country)t.elementAt(a)).getColor() + " " + ((Country)n.elementAt(b)).getColor();
               Vector attack = new Vector();
                 attack.add(((Country)t.elementAt(a)).getColor()+"");
                 attack.add((Country)n.elementAt(b));
                 options.add(attack);
            }
        }
          }
            }
        }
        Player[] playersGreatestToLeast = OrderPlayers(player);
        outer: for (int j=0; j<playersGreatestToLeast.length; j++) {
          for (int i=0; i<options.size(); i++) {
            if ( ((Country) ((Vector)options.get(i)).get(1)).getOwner().equals(playersGreatestToLeast[j])  ) {
              output = "attack " + ((String) ((Vector)options.get(i)).get(0)) + " " + ((Country) ((Vector)options.get(i)).get(1)).getColor();
              break outer;
            }
          }
        }

        /* attempt to attack continent which is almost all owned, if scenario is there */

        int count = 0;
        Country attackfrom = null;
                    boolean complex = false;

                    for (int i=0; i<cont.length; i++) {

      if ( mostlyOwned( cont[i] ) == true) {

          n = cont[i].getTerritoriesContained();

          for (int j=0; j<n.size(); j++) {
          
        if ( ((Country)n.elementAt(j)).getArmies() > count
            && ((Country)n.elementAt(j)).getOwner() == player
            && ((Country)n.elementAt(j)) != player.getCapital()) {
          count = ((Country)n.elementAt(j)).getArmies();
          attackfrom = (Country)n.elementAt(j);
        }
          }

          for (int b=0; b< n.size() ; b++) {
        if ( ((Country)n.elementAt(b)).getOwner() != player && (((Country)n.elementAt(b)).getArmies()+1) < count && attackfrom.isNeighbours((Country)n.elementAt(b)) == true) {
            output= "attack " + attackfrom.getColor() + " " + ((Country)n.elementAt(b)).getColor();
            complex = true;
            break;
        }
          }
      }
        }

        // else attempt to attack continent with the greatest territories owned, that has yet to be conquered.

        if (complex == false) {
      int value = 0;
      Continent choice = null;

      for (int i=0; i<cont.length; i++) {

          if ( cont[i].isOwned(player) == false) {

        n = cont[i].getTerritoriesContained();

        int check = 0;
        for (int j=0; j<n.size(); j++) {
             if ( ((Country)n.elementAt(j)).getOwner() == player && (((Country)n.elementAt(j)) != player.getCapital() || attackFromCap))
          check++;
        }

        if (check > value)
            choice = cont[i];
          }
      }

      if (choice !=null) {

                            //System.out.println(choice.getName()); TESTING
          n = ((Continent)choice).getTerritoriesContained();

          for (int j=0; j<n.size(); j++) {

        if ( ((Country)n.elementAt(j)).getArmies() > count
            && ((Country)n.elementAt(j)).getOwner() == player
            && (((Country)n.elementAt(j)) != player.getCapital() || attackFromCap)) {
            count = ((Country)n.elementAt(j)).getArmies();
            attackfrom = (Country)n.elementAt(j);
        }
          }

          for (int b=0; b< n.size() ; b++) {
        if ( ((Country)n.elementAt(b)).getOwner() != player && (((Country)n.elementAt(b)).getArmies()+1) < count && attackfrom.isNeighbours((Country)n.elementAt(b)) == true ) {
            output= "attack " + attackfrom.getColor() + " " + ((Country)n.elementAt(b)).getColor();
                                    break;
        }
          }
      }
        }

            Vector continentsToBreak = GetContinentsToBreak(player);
            String tmp = null;
            
            //Attempt to find a path to the continent - distance of 1, then 2, then 3 away.
            if (continentsToBreak != null) {
              outer: for (int q=1; q<4; q++) { 
                for (int i=0; i<continentsToBreak.size(); i++) {
                    for (int j=0; j<t.size(); j++) {
                      Vector tNeighbors = ((Country)t.get(j)).getNeighbours();
                      for (int k=0; k<tNeighbors.size(); k++) {
                        if (((Country)t.get(j)).getArmies()-1 > ((Country)tNeighbors.get(k)).getArmies() &&
                            ShortPathToContinent((Continent)continentsToBreak.get(i), (Country)t.get(j), (Country)tNeighbors.get(k), q)  &&
                           (((Country)t.get(j)).getColor() != player.getCapital().getColor() || attackFromCap)) {
                          tmp = "attack " + ((Country)t.get(j)).getColor() + " " + ((Country)tNeighbors.get(k)).getColor();
                          break outer;
                        }
                            
                      }
                    }
                  }
              }
            }
            if (tmp != null)
              output = tmp;
        
        
        
        // check to see if there are any players to eliminate

        Vector players = game.getPlayers();
                    Vector cankill = new Vector();

                    for (int i=0; i<players.size(); i++) {
      if (( (Player) players.elementAt(i)).getNoTerritoriesOwned() < 3 && ( (Player) players.elementAt(i)) != player)
          cankill.addElement((Player) players.elementAt(i));
                    }

        if (cankill.size() > 0) {
      for (int i=0; i<cankill.size(); i++) {
      Vector territories = ((Player) cankill.elementAt(i)).getTerritoriesOwned();
      for (int j=0; j<territories.size(); j++) {

          Vector neighbours = ((Country)territories.elementAt(j)).getNeighbours();
                            for (int k=0; k<neighbours.size(); k++) {
        if (((Country) neighbours.elementAt(k)).getOwner() == player
            && (((Country)territories.elementAt(j)).getArmies() + 1 < ((Country) neighbours.elementAt(k)).getArmies())
            && ((Country) neighbours.elementAt(k) != player.getCapital() || attackFromCap)
            &&  ((Country) neighbours.elementAt(k)).isNeighbours((Country)territories.elementAt(j))) {
            output= "attack " + ((Country) neighbours.elementAt(k)).getColor() + " " + ((Country)territories.elementAt(j)).getColor();
                                    //System.out.println("eliminate: " + output); TESTING
                                    break;
        }
          }
      }
        }
    }


    if ( output==null ) {
        output="endattack";
    }

    return output;

  }


  public String getBattleWon() {

    String output;

       /* Attempt to safeguard critical areas when moving armies to won country */

       Country attacker = game.getAttacker();
       Continent continent = attacker.getContinent();
       //If attacking from the capital, try to leave enough defense.
       if (attacker.getColor() == player.getCapital().getColor()) {
         if (attacker.getArmies() >= addEnemies(player.getCapital())*2 + 3)
           output = "move " + (attacker.getArmies() - (addEnemies(player.getCapital())*2 + 1));
         else 
           output = "move " + (attacker.getArmies()-1);
       }
       else if (continent.isOwned(player) == true || mostlyOwned(continent) == true) {

           /* Set 50% security limit */
           if (attacker.getArmies() > 6)
            output = "move " + (attacker.getArmies()-1);

           else if (attacker.getArmies() > 3 && attacker.getArmies() <= 6)
         output = "move " + (attacker.getArmies()-1);

           else
         output = "move all";
                   }
       else {
          output="move all";
       }

    return output;

  }



  public String getCapital() {

    return "capital " + findCapital().getColor();

  }

  /**
   * Returns the number of armies in most fortified neighbor.  If player owns all of the countries around it,
   * return 1, because there is still a potential for a threat
   * @param Country c which is the country that you want to know the enemies of the given player that are around
   * @return int with the number of Enemies around or 1, whichever is higher.
   */
  public int addEnemies(Country c) {

    int nearbyEnemies = 0;
    //Country cap = player.getCapital();
    Country[] countries = game.getCountries();
    for (int j=0; j<countries.length; j++) {
      if (countries[j].isNeighbours(c) && countries[j].getOwner() != player)
        if (countries[j].getArmies() > nearbyEnemies)
          nearbyEnemies = countries[j].getArmies();
    }
    return nearbyEnemies == 0 ? 1 : nearbyEnemies;
  }
  
  /**
   * Checks if the player's capital has enough armies and checks if its neighbours has enough armies
   * @param capital The capital country
   * @return String Returns the name of the capital
   */
  public String reinforceBase(Country capital) {
   String str = null;
   boolean foundCap = false;
   Vector players = game.getPlayers();
   //Reinforce base if there are not 3 times the number of surrounding enemies present.
   for (int i=0; i<players.size(); i++) {
      Player p2 = (Player) players.elementAt(i);
      Country cap = p2.getCapital();
      if (p2 == player)
    cap = capital;
      if (cap != null && cap.getOwner() == player) {
        if (cap.getArmies() < addEnemies(player.getCapital())*2 && cap.getArmies() < 50) {
            str = cap.getColor()+"";
          foundCap = true;
          break;
        }
      }
   }

   if (foundCap == false) {
      boolean found = false;
      for (int i=0; i<players.size(); i++) {
    Player p2 = (Player) players.elementAt(i);
    Country cap = p2.getCapital();
    if (p2 == player)
        cap = capital;
    if (cap != null && cap.getOwner() == player) {
        Vector v = cap.getNeighbours();
        for (int j=0; j<v.size(); j++) {
      Country c = (Country) v.elementAt(j);
      if (c.getOwner() == player && c.getArmies() < 4) {
          str = c.getColor()+"";
          found = true;
          break;
      }
        }
    }
    if (found == true)
        break;
          }
         }
         return str;
  }


  /**
   * get the best capital position for the current player
   *
   */
  public Country findCapital() {

    // TODO someone needs to document how this is working!

    Vector pt = player.getTerritoriesOwned();
    Country country = null;
    int difference1 = Integer.MAX_VALUE;
    int difference2 = Integer.MAX_VALUE;

    for (int i=0; i<pt.size(); i++) {

      int count = 0;
      Country c1 = (Country) pt.elementAt(i);
      Vector v = c1.getNeighbours();

      for (int j=0; j<v.size(); j++) {
        Country c2 = (Country) v.elementAt(j);
        if (c2.getOwner() == player) {
          count++;
        }
      }

      int diff1 = v.size() - count;
      int diff2 = addEnemies(c1) - c1.getArmies();

      if (diff1 <= difference1 && diff2 <= difference2) {

        difference1 = diff1;
        difference2 = diff2;

        country = c1;
      }
      // count = 0; // ??? wtf is this for ???
    }

//    Country country = pt.size() > 0 ? (Country)pt.get(0) : null;
//    for (int i=0; i<pt.size(); i++) {
//      Country tmp = (Country)pt.get(i);
//      if (tmp.getArmies() > country.getArmies())
//        country = tmp;
//    }
    return country;

  }

    /**
     * Checks through the enemy's capital and finds a neighbouring territory owned by the reinforcing player
     * @return String Returns the name of the reinforcing territory
     */
    public String attackCapital() {
  String str = null;
  Vector players = game.getPlayers();
  Country capital = null;
  for (int i=0; i<players.size(); i++) {
      Player p2 = (Player) players.elementAt(i);
      capital = p2.getCapital();
      if (capital != null && capital.getOwner() != player)
        break;
      }
      if (capital != null) {
      Vector v = capital.getNeighbours();
      for (int i=0; i<v.size(); i++) {
    Country c = (Country) v.elementAt(i);
    if (c.getOwner() == player && c.isNeighbours(capital)) {
        str = c.getColor()+"";
        break;
          }
      }
        }
        return str;
    }

    /**
     * Checks through the player's current owned territories and picks a neighbour if it is free
     * @param pt The player's territories
     * @return String Returns the name of the country if found, returns null otherwise
     */
    public String expandBase(Vector pt) {
        String str = null;
  boolean found = false;
  for (int i=0; i<pt.size(); i++) {
      Country c1 = (Country) pt.elementAt(i);
      Vector v = c1.getNeighbours();
      for (int j=0; j<v.size(); j++) {
    Country c2 = (Country) v.elementAt(j);
    if (c2.getOwner() == null) {
        str = c2.getColor()+"";
        found = true;
        break;
          }
            }
      if (found == true)
          break;
        }
        return str;
    }

    public String getRoll() {

    String output;

    int n=((Country)game.getAttacker()).getArmies() - 1;


    /* Only roll for as long as while attacking player has more armies than defending player */
    int m=((Country)game.getDefender()).getArmies();

    if (((Country)game.getAttacker()).getColor() == player.getCapital().getColor()) {
      if (player.getCapital().getArmies() > addEnemies(player.getCapital())*2+5)
        output = "roll "+3;
      else
        output = "retreat";
    } 
    else if (n > 3 && n > m) {
        output= "roll "+3;
    }
    else if (n <= 3 && n > m) {
        output= "roll "+n;
    }
    else {
        output= "retreat";
    }

    return output;

    }

    public String getTacMove() {

    String output=null;

        /* reinforces armies from less critical to more critical areas */

        Vector t = player.getTerritoriesOwned();
        Vector n;
        boolean possible = false;
                    int difference = 0;
                    Country sender = null;
                    Country receiver = null;
                    Country temp = null;
                    int highest = 1;

        for (int a=0; a<t.size(); a++) {

      Country country = ((Country)t.elementAt(a));
      difference  = country.getArmies();
      if (difference > highest && country.getColor() != player.getCapital().getColor())  {
          highest = difference;
          sender = country;
      }
        }

        if (sender != null)  {

      receiver = check1(sender);

      if (receiver == null) {
          n = sender.getNeighbours();
          for (int i=0; i<n.size(); i++) {
        temp = (Country) n.elementAt(i);
        if (temp.getOwner() == player) {
            possible = check2(temp);
        }
        if (possible == true)  { receiver = temp; break; }
          }
      }
        }

        if (receiver != null && receiver != sender) {
      output= "movearmies " + ((Country)sender).getColor() + " " + ((Country)receiver).getColor() + " " + (((Country)sender).getArmies()-1);
      //System.out.println(((Country)sender).getName()); TESTING
      //System.out.println(((Country)receiver).getName()); TESTING
        }

        if ( output == null ) {
      output = "nomove";
        }

    return output;

    }

    
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.