Files
portifolio-evandrodevbr/lib/jogo/mapas/escritorio.test.ts
T
evandro 67b32fcab3
CI / audit (push) Successful in 10m48s
CI / verify (push) Successful in 19m2s
CI / deploy (push) Successful in 2m14s
CI / e2e (push) Failing after 36m15s
feat(jogo): expediente dos mortos, jogo de zumbis em primeira pessoa
Etapa 1 inteira (logica com 100% de cobertura, cena 3D, toque, sons, bancada de desempenho, e2e) e a base da etapa 2 (mapa novo no Tiled, texturas, imagens dos itens, sons conferidos, golpe recortado e medido). Pagina /jogo fora do menu e do sitemap ate a medicao no celular.
2026-11-10 19:37:10 -03:00

132 lines
4.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { campoDeFluxo, direcaoNoCampo, lerMapa } from "../mapa";
import { AMBIENTES, ESCRITORIO, PORTAS } from "./escritorio";
const MAPA = lerMapa(ESCRITORIO);
const { largura, altura } = MAPA;
const andavel = (bloqueio: Uint8Array, x: number, z: number) =>
x >= 0 &&
z >= 0 &&
x < largura &&
z < altura &&
bloqueio[z * largura + x] === 0;
/** Quantas células andáveis a busca em largura alcança a partir do início. */
function alcancaveis(bloqueio: Uint8Array): number {
const inicio =
Math.floor(MAPA.inicio[1]) * largura + Math.floor(MAPA.inicio[0]);
const visto = new Uint8Array(largura * altura);
const fila = [inicio];
visto[inicio] = 1;
for (let k = 0; k < fila.length; k++) {
const x = fila[k] % largura;
const z = Math.floor(fila[k] / largura);
for (const [dx, dz] of [
[1, 0],
[-1, 0],
[0, 1],
[0, -1],
]) {
const i = (z + dz) * largura + x + dx;
if (andavel(bloqueio, x + dx, z + dz) && !visto[i]) {
visto[i] = 1;
fila.push(i);
}
}
}
return fila.length;
}
const totalAndavel = MAPA.solido.filter((c) => c === 0).length;
describe("mapa do escritório", () => {
it("tem pelo menos 40 × 28 células e é lido por lerMapa", () => {
expect(largura).toBeGreaterThanOrEqual(40);
expect(altura).toBeGreaterThanOrEqual(28);
expect(() => lerMapa(ESCRITORIO)).not.toThrow();
});
it("tem os 7 ambientes com nome", () => {
const nomes = AMBIENTES.map((a) => a.nome);
for (const nome of [
"recepção",
"área de mesas",
"sala de reunião",
"copa",
"sala do servidor",
"diretoria",
"almoxarifado",
]) {
expect(nomes).toContain(nome);
}
});
it("tem 6 ou mais nascedouros, todos a 8 m ou mais do início", () => {
expect(MAPA.nascedouros.length).toBeGreaterThanOrEqual(6);
for (const [x, z] of MAPA.nascedouros) {
expect(
Math.hypot(x - MAPA.inicio[0], z - MAPA.inicio[1]),
).toBeGreaterThanOrEqual(8);
}
});
it("alcança todo o chão a partir do início", () => {
expect(alcancaveis(MAPA.solido)).toBe(totalAndavel);
});
it("continua alcançando todo o chão sem qualquer uma das portas", () => {
expect(PORTAS.length).toBeGreaterThan(0);
for (const porta of PORTAS) {
const bloqueio = MAPA.solido.slice();
for (let z = porta.z; z < porta.z + porta.altura; z++) {
for (let x = porta.x; x < porta.x + porta.largura; x++) {
expect(andavel(bloqueio, x, z)).toBe(true);
bloqueio[z * largura + x] = 1;
}
}
expect(alcancaveis(bloqueio)).toBe(
totalAndavel - porta.largura * porta.altura,
);
}
});
it("não tem passagem com menos de 2 células: toda célula andável está num 2 × 2 andável", () => {
const livre = (x: number, z: number) => andavel(MAPA.solido, x, z);
for (let z = 0; z < altura; z++) {
for (let x = 0; x < largura; x++) {
if (!livre(x, z)) continue;
const emQuadrado = [
[-1, -1],
[-1, 0],
[0, -1],
[0, 0],
].some(
([ox, oz]) =>
livre(x + ox, z + oz) &&
livre(x + ox + 1, z + oz) &&
livre(x + ox, z + oz + 1) &&
livre(x + ox + 1, z + oz + 1),
);
expect([x, z, emQuadrado]).toEqual([x, z, true]);
}
}
});
it("o campo de fluxo leva cada nascedouro ao início em menos de 400 passos", () => {
const campo = campoDeFluxo(MAPA, MAPA.inicio[0], MAPA.inicio[1]);
const alvo = [Math.floor(MAPA.inicio[0]), Math.floor(MAPA.inicio[1])];
for (const [nx, nz] of MAPA.nascedouros) {
let x = Math.floor(nx);
let z = Math.floor(nz);
let passos = 0;
while ((x !== alvo[0] || z !== alvo[1]) && passos < 400) {
const [dx, dz] = direcaoNoCampo(MAPA, campo, x + 0.5, z + 0.5);
x += Math.round(dx);
z += Math.round(dz);
passos++;
}
expect([x, z]).toEqual(alvo);
expect(passos).toBeLessThan(400);
}
});
});