Skip to content

Commit

Permalink
baseEngine sorts tiles it returns
Browse files Browse the repository at this point in the history
  • Loading branch information
cedric-h committed Nov 7, 2022
1 parent 3690852 commit e393b6e
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 29 deletions.
4 changes: 4 additions & 0 deletions engine/baseEngine.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,10 @@ export function baseEngine() {
grid[i].push(s);
})

const legendIndex = t => state.legend.findIndex(l => l[0] == t.type);
for (const tile of grid)
tile.sort((a, b) => legendIndex(a) - legendIndex(b));

return grid;
}

Expand Down
103 changes: 74 additions & 29 deletions tests/sprigfuzzy.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,28 @@
import { baseEngine } from "../engine/baseEngine.js"
import { iterateReader } from "https://deno.land/[email protected]/streams/conversion.ts";
import * as pathUtils from "https://deno.land/std/path/mod.ts";

async function spadeRun(path) {
const H = Deno.env.get("HOME");
const p = Deno.run({
cmd: ["./spade", path],
cmd: [H + "/spade/pc_build/spade", H + "/sprig/games/" + path],
stdout: "piped",
stdin: "piped"
});

/* feels like this is necessary, to get 'er warmed up */
await new Promise(res => setTimeout(res, 100));

const decoder = new TextDecoder();
const encoder = new TextEncoder();
async function *mapReader() {
const decoder = new TextDecoder();

for await (const out of iterateReader(p.stdout))
yield decoder.decode(out).trim();
}

const encoder = new TextEncoder();
return {
out: iterateReader(p.stdout),
out: mapReader(),
simKey: key => p.stdin.write(encoder.encode(key + '\n')),
cleanup: () => p.close(),
};
Expand All @@ -27,14 +35,22 @@ let brokenGames = [];
let log = false;
async function main() {
brokenGames = [];
const tasks = [];
for await (const dirEntry of Deno.readDir('./games')) {
const name = dirEntry.name;
const isJS = name.slice(-3) === ".js";
if (!isJS) continue;
await testScript(name);
tasks.push((async () => {
const i = setInterval(() => console.log(name + ' is still running'), 10000);
await testScript(name);
clearInterval(i);
})());
}
await Promise.all(tasks);

console.log("broken games:", brokenGames);
for (const { error, name } of brokenGames)
console.log(` --- ${name} ---\n` + error);
console.log("number of broken games:", brokenGames.length);

return brokenGames;
Expand All @@ -50,41 +66,55 @@ async function testScript(name) {
/* generate simulated inputs */
const choose = arr => arr[Math.floor(Math.random() * arr.length)];
const shakespeareMonKeys = [...Array(1000)].map(_ => choose("wasdjilk".split('')));
// const shakespeareMonKeys = [...Array(10)].map(_ => choose("wasdjilk".split('')));

const spade = await spadeRun(name);
try {
const fn = new Function(...Object.keys(api), script);
const compareMaps = async () => {
const spadeMap = (await spade.out.next()).value;
const sprigMap = gridToString(api);

if (spadeMap != sprigMap) {
const text = `maps different!\nsprig map:\n${sprigMap}\nspade map:\n${spadeMap}`;
throw new Error(text);
}
}

console.log(`running ${name}!`);
const fn = new Function(...Object.keys(api), script);
fn(...Object.values(api)); /* init */

for (const key of shakespeareMonKeys) {
await compareMaps();
simulateKey(key);
await spade.simKey(key);
if (log) console.log(`<<< pressing ${key} >>>`);
if (log) console.log(gridToString(api));
}
} catch(e) {
cleanup();
console.log(`ERROR WHILE RUNNING "${name}"`);
brokenGames.push({
name,
error: e
})
}

cleanup();
finally {
cleanup();
spade.cleanup();
}
}

function gridToString(api) {
const w = api.width()
const h = api.height()
/* +1 is for newline */
const grid = [...Array((w + 1) * h)].fill('.');
for (let y = 0; y < h; y++) grid[y*(w + 1) + w] = '\n';
for (const [s] of api.getGrid())
if (s)
grid[s.y*(w + 1) + s.x] = s.type;

return grid.join('').trim();
const max_z = Math.max(...api.getGrid().map(x => x.length));
return new Array(h).fill(0).map((_, y) => (
new Array(max_z).fill(0).map((_, z) => (
new Array(w).fill(0).map((_, x) => {
const tile = api.getTile(x, y).reverse()[z];
return (tile) ? tile.type : '.';
}).join('')
)).join('|')
)).join('\n');
}

function simEngine() {
Expand All @@ -95,19 +125,21 @@ function simEngine() {

timeouts.forEach(clearTimeout);
timeouts = [];
api.setTimeout = (fn, n) => {
const t = setTimeout(fn, n);
timeouts.push(t);
return t;
}
api.setTimeout = () => {};
// api.setTimeout = (fn, n) => {
// const t = setTimeout(fn, n);
// timeouts.push(t);
// return t;
// }

intervals.forEach(clearInterval);
intervals = [];
api.setInterval = (fn, n) => {
const i = setInterval(fn, n);
intervals.push(i);
return i;
};
api.setInterval = () => {};
// api.setInterval = (fn, n) => {
// const i = setInterval(fn, n);
// intervals.push(i);
// return i;
// };

let tileInputs = {
w: [],
Expand All @@ -130,6 +162,13 @@ function simEngine() {
afterInputs.push(fn);
};

let jsr = 0x5EED;
const random = () => {
jsr^=(jsr<<17);
jsr^=(jsr>>13);
jsr^=(jsr<<5);
return (jsr>>>0)/4294967295;
};
api = {
/* you literally shouldn't use this */
getState: () => { throw new Error(" BAD! NO! ") },
Expand All @@ -152,7 +191,13 @@ function simEngine() {
...api,

/* gotta do watchu gotta do */
console: { log: () => {} }
console: { log: () => {} },
Math: new Proxy({}, {
get(target, prop, receiver) {
if (prop == "random") return random;
return Reflect.get(Math, prop, Math);
}
}),
};

return {
Expand Down

0 comments on commit e393b6e

Please sign in to comment.