Constants.java
1 package hlt; 2 3 import java.util.ArrayList; 4 import java.util.HashMap; 5 import java.util.Map; 6 7 public class Constants { 8 /** The maximum amount of halite a ship can carry. */ 9 public static int MAX_HALITE; 10 /** The cost to build a single ship. */ 11 public static int SHIP_COST; 12 /** The cost to build a dropoff. */ 13 public static int DROPOFF_COST; 14 /** The maximum number of turns a game can last. */ 15 public static int MAX_TURNS; 16 /** 1/EXTRACT_RATIO halite (rounded) is collected from a square per turn. */ 17 public static int EXTRACT_RATIO; 18 /** 1/MOVE_COST_RATIO halite (rounded) is needed to move off a cell. */ 19 public static int MOVE_COST_RATIO; 20 /** Whether inspiration is enabled. */ 21 public static boolean INSPIRATION_ENABLED; 22 /** A ship is inspired if at least INSPIRATION_SHIP_COUNT opponent ships are within this Manhattan distance. */ 23 public static int INSPIRATION_RADIUS; 24 /** A ship is inspired if at least this many opponent ships are within INSPIRATION_RADIUS distance. */ 25 public static int INSPIRATION_SHIP_COUNT; 26 /** An inspired ship mines 1/X halite from a cell per turn instead. */ 27 public static int INSPIRED_EXTRACT_RATIO; 28 /** An inspired ship that removes Y halite from a cell collects X*Y additional halite. */ 29 public static double INSPIRED_BONUS_MULTIPLIER; 30 /** An inspired ship instead spends 1/X% halite to move. */ 31 public static int INSPIRED_MOVE_COST_RATIO; 32 33 public static void populateConstants(final String stringFromEngine) { 34 final String[] rawTokens = stringFromEngine.split("[{}, :\"]+"); 35 final ArrayList<String> tokens = new ArrayList<>(); 36 for (int i = 0; i < rawTokens.length; ++i) { 37 if (!rawTokens[i].isEmpty()) { 38 tokens.add(rawTokens[i]); 39 } 40 } 41 42 if ((tokens.size() % 2) != 0) { 43 Log.log("Error: constants: expected even total number of key and value tokens from server."); 44 throw new IllegalStateException(); 45 } 46 47 final Map<String, String> constantsMap = new HashMap<>(); 48 49 for (int i = 0; i < tokens.size(); i += 2) { 50 constantsMap.put(tokens.get(i), tokens.get(i+1)); 51 } 52 53 SHIP_COST = getInt(constantsMap, "NEW_ENTITY_ENERGY_COST"); 54 DROPOFF_COST = getInt(constantsMap, "DROPOFF_COST"); 55 MAX_HALITE = getInt(constantsMap, "MAX_ENERGY"); 56 MAX_TURNS = getInt(constantsMap, "MAX_TURNS"); 57 EXTRACT_RATIO = getInt(constantsMap, "EXTRACT_RATIO"); 58 MOVE_COST_RATIO = getInt(constantsMap, "MOVE_COST_RATIO"); 59 INSPIRATION_ENABLED = getBoolean(constantsMap, "INSPIRATION_ENABLED"); 60 INSPIRATION_RADIUS = getInt(constantsMap, "INSPIRATION_RADIUS"); 61 INSPIRATION_SHIP_COUNT = getInt(constantsMap, "INSPIRATION_SHIP_COUNT"); 62 INSPIRED_EXTRACT_RATIO = getInt(constantsMap, "INSPIRED_EXTRACT_RATIO"); 63 INSPIRED_BONUS_MULTIPLIER = getDouble(constantsMap, "INSPIRED_BONUS_MULTIPLIER"); 64 INSPIRED_MOVE_COST_RATIO = getInt(constantsMap, "INSPIRED_MOVE_COST_RATIO"); 65 } 66 67 private static int getInt(final Map<String, String> map, final String key) { 68 return Integer.parseInt(getString(map, key)); 69 } 70 71 private static double getDouble(final Map<String, String> map, final String key) { 72 return Double.parseDouble(getString(map, key)); 73 } 74 75 private static boolean getBoolean(final Map<String, String> map, final String key) { 76 final String stringValue = getString(map, key); 77 switch (stringValue) { 78 case "true": return true; 79 case "false": return false; 80 default: 81 Log.log("Error: constants: " + key + " constant has value of '" + stringValue + 82 "' from server. Do not know how to parse that as boolean."); 83 throw new IllegalStateException(); 84 } 85 } 86 87 private static String getString(final Map<String, String> map, final String key) { 88 if (!map.containsKey(key)) { 89 Log.log("Error: constants: server did not send " + key + " constant."); 90 throw new IllegalStateException(); 91 } 92 return map.get(key); 93 } 94 }