From 6d51ea35745d465db2ccea5a24d2d3422fcfa1a1 Mon Sep 17 00:00:00 2001 From: William Muir Date: Wed, 27 Sep 2017 01:44:01 +1300 Subject: [PATCH] Created a random place token generator. Generates a location between any leg of the race in a random angle / distance of the radius of the centre point of the two gates to one of the gates #story[1293] --- .../java/seng302/gameServer/GameState.java | 47 +++----------- .../java/seng302/model/mark/MarkOrder.java | 14 ++-- src/main/java/seng302/model/token/Token.java | 13 ++++ .../java/seng302/utilities/RandomSpawn.java | 64 +++++++++++++++++++ 4 files changed, 97 insertions(+), 41 deletions(-) create mode 100644 src/main/java/seng302/utilities/RandomSpawn.java diff --git a/src/main/java/seng302/gameServer/GameState.java b/src/main/java/seng302/gameServer/GameState.java index dfb8dae4..5236a14e 100644 --- a/src/main/java/seng302/gameServer/GameState.java +++ b/src/main/java/seng302/gameServer/GameState.java @@ -4,6 +4,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Random; @@ -38,6 +39,7 @@ import seng302.model.mark.MarkOrder; import seng302.model.token.Token; import seng302.model.token.TokenType; import seng302.utilities.GeoUtility; +import seng302.utilities.RandomSpawn; import seng302.utilities.XMLParser; import seng302.visualiser.fxObjects.assets_3D.BoatMeshType; @@ -82,7 +84,7 @@ public class GameState implements Runnable { public static final Integer HANDLING_BOOST_MULTIPLIER = 2; private static final Double BAD_RANDOM_SPEED_PENALTY = 0.3; public static final Long BUMPER_DISABLE_TIME = 5_000L; - private static final Long TOKEN_SPAWN_TIME = 30_000L; + private static final Long TOKEN_SPAWN_TIME = 15_000L; private static Long previousUpdateTime; public static Double windDirection; @@ -99,13 +101,12 @@ public class GameState implements Runnable { private static GameStages currentStage; private static MarkOrder markOrder; private static long startTime; - private static Set marks; + private static List marks; private static List courseLimit; private static Integer maxPlayers = 8; - - private static List allTokens; private static List tokensInPlay; + private static RandomSpawn randomSpawn; private static List newMessageListeners; @@ -126,14 +127,12 @@ public class GameState implements Runnable { previousUpdateTime = System.currentTimeMillis(); markOrder = new MarkOrder(); //This could be instantiated at some point with a select map? newMessageListeners = new ArrayList<>(); - allTokens = makeTokens(); + marks = new MarkOrder().getAllMarks(); + randomSpawn = new RandomSpawn(markOrder.getOrderedUniqueCompoundMarks()); resetStartTime(); - - new Thread(this, "GameState").start(); //Run the auto updates on the game state - - marks = new MarkOrder().getAllMarks(); setCourseLimit("/server_config/race.xml"); + new Thread(this, "GameState").start(); //Run the auto updates on the game state } private void setCourseLimit(String url) { @@ -151,29 +150,10 @@ public class GameState implements Runnable { courseLimit = XMLParser.parseRace(document).getCourseLimit(); } - - /** - * Make a pre defined set of tokensInPlay. //TODO wmu16 - Should read from some file for each - * race ideally - * - * @return A list of possible tokensInPlay for this race - */ - private ArrayList makeTokens() { - Token token1 = new Token(TokenType.BOOST, 57.66946, 11.83154); - Token token2 = new Token(TokenType.BOOST, 57.66877, 11.83382); - Token token3 = new Token(TokenType.BOOST, 57.66914, 11.83965); - Token token4 = new Token(TokenType.BOOST, 57.66684, 11.83214); - return new ArrayList<>(Arrays.asList(token1, token2, token3, token4)); - } - public static String getHostIpAddress() { return hostIpAddress; } - public static Set getMarks() { - return Collections.unmodifiableSet(marks); - } - public static List getPlayers() { return players; } @@ -378,16 +358,9 @@ public class GameState implements Runnable { * Broadasts a new race status message to show this update */ private void spawnNewToken() { - Random random = new Random(); tokensInPlay.clear(); - - //Get a random token location with random type - Token token = allTokens.get(random.nextInt(allTokens.size())); - token.assignRandomType(); -// token.assignType(TokenType.RANDOM); - + Token token = randomSpawn.getRandomTokenLocation(); logger.debug("Spawned token of type " + token.getTokenType()); - tokensInPlay.add(token); } @@ -912,7 +885,7 @@ public class GameState implements Runnable { } private static Mark checkMarkCollision(ServerYacht yacht) { - Set marksInRace = GameState.getMarks(); + Set marksInRace = new HashSet<>(marks); for (Mark mark : marksInRace) { if (GeoUtility.getDistance(yacht.getLocation(), mark) <= MARK_COLLISION_DISTANCE) { diff --git a/src/main/java/seng302/model/mark/MarkOrder.java b/src/main/java/seng302/model/mark/MarkOrder.java index 0e250e99..7f296aee 100644 --- a/src/main/java/seng302/model/mark/MarkOrder.java +++ b/src/main/java/seng302/model/mark/MarkOrder.java @@ -24,8 +24,9 @@ import java.util.*; */ public class MarkOrder { private List raceMarkOrder; + private List orderedUniqueCompoundMarks; private Logger logger = LoggerFactory.getLogger(MarkOrder.class); - private Set allMarks; + private List allMarks; public MarkOrder(){ loadRaceProperties(); @@ -44,6 +45,10 @@ public class MarkOrder { return Collections.unmodifiableList(raceMarkOrder); } + public List getOrderedUniqueCompoundMarks() { + return orderedUniqueCompoundMarks; + } + /** * @param seqID The seqID of the current mark the boat is heading to * @return A Boolean indicating if this coming mark is the last one (finish line) @@ -75,8 +80,8 @@ public class MarkOrder { return raceMarkOrder.get(currentSeqID + 1); } - public Set getAllMarks(){ - return Collections.unmodifiableSet(allMarks); + public List getAllMarks() { + return Collections.unmodifiableList(allMarks); } /** @@ -89,7 +94,7 @@ public class MarkOrder { DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db; Document doc; - allMarks = new HashSet<>(); + allMarks = new ArrayList<>(); try { db = dbf.newDocumentBuilder(); @@ -105,6 +110,7 @@ public class MarkOrder { logger.debug("Loaded RaceXML for mark order"); List corners = data.getMarkSequence(); Map marks = data.getCompoundMarks(); + orderedUniqueCompoundMarks = new ArrayList<>(marks.values()); List course = new ArrayList<>(); for (Corner corner : corners){ CompoundMark compoundMark = marks.get(corner.getCompoundMarkID()); diff --git a/src/main/java/seng302/model/token/Token.java b/src/main/java/seng302/model/token/Token.java index ed8b87eb..0e6e86b8 100644 --- a/src/main/java/seng302/model/token/Token.java +++ b/src/main/java/seng302/model/token/Token.java @@ -15,11 +15,24 @@ public class Token extends GeoPoint { private TokenType tokenType; private Random random = new Random(); + //Constructor for creating a specific type client side public Token(TokenType tokenType, double lat, double lng) { super(lat, lng); this.tokenType = tokenType; } + //Making random type server side + public Token(double lat, double lng) { + super(lat, lng); + assignRandomType(); + } + + //Making random type server side + public Token(GeoPoint geoPoint) { + super(geoPoint.getLat(), geoPoint.getLng()); + assignRandomType(); + } + public TokenType getTokenType() { return tokenType; } diff --git a/src/main/java/seng302/utilities/RandomSpawn.java b/src/main/java/seng302/utilities/RandomSpawn.java new file mode 100644 index 00000000..0a0f0702 --- /dev/null +++ b/src/main/java/seng302/utilities/RandomSpawn.java @@ -0,0 +1,64 @@ +package seng302.utilities; + +import java.util.HashMap; +import java.util.List; +import java.util.Random; +import seng302.model.GeoPoint; +import seng302.model.mark.CompoundMark; +import seng302.model.token.Token; + +/** + * A class for generating and spawning tokens in random locations + * Created by wmu16 on 27/09/17. + */ +public class RandomSpawn { + + private static final Integer DEGREES_IN_CIRCLE = 360; + + private HashMap spawnRadii; + private Random random; + + /** + * @param markOrder this must be the ORDERED list of marks. Better yet UNIQUE to avoid over + * computation + */ + public RandomSpawn(List markOrder) { + this.spawnRadii = new HashMap<>(); + random = new Random(); + + spawnRadii = generateSpawnRadii(markOrder); + } + + private HashMap generateSpawnRadii(List markOrder) { + System.out.println(markOrder); + HashMap spawnRadii = new HashMap<>(); + for (int i = 0; i < markOrder.size() - 1; i++) { + GeoPoint spawnCentre = GeoUtility.getDirtyMidPoint( + markOrder.get(i).getMidPoint(), + markOrder.get(i + 1).getMidPoint()); + + Double distance = GeoUtility.getDistance(spawnCentre, markOrder.get(i).getMidPoint()); + spawnRadii.put(spawnCentre, distance); + } + + return spawnRadii; + } + + + /** + * @return A random token type at a random location in a random radii of the set of possible + * radii + */ + public Token getRandomTokenLocation() { + Object[] keys = spawnRadii.keySet().toArray(); + GeoPoint randomSpawnCentre = (GeoPoint) keys[random.nextInt(keys.length)]; + Double spawnRadius = spawnRadii.get(randomSpawnCentre); + Double randomDistance = spawnRadius * random.nextDouble(); + Double randomAngle = random.nextDouble() * DEGREES_IN_CIRCLE; + GeoPoint randomLocation = GeoUtility + .getGeoCoordinate(randomSpawnCentre, randomAngle, randomDistance); + return new Token(randomLocation); + + } + +}