Почему моя программа Actionscript 3 случайно застревает в бесконечном цикле? - PullRequest
0 голосов
/ 25 июня 2010

mBlocks - это двумерный массив объектов Block. Каждый раз, когда мое приложение запускается, оно запускает функцию InitGridNumbers. Иногда он застревает в бесконечном цикле. В других случаях он собирается и работает без проблем.

  public function InitGridNumbers():void
  {
   var tempRow:Array;
   var tempColumn:Array;
   var tempNum:int;
   for (var i:int = 0; i < mNumRows; i++)
   {
    tempRow = GetRow(i);
    for (var j:int = 0; j < mNumColumns; j++)
    {
     // if number is unassigned
     if (tempRow[j] == 0)
     {
      var cantMoveOn:Boolean = true;
      while (cantMoveOn)
      {
       tempNum = Math.random() * mNumColumns + 1;
       if (!CheckRow(i, tempNum) && !CheckColumn(j, tempNum))
        cantMoveOn = false;
      }
      mBlocks[i][j].SetNumber(tempNum);     
     }
    }
   }
  } 

  public function CheckRow(rowNum:int, checkNum:int):Boolean
  {
   var tempRow:Array = GetRow(rowNum);
   for (var i:int = 0; i < mNumColumns; i++)
   {
    if (checkNum == tempRow[i])
     return true;
   }
   return false;
  }

  public function CheckColumn(columnNum:int, checkNum:int):Boolean
  {
   var tempColumn:Array = GetColumn(columnNum);
   for (var i:int = 0; i < mNumColumns; i++)
   {
    if (checkNum == tempColumn[i])
     return true;
   }
   return false;
  }

  public function GetRow(rowNum:int):Array
  {
   var rowArray:Array = new Array(mNumRows);
   for (var i:int = 0; i < mNumRows; i++)
    rowArray[i] = mBlocks[rowNum][i].mNumber;

   return rowArray;
  }

  public function GetColumn(columnNum:int):Array
  {
   var columnArray:Array = new Array(mNumColumns);
   for (var i:int = 0; i < mNumColumns; i++)
    columnArray[i] = mBlocks[i][columnNum].mNumber;
   return columnArray;
  }

1 Ответ

2 голосов
/ 25 июня 2010

Начнем с того, что методы checkColumn, getColumn и getRow неверны.Чтобы получить строку, вы должны скопировать numColumns элементов, а чтобы получить столбец, вы должны скопировать numRows элементов.Другими словами, если есть r строк и c столбцов, будет c элементов в каждой строке и r элементов в каждом столбце.

public function checkColumn(columnNum:int, checkNum:int):Boolean
{
  var tempColumn:Array = getColumn(columnNum);
  for (var i:int = 0; i < mNumRows; i++)
  {
    if (checkNum == tempColumn[i])
      return true;
  }
  return false;
}

public function getRow(rowNum:int):Array
{
  var rowArray:Array = new Array();//needn't specify length in advance.
  for (var i:int = 0; i < mNumColumns; i++)
    rowArray[i] = mBlocks[rowNum][i].mNumber;

  return rowArray;
}
public function getColumn(columnNum:int):Array
{
  var columnArray:Array = new Array();
  for (var i:int = 0; i < mNumRows; i++)
    columnArray[i] = mBlocks[i][columnNum].mNumber;
  return columnArray;
}

while (cantMoveOn)
{
  //call Math.floor
  tempNum = Math.floor(Math.random() * mNumColumns) + 1;
  if (!checkRow(i, tempNum) && !checkColumn(j, tempNum))
    cantMoveOn = false;
}

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

Например, если есть четыре столбца и пять строк, tempNum всегда будет между одним и четырьмя.Теперь, если количество строк равно пяти и соответствующий столбец уже имеет все числа до четырех, оператор if никогда не будет иметь значение true, и, следовательно, вы окажетесь в бесконечном цикле

0 1 2 3
1
2
3
4

если сетка квадратная, как насчет этого:

0 1 2 3
4
0
0
...