-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcli.js
84 lines (72 loc) · 1.77 KB
/
cli.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
const readline = require("readline");
const log = require("log-update");
const chalk = require("chalk");
const { start, tick, control, distance, view, coords } = require("./engine.js");
const { merge, uFrame } = require("./grid");
const WORLD_W = 10;
const WORLD_H = 20;
const BLOCK = "▓";
const GHOST = "░";
const SPACE = " ";
const WALL_VALUE = 7;
const GHOST_VALUE = 8;
const colors = [
chalk.red,
chalk.green,
chalk.yellow,
chalk.blue,
chalk.magenta,
chalk.cyan,
chalk.white,
chalk.grey,
];
const ghost = (piece) =>
piece.map((row) => row.map((cell) => (cell === 0 ? 0 : GHOST_VALUE)));
const render = (world) =>
world
.map((row) =>
row
.map((v) =>
v !== 0 ? colors[v - 1](v === GHOST_VALUE ? GHOST : BLOCK) : SPACE
)
.join("")
)
.join("\n");
let state;
const update = (newState) => {
const world = view(newState);
state = newState;
if (newState.over) {
log(render(uFrame(world, WALL_VALUE)));
console.log("Game over!"); // eslint-disable-line no-console
process.exit();
}
const { x, y } = coords(state);
const m1 = merge(world, ghost(state.piece), x, y + distance(state));
const m2 = merge(m1, state.piece, x, y);
log(render(uFrame(m2, WALL_VALUE)));
};
setInterval(() => {
update(tick(state));
}, 1000);
readline.emitKeypressEvents(process.stdin);
process.stdin.setRawMode(true);
process.stdin.on("keypress", (key, data) => {
// eslint-disable-next-line default-case
switch (data.name) {
case "c":
if (data.ctrl) {
process.exit();
}
break;
case "left":
case "right":
case "up":
case "down":
update(control(state, data.name));
break;
case "space":
update(control(state, "drop"));
}
});
update(start(WORLD_W, WORLD_H));