midwest_daniel Posted January 13, 2010 Share Posted January 13, 2010 Windows XP Apache/2.0.59 (Win32) PHP/4.4.7 ------------------------------------------------------------------ Without listing the code, which is lengthy, here is the issue: In a section of code, I create an array (let's call it $array1) and populate it very carefully. Later in the code, I create a second array ($array2) and populate it as well. The problem comes after all of this: If I add a shuffle($array2) command after the second array, the first array ($array1) becomes populated differently---incorrectly---than it would have been if I had never shuffled $array2. This is a repeatable issue. My questions: 1. Why does shuffling the second array affect how a different array is populated? 2. How can shuffling an array change how code EARLIER in the script behaves? (The arrays are never equated or matched or associated with each other at all. Each array uses different code to populate it. They do not coexist in any loops or functions.). Thanks Quote Link to comment https://forums.phpfreaks.com/topic/188383-unpredictable-effects-of-shuffle/ Share on other sites More sharing options...
mikesta707 Posted January 13, 2010 Share Posted January 13, 2010 can you post the code that does this so I can try it out? Quote Link to comment https://forums.phpfreaks.com/topic/188383-unpredictable-effects-of-shuffle/#findComment-994511 Share on other sites More sharing options...
Maq Posted January 13, 2010 Share Posted January 13, 2010 My questions: 1. Why does shuffling the second array affect how a different array is populated? 2. How can shuffling an array change how code EARLIER in the script behaves? 1) That's impossible to answer unless, like mike mentioned, you provide code. 2) Because not everything is procedural. Quote Link to comment https://forums.phpfreaks.com/topic/188383-unpredictable-effects-of-shuffle/#findComment-994532 Share on other sites More sharing options...
midwest_daniel Posted January 14, 2010 Author Share Posted January 14, 2010 Here is the code, below. The shuffle($squareSet) command (later in the script) disrupts the desired population of the array $grid earlier in the script. I have no idea why. NOTE: The undesired result is almost never seen the first time, but rather only afer refreshing. Another head-scratcher... (The desired result is a grid of all numbers. An undesired result means the presence of the 'X' character.) (FYI, my workaround failed. Instead of shuffling the array, I created a string and shuffled that before exploding it into an array. However, the page fails to load with a 30-second timeout error when I try this. All for a string just over 256 characters exploding into an 81-element aray. Go figure.) Here's the original code: ------------------------------------------------------------------------------------------------------------------- ------------------------------------------------------------------------------------------------------------------- <?PHP $colsInBlock = 3; $rowsInBlock = 3; $blocksAcrossGrid = 3; $blocksDownGrid = 3; $difficulty = 1; // 0 is Easiest (All Nums Shown) $blockTotalSquares = $rowsInBlock * $colsInBlock; $gridSquaresAcross = $blocksAcrossGrid * $colsInBlock; $gridSquaresDown = $blocksDownGrid * $rowsInBlock; $gridTotalSquares = $gridSquaresAcross * $gridSquaresDown; $gridTotalBlocks = $blocksDownGrid * $blocksAcrossGrid; $numberDigits = $rowsInBlock * $colsInBlock; switch ($numberDigits){ case 9: $digitsList = array("X", "1", "2", "3", "4", "5", "6", "7", "8", "9"); default: $digitsList = array("X", "1", "2", "3", "4", "5", "6", "7", "8", "9"); } //End Switch $blockInterval = $gridSquaresAcross * $rowsInBlock; switch ($difficulty){ case 0: $squaresVisible = $gridTotalSquares; //All squares visible break; case 1: $squaresVisible = ((int)($gridTotalSquares * 36 / 81)); break; case 2: $squaresVisible = ((int)($gridTotalSquares * 32 / 81)); break; case 3: $squaresVisible = ((int)($gridTotalSquares * 30 / 81)); break; case 4: $squaresVisible = ((int)($gridTotalSquares * 28 / 81)); break; case 5: $squaresVisible = ((int)($gridTotalSquares * 25 / 81)); break; case 99: $squaresVisible = 0; // No squares visible break; default: $squaresVisible = -1; break; } //End Switch // POPULATE GRID ========================================================================= $maxTriesPerPuzzle = 400; $maxTriesPerDigit = 14; $gridTry = 0; $puzzleSuccess = 0; while ($puzzleSuccess == 0 && $gridTry < $maxTriesPerPuzzle){ $gridTry = $gridTry + 1; //Create Sudoku Number Matrix --- All squares with default value of Zero $grid = array(); $gridSize = $gridSquaresAcross * $gridSquaresDown; for ($gridSquares = 0; $gridSquares < $gridSize; $gridSquares++){ $grid[$gridSquares] = array(); $grid[$gridSquares][0] = "X"; // Number/Character in square $grid[$gridSquares][1] = 0; // Lock Status 0 = Unlocked 1 = Locked $grid[$gridSquares][2] = 0; // Visibility 0 = Hidden 1 = Visible } //Next $gridSquares $puzzleSuccess = 1; //Digit by digit into blocks for ($digits = 1; $digits < ($numberDigits + 1); $digits++){ $digitString = (string) $digits; $successfulDigit = 0; $digitTry = 0; while ($successfulDigit == 0 && $digitTry < $maxTriesPerDigit){ $successfulDigit = 1; $digitTry = $digitTry + 1; //Undo previous attempts on this digit - if applicable if ($digitTry > 1){ for ($undoSquares = 0; $undoSquares < $gridTotalSquares; $undoSquares++){ if ($grid[$undoSquares][0] == $digitString){ $grid[$undoSquares][0] = "X"; $grid[$undoSquares][1] = 0; } } //Next $undoSquares } // EndIf beyond first failed try for ($block = 0; $block < ($blocksAcrossGrid * $blocksDownGrid); $block++){ $freeBlockSquares = array(); for ($rowInBlock = 0; $rowInBlock< $rowsInBlock; $rowInBlock++){ for ($colInBlock = 0; $colInBlock< $colsInBlock; $colInBlock++){ $squareID = (Int) ($block / $blocksDownGrid) * $blockInterval + $rowInBlock * $gridSquaresAcross + (Int) ($block % $blocksAcrossGrid) * $colsInBlock + $colInBlock; if ($grid[$squareID][0] == "X" && $grid[$squareID][1] == 0){ array_push($freeBlockSquares, $squareID); } // EndIf available square } // Next $colInBlock } // Next $rowInBlock $freeCount = sizeof($freeBlockSquares); $rSquare = array_rand($freeBlockSquares); $squareChosen = $freeBlockSquares[$rSquare]; $grid[$squareChosen][0] = $digitsList[$digits]; // Number or Character in square $grid[$squareChosen][1] = 1; // Lock Status 0 = Unlocked 1 = Locked $grid[$squareChosen][2] = 0; // Visibility 0 = Hidden 1 = Visible //Digit Validation if ($grid[$squareChosen][0] == "X" || strlen($grid[$squareChosen][0]) < 1){ $successfulDigit = 0; } //EndIf for ($sweepDown = $squareChosen; $sweepDown > -1; $sweepDown = $sweepDown - $gridSquaresAcross){ if ($sweepDown != $squareChosen){ $grid[$sweepDown][1] = 1; // Lock Status 0 = Unlocked 1 = Locked } //EndIf } //Next $sweepDown for ($sweepUp = $squareChosen; $sweepUp < $gridTotalSquares; $sweepUp = $sweepUp + $gridSquaresAcross){ if ($sweepUp != $squareChosen){ $grid[$sweepUp][1] = 1; // Lock Status 0 = Unlocked 1 = Locked } //EndIf } //Next $sweepUp $startRow = $squareChosen; while ($startRow % $gridSquaresAcross > 0){ $startRow = $startRow - 1; } for ($sweepRight = $startRow; $sweepRight < ($startRow + $gridSquaresAcross); $sweepRight++){ if ($sweepRight != $squareChosen){ $grid[$sweepRight][1] = 1; // Lock Status 0 = Unlocked 1 = Locked } //EndIf } //Next $sweepRight //if ($successfulDigit == 0){ // break; //} } // Next $block //Release all locks on 'empty' squares for ($clearLocks = 0; $clearLocks < $gridTotalSquares; $clearLocks++){ if ($grid[$clearLocks][0] == "X"){ $grid[$clearLocks][1] = 0; if ($digits == $numberDigits){ $successfulDigit = 0; $puzzleSuccess = 0; break; } //EndIf } } //Next $clearLocks } // Wend try on digit if ($successfulDigit == 0){ $puzzleSuccess = 0; break; } } // Next $digits // END POPULATE GRID ===================================================================== } //Wend try on whole grid // CHOOSE VISIBLE SQUARES ------------------------ $maxVisblperBlock = (int)($blockTotalSquares * 5 / 9); $availForVisPerBlock = array(); // Keeps track of visible square limits per block for ($blkVis = 0; $blkVis < $gridTotalBlocks; $blkVis++){ $availForVisPerBlock[$blkVis] = $maxVisblperBlock; } // Next $squaresSet = range(0, ($gridSize - 1)); shuffle($squaresSet); // ********************************** <<<<<<< THIS COMMAND MESSES UP HOW ARRAY $grid IS POPULATED ******************************** $stillToBeVisible = $squaresVisible; $scrArrIdx = 0; while ($stillToBeVisible > 0){ $sqrToConsider = $squaresSet[$scrArrIdx]; $thisBlock = (int)($sqrToConsider / $blockInterval) * $rowsInBlock + (int)(($sqrToConsider % $gridSquaresAcross) / $colsInBlock); if ($availForVisPerBlock[$thisBlock] > 0){ $grid[$sqrToConsider][2] = 1; $stillToBeVisible = $stillToBeVisible - 1; $availForVisPerBlock[$thisBlock] = $availForVisPerBlock[$thisBlock] - 1; } // EndIf $scrArrIdx = $scrArrIdx + 1; } //Wend //if ($puzzleSuccess == 1){ // DRAW GRID WITH NUMBERS $cellID = 0; $blCl = "<td width='" . ((int) (100/$blocksAcrossGrid)) . "%'>"; //container for block $blClTbl = "<table border=0 width='100%' height='100%' cellspacing=1>"; //block table //Assemble grid by rows of blocks $allRows = ""; for ($grRs = 0; $grRs < $blocksDownGrid; $grRs++){ // $grRs is block-row number (e.g. 0-2) //Assemble row of blocks $blockRow = "<tr>"; for ($grR = 0; $grR < $blocksAcrossGrid; $grR++){ // $grR is Block# within the block-row //Assemble block by row $block = $blCl . $blClTbl; for ($blRs = 0; $blRs < $rowsInBlock; $blRs++){ // $blRs is 'mini-Row' within Block //Assemble row within block $blR = "<tr>"; for ($blRn = 0; $blRn < $colsInBlock; $blRn++){ // $blR is 'mini-Column' within Block // $cellID = $grRs * $blockInterval + $blR * $gridSquaresAcross + $grR * $blocksAcrossGrid ; $cellID = $grRs * $blockInterval + $blRs * $gridSquaresAcross + $grR * $blocksAcrossGrid + $blRn; $blR = $blR . "<td width='" . ((int) (100/$colsInBlock)) . "%' bgColor='FFFFFF'><span class='cell' ID='cell$cellID'>" . $grid[$cellID][0] . "</span></td>"; //Individual Cell } //Next $blRn $blR = $blR . "</tr>"; $block = $block . $blR; } //Next $blRs $block = $block . "</table></td>"; $blockRow = $blockRow . $block; } //Next $grR $blockRow = $blockRow . "</tr>"; $allRows = $allRows . $blockRow; } //Next $grRs echo $allRows; //} //End if $puzzleSuccess ?> Quote Link to comment https://forums.phpfreaks.com/topic/188383-unpredictable-effects-of-shuffle/#findComment-994837 Share on other sites More sharing options...
PFMaBiSmAd Posted January 14, 2010 Share Posted January 14, 2010 Your code does not contain any method of causing the result produced on one page request to be available on another page request so you will get a different result on every page refresh. Can you list the procedure or post the code showing how you are determining this problem is occurring? Your code also has some logic error concerning incorrect indexing in the following line, because it throws hundreds of error messages when the code executes (might be relevant to your problem because $squareChosen is used as an index for $grid to set the values) - $squareChosen = $freeBlockSquares[$rSquare]; Quote Link to comment https://forums.phpfreaks.com/topic/188383-unpredictable-effects-of-shuffle/#findComment-994857 Share on other sites More sharing options...
midwest_daniel Posted January 16, 2010 Author Share Posted January 16, 2010 The $grid array is firstly prepopulated with default values. Later on, each index is to have its value updated with something else. The characters displayed on screen are straight from the array. So if I see any "X" characters in the final display, this indicates that some default values were never given their proper value assignment. These "X" occurences only happen when I shuffle the other array later in the code. [Different results per load is by design. This is for the sake of randomness]. The undefined index notice is a mystery to me. PHP itself is supplying an existing index via the array_rand function. So I don't know why this is considered "undefined". A legitimate array element is being provided to the buggy line. I have reviewed these index values using my own customized console-type log file. They all appear to be in the correct numeric range. Thanks Quote Link to comment https://forums.phpfreaks.com/topic/188383-unpredictable-effects-of-shuffle/#findComment-996000 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.