diff --git a/code/games/2048/2048.html b/code/games/2048/2048.html new file mode 100644 index 0000000..411cd9e --- /dev/null +++ b/code/games/2048/2048.html @@ -0,0 +1,51 @@ + + + + + + + + + 2048 the game + + + + + + +
+
+
+ +
+
+
+
+
+
+ 2048 +
+
+ Use the arrow keys to push all the squares on the board to the top/left/right/down. Squares with the same number combine to give a square with a value equal to the sum of the two squares. The game ends once you reach 2048 or all the squares are filled and no more moves are possible +
+
+
+
+ +
+
+ + + + diff --git a/code/games/2048/2048.js b/code/games/2048/2048.js new file mode 100644 index 0000000..7f92c52 --- /dev/null +++ b/code/games/2048/2048.js @@ -0,0 +1,431 @@ +// setting up the canvas +var canvas = document.getElementById("myCanvas"); +var ctx = canvas.getContext("2d"); +// canvas has width="500" height="600" + +// setting up the parameters of the playing space + +// number of boxes in a standard game is 4 x 4 +var hsize = 4; // number of boxes horiontally +var vsize = 4; // number of boxes vertically + +// The playing board parameters (to be drawn in gray) +var boardx = 50; +var boardy = 100; +var boardwidth = 400; +var boardheight = 400; + +// The playing boards grid outlines (basically to make it look like a 4 x 4 grid) +var boxwidth = boardwidth / hsize; +var boxheight = boardheight / vsize; + +// Initialise a 2D array denoting the value of the current element at that position +var box_values = []; +for (var i = 0; i < hsize; i++) { + box_values[i] = []; + for (var j = 0; j < vsize; j++) { + box_values[i][j] = { x: boardx + i * boxwidth, y: boardy + j * boxheight, value: 0 } + } +} + +// colors +var boardColor = "#aaa" +var boxColor = [boardColor, "#f00", "#ff0", "#0f0", "#0ff", "#00f", "#f0f", "#a00", "#aa0", "#0a0", "#0aa", "#00a", "#a0a"] + +// maximum scores obtained in a session +var maxScore1 = 0; +var maxScore2 = 0; + +// check if the movement has taken place or not +var isMove = 0; + +// functions related to the logic of the game + +// get the count of the number of digits in a given number +function digCount(n) { + var m = n; + var ans = 0; + do { + ans++; + m = Math.floor(m / 10); + } while (m != 0); + return ans; +} + +// get the number of empty spaces in the grid +function getEmptyBox() { + var count = 0; + for (var i = 0; i < hsize; i++) { + for (var j = 0; j < vsize; j++) { + if (box_values[i][j].value == 0) + count++; + } + } + // console.log(count) + return count; +} + +// clear the board +function clearGrid() { + for (var i = 0; i < hsize; i++) { + for (var j = 0; j < vsize; j++) { + box_values[i][j].value = 0; + } + } +} + +// returns a copy of the board() +function copyGrid() { + var bv = []; + for (var i = 0; i < hsize; i++) { + bv[i] = []; + for (var j = 0; j < vsize; j++) { + bv[i][j] = box_values[i][j]; + } + } + return bv; +} + +// get the score1, that is the sum of all the values in the grid +function getScore1() { + var score1 = 0; + for (var i = 0; i < hsize; i++) { + for (var j = 0; j < vsize; j++) { + score1 += Math.floor(Math.pow(2, box_values[i][j].value - 1)); + } + } + return score1; +} + +// get the score2, that is the maximum value of all the values in the grid +function getScore2() { + var score2 = 0; + for (var i = 0; i < hsize; i++) { + for (var j = 0; j < vsize; j++) { + if (box_values[i][j].value > score2) + score2 = box_values[i][j].value; + } + } + return Math.floor(Math.pow(2, score2 - 1)); +} + +// get a random empty box to get a value 1 +function carryOn() { + if (getEmptyBox() == 0) + return; + var randx = Math.floor(Math.random() * 4); + var randy = Math.floor(Math.random() * 4); + while (box_values[randx][randy].value != 0) { + var randx = Math.floor(Math.random() * 4); + var randy = Math.floor(Math.random() * 4); + } + box_values[randx][randy].value = 1; +} + +// moves all the non-zero elements in a single row to the left +function moveAllUp(row, len) { + var i, j; + for (i = 0; i < len; i++) { + if (row[i].value == 0) { + for (j = i + 1; j < len && row[j].value == 0; j++) + ; + var k = j, l = i; + while (l < j) { + if (k < len) { + row[l].value = row[k].value; + row[k].value = 0; + } + else + row[l].value = 0; + l++; + k++; + } + } + } + return row; +} + +// fixes a single row, when the UP arrow is passed to it +function fixSingleRowUp(row, len) { + row = moveAllUp(row, len); + // merging + for (var i = 0; i < len - 1; i++) { + isMove = 1; + if (row[i].value == row[i + 1].value && row[i].value != 0) { + row[i].value++; + row[i + 1].value = 0; + } + } + row = moveAllUp(row, len); + return row; +} + +// moves all the non-zero elements in a single row to the left +function moveAllDown(row, len) { + var i, j; + for (i = len - 1; i >= 0; i--) { + if (row[i].value == 0) { + for (j = i - 1; j >= 0 && row[j].value == 0; j--) + ; + var k = j, l = i; + while (l > j) { + if (k >= 0) { + row[l].value = row[k].value; + row[k].value = 0; + } + else + row[l].value = 0; + l--; + k--; + } + } + } + return row; +} + +// fixes a single row, when the DOWN arrow is passed to it +function fixSingleRowDown(row, len) { + row = moveAllDown(row, len); + // merging + for (var i = len - 1; i > 0; i--) { + if (row[i].value == row[i - 1].value && row[i].value != 0) { + row[i].value++; + row[i - 1].value = 0; + isMove = 1; + } + } + row = moveAllDown(row, len); + return row; +} + +// moves all the elements on the board to the right +function rightMoveBoard(box_values) { + // console.log("Right arrow pressed"); + var oldBoardValues = JSON.stringify(box_values); + for (var i = 0; i < vsize; i++) { + var a = new Array(hsize); + for (var j = 0; j < hsize; j++) + a[j] = box_values[j][i]; + a = fixSingleRowDown(a, vsize); + for (var j = 0; j < hsize; j++) + box_values[j][i] = a[j]; + } + if (oldBoardValues == JSON.stringify(box_values)) + return 0; + else + return 1; +} + +// moves all the elements on the board to the left +function leftMoveBoard(box_values) { + // console.log("Left arrow pressed"); + var oldBoardValues = JSON.stringify(box_values); + for (var i = 0; i < vsize; i++) { + var a = new Array(hsize); + for (var j = 0; j < hsize; j++) + a[j] = box_values[j][i]; + a = fixSingleRowUp(a, vsize); + for (var j = 0; j < hsize; j++) + box_values[j][i] = a[j]; + } if (oldBoardValues == JSON.stringify(box_values)) + return 0; + else + return 1; +} + +// moves all the elements on the board to the up +function upMoveBoard(box_values) { + // console.log("Up arrow pressed"); + var oldBoardValues = JSON.stringify(box_values); + for (var i = 0; i < hsize; i++) { + box_values[i] = fixSingleRowUp(box_values[i], vsize); + } if (oldBoardValues == JSON.stringify(box_values)) + return 0; + else + return 1; +} + +// moves all the elements on the board to the down +function downMoveBoard(box_values) { + // console.log("Down arrow pressed"); + var oldBoardValues = JSON.stringify(box_values); + for (var i = 0; i < hsize; i++) { + box_values[i] = fixSingleRowDown(box_values[i], vsize); + } + if (oldBoardValues == JSON.stringify(box_values)) + return 0; + else + return 1; +} + +// returns 1 if no move is possible +function noOtherMovePossible() { + if (getEmptyBox() > 0) + return 0; + for (var i = 0; i < hsize; i++) { + for (var j = 0; j < vsize; j++) { + if (j + 1 < vsize && box_values[i][j].value == box_values[i][j + 1].value) { + return 0; + } + if (i + 1 < hsize && box_values[i][j].value == box_values[i + 1][j].value) { + return 0; + } + } + } + // for (var i = 0; i < hsize; i++) { + // for (var j = 0; j < vsize; j++) { + // console.log(box_values[i][j].value) + // } + // } + return 1; +} + +// Taking in user input + +// Event listeners to manage the input of the game +document.addEventListener("keyup", keyUpHandler, false); + +function keyUpHandler(e) { + if (e.key == "Up" || e.key == "ArrowUp" || e.key == "Down" || e.key == "ArrowDown" || e.key == "Left" || e.key == "ArrowLeft" || e.key == "Right" || e.key == "ArrowRight") { + isMove = 0; + if (e.key == "Right" || e.key == "ArrowRight") { + isMove = rightMoveBoard(box_values); + } + else if (e.key == "Left" || e.key == "ArrowLeft") { + isMove = leftMoveBoard(box_values); + } + else if (e.key == "Down" || e.key == "ArrowDown") { + isMove = downMoveBoard(box_values); + } + else if (e.key == "Up" || e.key == "ArrowUp") { + isMove = upMoveBoard(box_values); + } + draw(); + } +} + +// functions to draw different things + +// draw vertical lines from a given starting point and length and color +function drawVLine(x, y, length, color) { + ctx.beginPath(); + ctx.rect(x, y, 1, length); + ctx.fillStyle = color; + ctx.fill(); + ctx.closePath(); +} + +// draw horizontal lines from a given starting point and length and color +function drawHLine(x, y, length, color) { + // console.log(x, y) + ctx.beginPath(); + ctx.rect(x, y, length, 1); + ctx.fillStyle = color; + ctx.fill(); + ctx.closePath(); +} + +// draw the main board +function drawBoard() { + ctx.beginPath(); + ctx.rect(boardx, boardy, boardwidth, boardheight); + ctx.fillStyle = boardColor; + ctx.fill(); + ctx.closePath(); +} + +// draw the grid outline +function drawGridOutline() { + for (var i = 0; i <= 4; i++) + drawHLine(boardx, boardy + i * boxwidth, boardwidth, "#000"); + for (var i = 0; i <= 4; i++) + drawVLine(boardx + i * boxwidth, boardy, boardheight, "#000"); +} + +// type in the number/value of the given box +function writeValue(box) { + // console.log(box.value); + if (box.value == 0) + return; + ctx.font = "16px Arial"; + ctx.fillStyle = "black"; + var numberToPrint = Math.floor(Math.pow(2, box.value - 1)); + ctx.fillText(numberToPrint, box.x + boxwidth / 2 - 4 * digCount(numberToPrint), box.y + boxheight / 2 + 4); +} + +// draw a single box +function drawBox(box) { + // console.log(box); + ctx.beginPath(); + ctx.rect(box.x + 0.05 * boxwidth, box.y + 0.05 * boxheight, 0.9 * boxwidth, 0.9 * boxheight); + ctx.fillStyle = boxColor[box.value]; // color of the box depends on its value + ctx.fill(); + ctx.closePath(); + writeValue(box); +} + +// draw the entire grid +function drawGrid() { + for (var i = 0; i < hsize; i++) { + for (var j = 0; j < vsize; j++) { + drawBox(box_values[i][j]); + } + } +} + +// print the score1 +function drawScore1() { + ctx.font = "16px Arial"; + ctx.fillStyle = "#0095DD"; + ctx.fillText("Current Score: " + getScore1(), 8, 50); +} + +// print the score2 +function drawScore2() { + ctx.font = "16px Arial"; + ctx.fillStyle = "#0095DD"; + ctx.fillText("Maximum Value Obtained: " + getScore2(), 8, 70); +} + +// calculate and print the maximum score1 in this session +function drawMaxScore1() { + ctx.font = "16px Arial"; + ctx.fillStyle = "#0095DD"; + var score1 = getScore1(); + if (maxScore1 < score1) + maxScore1 = score1; + ctx.fillText("High Score: " + maxScore1, 8, 550); +} + +// calculate and print the maximum score2 in this session +function drawMaxScore2() { + ctx.font = "16px Arial"; + ctx.fillStyle = "#0095DD"; + var score2 = getScore2(); + if (maxScore2 < score2) + maxScore2 = score2; + ctx.fillText("High Score in Maximum Value Obtained: " + maxScore2, 8, 570); +} + +// the main draw function +function draw() { + if (getEmptyBox != 0) { + carryOn(); + } + ctx.clearRect(0, 0, canvas.width, canvas.height); // clears the canvas content + drawBoard(); + drawGridOutline(); + drawGrid(); + drawScore1(); + drawScore2(); + drawMaxScore1(); + drawMaxScore2(); + if (noOtherMovePossible() == 1) { + alert("GAME OVER!\nCurrent Score: " + getScore1() + "\nMaximum Value Obtained: " + getScore2()); + clearGrid(); + draw(); + } +} + +draw(); + diff --git a/code/js/popup.js b/code/js/popup.js index cf968d0..9f0c40e 100644 --- a/code/js/popup.js +++ b/code/js/popup.js @@ -506,6 +506,9 @@ document.addEventListener('DOMContentLoaded', function () window.open("../games/flappy-bird/flappy_bird.html"); }); + document.getElementById("2048").addEventListener('click', function(){ + window.open("../games/2048/2048.html"); + }); document.getElementById("saved_list").onclick = function () { window.open("/saved.html"); diff --git a/code/popup.html b/code/popup.html index 27ad73d..a4d064a 100644 --- a/code/popup.html +++ b/code/popup.html @@ -152,7 +152,8 @@ - +