anchor.diff:    Result := fStartQueue = fEndQueue;
   end;
   
  -procedure TKMFloodWithQueue.FloodFillWithQueue(const aX,aY: Integer; var aCnt_FINAL, aCnt_ACTUAL, aRESOURCE: Integer; const aProbability, aPROB_REDUCER: Single; var aPoints: TKMPointArray);
  +procedure TKMFloodWithQueue.FloodFillWithQueue(var aPointArr: TKMPointArray; var aCnt_FINAL, aCnt_ACTUAL, aRESOURCE: Integer; const aProbability, aPROB_REDUCER: Single; var aPoints: TKMPointArray);
   var
  -  X,Y: SmallInt;
  +  I,X,Y: SmallInt;
  +  Cnt, POMCnt: Integer;
     Probability, Prob_POM: Single;
   begin
     X := 0;
     Y := 0;
  +  Cnt := aCnt_actual;
  +  POMCnt := aCnt_actual;
     MakeNewQueue();
  -  InsertInQueue(aX, aY, aProbability);
  -  while RemoveFromQueue(X, Y, Probability) AND (aCnt_actual < aCnt_FINAL) do
  +  for I := Low(aPointArr) to High(aPointArr) do
  +    InsertInQueue(aPointArr[I].X, aPointArr[I].Y, aProbability);
  +  while RemoveFromQueue(X, Y, Probability) AND ((Probability = 1) OR (POMCnt < aCnt_FINAL) OR (Cnt < aCnt_FINAL)) do  // Probability = 1 in case that we need this shape in new mine
       if (   (fCount[Y,X] > 0)  OR  ( (aRESOURCE = Byte(btCoal)) AND (fCount[Y,X] < 0) )   )
          AND (fRNG.Random() < Probability) then
       begin
  -      aCnt_actual := aCnt_actual + abs(fCount[Y,X]);
  +      //aCnt_actual := aCnt_actual + abs(fCount[Y,X]); // After tests it looks like too inaccurate
  +      POMCnt := POMCnt + abs(fCount[Y,X]);
         fCount[Y,X] := 0;
   
  -      SetLength(aPoints, Length(aPoints)+1);
  +      SetLength(aPoints, Length(aPoints)+1); // Just a few interactions
         aPoints[ High(aPoints) ] := fPointsArr[Y,X];
  -      fFillResource.QuickFlood(fPointsArr[Y,X].X,fPointsArr[Y,X].Y, fSearchArr[ fPointsArr[Y,X].Y, fPointsArr[Y,X].X ], 0, aRESOURCE);
  +      fFillResource.QuickFlood(fPointsArr[Y,X].X, fPointsArr[Y,X].Y, fSearchArr[ fPointsArr[Y,X].Y, fPointsArr[Y,X].X ], 0, aRESOURCE);
  +      // Do not start flood fill until we know that final shape is smaller than desired shape
  +      if (POMCnt >= aCnt_FINAL) then
  +      begin
  +        fTileCounter.QuickFlood(fPointsArr[Y,X].X, fPointsArr[Y,X].Y, aRESOURCE, fActualIdx);
  +        Cnt := aCnt_actual + fTileCounter.Count;
  +        fActualIdx := fActualIdx + 1;
  +        if (fActualIdx = High(Byte)) then
  +          ClearCountVisitedArr();
  +      end;
   
         Prob_POM := Probability - aPROB_REDUCER;
         if Prob_POM > 0 then
         begin
  -        if X+1 <= High(fPointsArr[Y]) then InsertInQueue( X+1, Y,   Prob_POM );
  -        if X-1 >= Low(fPointsArr[Y]) then  InsertInQueue( X-1, Y,   Prob_POM );
  -        if Y-1 >= Low(fPointsArr) then     InsertInQueue( X,   Y-1, Prob_POM );
  -        if Y+1 <= High(fPointsArr) then    InsertInQueue( X,   Y+1, Prob_POM );
  +        if (aRESOURCE < Byte(btGold)) then
  +        begin
  +          if (X+1 <= High(fPointsArr[Y])) then InsertInQueue( X+1, Y, Prob_POM );
  +          if (X-1 >= Low(fPointsArr[Y]))  then InsertInQueue( X-1, Y, Prob_POM );
  +        end;
  +        if (Y-1 >= Low(fPointsArr))  then InsertInQueue( X, Y-1, Prob_POM );
  +        if (Y+1 <= High(fPointsArr)) then InsertInQueue( X, Y+1, Prob_POM );
         end;
       end;
  +
  +  aCnt_actual := Cnt;
  +  Cnt := 1;
  +  POMCnt := 0;
  +  while (Cnt > 0) AND (POMCnt < 10) do
  +  begin
  +    POMCnt := POMCnt + 1;
  +    fShapeFixer.QuickFlood(  fPointsArr[ aPointArr[0].Y,aPointArr[0].X ].X, fPointsArr[ aPointArr[0].Y,aPointArr[0].X ].Y, aRESOURCE, fActualIdx  );
  +    Cnt := fShapeFixer.Count;
  +    fActualIdx := fActualIdx + 1;
  +    if (fActualIdx = High(Byte)) then
  +      ClearCountVisitedArr();
  +  end;
   
     while RemoveFromQueue(X, Y, Probability) do
     begin
  
positive.code:     procedure QuickFlood(aX,aY,aSearch,aNewSearch: SmallInt; var aOutIdx: Integer; var aTileCounterArr: TInteger2Array; var aOutPointArr: TKMPointArray; var aOutLevelArr: TKMByteArray); reintroduce; overload;
    end;
  
  // Standard flood fill algorithm with queue instead of recursion -> first element is the closest to the center point, second is automatically second closest etc.
  // This is class for resources in RMG because it is quite complicated task (randomly generate something which must look like original template but still different...)
    TKMFloodWithQueue = class
    private
      fStartQueue, fEndQueue: TResElementPointer;
      fPointsArr: TKMPoint2Array;
      fSearchArr, fCount: TInteger2Array;
      fFillArr: TKMByte2Array;
      fFillResource: TKMFillBiome;
      fRNG: TKMRandomNumberGenerator;
    protected
      procedure MakeNewQueue();
      procedure InsertInQueue(aX,aY: Integer; aProbability: Single);
      function RemoveFromQueue(var aX,aY: SmallInt; var aProbability: Single): Boolean;
      function IsQueueEmpty(): boolean;
    public
      constructor Create(var aRNG: TKMRandomNumberGenerator; var aPointsArr: TKMPoint2Array; var aCount, aSearchArr: TInteger2Array; var aFillArr: TKMByte2Array);
      destructor Destroy;
      procedure FloodFillWithQueue(const aX,aY: Integer; var aCnt_FINAL, aCnt_ACTUAL, aRESOURCE: Integer; const aProbability, aPROB_REDUCER: Single; var aPoints: TKMPointArray);
    end;
  
  
  
negative.code:   protected
      procedure MarkAsVisited(const aX,aY: SmallInt); override;
    public
      constructor Create(aMinLimit, aMaxLimit: TKMPoint; var aSearchArr: TInteger2Array; var aFillArr: TKMByte2Array; const aScanEightTiles: Boolean = False); reintroduce;
      procedure QuickFlood(aX,aY,aSearch,aNewSearch,aFill: SmallInt); reintroduce;
    end;
  
  