The game got too tedious to play by hand, so I wrote a script to play it automatically. It handles CPU, I/O, and processes quite well - but doesn't recognize a crown on a process and doesn't handle memory management at all.
I found that even on the easy level, the number of processes keeps growing slowly, and there isn't enough CPU time to keep all processes satisfied. I feel like the game is inherently setting you up for failure. Here is the script if anyone wants to play with it:
// ==UserScript==
// @name Auto-play "You're the OS!" game
// @include https://plbrault.github.io/youre-the-os/
// ==/UserScript==
(async function() {
const IO_EVENTS = {x: 160, y: 25};
const CPUS = 4;
const CPU1 = {x: 50+46, y: 50+42};
const SQUARE = {w: 64+5, h: 64+5};
const PROCESS = {x: 50+46, y: 155+42};
const PROCESS_ROWS = 6;
const PROCESS_COLS = 7;
let cnv = document.querySelector("body > canvas");
while (cnv.width != 1280 || cnv.height != 720)
await new Promise(res => setTimeout(res, 100));
while (true) {
const pixels = new Uint32Array(cnv.getContext("2d").getImageData(0, 0, cnv.width, cnv.height).data.buffer);
function getPixel(x, y) { return pixels[y * cnv.width + x]; }
if (getPixel(IO_EVENTS.x, IO_EVENTS.y) == 0xFF808000);
await pressKey("Space");
let cpuStatuses = [];
for (let i = 0; i < CPUS; i++) {
const p = getPixel(CPU1.x + SQUARE.w * i, CPU1.y);
cpuStatuses.push(
p == 0xFF000000 ? 1 :
p == 0xFF9A9B9B ? 2 :
p == 0xFF00FF00 ? 3 :
p == 0xFFE6D8B0 ? 4 :
0);
}
let processStatuses = [];
for (let r = 0; r < PROCESS_ROWS; r++) {
for (let c = 0; c < PROCESS_COLS; c++) {
const p = getPixel(PROCESS.x + SQUARE.w * c, PROCESS.y + SQUARE.h * r);
let s =
p == 0xFF000000 ? 1 :
p == 0xFF9A9B9B ? 2 :
p == 0xFF00FF00 ? 3 :
p == 0xFF00FFFF ? 4 :
p == 0xFF00A5FF ? 5 :
p == 0xFF0000FF ? 6 :
p == 0xFF00008B ? 7 :
p == 0xFF000050 ? 8 :
0;
if (s >= 3)
processStatuses.push({r, c, status: s});
}
}
processStatuses.sort((a, b) => a.status - b.status);
for (let i = 0; i < cpuStatuses.length; i++) {
if (cpuStatuses[i] < 1)
continue;
if (cpuStatuses[i] >= 2)
await pressKey("Digit" + "1234567890".charAt(i));
const p = processStatuses.pop();
if (p !== undefined)
await clickMouse(PROCESS.x + SQUARE.w * p.c, PROCESS.y + SQUARE.h * p.r);
}
await new Promise(res => setTimeout(res, 300));
}
async function clickMouse(x, y) {
const rect = cnv.getBoundingClientRect();
const opts = {
bubbles: true,
clientX: rect.left + x * rect.width / 1280,
clientY: rect.top + y * rect.height / 720,
};
cnv.dispatchEvent(new MouseEvent("mousemove", {...opts, buttons: 0}));
cnv.dispatchEvent(new MouseEvent("mousedown", {...opts, buttons: 1}));
cnv.dispatchEvent(new MouseEvent("mouseup", {...opts, buttons: 0}));
await new Promise(res => requestAnimationFrame(res));
}
async function pressKey(code) {
cnv.dispatchEvent(new KeyboardEvent("keydown", {code, bubbles: true}));
cnv.dispatchEvent(new KeyboardEvent("keyup", {code, bubbles: true}));
await new Promise(res => requestAnimationFrame(res));
}
})();