Skip to content

Instantly share code, notes, and snippets.

@wavebeem
Created April 20, 2015 16:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wavebeem/ca85f8a70e4701e7a476 to your computer and use it in GitHub Desktop.
Save wavebeem/ca85f8a70e4701e7a476 to your computer and use it in GitHub Desktop.
99% mutation free, organic, non-GMO
var freeze = Object.freeze;
function array() {
return freeze([].slice.call(arguments));
}
function array_of_size(n) {
var xs = [];
while (n-- > 0) {
xs.push(null);
}
return freeze(xs);
}
function unary(f) {
return function(x) {
return f(x);
}
}
function binary(f) {
return function(x, y) {
return f(x, y);
}
}
function map(f, xs) {
return freeze(xs.map(unary(f)));
}
function mapi(f, xs) {
return freeze(xs.map(binary(f)));
}
var tiles = object(
'floor', '.',
'player', '@'
);
function K(k) {
return () => k;
}
function empty_matrix_2d(w, h) {
return map(function() {
return map(K(null), array_of_size(h));
}, array_of_size(w));
}
function object() {
var n = arguments.length;
if (n % 2 !== 0 || n < 2) {
throw new Error('object needs >= 2 even number of arguments');
}
var o = {};
for (var i = 0; i < n - 1; i += 2) {
o[arguments[i]] = arguments[i + 1];
}
return freeze(o);
}
function escaped(c) {
return "\x1b[" + c;
}
var CLEAR = escaped("H") + escaped("2J");
var W = 40;
var H = 20;
function world_initial() {
var w = empty_matrix_2d(H, W);
return map(partial(map, K(tiles.floor)), w);
}
function world_transform(f, w) {
return mapi((row, y) =>
mapi((data, x) =>
f(data, x, y),
row),
data);
}
function world_show(w) {
var s = "";
w.forEach(row => {
row.forEach(data => {
s += data;
});
s += "\n";
});
process.stdout.write(s);
}
function overlay_player(p) {
return (data, x, y) =>
(x === p.x && y === p.y)
? tiles.player
: data;
}
function player(x, y) {
return object(
'x', x,
'y', y,
'move', (dx, dy) => player(x + dx, y + dy)
);
}
function get(key, fallback, obj) {
return key in obj
? obj[key]
: fallback;
}
function game_state(the_player, the_world) {
return object(
'player', the_player,
'world', the_world,
'tick', key => {
var dx = 10 * get(key, 0, { h: -1, l: 1 });
var dy = 10 * get(key, 0, { k: -1, j: 1 });
var new_player = the_player.move(dx, dy);
return game_state(new_player, the_world);
}
);
}
function partial(f) {
var args = [].slice.call(arguments, 1);
return f.bind.apply(f, [null].concat(args));
}
function translate(x, y) {
x += 'px';
y += 'px';
return 'translate(' + [x, y] + ')';
}
var GameView = React.createClass({
getInitialState() {
return game_state(player(0, 0), world_initial());
},
render() {
return <div className="game">
<PlayerView player={this.state.player} />
</div>;
}
});
var PlayerView = React.createClass({
render() {
var p = this.props.player;
var style = { transform: translate(p.x, p.y) };
return <div className="player" style={style} />;
}
});
var the_root = React.render(
<GameView />,
document.getElementById('react')
);
setInterval(() => {
the_root.setState(the_root.state.tick('j'));
}, 300);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment