자바 스크립트, 4380 자, 65 (?) 점
ASCII? 검사. HTML? 검사. 문입니까? 검사. 문 열림? 검사. 인터렉티브? 검사. 공상? 제대로 배치 된 경첩이있는 이중 도어가 중요합니다. 생기 있는? 검사. 100 자 미만? 하아. 드로잉 용 시설을 사용하지 않습니까? 검사.
라이브 데모. (참고 : Firefox 테스트에서 문을 두 번 이상 클릭해도 작동하지 않습니다. 어떤 이유로 이벤트 처리기가 다시 시작되지 않고 이유에 대해 당황한 것입니다. 내가 잘못한 것을 지적하는 것은 환영받을 것입니다. 그래도 괜찮은 JS 성능을 위해 어쨌든 Chrome에서 이것을 실행하고 싶을 수도 있습니다.)
<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>
문이 닫히면 문은 다음과 같습니다.
