JavaScript, 4380 ký tự, 65 (?) Điểm
ASCII? Kiểm tra. HTML? Kiểm tra. Là một cánh cửa? Kiểm tra. Cửa có thể mở? Kiểm tra. Tương tác? Kiểm tra. Mến? Cửa đôi với bản lề được định vị đúng, tôi hy vọng rằng sẽ được tính. Hoạt hình? Kiểm tra. Dưới 100 ký tự? Hà. Không sử dụng các phương tiện dự định để vẽ? Kiểm tra.
Bản thử trực tiếp. (Lưu ý: Trong thử nghiệm của tôi với Firefox, nhấp vào cửa nhiều lần không hoạt động - vì một số lý do, trình xử lý sự kiện không kích hoạt lại và tôi gặp khó khăn tại sao; chỉ ra những gì tôi đã làm sai sẽ được hoan nghênh. Mặc dù vậy, dù sao đi nữa, bạn có thể muốn chạy cái này trong Chrome để có hiệu suất JS tốt.)
<title>Door</title>
<pre onmouseup="turn();" style="display: table; margin: auto; font-family: 'Monaco', monospace; font-size: 0.6em; line-height: 0.7em;">
</pre>
<p>Click doors to open or close.</p>
<script>
// Appearance of hit surface - global used to avoid allocating a record to return
var mat;
// Scene construction tools
function box(size,ms) {
return function (x, y, z) {
var vdist0 = Math.abs(x) - size[0];
var vdist1 = Math.abs(y) - size[1];
var vdist2 = Math.abs(z) - size[2];
mat = vdist0 > vdist1 && vdist0 > vdist2 ? ms[0] :
vdist1 > vdist0 && vdist1 > vdist2 ? ms[1] :
ms[2];
return Math.max(vdist0, vdist1, vdist2);
};
}
function translate(vec, obj) {
var dx = vec[0];
var dy = vec[1];
var dz = vec[2];
return function (x, y, z) { return obj(x - dx, y - dy, z - dz); };
}
function mirror(obj) {
return function (x, y, z) { return obj(-x, y, z); };
}
function spin(obj) {
return function (x, y, z) {
var a = Date.now() / 1000;
var s = Math.sin(a);
var c = Math.cos(a);
return obj(
x * c + z * s,
y,
x * -s + z * c
);
};
}
function doorturn(obj) {
return function (x, y, z) {
var a = pos;
var s = Math.sin(a);
var c = Math.cos(a);
return obj(
x * c + z * s,
y,
x * -s + z * c
);
};
}
function rotx(a, obj) {
return function (x, y, z) {
var s = Math.sin(a);
var c = Math.cos(a);
return obj(
x,
y * c + z * s,
y * -s + z * c
);
};
}
function roty(a, obj) {
return function (x, y, z) {
var s = Math.sin(a);
var c = Math.cos(a);
return obj(
x * c + z * s,
y,
x * -s + z * c
);
};
}
function union(as, bs) {
return function (x, y, z) {
var a = as(x, y, z); var am = mat;
var b = bs(x, y, z);
if (a < b) {
mat = am;
return a;
} else {
return b;
}
};
}
// Display parameters
var vw = 80, vh = 80;
var timestep = 1/30;
// Scene
var wallhwidth = 30;
var wallhheight = 35;
var wallmat = [";", "\u2014", ":"];
var dhwidth = 10;
var dhheight = 20;
var hthick = 2;
var door = translate([-dhwidth*2, 0, 0], doorturn(translate([hthick, 0, dhwidth], box([hthick, dhheight, dhwidth], [".", "\u2014", "|"]))));
var doors = union(door, mirror(door));
var wall = union(
union(
translate([dhwidth*2+wallhwidth, 0, -hthick], box([wallhwidth, wallhheight, hthick], wallmat)),
translate([-dhwidth*2-wallhwidth, 0, -hthick], box([wallhwidth, wallhheight, hthick], wallmat))),
translate([0, wallhheight-(wallhheight-dhheight)/2, -hthick], box([dhwidth*2, (wallhheight-dhheight)/2, hthick], wallmat)));
var floor = translate([0, -dhheight - 1.1, 0], box([100, 1, 100], ["/","/","/"]));
var sill = translate([0, -dhheight - 1, -hthick], box([dhwidth*2, 1, hthick], ["\\","%","\\"]));
var sbox = translate([0, 0, -12], spin(box([8, 8, 8], ["x", "y", "z"])))
var scene = union(sbox, union(union(wall, doors), union(floor, sill)));
var view = translate([vw/2, vh/2, -100], rotx(0.2, roty(-0.6, scene)));
// Animation state
var pos = -Math.PI/2;
var dpos = 0;
var interval;
// Main loop function
function r() {
// Update state
pos += dpos * timestep;
if (Math.abs(pos) >= Math.PI/2) {
dpos = 0;
pos = Math.PI/2 * pos / Math.abs(pos);
if (pos < 0) { // no animation needed
clearInterval(interval); interval = undefined;
}
}
// Render scene
var t = [];
for (var y = vh - 1; y >= 0; y--) {
for (var x = 0; x < vw; x++) {
var z = 0, distance;
while ((distance = view(x,y,z)) > 0.12) {
z -= distance;
if (!isFinite(z) || z < -1000) {
mat = " ";
break;
}
}
t.push(mat);
}
t.push("\n");
}
document.getElementsByTagName("pre")[0].textContent = t.join("");
}
// Click handler
function turn() {
if (dpos !== 0) {
dpos *= -1;
} else {
dpos = (pos < 0 ? 1 : -1) * 2.3;
}
if (!interval) {
interval = setInterval(r, timestep*1000);
}
}
// Render initial state
r();
</script>
Khi đóng cửa, các cửa trông như thế này: