Skip to main content
replaced http://codegolf.stackexchange.com/ with https://codegolf.stackexchange.com/
Source Link

Uses the same scoring mechanism as my ChoiceCat entrymy ChoiceCat entry. There is a little modification which helps to choose relevant cells at the first few steps as ChoiceCat doesn't care about the first few buckets as it doesn't see them as threat.

Uses the same scoring mechanism as my ChoiceCat entry. There is a little modification which helps to choose relevant cells at the first few steps as ChoiceCat doesn't care about the first few buckets as it doesn't see them as threat.

Uses the same scoring mechanism as my ChoiceCat entry. There is a little modification which helps to choose relevant cells at the first few steps as ChoiceCat doesn't care about the first few buckets as it doesn't see them as threat.

added 118 characters in body
Source Link
flawr
  • 44.1k
  • 7
  • 109
  • 253

ChoiceCat vs ChoiceCatcher:

ChoiceCat vs ChoiceCatcher

ChoiceCat vs ChoiceCatcher:

ChoiceCat vs ChoiceCatcher

added 783 characters in body
Source Link
randomra
  • 20.9k
  • 4
  • 48
  • 113

ChoiceCatChoiceCatcher

For every possible new cat positions we check its goodness and chooseUses the best onesame scoring mechanism as my ChoiceCat entry. GoodnessThere is the function of the two best neighboura little modification which helps to choose relevant cells who are further away from the cat position thanat the position whose score we calculate. We use only two cells because one can be blocked andfirst few steps as ChoiceCat doesn't care about the cat only needs one more to get away. Our function prefers two fairly good cells than one great and one bad. Positions withfirst few buckets have a score of 0 and the furthest free cells have a score of 1as it doesn't see them as threat.

ChoiceCatChoiceCatcher seems to score considerably better than the current catscatchers.

