Skip to content

Instantly share code, notes, and snippets.

@towc
Last active December 16, 2018 11:29
Show Gist options
  • Select an option

  • Save towc/044a6310d0307f500a851937abd326dc to your computer and use it in GitHub Desktop.

Select an option

Save towc/044a6310d0307f500a851937abd326dc to your computer and use it in GitHub Desktop.
const fs = require('fs');
const [WALL, EMPTY, ELF, GOB] = [0, 1, 'elf', 'gob'];
const maxDist = 200;
const ents = [];
const coord = (x, y) => ({ x, y });
const delta = (pos, x, y) => ({ x: pos.x + x, y: pos.y + y });
const cell = pos => board[pos.y][pos.x];
const setCell = (pos, v) => board[pos.y][pos.x] = v;
const addEnt = (x, y, type) => {
const ent = { x, y, hp: 200, type };
ents.push(ent);
return ent;
}
console._log = console.constructor.prototype.log.bind(console);
console.log = () => {};
const board =
fs.readFileSync('input', 'utf-8')
.split('\n')
.map((l, y) =>
l.split('')
.map((c, x) => {
switch (c) {
case '#': return WALL;
case '.': return EMPTY;
case 'E': return addEnt(x, y, ELF);
case 'G': return addEnt(x, y, GOB);
}
console.log('wut', c, x, y)
}));
const log = () => {
let str = board.map(l => l.map(c =>
c === WALL ? '#'
: c === EMPTY ? '.'
: c.type === ELF ? 'E'
: c.type === GOB ? 'G'
: '?'
).join('')).join('\n')
console._log(str);
console._log(ents.map(e => [e.type, e.hp]).join('|'))
}
const getNeighbours = pos => [
delta(pos, 0, -1),
delta(pos, -1, 0),
delta(pos, 1, 0),
delta(pos, 0, 1)
];
const checkTile = (ent, pos) => {
const checked = [ent, pos];
let toCheck = getNeighbours(pos);
let nextCheck = [];
let dist = 0;
distCheck:
while(++dist < maxDist) {
for(const pos of toCheck) {
const v = cell(pos);
if (v === EMPTY) {
const neighbours = getNeighbours(pos)
.filter(p => {
if (checked.some(q => q.x === p.x && q.y === p.y) || nextCheck.some(q => q.x === p.x && q.y === p.y)) {
return false;
}
const c = cell(p);
return c === EMPTY || c.dead || (c.type && c.type !== ent.type);
});
nextCheck.push(...neighbours)
}
if (!v.dead && v.type && v.type !== ent.type) {
break distCheck;
}
checked.push(pos);
};
toCheck = nextCheck;
nextCheck = [];
}
return dist;
}
const getNextTile = ent => {
const tiles = getNeighbours(ent)
.filter(p => cell(p) === EMPTY)
.map(p => ({ x: p.x, y: p.y, v: checkTile(ent, p) }))
.filter(c => c.v < maxDist);
return tiles.sort((a, b) => a.v - b.v || a.y - b.y || a.x - b.x)[0];
}
const getNextEnemy = ent => {
return getNeighbours(ent)
.map(p => cell(p))
.filter(c => !c.dead && c.type && c.type !== ent.type)
.sort((a, b) => a.hp - b.hp || a.y - b.y || a.x - b.x)
[0];
}
let rounds = 0;
loop: while(++rounds < 10000) {
ents.sort((a, b) => a.y - b.y || a.x - b.x);
log()
for(let i = 0; i < ents.length; ++i) {
const ent = ents[i];
console.log('trying', i, ent);
console.group();
if (ent.dead) {
console.groupEnd();
continue;
}
const enemy = getNextEnemy(ent);
if (enemy) {
console.log({ enemy })
enemy.hp -= 3;
if (enemy.hp <= 0) {
enemy.dead = true;
}
} else {
const nextTile = getNextTile(ent);
console.log({ nextTile })
if (nextTile) {
setCell(ent, EMPTY);
ent.x = nextTile.x;
ent.y = nextTile.y;
setCell(ent, ent);
}
const enemy = getNextEnemy(ent);
if (enemy) {
enemy.hp -= 3;
if (enemy.hp <= 0) {
enemy.dead = true;
}
}
}
console.groupEnd();
}
let type = ents[0].type;
let allTypesSame = true;
for(let i = 0; i < ents.length; ++i) {
const ent = ents[i];
if (ent.dead) {
setCell(ent, EMPTY);
ents.splice(i, 1);
--i;
} else {
if (type !== ent.type) {
allTypesSame = false;
}
}
}
if (allTypesSame) {
console._log('ended in ' + rounds);
const sum = ents.reduce((a, e) => a + e.hp, 0);
console._log(sum, sum * (rounds-1));
//console._log(ents);
break;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment