Как я понимаю, этот метод нужен только для того, чтобы удлиннить змею, и данное значение потом никуда не передается и просто удаляется в конце
if (snake.length < maxCell) {
snake.push({ x: px, y: py });
}
Баг выскакивает из-за того, что ты закидываешь значение head в конец массива, а потом весь массив на совпадение с head проверяешь
for (let i = 1; i < snake.length; i++) {
if (head.x === snake[i].x && head.y === snake[i].y) {
console.log("hii");
}
}
Добавляй другое значение в конец и все будет работать :)