diff --git a/debug/styles.css b/debug/styles.css
index 7ce06a7..d5ac13f 100644
--- a/debug/styles.css
+++ b/debug/styles.css
@@ -91,6 +91,10 @@ pre {
flex: 1;
width: 100%;
border: 1px solid #eee;
+ text-align: center;
+ font-size: 22px;
+ line-height: 4;
+ color: #fff;
}
.weight {
diff --git a/src/lib/moveTowardsFoodPf.ts b/src/lib/moveTowardsFoodPf.ts
index 48a8376..a284187 100644
--- a/src/lib/moveTowardsFoodPf.ts
+++ b/src/lib/moveTowardsFoodPf.ts
@@ -29,10 +29,7 @@ function sortedFood(request: BTRequest, weightOptions: WeightOptions): Sorted[]
food: food,
distance: path.distance,
direction: path.direction,
- weight: weight(request, food.x, food.y, {
- blockHeads: true,
- attackHeads: true,
- })
+ weight: weight(request, food.x, food.y, weightOptions)
});
}
}
@@ -71,7 +68,7 @@ function isSquadCloser(request: BTRequest, closest: Sorted, weightOptions: Weigh
export function moveTowardsFoodPf(request: BTRequest, weightOptions: WeightOptions, ignoreCloserSquads: boolean) {
const sorted = sortedFood(request, weightOptions);
if (!sorted.length) {
- log('moveTowardsFoodPf', 'no food');
+ request.log('moveTowardsFoodPf', 'no food');
return;
}
for (const closest of sorted) {
@@ -85,10 +82,10 @@ export function moveTowardsFoodPf(request: BTRequest, weightOptions: WeightOptio
}
// Check if squad is closer
if (!ignoreCloserSquads || !isSquadCloser(request, closest, weightOptions)) {
- log('moveTowardsFoodPf', closest.direction, closest.food, closest.weight, closest.distance);
+ request.log('moveTowardsFoodPf', closest.direction, closest.food, closest.weight, closest.distance);
return closest.direction;
}
}
}
- log('moveTowardsFoodPf', 'no options');
+ request.log('moveTowardsFoodPf', 'no options');
}
diff --git a/src/lib/weight.ts b/src/lib/weight.ts
index 8b472e8..79a34a4 100644
--- a/src/lib/weight.ts
+++ b/src/lib/weight.ts
@@ -101,9 +101,22 @@ const isNearTail = (data: BTData, x: number, y: number) => {
export interface WeightOptions {
blockHeads: boolean,
attackHeads: boolean,
+ borders?: boolean,
+ snakeBodies?: boolean,
+ deadEnds?: boolean,
}
export function weight(request: BTRequest, x: number, y: number, options: WeightOptions): number {
+ if (options.borders === undefined) {
+ options.borders = true;
+ }
+ if (options.snakeBodies === undefined) {
+ options.snakeBodies = true;
+ }
+ if (options.deadEnds === undefined) {
+ options.deadEnds = true;
+ }
+
request.grid[y][x].weight = computeWeight(request, x, y, options);
let color = Math.round((request.grid[y][x].weight) / 100 * 255);
@@ -123,13 +136,11 @@ function computeWeight(request: BTRequest, x: number, y: number, options: Weight
let result = 100;
for (const snake of request.body.board.snakes) {
- const body = snake.body;
- // const body = snake.body.filter((p1, i, a) => a.findIndex(p2 => p1.x == p2.x && p1.y == p2.y) === i);
- for (const [p, part] of body.entries()) {
+ for (const [p, part] of snake.body.entries()) {
// Is part of snake?
if (part.x == x && part.y == y) {
// Is end of snake?
- if (p != body.length - 1) {
+ if (p != snake.body.length - 1) {
// Is head of snake, and head blocking?
if (p === 0 && !options.blockHeads) {
continue;
@@ -152,13 +163,15 @@ function computeWeight(request: BTRequest, x: number, y: number, options: Weight
// return 75;
// }
- if (isDeadEnd(request.body, x, y) && !isNearTail(request.body, x, y)) {
- return 0;
- }
+ if (options.deadEnds) {
+ if (isDeadEnd(request.body, x, y) && !isNearTail(request.body, x, y)) {
+ return 1;
+ }
- const fillCount = floodFill(request, x, y);
- if (fillCount < request.body.you.body.length) {
- result = Math.min(result, fillCount);
+ const fillCount = floodFill(request, x, y);
+ if (fillCount < request.body.you.body.length) {
+ result = Math.min(result, fillCount);
+ }
}
if (options.attackHeads) {
@@ -176,43 +189,47 @@ function computeWeight(request: BTRequest, x: number, y: number, options: Weight
}
}
- for (const snake of request.body.board.snakes) {
- const body = snake.body;
- for (const [p, part] of body.entries()) {
- let tailWeight = 40;
- if (p == body.length - 1) {
- tailWeight = 55;
- }
- if (x + 1 == part.x && y == part.y) {
- result = Math.min(result, tailWeight);
- }
- if (x - 1 == part.x && y == part.y) {
- result = Math.min(result, tailWeight);
- }
- if (x == part.x && y + 1 == part.y) {
- result = Math.min(result, tailWeight);
- }
- if (x == part.x && y - 1 == part.y) {
- result = Math.min(result, tailWeight);
+ if (options.snakeBodies) {
+ for (const snake of request.body.board.snakes) {
+ const body = snake.body;
+ for (const [p, part] of body.entries()) {
+ let tailWeight = 40;
+ if (p == body.length - 1) {
+ tailWeight = 55;
+ }
+ if (x + 1 == part.x && y == part.y) {
+ result = Math.min(result, tailWeight);
+ }
+ if (x - 1 == part.x && y == part.y) {
+ result = Math.min(result, tailWeight);
+ }
+ if (x == part.x && y + 1 == part.y) {
+ result = Math.min(result, tailWeight);
+ }
+ if (x == part.x && y - 1 == part.y) {
+ result = Math.min(result, tailWeight);
+ }
}
}
}
// Borders
- if (x == 0) {
- result = Math.min(result, 35);
- }
+ if (options.borders) {
+ if (x == 0) {
+ result = Math.min(result, 35);
+ }
- if (y == 0) {
- result = Math.min(result, 35);
- }
+ if (y == 0) {
+ result = Math.min(result, 35);
+ }
- if (x == request.body.board.width - 1) {
- result = Math.min(result, 35);
- }
+ if (x == request.body.board.width - 1) {
+ result = Math.min(result, 35);
+ }
- if (y == request.body.board.height - 1) {
- result = Math.min(result, 35);
+ if (y == request.body.board.height - 1) {
+ result = Math.min(result, 35);
+ }
}
result = Math.min(result, 50);
diff --git a/src/server/snakes/tail-chase.ts b/src/server/snakes/tail-chase.ts
index fca2a31..2cd8dc6 100644
--- a/src/server/snakes/tail-chase.ts
+++ b/src/server/snakes/tail-chase.ts
@@ -29,9 +29,19 @@ export class TailChase extends BaseSnake implements ISnake {
private getFood(request: BTRequest): MoveDirection {
if (request.body.you.health < request.body.board.width || request.body.you.health < request.body.board.height) {
+ request.log('TailChase', 'gettingFood', {
+ blockHeads: true,
+ attackHeads: true,
+ borders: false,
+ snakeBodies: false,
+ deadEnds: false,
+ }, true);
return moveTowardsFoodPf(request, {
blockHeads: true,
attackHeads: true,
+ borders: false,
+ snakeBodies: false,
+ deadEnds: false,
}, true);
}
}
@@ -40,6 +50,9 @@ export class TailChase extends BaseSnake implements ISnake {
return moveTowardsTail(request, {
blockHeads: true,
attackHeads: false,
+ borders: false,
+ snakeBodies: false,
+ deadEnds: false,
});
}
diff --git a/src/web/controllers/debug.ts b/src/web/controllers/debug.ts
index f9e3648..5a02256 100644
--- a/src/web/controllers/debug.ts
+++ b/src/web/controllers/debug.ts
@@ -5,7 +5,7 @@ import { BTRequest } from '../../types/BTData';
interface DebugControllerScope extends AngularScope {
request: BTRequest,
- recomputeWeights: (blockHeads: boolean, attackHeads: boolean) => void,
+ recomputeWeights: (...any: any[]) => void,
}
export const DebugController = [
@@ -17,13 +17,16 @@ export const DebugController = [
loadGrid($scope.request);
});
- $scope.recomputeWeights = (blockHeads: boolean, attackHeads: boolean) => {
+ $scope.recomputeWeights = (blockHeads: boolean, attackHeads: boolean, snakeBodies: boolean, borders: boolean, deadEnds: boolean) => {
console.log('Recompute weights');
for (var y = 0; y < $scope.request.body.board.height; y++) {
for (var x = 0; x < $scope.request.body.board.width; x++) {
$scope.request.grid[y][x].weight = weight($scope.request, x, y, {
- blockHeads,
- attackHeads,
+ blockHeads: blockHeads || false,
+ attackHeads: attackHeads || false,
+ snakeBodies: snakeBodies || false,
+ borders: borders || false,
+ deadEnds: deadEnds || false,
});
}
}
diff --git a/src/web/grid.ts b/src/web/grid.ts
index 0d4ee78..0402c74 100644
--- a/src/web/grid.ts
+++ b/src/web/grid.ts
@@ -1,4 +1,4 @@
-import { BTRequest } from '../types/BTData';
+import { BTRequest, BTXY } from '../types/BTData';
import snakes from "../server/snakes";
import { invertColor } from '../lib/invertColor';
import * as Color from 'color';
@@ -71,13 +71,31 @@ export function loadGrid(request: BTRequest) {
} else if (request.body.you.squad && request.body.you.squad == snake.squad) {
color = '#3c69e7';
}
+ let previousPart: BTXY;
for (const [p, part] of snake.body.entries()) {
const col = getCol(part.x, part.y);
$('
').addClass('snake').css({
backgroundColor: color,
borderColor: new Color(color).darken(0.2).hex(),
borderRadius: p == 0 ? 100 : 0,
- }).text(' ').appendTo(col);
+ }).text(p === 0 ? ' ' : getArrow(part, previousPart)).appendTo(col);
+ previousPart = part;
}
}
-};
\ No newline at end of file
+};
+
+function getArrow(current: BTXY, previous?: BTXY) {
+ if (previous) {
+ if (current.x == previous.x - 1 && current.y == previous.y) {
+ return '→';
+ } else if (current.x == previous.x + 1 && current.y == previous.y) {
+ return '←';
+ } else if (current.x == previous.x && current.y == previous.y - 1) {
+ return '↓';
+ } else if (current.x == previous.x && current.y == previous.y + 1) {
+ return '↑';
+ }
+
+ }
+ return ' ';
+}