Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 34 additions & 1 deletion index.css
Original file line number Diff line number Diff line change
@@ -1 +1,34 @@
/* Стили для пятнашек опишите в этом файле */
body, html {
height: 100%;
}

#playground {
padding: 32px 32px;
}

#win {
margin: 0;
font-size: 50px;
display: inline-block;
text-align: center;
width: 100%;
color: black;
visibility: hidden;
}

.button {
background-color: white;
color: black;
text-align: center;
display: inline-block;
margin: 2px 2px;
height: 100px;
width: 100px;
font-size: 20px;
cursor: pointer;

}

.button:hover {
background-color: aliceblue;
}
29 changes: 15 additions & 14 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,22 @@
<link href="https://cdn.rawgit.com/mochajs/mocha/2.2.5/mocha.css" rel="stylesheet" />
</head>
<body>
<!-- Начальное состояние для игры "Пятнашки" формируем здесь -->
<!-- Начальное состояние для игры "Пятнашки" формируем здесь -->
<div id="playground"></div>
<p id="win">ура!</p>
<!-- Тестовый отчет будет формироваться на основании этого элемента -->
<div id="mocha"></div>

<!-- Тестовый отчет будет формироваться на основании этого элемента -->
<div id="mocha"></div>
<!-- Подключаем внешние библиотеки с CDN чтобы можно было смотреть домашку прямо с GitHub -->
<script src="https://cdn.rawgit.com/mochajs/mocha/2.2.5/mocha.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/chai/3.5.0/chai.js"></script>

<!-- Подключаем внешние библиотеки с CDN чтобы можно было смотреть домашку прямо с GitHub -->
<script src="https://cdn.rawgit.com/mochajs/mocha/2.2.5/mocha.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/chai/3.5.0/chai.js"></script>
<!-- Подключаем реализацию пятнашек -->
<script src="./index.js"></script>

<!-- Подключаем реализацию пятнашек -->
<script src="./index.js"></script>

<!-- Конфигурируем и запускаем тесты -->
<script>mocha.setup('bdd')</script>
<script src="./tests/index-test.js"></script>
<script>mocha.run();</script>
<!-- Конфигурируем и запускаем тесты -->
<script>mocha.setup('bdd')</script>
<script src="./tests/index-test.js"></script>
<script>mocha.run();</script>
</body>
</html>
</html>
131 changes: 130 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
@@ -1 +1,130 @@
// Логику пятнашек нужно описать в этом файле
var n = 4;
function getEmptyCellId(cellId, cells) {
cellId = parseInt(cellId);
if (cellId - 1 >= 0 && cellId % n !== 0) {
if (parseInt(cells[cellId - 1].value) === -1){
return cellId - 1;
}
}
if (cellId + 1 < 16 && cellId % n !== n-1) {
if (parseInt(cells[cellId + 1].value) === -1){
return cellId + 1;
}
}
if (cellId - n >= 0) {
if (parseInt(cells[cellId - n].value) === -1){
return cellId - n;
}
}
if (cellId + n < 16) {

if (parseInt(cells[cellId + n].value) === -1) {
return cellId + n;
}
}
return -1
}

function isWin(cells) {
for (var i = 0; i < cells.length - 1; i++) {
if (parseInt(cells[i].value) !== i + 1) {
return false;
}
}
return true;
}

function swapCells(nextCell, targetCell) {
nextCell.style.visibility = 'visible';
nextCell.value = targetCell.value;
targetCell.style.visibility = 'hidden';
targetCell.value = -1;
}

function swap(event) {
var e = event || window.event;

var targetCell = e.target || e.srcElement;
if (targetCell.tagName !== 'INPUT') {
return;
}
var playGround = document.getElementById('playground');
var cells = playGround.getElementsByClassName('button');
var winMessage = document.getElementById('win');
var nextCellId = getEmptyCellId(targetCell.id, cells);
if (nextCellId !== -1) {
swapCells(cells[nextCellId], targetCell);
}
if (isWin(cells)) {
winMessage.style.visibility = 'visible';
} else {
winMessage.style.visibility = 'hidden';
}
}

function compareRandom() {
return Math.random() - 0.5;
}

function startGame(board) {
var playGround = document.getElementById('playground');
var winMessage = document.getElementById('win');
winMessage.style.visibility = 'hidden';

var buttons = [];
for (var i = 0; i < n; i++){
buttons[i] = [];
for (var j = 0; j < n; j++)
{
buttons[i][j] = null;
}
}

if (board === undefined){
board = [];
var number = [];
for (i = 1; i< n*n; i++){
number.push(i)
}
number.sort(compareRandom);
number.unshift(-1);
var count = 0;
for (i = 0; i < n; i++) {
board[i] = [];
for(j = 0; j < n; j++)
{
board[i][j] = number[count];
count++
}
}
}

for (i = 0; i < n; i++) {
for (j = 0; j <n; j++){
var button = document.createElement('input');
button.id = i * n +j;
button.type = 'button';
button.className = 'button';
button.value = board[i][j];
if (board[i][j] === -1){
button.style.visibility = 'hidden';
}
else {
button.style.visibility = 'visible';
}
buttons[i][j] = button;
playGround.appendChild(button);
if ((i*4 + j + 1) % n === 0) {
playGround.appendChild(document.createElement('br'));
}
}
}

if (playGround.addEventListener) {
playGround.addEventListener('click', swap);
} else {
playGround.attachEvent('onclick', swap);
}
}

