Крошечная змейка на JavaScript (30 строк кода)

в 19:25, , рубрики: javascript, Веб-разработка, метки:

Прочитав статью про excel в 30 строк я загорелся глупой идеей — написать что-нибудь на 30 строк, не долго думая остановился на змейке

Особенности:

  • 30 строк необычного JavaScript (задача была уместить в 30 строк, так что код похлеще чем на ночных хакатонах)
  • Использованные библиотеки: отсутствуют

Крошечная змейка на JavaScript (30 строк кода)

Вот фиддл

И сам код:

Эстетам и перфекционистам лучше не смотреть

(function(width, height, length, current, dx, dy, x, y, hasFood, newEl){     
    
document.body.onkeydown = function(e){
    dx = (e.keyCode - 38) % 2, dy = (e.keyCode - 39) % 2;
};
    
var timer = setInterval(function () {
    x = (x + dx) < 0 ? width - 1 : (x + dx) % width; 
    y = (y + dy) < 0 ? height - 1 : (y + dy) % height;
    newEl = document.getElementsByClassName(y + '_' + x)[0]
    if(newEl.className.indexOf('s') > 0) {
    	clearInterval(timer), alert('Game Over! Score: ' + length)
    };
    if(newEl.className.indexOf('f') > 0) {
    	newEl.className = newEl.className.replace(' f', ''), length++, hasFood = false;
    }
    newEl.className += ' s', newEl.setAttribute('data-n', current++);

    for(var i = 0, min = Infinity, item, items = document.getElementsByClassName('s'), len = items.length; i < len && len > length; i++)
    	if(+items[i].getAttribute('data-n') < min)
    		min = +items[i].getAttribute('data-n'), item = items[i];

    if(!!item) item.className = item.className.replace(' s', '');

    for(var fItem, fX, fY; !hasFood; fX = Math.round(Math.random() * 10 % width), fY = Math.round(Math.random() * 10 % height))
    	if(!!fX && !!fY && document.getElementsByClassName(fY + '_' + fX)[0].className.indexOf('s') < 0)
    		hasFood = true, document.getElementsByClassName(fY + '_' + fX)[0].className += ' f';
}, 1000);

})(10, 10, 5, 1, 1, 0, 0, 0, false, null);

Признаюсь, я немного сэкономил, опустив код, которым я сгенерировал разметку. Да и сам подход, весьма и весьма плох, но все-таки в 30 строк я уложился.
Пару слов про «алгоритм» (понимаю, что читать этот «код» в Воскресение никому не захочется):

  • решил сэкономить на том, чтобы не делать массив и не мапить его на UI, а сделать «Dom addictive» алгоритм, который работает сразу с DOM'ом (клеточки змейки помечаются классом «s» а еда классом «f», по наличию этих классов и определяется коллизия со змеей или с едой).
  • каждая новая клетка змеи помечается атрибутом «data-n» который равен number++ (постоянно увеличивается)
  • ищем div'ы с классом «s» (клетки змеи) и находим клетку с минимальным значением data-n и делаем ее обычной (удаляем/перемещаем хвост змеи)

Не судите код строго и хороших Вам выходных!

Автор: DjComandos

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js