diff --git a/amysplayground.js b/amysplayground.js new file mode 100644 index 0000000..b984c2f --- /dev/null +++ b/amysplayground.js @@ -0,0 +1,50 @@ +var gameBoard = [[0, 2, 0, 0], [0, 2, 0, 0], [0, 2048, 4, 0], [0, 0, 4, 0]]; +var tile2048present = false; + +function getFreeSpaces(){ + var freeSpaces = []; +// 3. Iterate through the rows and the columns in the gameboard + for(var i = 0; i < 4; i++){ + for(var j = 0; j < 4; j++){ + // and find all that are empty + if (gameBoard[i][j] === 0){ + // keep a list of the indices in a new array saved as a variable + freeSpaces.push([i, j]); + } + } + } + return freeSpaces; +}; + +function addOneTile(){ + var num = Math.random(); + + var result; + if (num < 0.9) { + result = 2; + } else { + result = 4; + } + + var openSpots = this.getFreeSpaces(); + var selectedSpot = openSpots[Math.floor(Math.random() * openSpots.length)]; + gameBoard[selectedSpot[0]][selectedSpot[1]] = result; + console.log(selectedSpot); + return result; +} + +function isThere2048(){ + for(var i = 0; i < 4; i++){ + for(var j = 0; j < 4; j++){ + // and find all that are empty + if (gameBoard[i][j] === 2048){ + // keep a list of the indices in a new array saved as a variable + tile2048present = true; + } + } + } + return tile2048present; +} +console.log(getFreeSpaces()); +console.log(addOneTile()); +console.log(isThere2048()); diff --git a/index.html b/index.html index 4740408..ab8520a 100644 --- a/index.html +++ b/index.html @@ -26,7 +26,7 @@
-
2
+ diff --git a/javascripts/2048.js b/javascripts/2048.js index 5c5c1d9..a5ec75d 100644 --- a/javascripts/2048.js +++ b/javascripts/2048.js @@ -1,39 +1,316 @@ var Game = function() { // Game logic and initialization here - this.gameBoard = [[0, 0, 0, 0], [0, 2, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]; + this.gameBoard = [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]; + this.gameLost = false; + this.addOneTile(); + this.addOneTile(); + this.showBoard(); + this.score = 0; }; + +$(document).ready(function() { + console.log("ready to go!"); + // Any interactive jQuery functionality + var game = new Game(); + console.log(game.gameBoard); + + $('body').keydown(function(event){ + var arrows = [37, 38, 39, 40]; + if (arrows.indexOf(event.which) > -1) { + var tile = $('.tile'); + + game.moveTile(tile, event.which); + } + }); +}); + Game.prototype.moveTile = function(tile, direction) { // Game method here + var self = this; + if (self.gameLost === false) { switch(direction) { case 38: //up console.log('up'); - this.gameBoard = [[0, 2, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]; - $('.tile').animate({ top: '-=134'}, 100); + self.upMoveTiles(); + self.upTileCollision(); + self.upMoveTiles(); + self.isGameLost(); + self.addOneTile(); + console.log(self.gameBoard); + self.isGameLost(); + console.log(self.score); + console.log(self.gameLost); + this.showBoard(); break; case 40: //down console.log('down'); + self.downMoveTiles(); + self.downTileCollision(); + self.downMoveTiles(); + self.isGameLost(); + self.addOneTile(); + console.log(self.gameBoard); + self.isGameLost(); + console.log(self.score); + console.log(self.gameLost); + this.showBoard(); break; case 37: //left console.log('left'); + self.leftMoveTiles(); + self.leftTileCollision(); + self.leftMoveTiles(); + self.isGameLost(); + self.addOneTile(); + console.log(self.gameBoard); + self.isGameLost(); + console.log(self.score); + console.log(self.gameLost); + this.showBoard(); break; case 39: //right console.log('right'); + self.rightMoveTiles(); + self.rightTileCollision(); + self.rightMoveTiles(); + self.isGameLost(); + self.addOneTile(); + console.log(self.gameBoard); + self.isGameLost(); + console.log(self.score); + console.log(self.gameLost); + this.showBoard(); break; } +} }; -$(document).ready(function() { - console.log("ready to go!"); - // Any interactive jQuery functionality - var game = new Game(); - - $('body').keydown(function(event){ - var arrows = [37, 38, 39, 40]; - if (arrows.indexOf(event.which) > -1) { - var tile = $('.tile'); +Game.prototype.upMoveTiles = function(){ + var self = this; + // iterate through each "row" (each array within gameboard array) + self.gameBoard.forEach(function(row, rowIndex){ + // iterate through each "column" (each item within a row) + row.forEach(function(column, columnIndex){ + // don't look at tiles that don't have a a value to them, AND don't look left if column is farthest left + if (column !== 0 && rowIndex !== 0) { + // iterate through each item further left of current item + for (var i = rowIndex - 1; i >= 0; i--) { + // increment numSpaces to move up by 1 if the next tile up is 0 + if (self.gameBoard[i][columnIndex] === 0) { + self.gameBoard[i][columnIndex] = column; + self.gameBoard[i + 1][columnIndex] = 0; + } + } + } + }); + }); +}; - game.moveTile(tile, event.which); +Game.prototype.downMoveTiles = function(){ + var self = this; + // iterate through each "row" (each array within gameboard array) + for (var k = 2; k >= 0; k--) { + var row = self.gameBoard[k], rowIndex = k; + // iterate through each "column" (each item within a row) + for (var j = 0; j <= 3; j++) { + // row.forEach(function(column, columnIndex){ + var column = row[j], columnIndex = j; + // don't look at tiles that don't have a a value to them, AND don't look left if column is farthest down already + if (column !== 0) { + // iterate through each item further up of current item + for (var i = rowIndex; i < 3; i++) { + // increment numSpaces to move down by 1 if the next num down is 0 + if (self.gameBoard[i + 1][columnIndex] === 0) { + self.gameBoard[i + 1][columnIndex] = column; + self.gameBoard[i][columnIndex] = 0; + } + } + } } + } +}; + +Game.prototype.leftMoveTiles = function(){ + var self = this; + // iterate through each "row" (each array within gameboard array) + self.gameBoard.forEach(function(row, rowIndex){ + // iterate through each "column" (each item within a row) + row.forEach(function(column, columnIndex){ + var numSpaces = 0; + // don't look at tiles that don't have a a value to them, AND don't look left if column is farthest left + if (column !== 0 && columnIndex !== 0) { + // iterate through each item further left of current item + for (var i = columnIndex; i >= 0; i--) { + // increment numSpaces to move left by 1 if the next left over is 0 + if (row[i - 1] === 0) { + row[i - 1] = column; + row[i] = 0; + } + } + } + }); }); -}); +}; + +Game.prototype.rightMoveTiles = function(){ + var self = this; + // iterate through each "row" (each array within gameboard array) + for (var m = 0; m < self.gameBoard.length; m++) { + // iterate through each "column" (each item within a row) + var row = self.gameBoard[m], rowIndex = m; + + for (var j = 3; j >= 0; j--) { + var column = row[j], columnIndex = j; + // don't look at tiles that don't have a a value to them, AND don't look right if column is farthest right + if (column !== 0) { + for (var i = columnIndex + 1; i <= 3; i++) { + // increment numSpaces to move right by 1 if the next right over is 0 + if (row[i] === 0) { + // select current tile and move it appropriate num spaces right + row[i] = column; + row[i - 1] = 0; + } + } + } + } + } +}; + +Game.prototype.upTileCollision = function(){ + var self = this; + for(var i = 1; i <= 3; i++){ + for(var j = 0; j <= 3; j++){ + if(self.gameBoard[i][j] > 0){ + if(self.gameBoard[i - 1][j] === self.gameBoard[i][j]){ + self.gameBoard[i - 1][j] *= 2; + self.score += self.gameBoard[i - 1][j]; + self.gameBoard[i][j] = 0; + } + } + } + } +}; + +Game.prototype.downTileCollision = function(){ + var self = this; + for (var i = 3; i >= 1; i--) { // iterate through each row + for (var j = 0; j <= 3; j++) { // iterate through each tile in each row + if (self.gameBoard[i][j] > 0) { + if (self.gameBoard[i - 1][j] === self.gameBoard[i][j]) { + self.gameBoard[i][j] *= 2; + self.score += self.gameBoard[i][j]; + self.gameBoard[i - 1][j] = 0; + } + } + } + } +}; + +Game.prototype.leftTileCollision = function(){ + var self = this; + for (var i = 0; i <= 3; i++) { // iterate through each row + for (var j = 1; j <= 3; j++) { // iterate through each tile in each row + if (self.gameBoard[i][j] > 0) { + if (self.gameBoard[i][j - 1] === self.gameBoard[i][j]) { + self.gameBoard[i][j] *= 2; + self.score += self.gameBoard[i][j]; + self.gameBoard[i][j - 1] = 0; + } + } + } + } +}; + +Game.prototype.rightTileCollision = function(){ + var self = this; + for (var i = 0; i <= 3; i++) { // iterate through each row + for (var j = 3; j >= 1; j--) { // iterate through each tile in each row + if (self.gameBoard[i][j] > 0) { + if (self.gameBoard[i][j - 1] === self.gameBoard[i][j]) { + self.gameBoard[i][j] *= 2; + self.score += self.gameBoard[i][j]; + self.gameBoard[i][j - 1] = 0; + } + } + } + } +}; + +Game.prototype.flattenNums = function() { + var flattened = this.gameBoard.reduce(function(a, b) { + return a.concat(b); + }, []); + return flattened; +}; + +Game.prototype.isGameLost = function() { + // check if any number in flattened game board is 0 + var flattenedNums = this.flattenNums(), isGameLost = true, self = this; + for (var i = 0; i < flattenedNums.length; i++) { + if (flattenedNums[i] === 0) { + isGameLost = false; + } + } + + // check if any tiles can be combined with the tile to the right, or below + for (var m = 0; m <= 3; m++) { + for (var j = 0; j <= 3; j++) { + if (self.gameBoard[m][j] === self.gameBoard[m][j + 1]){ + isGameLost = false; + } + if (self.gameBoard[m + 1] !== undefined && self.gameBoard[m][j] === self.gameBoard[m + 1][j]) { + isGameLost = false; + } + } + } + self.gameLost = isGameLost; + return isGameLost; +}; + +Game.prototype.getFreeSpaces = function(){ + var freeSpaces = []; +// 3. Iterate through the rows and the columns in the gameboard + for(var i = 0; i <= 3; i++){ + for(var j = 0; j <= 3; j++){ + // and find all that are empty + if(this.gameBoard[i][j] === 0){ + // keep a list of the indices in a new array saved as a variable + freeSpaces.push([i, j]); + } + } + } + return freeSpaces; +}; + +Game.prototype.addOneTile = function(){ + var num = Math.random(); + + var result; + if (num < 0.9) { + result = 2; + } else { + result = 4; + } + + var openSpots = this.getFreeSpaces(); + var selectedSpot = openSpots[Math.floor(Math.random() * openSpots.length)]; + this.gameBoard[selectedSpot[0]][selectedSpot[1]] = result; + console.log(this.gameBoard[selectedSpot[0]][selectedSpot[1]]); + console.log(selectedSpot, result); + return result; +}; + +Game.prototype.showBoard = function() { + var self = this; + $('.tile').remove(); + + for (var r = 0; r <= 3; r++) { + for (var c = 0; c <= 3; c++) { + if (this.gameBoard[r][c] > 0) { + var tile = this.gameBoard[r][c]; + $('#gameboard').append('
' + tile + '
'); + } + } + } +}; diff --git a/thoughts.md b/thoughts.md new file mode 100644 index 0000000..c1da913 --- /dev/null +++ b/thoughts.md @@ -0,0 +1,56 @@ +Determining End of Game +* If all spaces in the game board contain a tile, and no tile is contiguous to a tile of the same value, the game is over. + +Scoring +* When two tiles of the same value collide, their combined value is added to the total score. +var totalScore = 0; + +Tile Movement +* When a directional key is pressed, all of the tiles in a row (for left or right keys) or column (up or down keys) will shift in the direction of the key press to the furthest spot possible +example: [0, 2, 4, 0] + right directional key becomes [0, 0, 2, 4] + +Combining Tiles +* When there are unimpeded tiles of the same value in a row or column and the directional button is pushed in the same direction as the line of values, the value closest to the edge of the board becomes combined with the preceding tile, and the tile that is considered the "bottom" disappears. +example [0, 2, 2, 0] + left key press becomes [4, 0, 0, 0] + +example: 2 2 2 push the right directional arrow becomes: 2 4 +vertical bottom 2 2 2 top push the up arrow becomes bottom 2 top 4 + +Any space that the original tile vacates becomes 0 (empty) + +Tile movement and combination occurs simultaneously with all rows or columns corresponding to a given key press. + +Random Tile Appearance +* After each directional key is pressed, a tile with a value of either two or 4 will appear randomly in an empty space on the game board. + +Steps to make this happen: +Generate a tile("value") +Check the board for empty spots(if any of the spots in the array ==== 0) +Use two nested loops to select a random empty spot on the board and select the value + + +// Returns a random integer between min (included) and max (included) +// Using Math.round() will give you a non-uniform distribution! +function getRandomIntInclusive(min, max) { + return Math.floor(Math.random() * (max - min + 1)) + min; +} + +//The Math.floor() function returns the largest integer less than or equal to a given number. + +function randomGameBoardIndex(min, max){ + return Math.floor(Math.random()(put an asterisk)(max-min+1)+min)); +} +randomGameBoardIndex(0, 15); + +myArray = [2, 4]; +var rand = myArray[Math.floor(Math.random() * myArray.length)]; + +* Turn Sequence of functions +Key Press +Tile Slide +Tile Combination +Tile Slide +Increment Score +Check for conditions to determine end of game +Check for 2048 tile +If EOG is false, Generate Random Tile