Skip to content

Instantly share code, notes, and snippets.

@mohebifar
Created May 9, 2015 10:48
Show Gist options
  • Save mohebifar/a413f7fe8b799584468f to your computer and use it in GitHub Desktop.
Save mohebifar/a413f7fe8b799584468f to your computer and use it in GitHub Desktop.
Puzzle Game
<h2>Puzzle Game</h2>
<h3>Made by <a href="https://girhub.com/mohebifar">Mohamad Mohebifar</a></h3>
<p>Moves: <span id="moves">0</span> - Use arrow keys to move pieces</p>
<div class="canvas"></div>
<div class="win">
<p>You win !</p>
<a class="btn" href="#">New Game</a>
</div>
<p>
<a class="btn" href="#">New Game</a>
</p>
/**
* Puzzle Class
*
* @constructor
*/
var Puzzle = function Puzzle(el) {
this.matrix = [];
this.el = document.querySelector(el);
this.movesEl = document.getElementById('moves');
this._moves = 0;
this._lock = false;
};
Puzzle.getNeighbors = function (index) {
var result = {
top: null,
bottom: null,
left: null,
right: null
};
if ([3, 7, 11, 15].indexOf(index) === -1) {
result.right = index + 1;
}
if ([0, 4, 8, 12].indexOf(index) === -1) {
result.left = index - 1;
}
if (index > 3) {
result.top = index - 4;
}
if (index < 12) {
result.bottom = index + 4;
}
return result;
};
Puzzle.getPositionByIndex = function (index) {
return [Math.floor(index % 4) * 125, Math.floor(index / 4) * 125];
};
Puzzle.prototype.getNeighbors = function (index) {
var neighbors = Puzzle.getNeighbors(index);
for (var position in neighbors) {
var value = neighbors[position];
if (value !== null) {
neighbors[position] = this.matrix[value];
}
}
return neighbors;
};
Puzzle.prototype.shuffle = function () {
var matrix = this.matrix;
var tempArray = [];
var n = matrix.length;
for (var i = 0; i < n; i++) {
tempArray.push(matrix.splice(Math.floor(Math.random() * matrix.length), 1)[0]);
}
this.matrix = tempArray;
return this;
};
Puzzle.prototype.createNumbers = function () {
for (var i = 0; i < 16; i++) {
this.matrix[i] = new Piece(this);
this.matrix[i].el = document.createElement('div');
this.matrix[i].el.innerHTML = i + 1;
this.matrix[i].realIndex = i;
this.el.appendChild(this.matrix[i].el);
}
this.matrix[15].el.innerHTML = '';
this.matrix[15].el.className = 'null';
this.matrix[15].isNull = true;
return this;
};
Puzzle.prototype.updatePositions = function () {
for (var i = 0; i < this.matrix.length; i++) {
var obj = this.matrix[i];
var position = Puzzle.getPositionByIndex(i);
obj.el.style.left = position[0] + 'px';
obj.el.style.top = position[1] + 'px';
}
return this;
};
Puzzle.prototype.__defineGetter__('nullPiece', function () {
for (var i = 0; i < this.matrix.length; i++) {
var obj = this.matrix[i];
if (obj.isNull) {
return obj;
}
}
});
Puzzle.prototype.move = function (direction) {
if (this._lock) {
return;
}
var nullPiece = this.nullPiece,
neighbors = nullPiece.getNeighbors();
switch (direction) {
case 'up':
nullPiece.replace(neighbors.bottom);
break;
case 'down':
nullPiece.replace(neighbors.top);
break;
case 'left':
nullPiece.replace(neighbors.right);
break;
case 'right':
nullPiece.replace(neighbors.left);
break;
}
this.moves++;
this.updatePositions();
this.checkWin();
};
Puzzle.prototype.checkWin = function () {
for (var i = 0; i < this.matrix.length; i++) {
var obj = this.matrix[i];
if (obj.realIndex !== obj.index) {
return false;
}
}
document.querySelector('.win').style.display = 'block';
this.lock();
return true;
};
Puzzle.prototype.__defineGetter__('moves', function () {
return this._moves;
});
Puzzle.prototype.__defineSetter__('moves', function (moves) {
this._moves = moves;
this.movesEl.innerHTML = this._moves;
});
Puzzle.prototype.unlock = function () {
this._lock = false;
};
Puzzle.prototype.lock = function () {
this._lock = true;
};
/**
* Pieces Class
*
* @param puzzle
* @constructor
*/
var Piece = function Piece(puzzle) {
this.el = null;
this.parent = puzzle;
this.isNull = false;
this.realIndex = 0;
};
Piece.prototype.__defineGetter__('index', function () {
return this.parent.matrix.indexOf(this);
});
Piece.prototype.getNeighbors = function () {
return this.parent.getNeighbors(this.index);
};
Piece.prototype.replace = function (piece) {
if (piece) {
var myIndex = this.index,
thatIndex = piece.index;
this.parent.matrix[myIndex] = piece;
this.parent.matrix[thatIndex] = this;
return this;
}
};
var puzzle = new Puzzle('.canvas').createNumbers().shuffle().updatePositions();
window.addEventListener('keydown', function (e) {
var key = e.keyCode;
switch (key) {
case 37:
puzzle.move('left');
break;
case 38:
puzzle.move('up');
break;
case 39:
puzzle.move('right');
break;
case 40:
puzzle.move('down');
break;
}
});
function newGame() {
puzzle.moves = 0;
puzzle.shuffle().updatePositions().unlock();
}
document.querySelector('.btn').addEventListener('click', function (e) {
e.preventDefault();
newGame();
});
document.querySelector('.win').addEventListener('click', function (e) {
e.preventDefault();
document.querySelector('.win').style.display = 'none';
});
body {
background-color: #f8f8f8;
color: #222;
text-align: center;
font-family: "Segoe UI Light", "Sourse Sans Pro", sans-serif;
}
a {
text-decoration: none;
color: #222;
}
a:hover {
color: #333;
}
.canvas {
-webkit-box-shadow: 0 0 30px rgba(0, 0, 0, 0.3);
-moz-box-shadow: 0 0 30px rgba(0, 0, 0, 0.3);
box-shadow: 0 0 30px rgba(0, 0, 0, 0.3);
width: 500px;
height: 500px;
margin: auto;
background-color: #eee;
position: relative;
border: 2px solid #DDD;
box-sizing: border-box;
}
.canvas > div {
width: 125px;
height: 125px;
position: absolute;
line-height: 125px;
font-size: 3em;
background-color: #F1F1F1;
color: #4B5F6D;
font-weight: bold;
font-family: "Segoe UI Light", sans-serif;
box-sizing: border-box;
border: 1px solid #DDD;
}
.canvas > div:not(.null) {
transition: .1s ease left, .1s ease top;
z-index: 50;
}
.win {
position: fixed;
transform: translate(-50%, -50%);
left: 50%;
top: 50%;
z-index: 600;
border-radius: 15px;
background-color: #fff;
box-shadow: 0 0 10px 900px rgba(0, 0, 0, .3), 0 0 15px rgba(0, 0, 0, 0.5);
text-transform: uppercase;
padding: 30px;
display: none;
}
.win p {
font-size: 4em;
}
.btn {
display: inline-block;
border-radius: 3px;
background-color: #fff;
border: 1px solid #000;
padding: 5px 15px;
font-weight: bold;
}
.btn:hover {
background-color: #fafafa;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment