/** * */ package testa.worm.cpu; import testa.TestA; import testa.util.Util; import testa.worm.Worm; import testa.worm.WormController; /** * J2DLoachTest - CPUWormController * @version 1.0 * @author Chris Dennett */ public final class CPUWormController extends WormController { private CPUWormOptimiser optimiser; private int[] temp1 = new int[2], temp2 = new int[2], temp3 = new int[3], collData1 = new int[3], collData2 = new int[3] ; private long lastControllerUpdateTimeMS = 0; private static final int EVENT_UNKNOWN = 0, EVENT_PERIODIC_UPDATE = 1, EVENT_PICKUP_SPAWN = 2, EVENT_PICKUP_COLLECTION = 3, EVENT_PICKUP_TIMEOUT = 4, EVENT_WORM_DEATH = 5, EVENT_WORM_MOVEMENT = 6, EVENT_WORM_COLLISION = 7 ; public static final String[] BLOCKING_PATTERN = new String[] { "S 0" + "S10", "S00" + "S10" }; /** * @param loach * @param optimiser */ public CPUWormController(TestA loach, CPUWormOptimiser optimiser) { super(loach, WC_TYPE_CPU); this.optimiser = optimiser; optimiser.addController(this); } /* (non-Javadoc) * @see testa.worm.WormController#dispose() */ @Override public void dispose() { optimiser.removeController(this); super.dispose(); } /* (non-Javadoc) * @see testa.worm.WormController#update() */ @Override public void update() { if (worm.getNoOfSegments() <= 0) return; long currUpdateTimeMS = loach.getCurrUpdateTimeMS(); if ((lastControllerUpdateTimeMS + 5 + TestA.RANDOM.nextInt(10)) < currUpdateTimeMS) { recheck(EVENT_PERIODIC_UPDATE, 0, 0, 0, 0); lastControllerUpdateTimeMS = currUpdateTimeMS; } } /* (non-Javadoc) * @see testa.worm.WormController#onDeath(int) */ @Override public void onDeath(int cause) { // TODO Auto-generated method stub } /* (non-Javadoc) * @see testa.worm.WormController#onGrowth(int) */ @Override public void onGrowth(int cause) { // TODO Auto-generated method stub } /* (non-Javadoc) * @see testa.worm.WormController#onShrink(int, boolean) */ @Override public void onShrink(int amount, boolean death) { // TODO Auto-generated method stub } /** * @return the optimiser */ public CPUWormOptimiser getOptimiser() { return optimiser; } /* (non-Javadoc) * @see testa.worm.WormController#onForwardMovement(boolean, int[]) */ @Override public void onForwardMovement(boolean succeeded, int[] collisionData) { recheck(EVENT_WORM_MOVEMENT, TestA.OBJ_TYPE_WORM, worm.getIndex(), 0, 0); } private int recheck(int event, int type, int index1, int index2, int index3) { if (worm.getNoOfSegments() <= 0) return Worm.DIRECTION_NONE; long currUpdateTimeMS = loach.getCurrUpdateTimeMS(); int wormCurrHeading = worm.getHeading(); int wormReverseHeading = Worm.clockDirection(wormCurrHeading, 2); // reverse int wormCurrDirection = worm.getDirection(); boolean flip = TestA.RANDOM.nextInt(2) == 1; boolean findOther = false; int bestDirection = wormCurrHeading; int bestDirectionScore = -20000; int score; //int[] considerationOrder = new int[4]; int noOfSegments = worm.getNoOfSegments(); int pickupDirection = Worm.DIRECTION_NONE; int nearestPickupIndex = findNearestPickupIndex(); int headX = worm.getHeadX(); int headY = worm.getHeadY(); if (nearestPickupIndex != -1) { int[] pickupTypes = loach.getPickupTypes(); int[] pickupPositions = loach.getPickupLocations(); int pickupX = pickupPositions[nearestPickupIndex * 2]; int pickupY = pickupPositions[(nearestPickupIndex * 2) + 1]; int xd = pickupX - headX; int yd = pickupY - headY; int xdiff = Util.difference(pickupX, headX); int ydiff = Util.difference(pickupY, headY); if (yd < 0) { // upwardly if (xd < 0) { if (ydiff > xdiff) { pickupDirection = Worm.DIRECTION_NORTH; } else { pickupDirection = Worm.DIRECTION_WEST; } } else { if (ydiff > xdiff) { pickupDirection = Worm.DIRECTION_EAST; } else { pickupDirection = Worm.DIRECTION_SOUTH; } } } else { // downwardly if (xd > 0) { if (ydiff < xdiff) { pickupDirection = Worm.DIRECTION_NORTH; } else { pickupDirection = Worm.DIRECTION_EAST; } } else { if (ydiff < xdiff) { pickupDirection = Worm.DIRECTION_WEST; } else { pickupDirection = Worm.DIRECTION_SOUTH; } } } } for (int i = 0; i < 4; i++) { int direction = Worm.clockDirection(wormCurrHeading, i); if (noOfSegments > 1 && direction == wormReverseHeading) continue; // check invalid score = 0; if (direction == wormCurrHeading) { score += 20 + TestA.RANDOM.nextInt(10); TestA.RANDOM.setSeed(System.nanoTime() + TestA.randwot++); } Worm.getMovementDelta(direction, temp2); int x = headX + temp2[0], y = headY + temp2[1]; if (loach.checkCollision(TestA.OBJ_TYPE_WORM, x, y, collData1)) { // check for positive pickup collision if (collData1[0] >= 20 && collData1[0] < 40) { score += 30 + TestA.PICKUP_INFOS[collData1[0] - 20].getDesire(); } else { score -= 5000; } } else { score += 10; if (nearestPickupIndex != -1 && direction == pickupDirection) { int[] types = loach.getPickupTypes(); //System.out.println("nearestPickupIndex: " + nearestPickupIndex); int foundType = types[nearestPickupIndex]; //System.out.println("foundtype: " + foundType); if (foundType != TestA.OBJ_TYPE_NONE) { int typeIndex = foundType - 20; //System.out.println("typeIndex: " + typeIndex); int currscore = TestA.PICKUP_INFOS[typeIndex].getDesire() * 2; //System.out.println("currscore: " + typeIndex); score += currscore; } } if (worm.getNoOfSegments() > 1) { int max = Math.min(4, worm.getNoOfSegments()); for (int j = 1; j < max; j++) { worm.getSegmentPos(temp3, j); if (Util.difference(temp3[0], x) < 2 || Util.difference(temp3[1], y) < 2) { score -= TestA.RANDOM.nextInt(10); TestA.RANDOM.setSeed(System.nanoTime() + TestA.randwot++); } } } } int quarterX = TestA.GRID_SEGS_IN_WIDTH / 4; int quarterY = TestA.GRID_SEGS_IN_HEIGHT / 4; int segmentsAwayFromWallX = 0, segmentsAwayFromWallY = 0; if (x < TestA.GRID_SEGS_IN_WIDTH / 2) { segmentsAwayFromWallX = x; } else { segmentsAwayFromWallX = TestA.GRID_SEGS_IN_WIDTH - x; } if (y < TestA.GRID_SEGS_IN_HEIGHT / 2) { segmentsAwayFromWallY = y; } else { segmentsAwayFromWallY = TestA.GRID_SEGS_IN_HEIGHT - y; } int currScore = 0; if (segmentsAwayFromWallX < quarterX) { currScore += ((TestA.GRID_SEGS_IN_WIDTH - segmentsAwayFromWallX) + TestA.RANDOM.nextInt(3)) / 4; } if (segmentsAwayFromWallY < quarterY) { currScore += ((TestA.GRID_SEGS_IN_HEIGHT - segmentsAwayFromWallY) + TestA.RANDOM.nextInt(3)) / 4; } //if (worm.getIndex() == 1) System.out.println("wallscore" + worm.getIndex() + ": " + currScore); score -= currScore; // random factor :) score += 6 - TestA.RANDOM.nextInt(12); TestA.RANDOM.setSeed(System.nanoTime() + TestA.randwot++); /* if (worm.getIndex() == 1 && worm.getLastCollisionData()[0] >= 5 && worm.getLastCollisionData()[0] <= 9) { System.out.println("direction1: " + Worm.getDirectionStr(direction)); System.out.println("directionScore1: " + score); } */ if (score > bestDirectionScore) { /* if (worm.getIndex() == 1 && worm.getLastCollisionData()[0] >= 5 && worm.getLastCollisionData()[0] <= 9) { System.out.println("made " + Worm.getDirectionStr(direction) + " best direction!!"); } */ bestDirection = direction; bestDirectionScore = score; } } if (bestDirection != Worm.DIRECTION_NONE && wormCurrDirection != bestDirection) { worm.setDirection(bestDirection); } /* if (worm.getIndex() == 1 && worm.getLastCollisionData()[0] >= 5 && worm.getLastCollisionData()[0] <= 9) { System.out.println("bestDirection1: " + Worm.getDirectionStr(bestDirection)); System.out.println("bestDirectionScore1: " + bestDirectionScore); } */ return bestDirection; } /** * * * @return -1 if pickup not found. */ public int findNearestPickupIndex() { int[] pickupTypes = loach.getPickupTypes(); int[] pickupLocations = loach.getPickupLocations(); long[] pickupSpawnTimes = loach.getPickupSpawnTimes(); int wormHeadX = worm.getHeadX(), wormHeadY = worm.getHeadY(); int nearestPickupIndex = -1; int nearestPickupDistance = -1; for (int i = 0; i < TestA.MAX_PICKUPS; i++) { if (pickupTypes[i] == TestA.OBJ_TYPE_NONE) continue; int x = pickupLocations[i * 2]; int y = pickupLocations[(i * 2) + 1]; int distance = Util.obtainPointToPointDistance(wormHeadX, wormHeadY, x, y); if (nearestPickupIndex == -1 || distance < nearestPickupDistance) { nearestPickupIndex = i; nearestPickupDistance = distance; } } return nearestPickupIndex; } /* (non-Javadoc) * @see testa.worm.WormController#onPickup(int, int) */ @Override public void onPickup(int type, int index) { recheck(EVENT_PICKUP_COLLECTION, loach.getPickupTypes()[index], index, worm.getIndex(), 0); } /* (non-Javadoc) * @see testa.worm.WormController#onArenaPickupCollection(int, int) */ @Override public void onArenaPickupCollection(int index, int wormIndex) { if (wormIndex != worm.getIndex()) recheck(EVENT_PICKUP_COLLECTION, loach.getPickupTypes()[index], index, wormIndex, 0); } /* (non-Javadoc) * @see testa.worm.WormController#onArenaPickupSpawn(int) */ @Override public void onArenaPickupSpawn(int index) { recheck(EVENT_PICKUP_SPAWN, loach.getPickupTypes()[index], index, 0, 0); } /* (non-Javadoc) * @see testa.worm.WormController#onArenaPickupTimeout(int) */ @Override public void onArenaPickupTimeout(int index) { recheck(EVENT_PICKUP_TIMEOUT, loach.getPickupTypes()[index], index, 0, 0); } }