package players; /** * @author randomra */ import java.util.Arrays; import main.Field; public class ChoiceCatChoiceCatcher implements CatCatcher { private class Values { public final int size; private double[][] f; Values(int size) { this.size = size; f = new double[size][size]; } public double read(int[] p) { int i = p[0]; int j = p[1]; i = (i % size + size) % size; j = (j % size + size) % size; return f[i][j]; } private double write(int[] p, double v) { int i = p[0]; int j = p[1]; i = (i % size + size) % size; j = (j % size + size) % size; return f[i][j] = v; } } final int[][] turns = { { -1, 1 }, { 0, 1 }, { 1, 0 }, { 1, -1 }, { 0, -1 }, { -1, 0 } };// all valid moves CW order final int stepCheck = 5; public String getName() { return "ChoiceCat";"ChoiceCatcher"; }  @Override  public int[] takeTurn(Field f) {  int[] bestPos = null; double bestPosValue = Double.MAX_VALUE; for (int i = 0; i < f.SIZE; i++) { for (int j = 0; j < f.SIZE; j++) { if (f.read(i, j) == Field.EMPTY) { Field myField = new Field(f); myField.placeBucket(new int[] { i, j }); double posValue = catTurnValue(myField); if (posValue < bestPosValue) { bestPosValue = posValue; bestPos = new int[] { i, j }; } } } } return bestPos; } private double catTurnValue(Field f) {  int[] pos = f.findCat(); int[]double[] bestMovevalues = { 0, 1new };double[6];   double bestMoveValue =int -1;count=0; for (int[] t : turns) { int[] currPos = { pos[0] + t[0], pos[1] + t[1] }; double moveValue = movePosValue(currPos, f); if (moveValue > bestMoveValue) { bestMoveValue = moveValue; bestMove = t; }values[count++]=moveValue; } Arrays.sort(values); return bestMove;values[5]; } private double movePosValue(int[] pos, Field f) { Values v = new Values(f.SIZE); for (int ring = stepCheck; ring >= 0; ring--) { for (int phase = 0; phase < 2; phase++) { for (int sidepos = 0; sidepos < Math.max(1, ring); sidepos++) { for (int side = 0; side < 6; side++) { int[] evalPos = new int[2]; for (int coord = 0; coord < 2; coord++) { evalPos[coord] = pos[coord] + turns[side][coord] * sidepos + turns[(side + 1) % 6][coord] * (ring - sidepos); } if (phase == 0) { if (ring == stepCheck) { // on outmost ring, init value v.write(evalPos, -1); } else { v.write(evalPos, posValue(evalPos, v, f)); } } else { // finalize position value for next turn v.write(evalPos, -v.read(evalPos)); } } } } } return -v.read(pos); } private double posValue(int[] pos, Values v, Field f) { if (f.read(pos[0], pos[1]) == Field.BUCKET) { return 0; } int count = 0;  int maxRoutes = 2;  double[] product = new double[6]; for (int[] t : turns) { int[] tPos = new int[] { pos[0] + t[0], pos[1] + t[1] }; if (v.read(tPos) > 0) { product[count] = 1 - 1 / (v.read(tPos) + 1); count++; } } Arrays.sort(product); double fp = 1; for (int i = 0; i < Math.min(count,2 maxRoutes); i++) { fp *= product[5 - i]; } double fp2 = 1; for (int i = 0; i < Math.min(count, 6); i++) { fp2 *= product[5 - i]; } double retValue = Math.min(count,2 maxRoutes) + fp; double retValue2 = Math.min(count, 6) + fp2; return -retValue;retValue - retValue2 / 1000000; }   } 

ChoiceCat

For every possible new cat positions we check its goodness and choose the best one. Goodness is the function of the two best neighbour cells who are further away from the cat position than the position whose score we calculate. We use only two cells because one can be blocked and the cat only needs one more to get away. Our function prefers two fairly good cells than one great and one bad. Positions with buckets have a score of 0 and the furthest free cells have a score of 1.

ChoiceCat seems to score better than the current cats.

package players; /** * @author randomra */ import java.util.Arrays; import main.Field; public class ChoiceCat implements Cat { private class Values { public final int size; private double[][] f; Values(int size) { this.size = size; f = new double[size][size]; } public double read(int[] p) { int i = p[0]; int j = p[1]; i = (i % size + size) % size; j = (j % size + size) % size; return f[i][j]; } private double write(int[] p, double v) { int i = p[0]; int j = p[1]; i = (i % size + size) % size; j = (j % size + size) % size; return f[i][j] = v; } } final int[][] turns = { { -1, 1 }, { 0, 1 }, { 1, 0 }, { 1, -1 }, { 0, -1 }, { -1, 0 } };// all valid moves CW order final int stepCheck = 5; public String getName() { return "ChoiceCat"; } public int[] takeTurn(Field f) { int[] pos = f.findCat(); int[] bestMove = { 0, 1 };   double bestMoveValue = -1; for (int[] t : turns) { int[] currPos = { pos[0] + t[0], pos[1] + t[1] }; double moveValue = movePosValue(currPos, f); if (moveValue > bestMoveValue) { bestMoveValue = moveValue; bestMove = t; } } return bestMove; } private double movePosValue(int[] pos, Field f) { Values v = new Values(f.SIZE); for (int ring = stepCheck; ring >= 0; ring--) { for (int phase = 0; phase < 2; phase++) { for (int sidepos = 0; sidepos < Math.max(1, ring); sidepos++) { for (int side = 0; side < 6; side++) { int[] evalPos = new int[2]; for (int coord = 0; coord < 2; coord++) { evalPos[coord] = pos[coord] + turns[side][coord] * sidepos + turns[(side + 1) % 6][coord] * (ring - sidepos); } if (phase == 0) { if (ring == stepCheck) { // on outmost ring, init value v.write(evalPos, -1); } else { v.write(evalPos, posValue(evalPos, v, f)); } } else { // finalize position value for next turn v.write(evalPos, -v.read(evalPos)); } } } } } return -v.read(pos); } private double posValue(int[] pos, Values v, Field f) { if (f.read(pos[0], pos[1]) == Field.BUCKET) { return 0; } int count = 0; double[] product = new double[6]; for (int[] t : turns) { int[] tPos = new int[] { pos[0] + t[0], pos[1] + t[1] }; if (v.read(tPos) > 0) { product[count] = 1 - 1 / (v.read(tPos) + 1); count++; } } Arrays.sort(product); double fp = 1; for (int i = 0; i < Math.min(count,2); i++) { fp *= product[5-i]; } double retValue = Math.min(count,2) + fp; return -retValue; } } 

ChoiceCatcher

Uses the same scoring mechanism as my ChoiceCat entry. There is a little modification which helps to choose relevant cells at the first few steps as ChoiceCat doesn't care about the first few buckets as it doesn't see them as threat.

ChoiceCatcher seems to score considerably better than the current catchers.

package players; /** * @author randomra */ import java.util.Arrays; import main.Field; public class ChoiceCatcher implements Catcher { private class Values { public final int size; private double[][] f; Values(int size) { this.size = size; f = new double[size][size]; } public double read(int[] p) { int i = p[0]; int j = p[1]; i = (i % size + size) % size; j = (j % size + size) % size; return f[i][j]; } private double write(int[] p, double v) { int i = p[0]; int j = p[1]; i = (i % size + size) % size; j = (j % size + size) % size; return f[i][j] = v; } } final int[][] turns = { { -1, 1 }, { 0, 1 }, { 1, 0 }, { 1, -1 }, { 0, -1 }, { -1, 0 } };// all valid moves CW order final int stepCheck = 5; public String getName() { return "ChoiceCatcher"; }  @Override  public int[] takeTurn(Field f) {  int[] bestPos = null; double bestPosValue = Double.MAX_VALUE; for (int i = 0; i < f.SIZE; i++) { for (int j = 0; j < f.SIZE; j++) { if (f.read(i, j) == Field.EMPTY) { Field myField = new Field(f); myField.placeBucket(new int[] { i, j }); double posValue = catTurnValue(myField); if (posValue < bestPosValue) { bestPosValue = posValue; bestPos = new int[] { i, j }; } } } } return bestPos; } private double catTurnValue(Field f) {  int[] pos = f.findCat(); double[] values = new double[6]; int count=0; for (int[] t : turns) { int[] currPos = { pos[0] + t[0], pos[1] + t[1] }; double moveValue = movePosValue(currPos, f); values[count++]=moveValue; } Arrays.sort(values); return values[5]; } private double movePosValue(int[] pos, Field f) { Values v = new Values(f.SIZE); for (int ring = stepCheck; ring >= 0; ring--) { for (int phase = 0; phase < 2; phase++) { for (int sidepos = 0; sidepos < Math.max(1, ring); sidepos++) { for (int side = 0; side < 6; side++) { int[] evalPos = new int[2]; for (int coord = 0; coord < 2; coord++) { evalPos[coord] = pos[coord] + turns[side][coord] * sidepos + turns[(side + 1) % 6][coord] * (ring - sidepos); } if (phase == 0) { if (ring == stepCheck) { // on outmost ring, init value v.write(evalPos, -1); } else { v.write(evalPos, posValue(evalPos, v, f)); } } else { // finalize position value for next turn v.write(evalPos, -v.read(evalPos)); } } } } } return -v.read(pos); } private double posValue(int[] pos, Values v, Field f) { if (f.read(pos[0], pos[1]) == Field.BUCKET) { return 0; } int count = 0;  int maxRoutes = 2;  double[] product = new double[6]; for (int[] t : turns) { int[] tPos = new int[] { pos[0] + t[0], pos[1] + t[1] }; if (v.read(tPos) > 0) { product[count] = 1 - 1 / (v.read(tPos) + 1); count++; } } Arrays.sort(product); double fp = 1; for (int i = 0; i < Math.min(count, maxRoutes); i++) { fp *= product[5 - i]; } double fp2 = 1; for (int i = 0; i < Math.min(count, 6); i++) { fp2 *= product[5 - i]; } double retValue = Math.min(count, maxRoutes) + fp; double retValue2 = Math.min(count, 6) + fp2; return -retValue - retValue2 / 1000000; }   } 
Source Link
randomra
  • 20.9k
  • 4
  • 48
  • 113
Loading