Games: Tetris
authorGustavo Martin Morcuende <gu.martinm@gmail.com>
Sun, 19 Jul 2015 18:40:48 +0000 (20:40 +0200)
committerGustavo Martin Morcuende <gu.martinm@gmail.com>
Sun, 19 Jul 2015 18:40:48 +0000 (20:40 +0200)
games/tetris/.jscsrc [new file with mode: 0644]
games/tetris/.jshintrc [new file with mode: 0644]
games/tetris/.tern-project [new file with mode: 0644]
games/tetris/.vimrc [new file with mode: 0644]
games/tetris/README.md [new file with mode: 0644]
games/tetris/index.html [new file with mode: 0644]
games/tetris/src/functions.js [new file with mode: 0644]

diff --git a/games/tetris/.jscsrc b/games/tetris/.jscsrc
new file mode 100644 (file)
index 0000000..5dd0d95
--- /dev/null
@@ -0,0 +1,47 @@
+{
+  "excludeFiles": ["node_modules/**", "bower_components/**"],
+  "validateIndentation": 2,
+  "disallowKeywords": ["with", "eval", "continue", "void"],
+  "disallowKeywordsOnNewLine": ["else"],
+  "disallowMixedSpacesAndTabs": true,
+  "disallowMultipleLineStrings": true,
+  "disallowNewlineBeforeBlockStatements": true,
+  "disallowSpaceAfterObjectKeys": true,
+  "disallowSpaceAfterPrefixUnaryOperators": ["++", "--", "+", "-", "~", "!"],
+  "disallowSpaceBeforeBinaryOperators": [","],
+  "disallowSpaceBeforePostfixUnaryOperators": ["++", "--"],
+  "disallowSpacesInAnonymousFunctionExpression": {
+    "beforeOpeningRoundBrace": true
+  },
+  "disallowSpacesInCallExpression": true,
+  "disallowSpacesInFunctionDeclaration": {
+    "beforeOpeningRoundBrace": true
+  },
+  "disallowSpacesInNamedFunctionExpression": {
+    "beforeOpeningRoundBrace": true
+  },
+  "disallowSpacesInsideArrayBrackets": true,
+  "requireSpaceBeforeKeywords": [
+    "else",
+    "while",
+    "catch"
+  ],
+  "disallowSpacesInsideParentheses": true,
+  "disallowTrailingComma": true,
+  "disallowTrailingWhitespace": true,
+  "requireCommaBeforeLineBreak": true,
+  "requireSpaceAfterBinaryOperators": ["?", ":", "+", "-", "/", "*", "%", "==", "===", "!=", "!==", ">", ">=", "<", "<=", "&&", "||"],
+  "requireSpaceBeforeBinaryOperators": ["?", ":", "+", "-", "/", "*", "%", "==", "===", "!=", "!==", ">", ">=", "<", "<=", "&&", "||"],
+  "requireSpaceAfterKeywords": ["if", "else", "for", "while", "do", "switch", "return", "try", "catch"],
+  "requireSpaceBeforeBlockStatements": true,
+  "requireSpacesInConditionalExpression": {
+    "afterTest": true,
+    "beforeConsequent": true,
+    "afterConsequent": true,
+    "beforeAlternate": true
+  },
+  "requireSpacesInForStatement": true,
+  "requireSpacesInFunction": {
+    "beforeOpeningCurlyBrace": true
+  }
+}
diff --git a/games/tetris/.jshintrc b/games/tetris/.jshintrc
new file mode 100644 (file)
index 0000000..cebc050
--- /dev/null
@@ -0,0 +1,26 @@
+{
+  "node": true,
+  "browser": true,
+  "esnext": true,
+  "bitwise": true,
+  "camelcase": true,
+  "curly": true,
+  "eqeqeq": true,
+  "immed": true,
+  "indent": 2,
+  "latedef": true,
+  "newcap": true,
+  "noarg": true,
+  "quotmark": "single",
+  "undef": true,
+  "unused": true,
+  "strict": true,
+  "trailing": true,
+  "smarttabs": true,
+  "maxcomplexity": 3,
+  "globals": {
+    "angular": false,
+    "_": true,
+    "moment": true
+  }
+}
diff --git a/games/tetris/.tern-project b/games/tetris/.tern-project
new file mode 100644 (file)
index 0000000..5e0cc85
--- /dev/null
@@ -0,0 +1,17 @@
+{
+  "libs": [
+    "browser",
+    "jquery",
+    "ecma5",
+    "underscore"
+  ],
+  "loadEagerly": [
+    "src/**/*.js",
+    "./*.js"
+  ],
+  "plugins": {
+    "angular": "./",
+    "doc_comment": "./",
+    "complete_strings": "./"
+  }
+}
diff --git a/games/tetris/.vimrc b/games/tetris/.vimrc
new file mode 100644 (file)
index 0000000..036db79
--- /dev/null
@@ -0,0 +1,106 @@
+" *************************** Code-analysis engine for JavaScript ***************************
+
+"http://ternjs.net/
+filetype plugin indent on
+"let g:tern#command = ["node", '~/.vim/bundle/tern_for_vim/autoload' . '/../node_modules/tern/bin/tern', '--persistent']
+"Hay que buscar algo mejor: node ~/.vim/bundle/tern_for_vim/node_modules/tern/bin/tern --persistent --verbose
+let g:tern#command = ["nothing"]
+let g:tern_request_timeout = 10
+
+"https://github.com/marijnh/tern_for_vim
+let g:tern_show_argument_hints='on_hold'
+let g:tern_map_keys=1
+
+
+
+
+" *************************** https://github.com/burnettk/vim-angular ***************************
+
+
+"https://github.com/othree/javascript-libraries-syntax.vim
+let g:used_javascript_libs = 'angularjs,angularui,jasmine,jquery'
+
+"https://github.com/pangloss/vim-javascript
+set regexpengine=1
+
+"https://github.com/scrooloose/syntastic
+let oldstatusline=&statusline       "save current configuration
+set statusline=
+set statusline+=%#WarningMsg#       "switch to 'WarningMsg' default theme color. See available colors with command :highlight
+set statusline+=%{SyntasticStatuslineFlag()}
+set statusline+=%*
+let &statusline.=oldstatusline      "concatenate configuration
+unlet oldstatusline
+let g:syntastic_always_populate_loc_list = 1
+let g:syntastic_auto_loc_list = 1
+let g:syntastic_check_on_open = 1
+let g:syntastic_check_on_wq = 0
+"http://jshint.com
+let g:syntastic_javascript_checkers = ['jshint', 'jscs']
+
+
+" *************************** Line numbers ***************************
+set number
+
+
+" *************************** Because broken editors are being used by some naïve developers ***************************
+" set binary
+" set noeol
+
+
+" *************************** Save session on quitting Vim ***************************
+autocmd VimLeave * NERDTreeClose
+autocmd VimLeave * call MakeSession()
+
+" *************************** Restore session on starting Vim ***************************
+" autocmd VimEnter * call MySessionRestoreFunction()
+autocmd VimEnter * call LoadSession()
+autocmd VimEnter * NERDTree
+
+function! MakeSession()
+  let b:sessiondir = $HOME . "/.vim/sessions" . getcwd()
+  if (filewritable(b:sessiondir) != 2)
+    exe 'silent !mkdir -p ' b:sessiondir
+    redraw!
+  endif
+  let b:filename = b:sessiondir . '/session.vim'
+  exe "mksession! " . b:filename
+endfunction
+
+function! LoadSession()
+  let b:sessiondir = $HOME . "/.vim/sessions" . getcwd()
+  let b:sessionfile = b:sessiondir . "/session.vim"
+  if (filereadable(b:sessionfile))
+    exe 'source ' b:sessionfile
+  else
+    echo "No session loaded."
+  endif
+endfunction
+
+map <lt>r :NERDTreeFind<cr>
+
+
+" *************************** Indentation ***************************
+set tabstop=2
+set shiftwidth=2
+set expandtab
+
+
+" *************************** Spelling ***************************
+"Corrección ortográfica. En consola :setlocal spell spelllang=es
+"Los diccionarios en español hay que bajárselos de aquí: http://ftp.vim.org/vim/runtime/spell/
+"y dejarlos en esta ruta: /usr/share/vim/vim72/spell
+"Ver http://plagatux.es/2008/12/correcion-ortografica-en-vim/
+"si queremos tener un fichero donde se vayan agregando las palabras que no sean reconocidas
+set spellfile=~/.vim/dict.add
+"Para habilitarlo siempre:
+"runtime plugins/spellfile.vim <----- Esto no parece necesario :(
+"setlocal spell spelllang=es
+setlocal spell spelllang=en
+"    * ]s – Siguiente falta ortográfica
+"    * [s - Anterior falta ortográfica
+"    * z= - Mostrar sugerencias para una palabra incorrecta.
+"    * zg - Añadir una palabra al diccionario.
+"    * zug - Deshacer la adición de una palabra al diccionario.
+"    * zw - Eliminar una palabra del diccionario.
+"set nospell para deshabilitarlo
diff --git a/games/tetris/README.md b/games/tetris/README.md
new file mode 100644 (file)
index 0000000..a049f63
--- /dev/null
@@ -0,0 +1,11 @@
+# Using tern:
+https://github.com/marijnh/tern_for_vim
+
+# Run in a different console the tern server (better than being loaded by vim)
+~/.vim/bundle/tern_for_vim/node_modules/tern/bin/tern --persistent --verbose --host 127.0.0.1
+
+export PATH=/opt/node/node-v0.10.33-linux-x64/bin:$PATH
+
+# Global installs of systaxis checks
+npm install -g jshint
+npm install -g jscs
diff --git a/games/tetris/index.html b/games/tetris/index.html
new file mode 100644 (file)
index 0000000..bdb2dda
--- /dev/null
@@ -0,0 +1,84 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <title>Javascript Tetris</title>
+  <style>
+    body      { font-family: Helvetica, sans-serif; }
+    #tetris   { margin: 1em auto; padding: 1em; border: 4px solid black; border-radius: 10px; background-color: #F8F8F8; }
+    #stats    { display: inline-block; vertical-align: top; }
+    #canvas   { display: inline-block; vertical-align: top; background-color: black; box-shadow: 10px 10px 10px #999; border: 2px solid #333; }
+    #menu     { display: table-cell; vertical-align: top; position: relative; }
+    #menu p   { margin: 0.5em 0; text-align: center; }
+    #menu p a { text-decoration: none; color: black; }
+    #upcoming { display: block; margin: 0 auto; background-color: black; box-shadow: 10px 10px 10px #999; border: 2px solid #333; }
+    #score    { color: red; font-weight: bold; vertical-align: middle; }
+    #rows     { color: blue; font-weight: bold; vertical-align: middle; }
+    #stats    { position: absolute; bottom: 0em; right: 1em; }
+    @media screen and (min-width:   0px) and (min-height:   0px)
+    { #tetris { font-size: 0.75em; width: 400px; }
+      #menu { width: 200px; height: 200px; } 
+      #upcoming { width:  50px; height:  50px; } 
+      #canvas { width: 100px; height: 200px; } 
+    } /* 10px chunks */
+    @media screen and (min-width: 400px) and (min-height: 400px)
+    { #tetris { font-size: 1.00em; width: 500px; }
+      #menu { width: 300px; height: 300px; }
+      #upcoming { width:  75px; height:  75px; }
+      #canvas { width: 150px; height: 300px; }
+    } /* 15px chunks */
+    @media screen and (min-width: 500px) and (min-height: 500px)
+    { #tetris { font-size: 1.25em; width: 600px; }
+      #menu { width: 400px; height: 400px; }
+      #upcoming { width: 100px; height: 100px; }
+      #canvas { width: 200px; height: 400px; }
+    } /* 20px chunks */
+    @media screen and (min-width: 600px) and (min-height: 600px)
+    { #tetris { font-size: 1.50em; width: 700px; }
+      #menu { width: 500px; height: 500px; }
+      #upcoming { width: 125px; height: 125px; }
+      #canvas { width: 250px; height: 500px; }
+    } /* 25px chunks */
+    @media screen and (min-width: 700px) and (min-height: 700px)
+    { #tetris { font-size: 1.75em; width: 800px; }
+      #menu { width: 600px; height: 600px; }
+      #upcoming { width: 150px; height: 150px; }
+      #canvas { width: 300px; height: 600px; }
+    } /* 30px chunks */
+    @media screen and (min-width: 800px) and (min-height: 800px)
+    { #tetris { font-size: 2.00em; width: 900px; }
+      #menu { width: 700px; height: 700px; }
+      #upcoming { width: 175px; height: 175px; }
+      #canvas { width: 350px; height: 700px; }
+    } /* 35px chunks */
+    @media screen and (min-width: 900px) and (min-height: 900px)
+    { #tetris { font-size: 2.25em; width: 1000px; }
+      #menu { width: 800px; height: 800px; }
+      #upcoming { width: 200px; height: 200px; }
+      #canvas { width: 400px; height: 800px; }
+    } /* 40px chunks */
+  </style>
+</head>
+
+<body>
+
+  <div id="tetris">
+    <div id="menu">
+      <p><canvas id="upcoming"></canvas></p>
+    </div>
+    <div style="display: table-cell">
+      <canvas id="canvas">
+        Your browser does not support the &lt;canvas&gt; element
+      </canvas>
+    </div>
+    <div id="menu">
+      <p>score <span id="score">00000</span></p>
+      <p>rows <span id="rows">0</span></p>
+    </div>
+  </div> 
+
+  <script src="src/functions.js"></script>
+  
+
+</body>
+</html>
+
diff --git a/games/tetris/src/functions.js b/games/tetris/src/functions.js
new file mode 100644 (file)
index 0000000..e2a66ed
--- /dev/null
@@ -0,0 +1,403 @@
+'use strict';
+
+var KEY = { ESC: 27, SPACE: 32, LEFT: 37, UP: 38, RIGHT: 39, DOWN: 40 };
+var MAPWIDTH = 10;
+var MAPHEIGHT = 20;
+var TILEWIDTH;
+var TILEHEIGHT;
+var board;
+var boardCanvas;
+var boardContext;
+var boardUpComingCanvas;
+var upComingContext;
+var play = false;
+var score;
+var rows;
+
+
+var shapes = [
+  // Tower piece: I
+  { blocks: [0x0F00, 0x2222, 0x00F0, 0x4444], color: 'red' },
+  // The right knight piece: J
+  { blocks: [0x44C0, 0x8E00, 0x6440, 0x0E20], color: 'white' },
+  // The left knight piece: L
+  { blocks: [0x4460, 0x0E80, 0xC440, 0x2E00], color: 'purple' },
+  // The box piece: O
+  { blocks: [0xCC00, 0xCC00, 0xCC00, 0xCC00], color: 'blue' },
+  // The right leaner piece: S
+  { blocks: [0x06C0, 0x8C40, 0x6C00, 0x4620], color: 'green' },
+  // The pyramid piece: T
+  { blocks: [0x0E40, 0x4C40, 0x4E00, 0x4640], color: 'yellow' },
+  // The left leaner piece: Z
+  { blocks: [0x0C60, 0x4C80, 0xC600, 0x2640], color: 'cyan' }
+];
+
+
+
+
+
+function emptyBoard(m, n) {
+  var i;
+  var mat = [];
+  for (i = 0; i < n; i+= 1) {
+    mat[i] = [];
+  }
+
+  return mat;
+}
+
+function resize() {
+  boardCanvas = document.getElementById('canvas');
+  boardCanvas.width = boardCanvas.clientWidth;
+  boardCanvas.height = boardCanvas.clientHeight;
+  TILEWIDTH = boardCanvas.width / MAPWIDTH;
+  TILEHEIGHT = boardCanvas.height / MAPHEIGHT;
+  boardContext = boardCanvas.getContext('2d');
+
+
+  boardUpComingCanvas = document.getElementById('upcoming');
+  boardUpComingCanvas.width = boardUpComingCanvas.clientWidth;
+  boardUpComingCanvas.height = boardUpComingCanvas.clientHeight;
+  upComingContext = boardUpComingCanvas.getContext('2d');
+}
+
+function drawTile(context, color, x, y) {
+  context.fillStyle = color;
+  context.fillRect(x * TILEWIDTH, y * TILEHEIGHT, TILEWIDTH, TILEHEIGHT);
+}
+
+function getPositions(piece) {
+  var positions = [];
+  var bit;
+  var row = 0, col = 0;
+  var blocks = shapes[piece.shape].blocks[piece.rotation];
+
+  for(bit = 0x8000; bit >= 0x0001; bit = bit >> 1) {
+
+    if (blocks & bit) {
+      var position = {
+        x : piece.x + col,
+        y : piece.y + row
+      };
+      positions.push(position);
+    }
+
+    col++;
+    if (col === 4) {
+      row++;
+      col = 0;
+    }
+  }
+
+  return positions;
+}
+
+function pieceBlocks(piece, fn) {
+  var i;
+  var positions = getPositions(piece);
+  for(i = 0; i < positions.length; i += 1) {
+    if (fn(positions[i])) {
+      return true;
+    }
+  }
+
+  return false;
+}
+
+function drawPiece(context, piece) {
+  var color = shapes[piece.shape].color;
+  pieceBlocks(piece, function(position) {
+    drawTile(context, color, position.x, position.y);
+  });
+}
+
+function setPiece(board, piece) {
+  var color = shapes[piece.shape].color;
+  pieceBlocks(piece, function(position) {
+    board[position.x][position.y] = color;
+  });
+}
+
+function checkBoardBoundaries(x, y) {
+  return x === MAPWIDTH ||
+         x < 0 ||
+         y === MAPHEIGHT;
+}
+
+function checkOtherPieces(board, x, y) {
+
+  if(typeof board[x][y] !== 'undefined') {
+    return true;
+  }
+
+  return false;
+}
+
+function checkColision(board, piece) {
+  return pieceBlocks(piece, function(position) {
+    if (checkBoardBoundaries(position.x, position.y) ||
+        checkOtherPieces(board, position.x, position.y)) {
+      return true;
+    }
+
+    return false;
+  });
+}
+
+function drawBoard(board, context, m, n) {
+  var x, y;
+
+  for (x = 0; x < m; x += 1) {
+    for (y = 0; y < n; y += 1) {
+      if(typeof board[x][y] !== 'undefined') {
+        drawTile(context, board[x][y], x, y);
+      }
+    }
+  }
+
+}
+
+function checkRows(board, m, n, fn) {
+  var filled, x, y, filledLines;
+
+  filledLines = 0;
+  for (y = 0; y < n; y += 1) {
+
+    filled = true;
+    for (x = 0; x< m; x += 1) {
+      if(typeof board[x][y] === 'undefined') {
+        filled = false;
+      }
+    }
+    
+    if (filled) {
+      filledLines++;
+      fn(board, m, y);
+    }
+  }
+  
+  if (filledLines !== 0) {
+    updateScore(filledLines);
+    updateRows(filledLines);
+  } 
+}
+
+function removeRow(board, m, n) {
+  var x, y;
+  for(x = 0; x< m; x += 1) {
+    for (y = n; y > 0; y -= 1) {
+      board[x][y] = board[x][y - 1];
+    }
+  }
+}
+
+function updateScore(n) {
+  // 1: 100
+  // 2: 200
+  // 3: 400
+  // 4: 800
+  var newScore = (100*Math.pow(2,n-1));
+  score = score + newScore;
+  document.getElementById('score').innerHTML = ('00000' + Math.floor(score)).slice(-5);
+}
+
+function updateRows(n) {
+  rows = rows + n;
+  document.getElementById('rows').innerHTML = rows;
+}
+
+function move(piece, x, y) {
+  piece.x = piece.x + x;
+  piece.y = piece.y + y; 
+}
+
+function getRandomInt(min, max) {
+  return Math.floor(Math.random() * (max - min)) + min;
+}
+
+function makeRandomPiece() {
+  var shape = getRandomInt(0, 7);
+  var rotation = getRandomInt(0, 4);
+  var piece = {
+    shape: shape,
+    rotation: rotation
+  };
+
+  return piece;
+}
+
+// 10 secs
+var last = null;
+var step = 1000;
+var currentPiece;
+var upComingPiece;
+
+
+
+// TODO: polyfill
+function frame(timestamp) {
+  if (!play) {
+    return;
+  }
+
+  if (!last) {
+    last = timestamp;
+  }
+  var progress = timestamp - last;
+  if (progress >= step) {
+
+    var forwardPiece = {
+      shape: currentPiece.shape,
+      rotation: currentPiece.rotation,
+      x: currentPiece.x,
+      y: currentPiece.y + 1
+    };
+
+    if (checkColision(board, forwardPiece)) {
+      setPiece(board, currentPiece);
+
+      checkRows(board, MAPWIDTH, MAPHEIGHT, function(board, m, n) {
+        removeRow(board, m, n);
+      });
+
+
+      currentPiece = upComingPiece;
+      currentPiece.x = 2;
+      currentPiece.y = -1;
+
+      upComingPiece = makeRandomPiece();
+      upComingPiece.x = 1;
+      upComingPiece.y = 1;
+    }
+
+    move(currentPiece, 0, 1);
+
+    boardContext.clearRect(0, 0, boardCanvas.width, boardCanvas.height);
+    drawBoard(board, boardContext, MAPWIDTH, MAPHEIGHT);
+    drawPiece(boardContext, currentPiece);
+
+    upComingContext.clearRect(0, 0, boardUpComingCanvas.width, boardUpComingCanvas.height);
+    drawPiece(upComingContext, upComingPiece);
+
+    last = timestamp;
+  }
+  window.requestAnimationFrame(frame);
+}
+
+function init() {
+  currentPiece = makeRandomPiece();
+  currentPiece.x = 2;
+  currentPiece.y = -1;
+  upComingPiece = makeRandomPiece();
+  upComingPiece.x = 1;
+  upComingPiece.y = 1;
+
+  score = 0;
+  document.getElementById('score').innerHTML = '00000';
+
+  rows = 0;
+  document.getElementById('rows').innerHTML = '0';
+
+  board = emptyBoard(MAPWIDTH, MAPHEIGHT);
+  resize();
+
+  window.requestAnimationFrame(frame);
+}
+
+function keydown(ev) {
+
+  switch(ev.keyCode) {
+    case KEY.ESC:
+      play = false;
+      ev.preventDefault();
+      break;
+    case KEY.SPACE:
+      play = true;
+      init();
+      ev.preventDefault();
+      break;
+  }
+
+  if (!play) {
+    return;
+  }
+  var forwardPiece = {
+    shape: currentPiece.shape,
+    rotation: currentPiece.rotation,
+    x: currentPiece.x,
+    y: currentPiece.y
+  };
+  switch(ev.keyCode) {
+    case KEY.LEFT:
+     move(forwardPiece, -1, 0);
+      if (!checkColision(board, forwardPiece)) {
+        move(currentPiece, -1, 0);
+        boardContext.clearRect(0, 0, boardCanvas.width, boardCanvas.height);
+        drawBoard(board, boardContext, MAPWIDTH, MAPHEIGHT);
+        drawPiece(boardContext, currentPiece);
+      }
+      ev.preventDefault();
+      break;
+    case KEY.RIGHT:
+     move(forwardPiece, 1, 0);
+      if (!checkColision(board, forwardPiece)) {
+        move(currentPiece, 1, 0);
+        boardContext.clearRect(0, 0, boardCanvas.width, boardCanvas.height);
+        drawBoard(board, boardContext, MAPWIDTH, MAPHEIGHT);
+        drawPiece(boardContext, currentPiece);
+      }
+      ev.preventDefault();
+      break;
+    case KEY.UP:
+      var rotation = (forwardPiece.rotation + 1) % 4;
+      forwardPiece.rotation = rotation;
+      if (!checkColision(board, forwardPiece)) {
+        currentPiece.rotation = rotation;
+        boardContext.clearRect(0, 0, boardCanvas.width, boardCanvas.height);
+        drawBoard(board, boardContext, MAPWIDTH, MAPHEIGHT);
+        drawPiece(boardContext, currentPiece);
+      }
+      ev.preventDefault();
+      break;
+    case KEY.DOWN:
+      move(forwardPiece, 0, 1);
+      if (checkColision(board, forwardPiece)) {
+        setPiece(board, currentPiece);
+
+        checkRows(board, MAPWIDTH, MAPHEIGHT, function(board, m, n) {
+          removeRow(board, m, n);
+        });
+
+        currentPiece = upComingPiece;
+        currentPiece.x = 2;
+        currentPiece.y = -1;
+
+        upComingPiece = makeRandomPiece();
+        upComingPiece.x = 1;
+        upComingPiece.y = 1;
+      }
+
+      move(currentPiece, 0, 1);
+
+      boardContext.clearRect(0, 0, boardCanvas.width, boardCanvas.height);
+      drawBoard(board, boardContext, MAPWIDTH, MAPHEIGHT);
+      drawPiece(boardContext, currentPiece);
+
+      upComingContext.clearRect(0, 0, boardUpComingCanvas.width, boardUpComingCanvas.height);
+      drawPiece(upComingContext, upComingPiece);
+
+      ev.preventDefault();
+      break;
+  }
+}
+
+function addEvents() {
+  document.addEventListener('keydown', keydown, false);
+  window.addEventListener('resize', resize, false);
+}
+
+addEvents();
+
+
+