2016-03-24 4 views
0

У меня есть сценарий, который случайным образом распределяет 54 игральных карты на 4 игрока, он будет генерировать 2 случайных числа, чтобы получить случайную карту, номер категории (от 1 до 4), что означает: «сердца , пики, бриллианты, клубы "и номер карты (от 1 до 13).jquery: избегайте слишком много рекурсии

Проблема в том, что в этом скрипте слишком много рекурсий, так как я могу избежать этой ошибки, вызвав функции в потоках или что-то подобное?

мой код:

$(document).ready(function(){ 
    var human = []; 
    var east = []; 
    var west = []; 
    var north = []; 
    var used_cards = []; 

    distributeCards(north,$('#north')); 
    distributeCards(east,$('#east'),'vertical'); 
    distributeCards(west,$('#west')); 
    distributeCards(human,$('#south')); 

    function distributeCards(array,container,view){ 
     for(var i = 0; i < 13; i++){ 
      var category,card; 
      do{ 
       var uniqueCard = uniqueRandomCard(); 
      }while(typeof uniqueCard === "undefined") 
      category = uniqueCard[0]; 
      card = uniqueCard[1]; 
      array.push(uniqueCard); 
      var category_name = ''; 
      if(category === 1){ 
       category_name = 'hearts'; 
      } 
      else if(category === 2){ 
       category_name = 'spades'; 
      } 
      else if(category === 3){ 
       category_name = 'diamonds'; 
      } 
      else if(category === 4){ 
       category_name = 'clubs'; 
      } 
      if(card === 1){ 
       card = 'ace'; 
      } 
      else if(card === 11){ 
       card = 'jack'; 
      } 
      else if(card === 12){ 
       card = 'queen'; 
      } 
      else if(card === 13){ 
       card = 'king'; 
      } 
      if(view === 'vertical'){ 
       $(container).children('.row').append('<img src="cards/backRotate.png" class="card"/>'); 
      } 
      else if(view === 'horizontal'){ 
       $(container).children('.row').append('<img src="cards/back.png" class="card"/>'); 
      } 
     } 
    } 
    function randomNumberFromRange(min,max){ 
     return Math.round(Math.floor(Math.random()*max)+min); 
    } 
    function uniqueRandomCard(){ 
     var card = randomNumberFromRange(1, 13); 
     var category = randomNumberFromRange(1, 4); 
     if(!inAssocArray(category,card,used_cards)){ 
      var array = []; 
      array[0] = category; 
      array[1] = card; 
      used_cards.push(array); 
      return array; 
     } 
     else{ 
      uniqueRandomCard(); 
     } 
    } 
    function inAssocArray(key,value,array){ 
     var flag = false; 
     for(var i = 0; i < array.length; i++){ 
      if(array[i][0] === key && array[i][1]=== value){ 
       flag = true; 
      } 
     } 
     return flag; 
    } 
}); 
+2

Ваша уникальная функция RandomCard() кажется единственной с рекурсией, и она имеет логическую ошибку в том, что она, когда она вызывает себя, ничего не делает с возвращаемым значением. Вы справляетесь с этим через цикл while в другой функции, которая проверяет неопределенные, но не лучше ли исправить ее напрямую? Но я не знаю, почему вы вообще используете рекурсию - не могли бы вы просто использовать цикл while в uniqueRandomCard()? – nnnnnn

+0

@nnnnnn он должен быть вызван рекурсивно, пока он не вернет значение, которое не найдено в массиве 'used_cards' – Mohammad

+0

@nnnnnn Да, цикл while был бы лучшей идеей, как я не думал попробовать! спасибо – Mohammad

ответ

1

Закрепление рекурсии так, как вы реализовали его довольно легко. Просто замените ваш вызов и оператор if инструкцией while.

function uniqueRandomCard(){ 
    var card = randomNumberFromRange(1, 13); 
    var category = randomNumberFromRange(1, 4); 
    while(inAssocArray(category,card,used_cards)) { 
    card = randomNumberFromRange(1, 13); 
    category = randomNumberFromRange(1, 4); 
    } 
    var array = []; 
    array[0] = category; 
    array[1] = card; 
    used_cards.push(array); 
    return array; 
} 

Это, как говорится, есть некоторые основные лучшие способы обработки ограниченных наборов, подобных этому. Хранение неиспользуемых карт и случайный выбор из них намного выше.