Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- 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;
- }
- }
Add Comment
Please, Sign In to add comment