在控制台打开。
ESC:退出程序 上:直接到底 下:加速下落 左右:移动 空格:顺时针旋转
let draw=(o)=>{
let s=process.stdout
s.cursorTo(0, 0)
s.clearScreenDown()
o.map(a=>s.write(a.join('')+'\n'))
}
let rotate90=(a, r=-1)=>{
let n=a.length, b=[]
for(let i=0; i<n; i++) {
for(let j=0; j<n; j++) {
let [_i, _j]=r===-1? [n-j-1, i]: [j, n-i-1]
b[_i]=b[_i]||[]
b[_i][_j]=a[i][j]
}
}
return b
}
let fill=(y, x)=>[...new Array(y)].map(_=>[...new Array(x||y)].map(_=>0))
let rnd=n=>Math.random()*n|0
let fill_map=(map, shape)=>{
let q=[]
for(let i=0; i<4; i++) {
for(let j=0; j<4; j++) {
if(!shape[i][j]) continue
if(j+px<0 || j+px>=X) return 0
if(i+py<0 || i+py>=Y || map[i+py][j+px]) return -1
if(shape[i][j]) q.push([i, j])
}
}
q.map(([i, j])=>map[i+py][j+px]=shape[i][j])
return map
}
let clean_map=_=>{
let n=0
for(let i=map.length; i--; ) {
if(map[i].indexOf(0)!==-1) continue
map.splice(i, 1)
n++
}
map=fill(n, X).concat(map)
if(map[2].indexOf(1)>-1) gameover=true
if(!n) return
c+=n
score+=Math.ceil(Math.pow(5, n-1))
}
let test_map=_=>{
let r_map=copy(map)
r_map=fill_map(r_map, p)
return r_map
}
let draw_map=(r_map)=>{
if(r_map===0) ;else if(r_map===-1) {
px=undefined
map=map_t
fn()
}else{
map_t=copy(r_map)
draw([
'='.repeat(X).split(''),
...map_t.slice(2, map_t.length).map(t=>t.map(o=>o?' ':'#')),
'='.repeat(X).split(''),
['score: ', score],
['clear: ', c],
gameover? ['-- gameover --']: [],
])
}
}
let copy=m=>[...new Array(m.length)].map((_, i)=>m[i].slice(0, m[i].length))
const X=10, Y=16
/**
1 2 3 4
5 6 7 8
9 a b c
d e f g
*/
const SHAPES=[
'1234',
'7abc',
'9ab7',
'6abc',
'376a',
'267b',
'67ab',
].map((o)=>{
let n=4, r=fill(n)
o.split('').map(a=>{
let g=parseInt(a, 16)-1
r[Math.floor(g/n)][g%n]=1
})
return r
})
const stdin=process.stdin
stdin.setRawMode(true)
stdin.resume()
stdin.on('data', c=>{
let o=c[c.length-1], b, r_map
if(o===27) process.exit()
if(o===32) {
let n=px<X/2?1:-1, h=0
for(let i=0; i<4; i++) {
p=rotate90(p, 1)
let r=test_map()
if(r!==-1 && r!==0) {
h=0
break
}
p=rotate90(p, -1)
px+=n
h++
}
px-=h*n
}
if(o===68) px--, b=_=>px++
if(o===67) px++, b=_=>px--
if(o===66) py++, b=_=>py--
if(o===65) {
for(;++py;) {
r_map=test_map()
if(r_map===0 || r_map===-1) break
}
py--
}
r_map=test_map()
if(r_map===0 || r_map===-1) b && b()
else draw_map(r_map)
})
let px, py, p, map=fill(Y, X), map_t, score=0, c=0, gameover, fn=_=>{
if(gameover) {
clearInterval(tt)
process.exit()
}else if(px===undefined) {
px=X/2-2
py=0
p=SHAPES[rnd(SHAPES.length)]
for(let i=rnd(4); i--; ) p=rotate90(p)
clean_map()
}else{
py++
}
draw_map(test_map())
}
fn()
let tt=setInterval(fn, 5e2)
相关文档
随便看看
畅言模块加载中