var figs = [ //[ 0, 0, 4, 0], // 0 0 // 0 0 [ 1, 1, 0, 1, 1, 0, 0, 0], // 0000 [ -2, 0, -1, 0, 0, 0, 1, 0], // 00 // 00 [ -1, 0, 0, 0, 0, 1, 1, 1], // 00 // 00 [ 0, 0, 0, 1, -1, 1, 1, 0], // 0 // 000 [ 0, 0, 1, 0, 0, 1, -1, 0 ], // 0 // 000 [ 0, 0, -1, 0, -2, 0, 0, 1 ], [ 0, 0, -1, 0, -2, 0, 0, -1 ] ]; var Buffer = require('buffer').Buffer; var startpos = [4, 15]; var cupsize = [10, 20]; var cup = new Buffer(cupsize[0]*cupsize[1]); var moveInterval; function clearCup() { for (var i=0; i = cupsize[0]) return true; if (y >= cupsize[1]) return true; if (cup[x + y*cupsize[0]]) return true; } return false; } function putfig(num, pos, angle) { angle %= 4; var fig = getTransformedFigure(num, angle, pos); for (var i=0; i < fig.length; i+= 2) { var x = fig[i]; var y = fig[i+1] var ind = x + y*cupsize[0]; cup[ind] = 1; } } function deleteLines() { for (var y=0; y < cupsize[1]; ++y) { var count = 0; for (var x=0; x < cupsize[0]; ++x) { var i = x + y*cupsize[0]; if (cup[i] == 1) count++; } if (count == cupsize[0]) // full line; { var count = 0; for (var yy=y; yy < cupsize[1] - 1; ++yy) { for (var xx=0; xx < cupsize[0]; ++xx) { var ii = xx + yy*cupsize[0]; cup[ii] = cup[ii+cupsize[0]]; } } y--; } } } var x11 = require('../lib'); var Exposure = x11.eventMask.Exposure; var KeyPress = x11.eventMask.KeyPress; var sqsize = 15; var wid, cidBlack, cidWhite; var angle = 0; var gamestate = 'stopped'; var timer; var X; var pos = [4, 13]; var fignum = 0; function timerMove() { var newpos = [pos[0], pos[1]]; newpos[1]--; if (intersects(fignum, newpos, angle)) { putfig(fignum, pos, angle); deleteLines(); fignum = parseInt((Math.random()*100)%figs.length); pos[0] = startpos[0]; pos[1] = startpos[1]; angle = 0; if (intersects(fignum, pos, angle)) { process.exit(0); } draw(); } else { pos = newpos; draw(); } } function startGame() { // start timers set up cirrent + next figure, clear cup clearCup(); moveInterval = setInterval(timerMove, 200); } function getTransformedFigure(num, angle, pos) { var tfig = []; var fig = figs[num]; for (var i=0; i < fig.length; i+=2) { var figx = fig[i]; var figy = fig[i+1] var x = pos[0] + anglecoeff[angle*4]*figx + anglecoeff[angle*4+1]*figy; var y = pos[1] + anglecoeff[angle*4+2]*figx + anglecoeff[angle*4+3]*figy; tfig.push(x); tfig.push(y); } return tfig; } function draw() { var whiterects = []; var blackrects = []; for (var x=0; x < cupsize[0]; ++x) { for (var y=0; y < cupsize[1]; ++y) { var index = x + y*cupsize[0]; var rect = [x*sqsize, (cupsize[1]-1)*sqsize - y*sqsize, sqsize, sqsize]; if (cup[index] != 0) blackrects = blackrects.concat(rect); else whiterects = whiterects.concat(rect); } } var fig = getTransformedFigure(fignum, angle, pos); for (var i=0; i < fig.length; i+=2) { var x = fig[i]; var y = fig[i+1] blackrects = blackrects.concat([x*sqsize, (cupsize[1]-1)*sqsize - y*sqsize, sqsize, sqsize]); } X.PolyFillRectangle(wid, cidWhite, whiterects); X.PolyFillRectangle(wid, cidBlack, blackrects); } function rotate(v) { var newangle = angle + v; if (newangle < 0) newangle = 3; if (newangle >= 4) newangle = 0; if (intersects(fignum, pos, newangle)) return; angle = newangle; draw(); } function rotateUp() { rotate(1); } function rotateDown() { rotate(-1); } function moveX(v) { var newpos = [pos[0] + v, pos[1]]; if (intersects(fignum, newpos, angle)) return; pos = [newpos[0], newpos[1]]; draw(); } function moveLeft() { moveX(-1); } function moveRight() { moveX(1); } function drop() { var newpos = [pos[0], pos[1]]; while (!intersects(fignum, newpos, angle)) newpos[1]--; newpos[1]++; pos = [newpos[0], newpos[1]]; draw(); } x11.createClient(function(err, display) { var ks = x11.keySyms; var ks2Name = {}; for (var key in ks) ks2Name[ ks[key].code ] = key; var kk2Name = {}; var min = display.min_keycode; var max = display.max_keycode; X = display.client; X.GetKeyboardMapping(min, max-min, function(err, list) { for (var i=0; i < list.length; ++i) { var name = kk2Name[i+min] = []; var sublist = list[i]; for (var j =0; j < sublist.length; ++j) name.push(ks2Name[sublist[j]]); } var root = display.screen[0].root; var white = display.screen[0].white_pixel; var black = display.screen[0].black_pixel; wid = X.AllocID(); X.CreateWindow(wid, root, 0, 0, cupsize[0]*sqsize, cupsize[1]*sqsize, 0, 0, 0, 0, { backgroundPixel: white, eventMask: KeyPress|Exposure }); cidBlack = X.AllocID(); cidWhite = X.AllocID(); X.CreateGC(cidBlack, wid, { foreground: black, background: white } ); X.CreateGC(cidWhite, wid, { foreground: white, background: black } ); X.MapWindow(wid); clearCup(); startGame(); X.on('event', function(ev) { switch(ev.type) { case 6: break; case 12: // expose draw(); break; case 2: var key = kk2Name[ev.keycode][0]; console.log(key); switch(key) { case 'XK_Up': rotateUp(); break; case 'XK_Down': rotateDown(); break; case 'XK_Left': moveLeft(); break; case 'XK_Right': moveRight(); break; case 'XK_space': drop(); break; } break; default: console.log('default event', ev); } }); X.on('end', function() { clearInterval(moveInterval); }); }); });