/// Detects pyramid or hole (if any) at the given coordinates in the <see cref="grid" />, and randomly switches /// between pyramid and hole, based on <see cref="probabilityP" /> and <see cref="probabilityQ" /> parameters /// (or switches anyway, if forceSwitch is on). /// </summary> public void RandomlySwitchFourCells(bool forceSwitch) { uint randomNumber1 = Random1.NextUInt32(); var centerX = (int)(randomNumber1 & (GridWidth - 1)); var centerY = (int)((randomNumber1 >> 16) & (GridHeight - 1)); int centerIndex = GetIndexFromXY(centerX, centerY); uint randomNumber2 = Random2.NextUInt32(); uint randomVariable1 = randomNumber2 & ((1 << 16) - 1); uint randomVariable2 = (randomNumber2 >> 16) & ((1 << 16) - 1); int rightNeighbourIndex; int bottomNeighbourIndex; // Get neighbor indexes: int rightNeighbourX = (centerX < GridWidth - 1) ? centerX + 1 : 0; int rightNeighbourY = centerY; int bottomNeighbourX = centerX; int bottomNeighbourY = (centerY < GridHeight - 1) ? centerY + 1 : 0; rightNeighbourIndex = rightNeighbourY * GridWidth + rightNeighbourX; bottomNeighbourIndex = bottomNeighbourY * GridWidth + bottomNeighbourX; // We check our own {dx,dy} values, and the right neighbor's dx, and bottom neighbor's dx. if ( // If we get the pattern {01, 01} we have a pyramid: ((GetGridDx(centerIndex) && !GetGridDx(rightNeighbourIndex)) && (GetGridDy(centerIndex) && !GetGridDy(bottomNeighbourIndex)) && (forceSwitch || randomVariable1 < IntegerProbabilityP)) || // If we get the pattern {10, 10} we have a hole: ((!GetGridDx(centerIndex) && GetGridDx(rightNeighbourIndex)) && (!GetGridDy(centerIndex) && GetGridDy(bottomNeighbourIndex)) && (forceSwitch || randomVariable2 < IntegerProbabilityQ)) ) { // We make a hole into a pyramid, and a pyramid into a hole. SetGridDx(centerIndex, !GetGridDx(centerIndex)); SetGridDy(centerIndex, !GetGridDy(centerIndex)); SetGridDx(rightNeighbourIndex, !GetGridDx(rightNeighbourIndex)); SetGridDy(bottomNeighbourIndex, !GetGridDy(bottomNeighbourIndex)); } }