Помогите, не срабатывает рекурсия

197
27 февраля 2018, 04:39

Привет. Пишу мини игру "карточный жребий". Суть ее в том что случайно генерируется число от 1 до 13 и потом div присваивается соответственный класс. Для усложнения задачи написал несколько различных механизмов но до ума не все еще довел, не судите строго. А суть вопроса заключается в некотором решении, для избежания повтора карт. Я использовал рекурсию и поставил ее на условия поиска в массиве, но по какой-то причине она то работает то не работает. Помогите поправить код.

var curArr = []; 
var currentCard; 
var j = 0; 
var rezFind; 
var cardLength; 
var playerIndex; 
var on = 0; 
 
$('.card').click(function() { 
  if (j == 0) { 
    random(); 
  } 
  rubaha = $(this).attr('class'); 
  if (rubaha == 'card shirt') { 
    $(this).removeClass('shirt').addClass("c" + currentCard); 
    curArr[j] = currentCard; 
    j++; 
    randCheck(); 
  } 
}); 
 
function random() { 
  currentCard = Math.floor(Math.random() * 13 + 1); 
} 
 
function randCheck() { 
  random(); 
  find(); 
  if (rezFind == 1) { 
    randCheck(); 
  } 
} 
 
function find() { 
 
  for (var i = 0; i < curArr.length; i++) { 
    if (currentCard == curArr[i]) { 
      rezFind = 1; 
    } else { 
      rezFind = 0; 
    } 
  } 
} 
 
$('.player').click(function() { 
  playerIndex = $(this).index() + 2; 
  cardLength = $('.card').length; 
  addCard(); 
 
}); 
 
function addCard() { 
  $('.card').removeClass().addClass('card shirt'); 
  for (var i = 2; i < playerIndex; i++) { 
 
  } 
  for (var i = 2; i < cardLength; i++) { 
 
  } 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
<div class="wrapper"> 
  <div class="playerLength"> 
    <p class="player player2">X2</p> 
    <p class="player player3">X3</p> 
    <p class="player player4">X4</p> 
    <p class="player player5">X5</p> 
  </div> 
 
  <div class="cards"> 
    <div class="card shirt"></div> 
    <div class="card shirt"></div> 
    <div class="card shirt"></div> 
    <div class="card shirt"></div> 
    <div class="card shirt"></div> 
  </div> 
</div>

Answer 1

Старайтесь не использовать рекурсии в JS насколько это возможно. Рекурсивный вызов всегда влечет за собой лишний расход памяти и дополнительное процессорное время. Лучше такой вызов заменить на цикл. К тому же рекомендуется не хранить в глобальной области видимости переменные вашего функционального модуля, лучше прячьте всё в функцию или объект, за фасадом которого уже скрывается вся реализация вашего решения. Вы только выдавайте интерфейс. Я ниже набросал что-то подобное синглтона на вашу задачу.

var cardRandomizer = (function() {
var cardsArr = [],
    cardVariation = 13;
function getNextUniqueCard() {
    //Здесь получим следующую уникальную карту
    //Необходимо проверить что-бы количество выпавших карт было не больше
    //числа вариаций этой колоды, грубо говоря если всего 2 карты, 
    //то нет смысла обрабатывать более двух вариаций
    if (cardsArr.length >= cardVariation) return;
    var pass = true;
    while(pass) {
        currentCard = randomCard(cardVariation);
        for (var i = 0; i < cardsArr.length; i++) {
            if(cardsArr[i] == currentCard) {
                break;
            }
        };
        pass = (i != cardsArr.length);
    };
    cardsArr.push(currentCard);
};
function getNextCard() {
    //Здесь получим просто следующую карту
    currentCard = randomCard(cardVariation);
    cardsArr.push(currentCard);
};
function randomCard(cardVariation) {
    //Здесь задаем алгоритм генерации случайного числа
    return Math.floor(Math.random() * cardVariation + 1);
};
function getCards() {
    //Здесь получаем массив карт
    return cardsArr;
};
function setCardVariation(col) {
    //Здесь должна быть проверка на передаваемый параметр
    cardVariation = col;
};
function clearArrCards() {
    //очистка массива карт
    cardsArr = [];
};
var API = {
    setCardVariation: setCardVariation,
    clearArrCards: clearArrCards,
    getNextUniqueCard: getNextUniqueCard,
    getNextCard: getNextCard,
    getCards: getCards
};
return API;
})();
cardRandomizer.getNextUniqueCard();
cardRandomizer.getNextUniqueCard();
cardRandomizer.getNextUniqueCard();
cardRandomizer.getNextUniqueCard();
cardRandomizer.getNextUniqueCard();
cardRandomizer.getNextUniqueCard();
console.log(cardRandomizer.getCards());
Answer 2

Все оказалось очень просто. Не стоило засовывать изменение переменной в цикл, там то функция find и теряла значение. Вот как решил проблему.

var randCheck = function () {
random();
find();
if (rezFind == 1) {
    rezFind = 0;
    return randCheck();
}
}
var find = function () {
for (var i = 0; i < curArr.length; i++) {
    if (currentCard == curArr[i]) {
        rezFind = 1;
    }
}
}
READ ALSO
ACF + сравнение товаров

ACF + сравнение товаров

Есть сайт на WordPress на нем реализован каталог товаров с помощью пользовательских типов записей + ACF произвольные поля, с помощью которых заполняются...

131
Js/Jq разница между $(this) и this

Js/Jq разница между $(this) и this

Здравствуйте, подскажите в чем разница между передачей элемента в on click:

223