Skip to content

Instantly share code, notes, and snippets.

@lambda-fairy
Created July 22, 2014 06:36
Show Gist options
  • Select an option

  • Save lambda-fairy/d6b033a6afd94dc0a6e3 to your computer and use it in GitHub Desktop.

Select an option

Save lambda-fairy/d6b033a6afd94dc0a6e3 to your computer and use it in GitHub Desktop.
Minimal Tetris implementation
<!DOCTYPE html>
<html>
<head>
<title>Blahtris</title>
<style type="text/css">
div#sandbox {
float: left;
position: relative;
}
div#msgbox {
position: absolute;
top: 45%;
left: 0;
right: 0;
text-align: center;
}
div#grid-holder {
border: 1px solid #aaa;
float: left;
position: relative;
margin: 1em 1em 0.5em;
}
div.hide {
visibility: hidden;
}
div.asplode {
background: #afa;
color: #0a0;
font-size: 1.5em;
}
div.pause {
background: #aaf;
color: #00f;
font-size: 1.5em;
}
div.fail {
background: #faa;
color: #f00;
font-size: 1.5em;
}
table#grid {
border-spacing: 0;
}
table#grid td {
width: 1em;
height: 1em;
}
td.full {
background: #333;
}
td.empty {
background: #ccc;
}
p#instructions {
clear: both;
font-size: 75%;
line-height: 1em;
background: #ccc;
color: #999;
margin: 0.5em;
}
p#instructions span {
float: left;
position: relative;
margin: 0 0.75em;
}
</style>
<script type="text/javascript">
var w = 10, h = 20;
var cells;
var msgbox;
var matrix;
var blockNum, rotation;
var going = true;
var blocks = [
[
[
[0,0,0,0],
[0,1,1,0],
[0,1,1,0],
[0,0,0,0],
],
],
[
[
[0,0,0,0],
[0,1,1,0],
[0,0,1,0],
[0,0,1,0],
],
[
[0,0,0,0],
[0,0,0,1],
[0,1,1,1],
[0,0,0,0],
],
[
[0,0,0,0],
[0,1,0,0],
[0,1,0,0],
[0,1,1,0],
],
[
[0,0,0,0],
[0,1,1,1],
[0,1,0,0],
[0,0,0,0],
],
],
[
[
[0,0,0,0],
[0,1,1,0],
[0,1,0,0],
[0,1,0,0],
],
[
[0,0,0,0],
[0,1,1,1],
[0,0,0,1],
[0,0,0,0],
],
[
[0,0,0,0],
[0,0,1,0],
[0,0,1,0],
[0,1,1,0],
],
[
[0,0,0,0],
[0,1,0,0],
[0,1,1,1],
[0,0,0,0],
],
],
[
[
[0,1,0,0],
[0,1,0,0],
[0,1,0,0],
[0,1,0,0],
],
[
[0,0,0,0],
[1,1,1,1],
[0,0,0,0],
[0,0,0,0],
],
],
[
[
[0,0,0,0],
[0,0,1,0],
[0,1,1,1],
[0,0,0,0],
],
[
[0,0,0,0],
[0,0,1,0],
[0,0,1,1],
[0,0,1,0],
],
[
[0,0,0,0],
[0,0,0,0],
[0,1,1,1],
[0,0,1,0],
],
[
[0,0,0,0],
[0,0,1,0],
[0,1,1,0],
[0,0,1,0],
],
],
];
var current = null;
var offsetx = 0, offsety = 0;
function createMatrix(rows, cols, value) {
var res = new Array(rows);
for(var j = 0; j < rows; j++) {
res[j] = new Array(cols);
for(var i = 0; i < cols; i++) {
res[j][i] = value;
}
}
return res;
}
function paint() {
for(var j = 0; j < h; j++) {
for(var i = 0; i < w; i++) {
if(matrix[j][i] || (current && j >= offsety && j < offsety+4 && i >= offsetx && i < offsetx+4 && current[j-offsety][i-offsetx])) {
cells[j][i].className = "full";
} else {
cells[j][i].className = "empty";
}
}
}
}
function cement() {
if(!current) return;
for(var j = 0; j < 4; j++) {
if(j+offsety < h) {
for(var i = 0; i < 4; i++) {
if(i+offsetx < w) {
matrix[j+offsety][i+offsetx] |= current[j][i];
}
}
}
}
current = null;
}
function overlapsWithMatrix() {
if(!current) {
return true;
}
for(var j = 0; j < 4; j++) {
for(var i = 0; i < 4; i++) {
if(current[j][i] && (j+offsety >= h || i+offsetx >= w || i+offsetx < 0 || matrix[j+offsety][i+offsetx])) {
return true;
}
}
}
return false;
}
function aSplodeRow(row) {
for(var j = row-1; j >= 0; j--) {
for(var i = 0; i < w; i++) {
matrix[j+1][i] = matrix[j][i];
if(j == 0) {
matrix[j][i] = 0;
}
}
}
msgbox.className = "asplode";
msgbox.innerHTML = "Blam!";
setTimeout(function() { msgbox.className = "hide"; }, 500);
}
function checkFullRow() {
for(var j = h-1; j >= 0; j--) {
var isFull = true;
for(var i = 0; i < w; i++) {
if(!matrix[j][i]) {
isFull = false;
break;
}
}
if(isFull) {
aSplodeRow(j);
return true;
}
}
return false;
}
function moveDown() {
++offsety;
if(!overlapsWithMatrix()) {
return true;
} else {
--offsety;
return false;
}
}
function moveLeft() {
--offsetx;
if(!overlapsWithMatrix()) {
return true;
} else {
++offsetx;
return false;
}
}
function moveRight() {
++offsetx;
if(!overlapsWithMatrix()) {
return true;
} else {
--offsetx;
return false;
}
}
function rotateCW() {
var newRotation = (rotation + 1) % blocks[blockNum].length;
current = blocks[blockNum][newRotation];
if(overlapsWithMatrix()) {
current = blocks[blockNum][rotation];
} else {
rotation = newRotation;
paint();
}
}
function drop() {
while(moveDown()) ; // keep moving down 'til I reach the bottom
paint();
}
function togglePause() {
if(going) {
going = false;
msgbox.className = "pause";
msgbox.innerHTML = "Paused";
} else {
going = true;
msgbox.className = "hide";
loop();
}
}
function handleKeyboard(e) {
e = e || window.event; // hack for IE
var bindings = {
32: drop,
37: moveLeft,
38: rotateCW,
39: moveRight,
80: togglePause,
};
if(bindings[e.keyCode]) {
var f = bindings[e.keyCode];
if(f()) {
paint();
}
return false;
}
return true;
}
function youLose() {
msgbox.className = "fail";
msgbox.innerHTML = "You Lose!"
}
function loop() {
if(!going)
return;
if(!moveDown()) {
cement();
// only place a new block when there's no more lines to asplode
if(!checkFullRow()) {
offsetx = parseInt(w / 2) - 2;
offsety = 0;
blockNum = parseInt(Math.random()*(blocks.length));
rotation = parseInt(Math.random()*(blocks[blockNum].length));
current = blocks[blockNum][rotation];
if(overlapsWithMatrix()) {
youLose();
return;
}
}
}
paint();
setTimeout(loop, 1000);
}
window.onload = function() {
var gridHolder = document.createElement("div");
gridHolder.id = "grid-holder";
var grid = document.createElement("table");
grid.id = "grid";
cells = new Array(h);
for(var j = 0; j < h; j++) {
var row = document.createElement("tr");
cells[j] = new Array(w);
for(var i = 0; i < w; i++) {
var cell = document.createElement("td");
cells[j][i] = cell;
row.appendChild(cell);
}
grid.appendChild(row);
}
msgbox = document.createElement("div");
msgbox.id = "msgbox";
msgbox.className = "hide";
var sandbox = document.getElementById("sandbox");
document.onkeydown = handleKeyboard;
gridHolder.appendChild(grid);
gridHolder.appendChild(msgbox);
sandbox.appendChild(gridHolder);
var inst = document.createElement("p");
inst.id = "instructions";
inst.innerHTML = "<span>&#x25C0; &#x25B6; Move</span> <span>&#x25B2; Rotate</span> <span><b>[Space]</b> Drop</span>";
sandbox.appendChild(inst);
matrix = createMatrix(h, w, 0);
loop();
};
</script>
</head>
<body>
<div id="sandbox"></div>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment