Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package bots;
- import java.util.*;
- import pirates.game.*;
- public class MyBot implements PirateBot
- {
- //Global declarations
- List<Location> occupied = new ArrayList<>();
- public final int maxMoves = 6;
- public int movesLeft;
- public int shahidIndex = -1;
- public class Move
- {
- boolean moved = false;
- Pirate pirate;
- Location location;
- int moves;
- PirateGame game;
- //check in the constractor if we can move to this location
- public Move(PirateGame game,Pirate pirate, Location loc, int moves)
- {
- this.game = game;
- this.pirate = pirate;
- this.location = chosePath(loc, moves);
- if (this.location != null) {
- this.moves = moves;
- movesLeft -= moves;
- occupied.add(this.location);
- }
- else
- {
- moved = true; //Setting this flag to make to not move the ship
- }
- }
- public Location chosePath(Location finalDestination, int plannedMoves) {
- // get a list of possible locations for the pirate ship after assigning it a number of steps ("moves") towards the destination
- List<Location> possibleLocations = game.getSailOptions(pirate, finalDestination, plannedMoves);
- printLocations(possibleLocations, game);
- prioritizeLocations(possibleLocations, game, pirate); //Sorting the locations by priority
- printLocations(possibleLocations, game);
- //printOccupied(game);
- for(Location tempLoc : possibleLocations)
- {
- if(!occupied.contains(tempLoc))
- return tempLoc;
- }
- return null;
- }
- public void run()
- {
- if(moved || moves <= 0)
- return;
- game.setSail(pirate, location);
- //printOccupied(game);
- }
- }
- @Override
- public void doTurn(PirateGame game)
- {
- movesLeft = maxMoves;
- List<Pirate> pirates = game.mySoberPirates();
- if (pirates.size() == 0)
- return;
- List<Pirate> Ships = new ArrayList<>(); //Ships to move this turn
- List<Move> moves = new ArrayList<>();
- Pirate shaid = null; //Kills himself
- //If we want a shahid
- chooseAShahid(pirates, game);
- if (shahidIndex != -1)
- shaid = game.allMyPirates().get(shahidIndex);
- //cehck which pirates are moved
- for(int i = 0; i < pirates.size(); i++)
- {
- if (pirates.get(i).getId() == shahidIndex)
- continue;
- //We fire or move
- if(!fire(pirates.get(i), game)) {
- Ships.add(pirates.get(i));
- }
- }
- Ships = prioritizePirates(Ships);
- //avoid ships
- avoidShips(game, pirates);
- //Move all the ships if there are ships to move
- if (Ships.size() != 0)
- moves.addAll(generateMoves(game,Ships));
- //Move the shahid with the remaining turns
- if (shahidIndex != -1) {
- if (!fire(shaid, game)) {
- moves.add(shahidMove(shaid, game));
- }
- }
- for(int i = 0; i < moves.size(); i++)
- {
- moves.get(i).run();
- }
- occupied = new ArrayList<>();
- }
- public void avoidShips(PirateGame game, List<Pirate> pirates)
- {
- avoidTheDrunk(game, game.myDrunkPirates()); //Avoids drunk ships
- //dont move to current position of either of our ships, needs to be updated
- for(int i = 0; i < pirates.size(); i++)
- {
- occupied.add(pirates.get(i).getLocation());
- }
- List<Pirate> myLost = game.myLostPirates();
- for (int i = 0; i < myLost.size(); i++) {
- occupied.add(myLost.get(i).getInitialLocation());
- }
- List<Pirate> enemyLost = game.enemyLostPirates();
- for (int i = 0; i < enemyLost.size(); i++) {
- occupied.add(enemyLost.get(i).getInitialLocation());
- }
- //printOccupied(game);
- }
- public void avoidTheDrunk(PirateGame game, List<Pirate> pirates) {
- List<Pirate> enemies = game.enemyDrunkPirates();
- for (int i = 0; i < enemies.size(); i++) {
- occupied.add(enemies.get(i).getLocation());
- }
- for (int i = 0; i < pirates.size(); i++) {
- occupied.add(pirates.get(i).getLocation());
- }
- }
- void chooseAShahid(List<Pirate> pirates, PirateGame game) {
- if(game.treasures().size() == 1)
- return;
- if (pirates.size() > maxMoves || pirates.size() > 1) {
- if (shahidIndex != -1 && !game.myLostPirates().contains(game.allMyPirates().get(shahidIndex)))
- return;
- shahidIndex = -1;
- int worseIndex = -1;
- for (Pirate temp : pirates) {
- if (!temp.hasTreasure()) {
- worseIndex = temp.getId();
- if (temp.getReloadTurns() == 0) {
- shahidIndex = temp.getId();
- }
- }
- }
- if (shahidIndex == -1)
- shahidIndex = worseIndex;
- }
- else if (game.enemyPiratesWithoutTreasures().size() != 0)
- shahidIndex = -1;
- }
- //fire function
- public boolean fire(Pirate pirate, PirateGame game) {
- //Cant fire if have treasure
- if (pirate.hasTreasure())
- return false;
- //reloading
- if(pirate.getReloadTurns() != 0)
- return false;
- List<Pirate> enemy = game.enemySoberPirates();
- //index of enemy in range
- int canFire = -1;
- //Fires if can. Prefers treasure
- for (int i = 0; i < enemy.size(); i++) {
- Pirate enemyTemp = enemy.get(i);
- if (game.inRange(pirate, enemyTemp)) {
- //If in range and has treasure fuck this bitch
- if (enemyTemp.hasTreasure()) {
- game.attack(pirate, enemyTemp);
- return true;
- }
- else
- canFire = i;
- }
- }
- if(canFire != -1)
- {
- game.attack(pirate, enemy.get(canFire));
- return true;
- }
- else
- return false;
- }
- List<Pirate> prioritizePirates(List<Pirate> ships) {
- List<Pirate> hasTreasure = new ArrayList<>();
- List<Pirate> withoutTreasure = new ArrayList<>();
- for (int i = 0; i < ships.size(); i++) {
- if (ships.get(i).hasTreasure())
- hasTreasure.add(ships.get(i));
- else
- withoutTreasure.add(ships.get(i));
- }
- hasTreasure.addAll(withoutTreasure);
- return hasTreasure;
- }
- //Sorts the possible routs by priority (0 is safest way, arr.length is most dangerous)
- void prioritizeLocations(List<Location> unsorted, PirateGame game, Pirate pirate) {
- int[] values = new int[unsorted.size()];
- int minDist; //Minimum distance
- int currentDist; //Temporary variable
- for (int i = 0; i < unsorted.size(); i++) {
- minDist = Integer.MAX_VALUE;
- for (Pirate enemy : game.enemySoberPirates()) {
- currentDist = game.distance(enemy, unsorted.get(i));
- if (currentDist < minDist)
- minDist = currentDist;
- }
- values[i] = minDist; //Rating a location by the distance from the closest enemy ship
- }
- quickSort(values, 0, values.length - 1, unsorted); //Sorts safe first
- boolean treasure = pirate.hasTreasure();
- if (treasure)
- game.debug("We have a treasure, ID: " + pirate.getId());
- boolean booze = pirate.getReloadTurns() <= 0;
- if (booze)
- game.debug("We have booze, ID: " + pirate.getId());
- if (!pirate.hasTreasure() && pirate.getReloadTurns() <= 0) { //Go dangerous if got no treasure but have booze
- Collections.reverse(unsorted); //Dangerous road
- game.debug("We went the dangerous road! ID: " + pirate.getId());
- }
- else
- game.debug("We went safe. ID: " + pirate.getId());
- }
- //A part of quickSort
- int partition(int arr[], int left, int right, List<Location> toSort)
- {
- int i = left, j = right;
- int tmp;
- Location tmpLocation;
- int pivot = arr[(left + right) / 2];
- while (i <= j) {
- while (arr[i] < pivot)
- i++;
- while (arr[j] > pivot)
- j--;
- if (i <= j) {
- tmp = arr[i];
- tmpLocation = toSort.get(i);
- arr[i] = arr[j];
- toSort.add(i, toSort.get(j));
- toSort.remove(i);
- arr[j] = tmp;
- toSort.add(j, tmpLocation);
- toSort.remove(j);
- i++;
- j--;
- }
- }
- return i;
- }
- //Sorts the given Location list by the values in arr (arr[i] holds the value for toSort.get(i))
- void quickSort(int arr[], int left, int right, List<Location> toSort) {
- int index = partition(arr, left, right, toSort);
- if (left < index - 1)
- quickSort(arr, left, index - 1, toSort);
- if (index < right)
- quickSort(arr, index, right, toSort);
- }
- //shaid moves
- Move shahidMove(Pirate pirate, PirateGame game) {
- List<Pirate> victims = game.enemyPiratesWithTreasures();
- //if no pirates with treasuser
- if(victims.isEmpty())
- {
- Location loc = game.enemySoberPirates().get(0).getInitialLocation();
- return new Move(game, pirate, loc, movesLeft);
- }
- int minDist = Integer.MAX_VALUE;
- int bestVictim = 0;
- //finds best jew to murder
- for (int i = 0; i < victims.size(); i++) {
- int dist = game.distance(victims.get(i).getLocation(), victims.get(i).getInitialLocation());
- if (dist < minDist) {
- minDist = dist;
- bestVictim = i;
- }
- }
- Location loc = victims.get(bestVictim).getInitialLocation();
- return new Move(game, pirate, loc, movesLeft);
- }
- boolean treasureCollision(PirateGame game, Pirate pirate, Treasure treasure) {
- if (pirate.getReloadTurns() > 0)
- return false;
- if (game.distance(pirate.getLocation(), treasure.getLocation()) <= maxMoves) {
- List<Pirate> enemies = game.enemySoberPirates();
- for (int i = 0; i < enemies.size(); i++) {
- if (game.distance(enemies.get(i).getLocation(), treasure.getLocation()) <= maxMoves) {
- return true;
- }
- }
- }
- return false;
- }
- //get the closest pirate treasure
- public List<Move> generateMoves(PirateGame game, List<Pirate> pirates)
- {
- List<Treasure> treasures = game.treasures();
- List<Move> moves = new ArrayList<>();
- //no treasures
- if(treasures.isEmpty())
- {
- //find ship with treasure and return to base
- for(int i = 0 ; i <pirates.size(); i++)
- {
- Pirate pirate = pirates.get(i);
- if(pirate.hasTreasure())
- {
- moves.add( new Move(game, pirate,pirate.getInitialLocation(), 1));
- }
- }
- return moves;
- }
- //treasures
- int [] ids = new int[2];
- int minPath = Integer.MAX_VALUE;
- int tempPath;
- for(int i = 0; i < pirates.size(); i++)
- {
- Pirate pirate = pirates.get(i);
- //check if ship with treauser
- if(pirate.hasTreasure())
- {
- moves.add(new Move(game, pirate, pirate.getInitialLocation(), 1));
- }
- else
- {
- //IF NOT THEN FIND PAIR
- for(int j = 0; j < treasures.size(); j++)
- {
- tempPath = game.distance(pirates.get(i), treasures.get(j));
- if( tempPath < minPath)
- {
- minPath = tempPath;
- ids[0] = i;
- ids[1] = j;
- }
- }
- }
- }
- int tempMove;
- //If we gonna collide avoid it, we subtract 2 because the enemy with the treasure collides with us after we shoot at it.
- if (treasureCollision(game, pirates.get(ids[0]), treasures.get(ids[1]))) {
- if (movesLeft > 2)
- tempMove = movesLeft - 2;
- else
- tempMove = 0;
- }
- else {
- tempMove = movesLeft;
- }
- if(pirates.get(ids[0]).hasTreasure())
- return moves;
- moves.add(new Move(game, pirates.get(ids[0]), treasures.get(ids[1]).getLocation(), tempMove));
- return moves;
- }
- //Helper function printing all the occupied positions on this turn
- public void printOccupied(PirateGame game)
- {
- for(Location loc : occupied)
- game.debug(loc.row + ", " + loc.col);
- }
- //Helper function to present locations in debug
- void printLocations(List<Location> locations, PirateGame game) {
- for (Location temp : locations) {
- game.debug(temp.row + ", " + temp.col);
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement