diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..496ee2c --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.DS_Store \ No newline at end of file diff --git a/README.md b/README.md index 40920f6..d1d7c2d 100644 --- a/README.md +++ b/README.md @@ -17,14 +17,38 @@ Recreate as much of the original game as is reasonable in the one week we have a ### Project Baseline - Play a couple games of [2048](http://gabrielecirulli.github.io/2048/). Think about everything that's likely happening in the code to support what's happening on the screen. Once you've got a feel for the game, talk with your pair and answer the following questions: 1. How does scoring work? + We will add the total of all new tiles at the end of the turn. This means that a board with a 2 + 2 collision will accrue points for both the 4 that is created and the new tile that spawns. The total for such a board would be 10 coming from 2 + 2, + 4, +2 as the new tile. + 1. When do tiles enter the game? + At the end of every non-losing turn. + 1. How do you know if you've won? + The background color becomes much more obnoxious, which occurs if we have a tile that is 2048 or greater. + 1. How do you know if you've lost? + There are no more available moves. Also, it's possible that the game will mock you. This feature to be added at some point. + 1. What makes tiles move? + A keypress event of the right, left, up, or down arrows. To humor old school gamers, we will also accept A, S, D, and W. + 1. What happens when they move? + - Tiles move their available spaces (which changes our data matrix to reflect the new values, as calculated by our collision math). + - The new tile is spawned + - The board is redrawn as necessary in the browser + - The score is updated + 1. How would you know how far a tile should move? + A tile slides until it hits a !null square. Collsion math will then determine if it moves one further. + 1. How would you know if tiles would collide? + If tile_value === next_square_value, tiles should collide. + 1. What happens when tiles collide? + - In our data matrix, the values of the tiles are combined in the slot furthest in the direction of movement. + - The moving tile's slot is then "zeroed out" by being reset to null. + - The representation of the board is updated + - The score is recalculated using the combined total. + - Document your answers to these questions in this README. - Use your discussion and answers to create tasks for a trello board. Organize those tasks into deliverable components (e.e., _Scoring_, _Tile Collision_, _Win/Loss_). - Open a PR with your discussion notes and answers to the above questions. Include a link to your Trello board. Indicate in the PR which deliverable(s) you are targeting first. diff --git a/assets/move-down.svg b/assets/move-down.svg new file mode 100644 index 0000000..fe707a3 --- /dev/null +++ b/assets/move-down.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/move-left.svg b/assets/move-left.svg new file mode 100644 index 0000000..de07eee --- /dev/null +++ b/assets/move-left.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/move-right.svg b/assets/move-right.svg new file mode 100644 index 0000000..b622311 --- /dev/null +++ b/assets/move-right.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/move-up.svg b/assets/move-up.svg new file mode 100644 index 0000000..7d5b662 --- /dev/null +++ b/assets/move-up.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/index.html b/index.html index 4740408..96fbd00 100644 --- a/index.html +++ b/index.html @@ -7,26 +7,28 @@ -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
2
+ diff --git a/javascripts/2048.js b/javascripts/2048.js index 4b2746c..6db1710 100644 --- a/javascripts/2048.js +++ b/javascripts/2048.js @@ -1,36 +1,169 @@ var Game = function() { - // Game logic and initialization here + this._board = [[null, null, null, null], + [null, null, null, null], + [null, null, null, null], + [null, null, null, null]] + + this._availableSpaces = [[0, 1], [0, 2], [0, 3], [1, 0], [1, 1], [1, 2], [2, 0], [2, 1], [2, 2], [2, 3], [3, 0], [3, 1], [3, 2]] + this._score = 0 }; -Game.prototype.moveTile = function(tile, direction) { +Game.prototype.moveTile = function(tile, direction, callback) { // Game method here switch(direction) { case 38: //up console.log('up'); + this.moveUp() + callback break; case 40: //down console.log('down'); + this.moveDown() + callback break; case 37: //left console.log('left'); + this.moveLeft() + callback break; case 39: //right console.log('right'); + this.moveRight() + callback break; } }; +Game.prototype.updateBoard = function() { + for (i = 0; i < 4; i++) { + for (j = 0; j < 4; j++) { + // this._board[i][j] = Number(this._board[i][j]) + slot = "\"[" + i.toString() + "][" + j.toString() + "]\"" + // console.log(slot) + if (this._board === null || this._board[i][j] === 0 || isNaN(this._board[i][j]) || typeof this._board[i][j] === 'undefined') { + this._board[i][j] = null + $('div[id='+ slot + ']').removeClass('full') + } else { + $('div[id='+ slot + ']').html(this._board[i][j]) + $('div[id='+ slot + ']') + }} + } + +} + +Game.prototype.boardCleaner = function () { + this._availableSpaces = [] + for (let i = 0; i < 4; i++) { + for (let j = 0; j < 4; j++) { + if (this._board[i][j] === null || this._board[i][j] === 0) { + this._availableSpaces.push([i, j]) + } + } + } + +} + +Game.prototype.collide = function (spaceOne, spaceTwo) { + // spaces specified hold values + if (spaceOne === spaceTwo) { + spaceOne += spaceTwo + this._score += spaceOne + } else if (spaceOne === null || spaceOne === 0 || typeof spaceOne === 'undefined' || isNaN(spaceOne)) { + spaceOne = spaceTwo + } else { + return false + } + + return spaceOne +} + +Game.prototype.moveLeft = function () { + for (let i = 0; i < 4; i++) { + for (let j = 0; j < 3; j++) { + for (let k = j; k >= 0; k--) { + let newValue = this.collide(this._board[i][k], this._board[i][k + 1]) + if (newValue !== false) { + this._board[i][k] = Number(newValue) + this._board[i][k + 1] = null + } + } + } + } +} + +Game.prototype.moveRight = function () { + for (let i = 0; i < 4; i++) { + for (let j = 3; j > 0; j--) { + for (let k = j; k <= 3; k++) { + let newValue = this.collide(this._board[i][k], this._board[i][k - 1]) + if (newValue !== false) { + this._board[i][k] = Number(newValue) + this._board[i][k - 1] = null + } + } + } + } +} + +Game.prototype.moveDown = function () { + for (let i = 0; i < 4; i++) { + for (let j = 3; j > 0; j--) { + for (let k = j; k <= 3; k++) { + let newValue = this.collide(this._board[k][i], this._board[k - 1][i]) + if (newValue !== false) { + this._board[k][i] = Number(newValue) + this._board[k - 1][i] = null + } + } + } + } +} + +Game.prototype.moveUp = function () { + for (let i = 0; i < 4; i++) { + for (let j = 0; j < 3; j++) { + for (let k = j; k >= 0; k--) { + let newValue = this.collide(this._board[k][i], this._board[k + 1][i]) + if (newValue !== false) { + this._board[k][i] = Number(newValue) + this._board[k + 1][i] = null + } + } + } + } +} + +Game.prototype.addTile = function () { + console.log(this._availableSpaces) + console.log(Math.floor(Math.random() * this._availableSpaces.length)) + let random = this._availableSpaces[Math.floor(Math.random() * this._availableSpaces.length)] + console.log(random) + this._score += 2 + let firstIndex = random.toString()[0] + let secondIndex = random.toString()[2] + this._board[Number(firstIndex)][Number(secondIndex)] = Number(2) + this.boardCleaner() +} + $(document).ready(function() { console.log("ready to go!"); // Any interactive jQuery functionality var game = new Game(); + game.addTile(game.updateBoard()) + $('body').keydown(function(event){ var arrows = [37, 38, 39, 40]; + var border = $('#flash-background') + var directions = ['left', 'up', 'right', 'down'] if (arrows.indexOf(event.which) > -1) { + var direction = arrows.indexOf(event.which) var tile = $('.tile'); - - game.moveTile(tile, event.which); + game.moveTile(tile, event.which, game.addTile()) + $('#flash-background').removeClass('up-background right-background left-background down-background').addClass(directions[direction] + '-background') + console.log(game._board) + game.updateBoard() + game.boardCleaner() } }); }); diff --git a/javascripts/movement.js b/javascripts/movement.js new file mode 100644 index 0000000..02f4483 --- /dev/null +++ b/javascripts/movement.js @@ -0,0 +1,79 @@ +Game.prototype.moveLeft = function () { + for (let i = 3; i >= 0; i --) { + for (let j = 3; j >= 0; j --) { + this.collide(this.board[i][j], this.board[i][j-1]) + } + } + } +} + +Game.prototype.moveRight = function () { + for (let i = 0; i < 4; i ++) { + for (let j = 0; j < 4; j ++) { + this.collide(this.board[i][j], this.board[i][j+1]) + } + } + } +} + +Game.prototype.moveUp = function () { + for (let i = 3; i >= 0; i --) { + for (let j = 3; j >= 0; j --) { + this.collide(this.board[i][j], this.board[i+1][j]) + } + } + } +} + +Game.prototype.moveDown = function () { + for (let i = 3; i > 0; i --) { + for (let j = 3; j > 0; j --) { + this.collide(this.board[i][j], this.board[i+1][j]) + } + } + } +} + +// Game.prototype.checkLeft = function (array) { +// if (array === [null, null, null, null]) { +// return array +// } + +// for (let i in array) { +// if (array[i] === null) { +// array[i] = array[i+1] +// array[i+1] = null +// } +// } +// } + + +// Game.prototype.collideLeft = function (array) { +// for (let i = 3; i > 0; i--) { +// if (array[i] === array[i-1]) { +// array[i] += array[i-1] +// } else if (array[i] === null) { +// array[i] = array[i-1] +// } else { +// array[i] = array[i] +// } +// } + +// return array +// } + +// is array 4 empty? +// is it mergable? + +// is array 3 now empty? +// is it mergable + + + + + + +// is array 0 empty? + +// if no, is array 1 mergable? + diff --git a/stylesheets/2048.css b/stylesheets/2048.css index 2a46a94..c21ef8f 100644 --- a/stylesheets/2048.css +++ b/stylesheets/2048.css @@ -1,9 +1,9 @@ html { - font: normal normal 30px/1 "Clear Sans", "Helvetica Neue", Arial, sans-serif; + font: normal normal 30px/1 "Comic Sans MS", cursive, sans-serif; } #gameboard { - background: #bbada0; + background: purple; border-radius: 0.5rem; height: 18.5rem; margin: 1rem auto; @@ -20,13 +20,45 @@ html { width: 4rem; } +.up-background { + background-color: deeppink; + background-image: url('../assets/move-up.svg'); + background-size: 10%; + background-repeat: repeat; + padding: 2rem; +} + +.down-background { + background-color: green; + background-image: url('../assets/move-down.svg'); + background-size: 10%; + background-repeat: repeat; + padding: 2rem; +} + +.right-background { + background-color: cyan; + background-image: url('../assets/move-right.svg'); + background-size: 10%; + background-repeat: repeat; + padding: 2rem; +} + +.left-background { + background-color: orange; + background-image: url('../assets/move-left.svg'); + background-size: 10%; + background-repeat: repeat; + padding: 2rem; +} + .tile { position: absolute; top: 0; left: 0; transition: all 0.2s ease-in-out; - color: #f9f6f2; - background: #000; + color: #000; + background: greenyellow; border-radius: 0.5rem; font-size: 1.5rem; @@ -59,3 +91,5 @@ html { .tile[data-val="512"] { background: #edc850; } .tile[data-val="1024"] { background: #edc53f; } .tile[data-val="2048"] { background: #edc22e; } + +.full { background-color: greenyellow; }