document.body.onload = startGame();
168 changes: 166 additions & 2 deletions tests/index-test.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,167 @@
var expect = chai.expect;


function clearPlayground() {
var playground = document.getElementById('playground');
playground.innerHTML = '';
}

describe('Tag', function() {
it('should ...');
});
var clickEvent = document.createEvent('Events');
clickEvent.initEvent('click', true, false);
var cells = [];
var hiddenCell = null;
var cellsWithoutEmpty = null;
clearPlayground();
beforeEach(function () {
startGame();
cells = [].slice.call(document.getElementsByClassName('button'));
hiddenCell = cells.filter(function(item) {
return parseInt(item.value) === -1;
})[0];
cellsWithoutEmpty = cells.filter(function(item) {
return item.value !== -1;
});
});
afterEach(function () {
clearPlayground();
});
after(function () {
startGame();
});

it('should generate 15 visible numbered cells', function() {
cells = [].slice.call(document.getElementsByClassName('button'));
chai.expect(cells.filter(function(item) {
return item.style.visibility === 'hidden';
})).to.have.length(1);
chai.expect(cells.filter(function(item) {
return item.style.visibility === 'visible';
})).to.have.length(15);
});

it('should move the cell to a neighboring empty cell in the upper left corner by click', function() {
var neighboursOfHiddenCell = cells.filter(function(item) {
return getEmptyCellId(item.id, cells) !== -1;
});

var hiddenCellValue = hiddenCell.value;
neighboursOfHiddenCell.forEach(function (neighbour) {
var neighbourValue = neighbour.value;

neighbour.dispatchEvent(clickEvent);
expect(neighbour.value).to.eql(hiddenCellValue);
expect(hiddenCell.style.visibility).to.equal('visible');
expect(hiddenCell.value).to.eql(neighbourValue);
expect(neighbour.style.visibility).to.equal('hidden');
hiddenCell.dispatchEvent(clickEvent);
});
});

it('should move the cell to a neighboring empty cell in the middle by click', function() {
var board = [
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, -1, 11],
[12, 13, 14, 15]
];
clearPlayground();
startGame(board);
cells = [].slice.call(document.getElementsByClassName('button'));

var neighboursOfHiddenCell = cells.filter(function(item) {
return getEmptyCellId(item.id, cells) !== -1;
});

hiddenCell =cells.filter(function(item) {
return parseInt(item.value) === -1;
})[0];
var hiddenCellValue = hiddenCell.value;

neighboursOfHiddenCell.forEach(function (neighbour) {
var NeighbourValue = neighbour.value;
neighbour.dispatchEvent(clickEvent);
expect(neighbour.value).to.eql(hiddenCellValue);
expect(hiddenCell.style.visibility).to.equal('visible');
expect(hiddenCell.value).to.eql(NeighbourValue);
expect(neighbour.style.visibility).to.equal('hidden');
hiddenCell.dispatchEvent(clickEvent);
});
});

it('should move the cell to a neighboring empty cell in the lower right corner by click', function() {
var board = [
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 15, 11],
[12, 13, 14, -1]
];
clearPlayground();
startGame(board);
cells = [].slice.call(document.getElementsByClassName('button'));

var neighboursOfHiddenCell = cells.filter(function(item) {
return getEmptyCellId(item.id, cells) !== -1;
});
hiddenCell =cells.filter(function(item) {
return parseInt(item.value) === -1;
})[0];
var hiddenCellValue = hiddenCell.value;
neighboursOfHiddenCell.forEach(function (neighbour) {
var NeighbourValue = neighbour.value;


neighbour.dispatchEvent(clickEvent);
expect(neighbour.value).to.eql(hiddenCellValue);
expect(hiddenCell.style.visibility).to.equal('visible');
expect(hiddenCell.value).to.eql(NeighbourValue);
expect(neighbour.style.visibility).to.equal('hidden');

hiddenCell.dispatchEvent(clickEvent);
});
});

it('shouldn\'t move empty cell by click', function() {
var hiddenCell = cells.filter(function(item) {
return parseInt(item.value) === -1;
})[0];
var expectedHiddenCellValue = hiddenCell.value;

hiddenCell.dispatchEvent(clickEvent);
expect(hiddenCell.style.visibility).to.equal('hidden');
expect(hiddenCell.value).to.eql(expectedHiddenCellValue);
});

it('shouldn\'t move cells, which have no empty neighboring cells', function() {
var cellsWithoutEmptyNeighbour = cells.filter(function(item) {
return getEmptyCellId(item.id, cells) === -1 && parseInt(item.value) !== -1;
});
var HiddenCellValue = hiddenCell.value;

cellsWithoutEmptyNeighbour.forEach(function(cell) {
cell.dispatchEvent(clickEvent);
var CellValue = cell.value;
expect(cell.value).to.eql(CellValue);
expect(hiddenCell.value).to.eql(HiddenCellValue);
});

});

it('should show win message', function() {
var board = [
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
[13, 14, -1, 15]
];
clearPlayground();
startGame(board);
cells = [].slice.call(document.getElementsByClassName('button'));
var winMessage = document.getElementById('win');

expect(winMessage.style.visibility).to.equal('hidden');
cells[cells.length - 1].dispatchEvent(clickEvent);
expect(winMessage.style.visibility).to.equal('visible');
winMessage.style.visibility = 'hidden';
});
});