// Joseph Nguyen // 12/05/2015 // CSE142, Autumn 2015, Section AQ // TA: Ryan Parsons // Programming Assignment #9 HuskyJosephNguyen // /* 1. Huskies will hop an empty space or attack if enemy is in front until another husky is found in front, left, right, or back 2. Then once the HuskyJosephNguyen finds another one of its kind (including newly infected husky "babies" 3. Every (NUMBER OF HUSKIES ALIVE) * 10 calls to getMove, the Direction will change 4. The husky swarms will move a little bit in that direction 5. Then the huskies will stop and "rest" but some will keep guard for "enemy soldiers" 6. After a fair amount of time the huskies will move again in the same direction 7. Repeat Steps 4-6 several times and then the direction will change P.S. Few lost huskies will move in random directions trying to "look" for another husky Basically the strategy of this husky is to form several pack of 15+ huskies Which will later merge to have 1 or 2 pack of 30+ huskies Then the pack will go to one direction (taking breaks every second or two) and randomly pick another * */ import java.awt.Color; //so I can use Color import java.util.*; //so I can use Random public class HuskyJosephNguyen extends Critter { //every husky has a number that represents when it was constructed //if totalNum is 1 then its the first husky object constructed private static int totalNum; private int myNum; //so CritterInfo can be accessed in other methods without having to parameterize it private CritterInfo info; private int numHusky; private int numWall; private int numEnemies; private ArrayList neighbors; private Direction direction; private boolean safe; private Random rand; //these will be used in other methods private static int turnsAlive; private static Direction targetDirection; private static int countYears; private static boolean packOfHuskiesMove; private static int targetNumberOfTurns; private static int turnsCountingInThisInterval; //a static field to keep all track the Huskies created and dead huskies will be removed private static ArrayList history; public HuskyJosephNguyen() { totalNum++; myNum = totalNum; if(myNum == 1){ history = new ArrayList(); targetDirection = Direction.NORTH; targetNumberOfTurns = 30; } neighbors = new ArrayList(); rand = new Random(); history.add(this); safe = false; turnsAlive = history.get(0).getTurnsAlive(); packOfHuskiesMove = history.get(0).getPackOfHuskies(); targetNumberOfTurns = history.get(0).getTargetNumberOfTurns(); } // determines the next schoolOfHuskiesMoving of the HuskyJosephNguyen public Action getMove(CritterInfo info) { this.info = info; deleteDead(); updateFields(); if(turnsCountingInThisInterval == targetNumberOfTurns){ switchManevuers(); } if(info.getFront() == Neighbor.OTHER) { return Action.INFECT; }else if (neighbors.get(1) == Neighbor.OTHER) { return Action.LEFT; }else if (neighbors.get(3) == Neighbor.OTHER) { return Action.RIGHT; }else if(packOfHuskiesMove){ return schoolOfHuskiesMoving(); }else{ return hopUntilPackFound(); } } // makes the Husky black in the simulator public Color getColor() { return Color.BLACK; } // shows the Husky number in the simulator public String toString() { return "J"; } /* * private methods begin * */ //remove dead huskies in the history arraylist field private void deleteDead(){ for(int i = 0; i < history.size(); i++){ if(history.get(i).getTurnsAlive() + 10 < turnsAlive){ history.remove(i); } } } //determine the surroundings and update fields private void updateFields() { direction = info.getDirection(); turnsAlive++; neighbors.clear(); neighbors.add(info.getFront()); neighbors.add(info.getLeft()); neighbors.add(info.getBack()); neighbors.add(info.getRight()); /* int wall = 0; if(info.getFront() == Neighbor.WALL){ wall++; } if(info.getLeft() == Neighor.WALL){ wall++; } numWall = wall; */ } //every 30-100 calls to getMove() the huskies swarm either stop moving or start moving //They change direction every 90-300 calls to getMove() private void switchManevuers() { turnsCountingInThisInterval = 0; countYears++; if(packOfHuskiesMove){ targetNumberOfTurns = (int) (history.size() * 0.7); }else{ targetNumberOfTurns = history.size() * 7; } if(countYears % 7 == 0){ //888888888888888888888888888 int randomDirection = rand.nextInt(4); Direction[] possibleDirections = {Direction.NORTH, Direction.WEST, Direction.SOUTH, Direction.EAST}; Direction selectedDirection = possibleDirections[randomDirection]; while(targetDirection == selectedDirection){ randomDirection = rand.nextInt(4); selectedDirection = possibleDirections[randomDirection]; } targetDirection = selectedDirection; } if(packOfHuskiesMove){ packOfHuskiesMove = false; }else{ packOfHuskiesMove = true; } } //Huskies will attack any enemy in front but will hop until another husky is found //in front, left, right, or back private Action hopUntilPackFound() { turnsCountingInThisInterval++; if(lookingForOtherHuskies()) { safe = true; return Action.RIGHT; }else if(!(lookingForOtherHuskies())){ safe = false; } if (safe){ return huskyTribeNotMoving(true); }else{ return Action.HOP; } } //checks if there is any husky to the left, right, front, or back private boolean lookingForOtherHuskies() { return (info.getFront() == Neighbor.SAME || info.getBack() == Neighbor.SAME || info.getRight() == Neighbor.SAME || info.getLeft() == Neighbor.SAME); } //Pack needs to defend its village, the best way to do that is to act like a flytrap for //10 turns, then move 10 steps in a random direction and back and forth private Action huskyTribeNotMoving(boolean passedFromHopUntilPackFoundMethod) { if(!passedFromHopUntilPackFoundMethod){ turnsCountingInThisInterval++; } if(numWall == 2 && numEnemies == 0 && numHusky == 0){ return Action.RIGHT; }else if(neighbors.get(0) == Neighbor.SAME || neighbors.get(0) == Neighbor.WALL) { return Action.RIGHT; }else{ return Action.LEFT; } } //huskies move in the target direction private Action schoolOfHuskiesMoving() { turnsCountingInThisInterval++; if (!(direction == targetDirection)) { return Action.LEFT; }else if(info.getFront() != Neighbor.SAME && info.getFront() != Neighbor.WALL){ return Action.HOP; }else{ return Action.LEFT; } } //accessor methods begin here //returns the number of turns the oldest husky (still alive) was alive private int getTurnsAlive(){ return turnsAlive; } //returns the turn number that the huskies private int getTargetNumberOfTurns() { return targetNumberOfTurns; } //returns if huskies are moving or not private boolean getPackOfHuskies() { return packOfHuskiesMove; } /**Several things I need to improve: * * When the pack of Huskies are in the corner they sometimes look like this ********* ******* ****** ***** ** * * * * * * * * * * * They should be more clumped up */ /* Also another weakness of the husky is that if they are cornered * they may try to move towards the wall * One remedy is to count all the huskies and ask if there is a wall in a specified dirction * The problem is that huskies whose getMove method is not called yet will have an error * */ }