Skip to content

Instantly share code, notes, and snippets.

@dagstuan
Created June 10, 2022 07:01
Show Gist options
  • Save dagstuan/798a9c79754d2bfbc6cdbeda63d2b0a9 to your computer and use it in GitHub Desktop.
Save dagstuan/798a9c79754d2bfbc6cdbeda63d2b0a9 to your computer and use it in GitHub Desktop.
var inputs: string[] = readline().split(' ');
const width: number = parseInt(inputs[0]);
const height: number = parseInt(inputs[1]);
const playercount: number = parseInt(inputs[2]);
const foodcount: number = parseInt(inputs[3]);
const myid: number = parseInt(inputs[4]);
type Position = {
x: number,
y: number,
};
function sliceIntoChunks(arr, chunkSize) {
const res = [];
for (let i = 0; i < arr.length; i += chunkSize) {
const chunk = arr.slice(i, i + chunkSize);
res.push(chunk);
}
return res;
}
const legalDirections = ['N', 'S', 'W', 'E'] as const;
type LegalDirection = typeof legalDirections[number];
let prevMove: LegalDirection;
const calcDistance = (p1: Position, p2: Position) => {
var a = p1.x - p2.x;
var b = p1.y - p2.y;
return Math.abs(Math.sqrt( a*a + b*b ));
}
const getOppositeDirection = (dir: LegalDirection): LegalDirection => {
switch(dir) {
case 'N':
return 'S'
case 'S':
return 'N'
case 'W':
return 'E'
case 'E':
return 'W'
default:
return null
}
}
const getNextPos = (currPos: Position, dir: LegalDirection): Position => {
switch(dir) {
case 'N':
return { x: currPos.x, y: currPos.y - 1 }
case 'S':
return { x: currPos.x, y: currPos.y + 1 }
case 'W':
return { x: currPos.x - 1, y: currPos.y }
case 'E':
return { x: currPos.x + 1, y: currPos.y }
}
}
const isOutsideBoundary = (p: Position) => {
return p.x < 0 || p.x >= width || p.y < 0 || p.y >= height
}
const isColliding = (p: Position, mySnake: Position[], otherSnakes: Position[][]): boolean => {
const allCoordinates = otherSnakes.flat().concat(mySnake);
return allCoordinates.find(c => c.x === p.x && c.y === p.y) !== undefined;
}
const containsPoint = (p: Position, positions: Position[]) => {
return positions.find(pos => pos.x === p.x && pos.y === p.y)
}
const isWithinItself = (p: Position, mySnake: Position[]) => {
return containsPoint(getNextPos(p, 'N'), mySnake) &&
containsPoint(getNextPos(p, 'S'), mySnake) &&
containsPoint(getNextPos(p, 'E'), mySnake) &&
containsPoint(getNextPos(p, 'W'), mySnake);
}
// game loop
while (true) {
let mySnake: Position[];
let myScore: number;
const otherSnakes: Position[][] = [];
const aliveplayers: number = parseInt(readline());
for (let i = 0; i < aliveplayers; i++) {
var inputs: string[] = readline().split(' ');
const id: number = parseInt(inputs[0]);
var isMe = id === myid;
const score: number = parseInt(inputs[1]);
const size: number = parseInt(inputs[2]);
const snake: string = inputs[3];
var splitSnake = snake.split(',');
var snakePositions: Position[] = [];
while(splitSnake.length > 0) {
var pos = splitSnake.splice(0, 2);
snakePositions.push({
x: parseInt(pos[0]),
y: parseInt(pos[1])
})
}
if (isMe) {
myScore = score;
mySnake = snakePositions;
} else {
otherSnakes.push(snakePositions)
}
}
const myHead = mySnake[0];
console.error(`myHead x: ${myHead.x}, myHead y: ${myHead.y}`);
const foods: Position[] = [];
for (let i = 0; i < foodcount; i++) {
var inputs: string[] = readline().split(' ');
const x: number = parseInt(inputs[0]);
const y: number = parseInt(inputs[1]);
foods.push({x, y});
}
let minDistance = 99999;
let closestFood: Position;
foods.forEach(f => {
var dist = calcDistance(myHead, f);
if (dist < minDistance) {
minDistance = dist;
closestFood = f;
}
});
console.error(`closestFood! ${closestFood.x},${closestFood.y}. distance ${minDistance}`)
var dirsAndDistances = legalDirections
.filter(d => d !== getOppositeDirection(prevMove))
.map(dir => {
var nextPos = getNextPos(myHead, dir);
var nextDistance = calcDistance(nextPos, closestFood);
console.error(`dir: ${dir}, nextPos: ${nextPos.x},${nextPos.y}, dist: ${nextDistance}`)
return {
dir,
nextPos,
nextDistance,
}
})
.filter(x => !isOutsideBoundary(x.nextPos))
.filter(x => !isColliding(x.nextPos, mySnake, otherSnakes))
.filter(x => !isWithinItself(x.nextPos, mySnake))
.sort((a, b) => {
if (a.nextDistance < b.nextDistance) {
return -1
}
if (a.nextDistance > b.nextDistance) {
return 1
}
return 0
});
console.error(`prevMove: ${prevMove}`)
var prevMoveDir = dirsAndDistances.find(d => d.dir == prevMove);
if (prevMoveDir !== undefined && prevMoveDir.nextDistance < minDistance) {
console.log(prevMoveDir.dir)
}
else {
var dirToGo = dirsAndDistances[0]
console.error(`DirToGo: ${dirToGo.dir}`)
prevMove = dirToGo.dir;
console.log(dirToGo.dir);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment