Приветствую.
Пока без всяких сборщиков, фреймворков и реактивных вещей, старый добрый скрипт, делаю чтобы с использованием объектов и кое какой структурой типа MVC.
Только
C тут не стал делать.
Модель отвечает за данные и алгоритмы.
А Вьюха - за html и события.
Главное чтобы не лапшекод перемешанный, а с разделением ответственности.
Вроде наглядно получилось, ваше мнение по улучшению?
Вы таким бы способом делали, если на объектах ( а не просто процедурно)?
Реализация игры "
Пятнашки":
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
td {
border: 2px solid black;
width: 20px;
height: 20px;
text-align: center;
}
</style>
<script
src="https://code.jquery.com/jquery-3.6.0.min.js"
integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4="
crossorigin="anonymous"></script>
<script>
$(document).ready(function(){
'use strict';
let model = new Model();
let view = new View(model, '#tablefield', '#result', '#process');
function View(model, tablefieldId, resultId, startGameButton) {
this.model = model;
this.$tablefield = $(tablefieldId);
this.$result = $(resultId);
this.$startGameButton = $(startGameButton);
let _view = this;
this.$startGameButton.click(function(){
if (!_view.model.getIsGameOver()) {
_view.$result.html('Игра уже идет').show().fadeOut(2000);
return;
}
_view.model.startGame();
_view.showTable();
_view.initializeTable();
$(this).prop('disabled', true);
});
this.showTable = function () {
let table = this.model.table;
this.$tablefield.html('');
let res = '<table>';
for (let i = 0; i < table.length; i++){
res += '<tr>';
for (let j = 0; j < table[i].length; j++){
let cell = table[i][j];
res += '<td style="' + '' + '">';
res += cell;
res += '</td>';
}
res += '</tr>';
}
res += '</table>';
this.$tablefield.html(res);
this.$result.html('Игра начинается, соберите числа от 1 до 15 по рядам сверху вниз').show().fadeOut(4000);
}
this.initializeTable = function (){
$('td').click(function(){
let model = _view.model;
if (model.getIsGameOver()) {
_view.$result.html('Игра завершена, начните новую игру').show().fadeOut(2000);
return;
}
let $td = $(this);
if ($td.html() == '') {
_view.$result.html('Пустую ячейку нельзя перемещать').show().fadeOut(2000);
return;
}
let $tr = $td.parent();
let $table = $tr.parent();
let x = $td.prevAll().length;
let y = $tr.prevAll().length;
if (model.getIsMoveOk(x, y)) {
let coord = model.getEmptyCellCoordinates();
let $emptyTd = $table.children().eq(coord.y).children().eq(coord.x);
let val = $td.html();
model.makeMove(x, y);
$emptyTd.html(val);
$td.html('');
if (model.getIsSuccess()) {
_view.$result.html('ВЫ УСПЕШНО СОБРАЛИ ПАЗЛ. ПОЗДРАВЛЯЕМ !!!').show();
model.isGameOver = true;
_view.$startGameButton.prop('disabled', false);
}
} else {
_view.$result.html('Ход не корректен, выберите ячейку рядом с пустой').show().fadeOut(2000);
}
});
}
}
function Model() {
this.isGameOver = true;
this.table = [];
this.getIsGameOver = function(){
return this.isGameOver;
}
this.startGame = function(){
this.isGameOver = false;
this.table = [];
let numbers = [];
while (numbers.length < 16) {
let num = this.getRandomNumber(0, 15);
if (numbers.indexOf(num) === -1) {
numbers.push(num);
}
}
// для демо игры
//numbers = [1,2,3,4,5,6,7,8,9,10,11,12,13,0,14,15];
for (let i = 0; i < 4; i++){
this.table.push([]);
for (let j = 0; j < 4; j++){
let el = numbers.shift();
this.table[i].push(el ? el : '');
}
}
//console.log(this.table);
}
this.getIsMoveOk = function(x, y){
let coord = this.getEmptyCellCoordinates();
return (Math.abs(coord.x - x) + Math.abs(coord.y - y)) == 1
}
this.makeMove = function(x, y){
let coord = this.getEmptyCellCoordinates();
let val = this.table[y][x];
this.table[y][x] = '';
this.table[coord.y][coord.x] = val;
//console.log(this.table);
}
this.getEmptyCellCoordinates = function() {
for (let i = 0; i < this.table.length; i++){
for (let j = 0; j < this.table[i].length; j++){
if (!this.table[i][j]) {
return {
x: j,
y: i,
};
}
}
}
}
this.getIsSuccess = function() {
let start = 0;
for (let i = 0; i < this.table.length; i++){
for (let j = 0; j < this.table[i].length; j++){
start++;
if (start <= 15 && start != this.table[i][j]) {
return false;
}
}
}
return true;
}
this.getRandomNumber = function(min, max){
let delta = Math.floor(max - min + 1);
let num = Math.random() * delta;
return min + Math.floor(num);
};
}
});
</script>
</head>
<body >
<button id="process">Начать игру</button>
<div id="tablefield">
</div>
<div id="result" style="color:red;">
</div>
</body>
</html>