#include <Array.au3>

; Globale Konstanten für FF5 (damit sie nicht als Parameter in der Rekursion sind da sie eh immer gleich bleiben)
Global $__FF_iColArea = 0
Global $__FF_iColFill = 0

; Einstellungen zum Ausprobieren
Global $n = 1 					; Anzahl Runden deren mittlere Zeit gemessen wird
Global $aPos = [2,2] 			; Startposition fürs FloodFill
Global $bArrayDisplay  = true   	; Will man die Arrays sehen
Global $bRandomize     = False	; Zufällige Startadressen ?
Global $bInfoReadWrite = false 	; Will man einen Plot in die Konsole mit den Reads/Writes?
Global $bInfoReadWriteSmall = False ; Nur R/W ohne Tabelle
Global $iFill = 123 				; Was wird ins Array geschrieben

If $bInfoReadWriteSmall Then
	$bInfoReadWrite = False
	$n = 1
EndIf
If $bInfoReadWrite Then $n = 1 ; Macht nur sinn 1x durchlaufen zu lassen wenn man diese Information will.
If $bArrayDisplay Then $n = 1

; Die "Bitmap" wird hier erstellt. Es wird angenommen, dass die FloodFill Algorithmen iW und iH kennen (global)
Global Const $iW = 80
Global Const $iH = 80
Global $aBitmap[$iH][$iW], $aReads[$iH][$iW], $aWrites[$iH][$iW], $iPixel = 0
SRandom(@MIN * 60 * 1000 + @SEC * 1000 + @MSEC)

Func Reset() ; Hier kann sich jeder eine "bitmap" basteln mit 2 Farben
	$iPixel = 0


	For $y = 0 To $iW - 1 Step 1
		For $x = 0 To $iH - 1 Step 1
			$aBitmap[$y][$x] = ($x - 8) ^ 2 + ($y - 8) ^ 2 < 6 ^ 2 ? 2 : 1
			$aBitmap[$y][$x] = ($x - 16) ^ 2 + ($y - 16) ^ 2 < 6 ^ 2 ? 2 : $aBitmap[$y][$x]
			If $aBitmap[$y][$x] = 2 Then $iPixel += 1
			$aReads[$y][$x] = 0
			$aWrites[$y][$x] = 0
		Next
	Next

	; Bereiche in der mitte
	$aBitmap[5][5] = 1
	$aBitmap[5][6] = 1
	$aBitmap[5][7] = 1
	$aBitmap[8][5] = 1
	$aBitmap[8][6] = 1
	$aBitmap[8][7] = 1
	$aBitmap[10][14] = 1
	$aBitmap[11][14] = 1
	$aBitmap[12][14] = 1
	$aBitmap[10][12] = 1
	$aBitmap[11][12] = 1
	$aBitmap[12][12] = 1

	; 4 bereiche am Rand die man nur diagonal erreichen kann
	$aBitmap[15][0] = 2
	$aBitmap[16][1] = 2
	$aBitmap[17][0] = 2
	$aBitmap[0][3] = 2
	$aBitmap[1][4] = 2
	$aBitmap[0][5] = 2
	$aBitmap[1][23] = 2
	$aBitmap[2][22] = 2
	$aBitmap[3][23] = 2
	$aBitmap[23][7] = 2
	$aBitmap[22][8] = 2
	$aBitmap[23][9] = 2


	    $aBitmap[19][2] = 2
    $aBitmap[18][2] = 2
    $aBitmap[17][2] = 2
    $aBitmap[15][2] = 2
    $aBitmap[15][3] = 2
    $aBitmap[16][4] = 2
    $aBitmap[17][5] = 2
    $aBitmap[18][4] = 2
    $aBitmap[19][4] = 2
    $aBitmap[16][1] = 2
    $aBitmap[15][0] = 2
    $aBitmap[17][0] = 2
    $aBitmap[19][3] = 2
    $aBitmap[7][7] = 1


for $x=0 to $iW-2 step 2;Kamm
for $y=30 to $iH-1
		 $aBitmap[$y][$x] = 2
	Next
next


EndFunc   ;==>Reset
; ################################################################################

Global $iTimer
Reset()
If $bArrayDisplay Then _ArrayDisplay($aBitmap, 'Original')

;   OBACHT die Zahl muss der Anzahl Funktionen entsprechen
;           \ /
Local $aAlgo[6][4] = [[FF_Andy1], [FF_Andy2], [FF_Andy3], [FF3], [FF4x], [FF5x]], $iUBound = UBound($aAlgo)

For $i = 1 To $n Step 1
	For $ii = 0 To $iUBound - 1 Step 1
		If $bRandomize Then $aPos = rnd()
		Reset() ; "Bitmap" zurücksetzen
		$iTimer = TimerInit()
		$aAlgo[$ii][0]($aPos[0], $aPos[1], $iFill)
		$aAlgo[$ii][1] += TimerDiff($iTimer)
		If $n = 1 Then
			ConsoleWrite(StringLeft(FuncName($aAlgo[$ii][0]) & ':           ', 11) & StringFormat('%.3f', $aAlgo[$ii][1]) & ' ms' & @CRLF)
			Info()
			ConsoleWrite(@CRLF)
			If $bArrayDisplay Then _ArrayDisplay($aBitmap, FuncName($aAlgo[$ii][0]))
		EndIf
	Next
Next

If $n > 1 Then
	ConsoleWrite('Mittelwert aus ' & $n & ' Durchläufen' & @CRLF)
	For $ii = 0 To $iUBound - 1 Step 1
		ConsoleWrite(StringLeft(FuncName($aAlgo[$ii][0]) & ':           ', 11) & StringFormat('%.3f', $aAlgo[$ii][1]/$n) & ' ms' & @CRLF)
	Next
EndIf

Func FF_Andy1($x, $y, $iColFill)
	Dim $liste[$iW * $iH] ;maximaler Füllbereich, normalerweise eine "leere" Bitmap
	Dim $bitmap_marker[$iW * $iH]
	Local $iColRead = Read($x, $y)
	$counter = 0 ;für Listenelement
	$listcounter = 0 ;anzahl elemente in liste
	$liste[$listcounter] = $y * $iW + $x ;position pixel in bitmap
	Write($x, $y, $iColFill)
	While 1 ;$listende_nicht_erreicht

		;koordinate nächstes Element in der Liste, diese umrecherei ist in einer bitmap völlig unnötig.....
		$x = Mod($liste[$counter], $iW)
		$y = Int($liste[$counter] / $iH)


		;4 Nachbarpunkte auf $iColRead testen
		$xL = $x - 1 ;linker pixel
		$yL = $y
		$xR = $x + 1 ;rechter pixel
		$yR = $y
		$xO = $x ;oberer Pixel
		$yO = $y - 1
		$xU = $x ;unterer Pixel
		$yU = $y + 1

		If $xL >= 0 And $xL < $iW And $bitmap_marker[$yL * $iW + $xL] = 0 Then ;wenn im bereich und noch nicht in der Liste
			If Read($xL, $yL) = $iColRead Then ;Pixel mit $iColRead gefunden
				Write($xL, $yL, $iColFill)
				$listcounter += 1
				$liste[$listcounter] = $yL * $iW + $xL ;position pixel in bitmap
				$bitmap_marker[$yL * $iW + $xL] = 1
			EndIf
		EndIf
		If $xR >= 0 And $xR < $iW And $bitmap_marker[$yR * $iW + $xR] = 0 Then
			If Read($xR, $yR) = $iColRead Then ;Pixel mit $iColRead gefunden
				Write($xR, $yR, $iColFill)
				$listcounter += 1
				$liste[$listcounter] = $yR * $iW + $xR ;position pixel in bitmap
				$bitmap_marker[$yR * $iW + $xR] = 1
			EndIf
		EndIf
		If $yO >= 0 And $yO < $iH And $bitmap_marker[$yO * $iW + $xO] = 0 Then
			If Read($xO, $yO) = $iColRead Then ;Pixel mit $iColRead gefunden
				Write($xO, $yO, $iColFill)
				$listcounter += 1
				$liste[$listcounter] = $yO * $iW + $xO ;position pixel in bitmap
				$bitmap_marker[$yO * $iW + $xO] = 1
			EndIf
		EndIf
		If $yU >= 0 And $yU < $iH And $bitmap_marker[$yU * $iW + $xU] = 0 Then
			If Read($xU, $yU) = $iColRead Then ;Pixel mit $iColRead gefunden
				Write($xU, $yU, $iColFill)
				$listcounter += 1
				$liste[$listcounter] = $yU * $iW + $xU ;position pixel in bitmap
				$bitmap_marker[$yU * $iW + $xU] = 1
			EndIf
		EndIf
		If $listcounter = $counter Then ExitLoop
		$counter = $counter + 1
		;    _arraydisplay($liste)
;~         If $bArrayDisplay Then _ArrayDisplay($aBitmap)

	WEnd

;~     If $bArrayDisplay Then _ArrayDisplay($areads)
;~     If $bArrayDisplay Then _ArrayDisplay($bitmap_marker)

EndFunc   ;==>FF_Andy1

Func FF_Andy2($x, $y, $iColFill)
	Dim $liste[$iW * $iH] ;maximaler Füllbereich, normalerweise eine "leere" Bitmap
	Dim $bitmap_marker[$iW * $iH]
	Local $iColRead = Read($x, $y)
	$counter = 0 ;für Listenelement
	$listcounter = 0 ;anzahl elemente in liste
	$liste[$listcounter] = $y * $iW + $x ;position pixel in bitmap
	Write($x, $y, $iColFill)

	While 1 ;$listende_nicht_erreicht

		;koordinate nächstes Element in der Liste, diese umrecherei ist in einer bitmap völlig unnötig.....
		$x = Mod($liste[$counter], $iW)
		$y = Int($liste[$counter] / $iH)


		;4 Nachbarpunkte auf $iColRead testen
		$xL = $x - 1 ;linker pixel
		$xR = $x + 1 ;rechter pixel
		$yO = $y - 1
		$yU = $y + 1

		$pos = $y * $iW + $xL
		If $xL >= 0 And $bitmap_marker[$pos] = 0 Then ;wenn im bereich und noch nicht in der Liste
			If Read($xL, $y) = $iColRead Then ;Pixel mit $iColRead gefunden
				Write($xL, $y, $iColFill)
				$listcounter += 1
				$liste[$listcounter] = $pos ;position pixel in bitmap
				$bitmap_marker[$pos] = 1
			EndIf
		EndIf
		$pos = $y * $iW + $xR
		If $xR < $iW And $bitmap_marker[$pos] = 0 Then
			If Read($xR, $y) = $iColRead Then ;Pixel mit $iColRead gefunden
				Write($xR, $y, $iColFill)
				$listcounter += 1
				$liste[$listcounter] = $pos ;position pixel in bitmap
				$bitmap_marker[$pos] = 1
			EndIf
		EndIf
		$pos = $yO * $iW + $x
		If $yO >= 0 And $bitmap_marker[$pos] = 0 Then
			If Read($x, $yO) = $iColRead Then ;Pixel mit $iColRead gefunden
				Write($x, $yO, $iColFill)
				$listcounter += 1
				$liste[$listcounter] = $pos ;position pixel in bitmap
				$bitmap_marker[$pos] = 1
			EndIf
		EndIf
		$pos = $yU * $iW + $x
		If $yU < $iH And $bitmap_marker[$pos] = 0 Then
			If Read($x, $yU) = $iColRead Then ;Pixel mit $iColRead gefunden
				Write($x, $yU, $iColFill)
				$listcounter += 1
				$liste[$listcounter] = $pos ;position pixel in bitmap
				$bitmap_marker[$pos] = 1
			EndIf
		EndIf
		If $listcounter = $counter Then ExitLoop
		$counter = $counter + 1
		;    _arraydisplay($liste)
;~         If $bArrayDisplay Then _ArrayDisplay($aBitmap)

	WEnd

;~     If $bArrayDisplay Then _ArrayDisplay($areads)
;~     If $bArrayDisplay Then _ArrayDisplay($bitmap_marker)

EndFunc   ;==>FF_Andy2

Func FF_Andy3($x, $y, $iColFill)
    Dim $liste[$iW * $iH]                               ;maximaler Füllbereich, normalerweise eine "leere" Bitmap
    Dim $bitmap_marker[$iW * $iH]
    Local $iColRead = Read($x, $y)
    $counter = 0                                        ;für Listenelement
    $listcounter = 0                                    ;anzahl elemente in liste
    $liste[$listcounter] = BitShift($x,-16)+$y          ;position pixel in bitmap mit x- und y-koordinate
    Write($x, $y, $iColFill)
    While 1                                             ;$listende_nicht_erreicht
        $y=bitand($liste[$counter],0xFFFF) ;16 LSB
        $x=Bitshift($liste[$counter],16) ;16 MSB
        $xL = $x - 1                                    ;linker pixel
        $xR = $x + 1                                    ;rechter pixel
        $yO = $y - 1
        $yU = $y + 1
        $pos = $y * $iW + $xL
        If $xL >= 0 And $bitmap_marker[$pos] = 0 Then   ;wenn im bereich und noch nicht in der Liste
            If Read($xL, $y) = $iColRead Then           ;Pixel mit $iColRead gefunden
                Write($xL, $y, $iColFill)
                $listcounter += 1
                $liste[$listcounter] = BitShift($xL,-16)+$y             ;position pixel in bitmap
                $bitmap_marker[$pos] = 1
            EndIf
        EndIf
        $pos = $y * $iW + $xR
        If $xR < $iW And $bitmap_marker[$pos] = 0 Then
            If Read($xR, $y) = $iColRead Then           ;Pixel mit $iColRead gefunden
                Write($xR, $y, $iColFill)
                $listcounter += 1
                $liste[$listcounter] = BitShift($xR,-16)+$y             ;position pixel in bitmap
                $bitmap_marker[$pos] = 1
            EndIf
        EndIf
        $pos = $yO * $iW + $x
        If $yO >= 0 And $bitmap_marker[$pos] = 0 Then
            If Read($x, $yO) = $iColRead Then           ;Pixel mit $iColRead gefunden
                Write($x, $yO, $iColFill)
                $listcounter += 1
                $liste[$listcounter] = BitShift($x,-16)+$yO             ;position pixel in bitmap
                $bitmap_marker[$pos] = 1
            EndIf
        EndIf
        $pos = $yU * $iW + $x
        If $yU < $iH And $bitmap_marker[$pos] = 0 Then
            If Read($x, $yU) = $iColRead Then           ;Pixel mit $iColRead gefunden
                Write($x, $yU, $iColFill)
                $listcounter += 1
                $liste[$listcounter] = BitShift($x,-16)+$yU            ;position pixel in bitmap
                $bitmap_marker[$pos] = 1
            EndIf
        EndIf
        If $listcounter = $counter Then ExitLoop
        $counter = $counter + 1
    WEnd
EndFunc

Func FF5x($x, $y, $iColFill) ; Initialisierung
	$__FF_iColArea = Read($x, $y)
	$__FF_iColFill = $iColFill
	Write($x, $y, $iColFill)
	For $xMax = $x + 1 To $iW - 1 Step 1
		If Read($xMax, $y) <> $__FF_iColArea Then ExitLoop
		Write($xMax, $y, $__FF_iColFill)
	Next
	For $xMin = $x - 1 To 0 Step -1
		If Read($xMin, $y) <> $__FF_iColArea Then ExitLoop
		Write($xMin, $y, $__FF_iColFill)
	Next
	If $y > 0 Then
		For $i = $xMin + 1 To $xMax - 1 Step 1
			If Read($i, $y - 1) = $__FF_iColArea Then $i = FF5($i, $y - 1, 1, $xMin, $xMax)
		Next
	EndIf
	If $y < $iH - 1 Then
		For $i = $xMin + 1 To $xMax - 1 Step 1
			If Read($i, $y + 1) = $__FF_iColArea Then $i = FF5($i, $y + 1, 2, $xMin, $xMax)
		Next
	EndIf
EndFunc   ;==>FF5x

Func FF5($x, $y, $iDirection, $xMinOffset, $xMaxOffset) ; Rekursiver Teil
	Write($x, $y, $__FF_iColFill)
	For $xMax = $x + 1 To $iW - 1 Step 1
		If Read($xMax, $y) <> $__FF_iColArea Then ExitLoop
		Write($xMax, $y, $__FF_iColFill)
	Next
	For $xMin = $x - 1 To 0 Step -1
		If Read($xMin, $y) <> $__FF_iColArea Then ExitLoop
		Write($xMin, $y, $__FF_iColFill)
	Next
	If $y > 0 Then
		For $i = $xMin + 1 To $xMinOffset - 1 Step 1
			If Read($i, $y - 1) = $__FF_iColArea Then
				Write($i, $y - 1, $__FF_iColFill)
				For $xMax2 = $i + 1 To $iW - 1 Step 1
					If Read($xMax2, $y - 1) <> $__FF_iColArea Then ExitLoop
					Write($xMax2, $y - 1, $__FF_iColFill)
				Next
				For $xMin2 = $i - 1 To 0 Step -1
					If Read($xMin2, $y - 1) <> $__FF_iColArea Then ExitLoop
					Write($xMin2, $y - 1, $__FF_iColFill)
				Next
				If $y > 1 Then
					For $i2 = $xMin2 + 1 To $xMin - 1 Step 1
						If Read($i2, $y - 2) = $__FF_iColArea Then $i2 = FF5($i2, $y - 2, 1, $xMin2, $xMax2)
					Next
					For $i2 = ($xMin > $xMin2 + 1 ? $xMin : $xMin2 + 1) To ($xMax - 1 > $xMax2 ? $xMax2 - 1 : $xMax - 2) Step 1
						If Read($i2, $y - 2) = $__FF_iColArea Then $i2 = FF5($i2, $y - 2, 1, $xMin2, $xMax2)
					Next
					For $i2 = $xMax - 1 To $xMax2 - 1 Step 1
						If Read($i2, $y - 2) = $__FF_iColArea Then $i2 = FF5($i2, $y - 2, 1, $xMin2, $xMax2)
					Next
				EndIf
				If $y < $iH Then
					For $i2 = $xMin2 + 1 To $xMin - 1 Step 1
						If Read($i2, $y) = $__FF_iColArea Then $i2 = FF5($i2, $y, 2, $xMin2, $xMax2)
					Next
					For $i2 = $xMax - 1 To $xMax2 - 1 Step 1
						If Read($i2, $y) = $__FF_iColArea Then $i2 = FF5($i2, $y, 2, $xMin2, $xMax2)
					Next
				EndIf
				$i = $xMax2 + 1 ; Wir wissen, dass man bis xMax2 laufen kann -> $i Abfrage überflüssig
			EndIf
		Next
		If $iDirection = 1 Then
			For $i = ($xMinOffset > $xMin + 1 ? $xMinOffset : $xMin + 1) To ($xMaxOffset - 1 > $xMax ? $xMax - 1 : $xMaxOffset - 2) Step 1
				If Read($i, $y - 1) = $__FF_iColArea Then
					Write($i, $y - 1, $__FF_iColFill)
					For $xMax2 = $i + 1 To $iW - 1 Step 1
						If Read($xMax2, $y - 1) <> $__FF_iColArea Then ExitLoop
						Write($xMax2, $y - 1, $__FF_iColFill)
					Next
					For $xMin2 = $i - 1 To 0 Step -1
						If Read($xMin2, $y - 1) <> $__FF_iColArea Then ExitLoop
						Write($xMin2, $y - 1, $__FF_iColFill)
					Next
					If $y > 1 Then
						For $i2 = $xMin2 + 1 To $xMin - 1 Step 1
							If Read($i2, $y - 2) = $__FF_iColArea Then $i2 = FF5($i2, $y - 2, 1, $xMin2, $xMax2)
						Next
						For $i2 = ($xMin > $xMin2 + 1 ? $xMin : $xMin2 + 1) To ($xMax - 1 > $xMax2 ? $xMax2 - 1 : $xMax - 2) Step 1
							If Read($i2, $y - 2) = $__FF_iColArea Then $i2 = FF5($i2, $y - 2, 1, $xMin2, $xMax2)
						Next
						For $i2 = $xMax - 1 To $xMax2 - 1 Step 1
							If Read($i2, $y - 2) = $__FF_iColArea Then $i2 = FF5($i2, $y - 2, 1, $xMin2, $xMax2)
						Next
					EndIf
					If $y < $iH Then
						For $i2 = $xMin2 + 1 To $xMin - 1 Step 1
							If Read($i2, $y) = $__FF_iColArea Then $i2 = FF5($i2, $y, 2, $xMin2, $xMax2)
						Next
						For $i2 = $xMax - 1 To $xMax2 - 1 Step 1
							If Read($i2, $y) = $__FF_iColArea Then $i2 = FF5($i2, $y, 2, $xMin2, $xMax2)
						Next
					EndIf
					$i = $xMax2 + 1 ; Wir wissen, dass man bis xMax2 laufen kann -> $i Abfrage überflüssig
				EndIf
			Next
		EndIf
		For $i = $xMaxOffset - 1 To $xMax - 1 Step 1
			If Read($i, $y - 1) = $__FF_iColArea Then
				Write($i, $y - 1, $__FF_iColFill)
				For $xMax2 = $i + 1 To $iW - 1 Step 1
					If Read($xMax2, $y - 1) <> $__FF_iColArea Then ExitLoop
					Write($xMax2, $y - 1, $__FF_iColFill)
				Next
				For $xMin2 = $i - 1 To 0 Step -1
					If Read($xMin2, $y - 1) <> $__FF_iColArea Then ExitLoop
					Write($xMin2, $y - 1, $__FF_iColFill)
				Next
				If $y > 1 Then
					For $i2 = $xMin2 + 1 To $xMin - 1 Step 1
						If Read($i2, $y - 2) = $__FF_iColArea Then $i2 = FF5($i2, $y - 2, 1, $xMin2, $xMax2)
					Next
					For $i2 = ($xMin > $xMin2 + 1 ? $xMin : $xMin2 + 1) To ($xMax - 1 > $xMax2 ? $xMax2 - 1 : $xMax - 2) Step 1
						If Read($i2, $y - 2) = $__FF_iColArea Then $i2 = FF5($i2, $y - 2, 1, $xMin2, $xMax2)
					Next
					For $i2 = $xMax - 1 To $xMax2 - 1 Step 1
						If Read($i2, $y - 2) = $__FF_iColArea Then $i2 = FF5($i2, $y - 2, 1, $xMin2, $xMax2)
					Next
				EndIf
				If $y < $iH Then
					For $i2 = $xMin2 + 1 To $xMin - 1 Step 1
						If Read($i2, $y) = $__FF_iColArea Then $i2 = FF5($i2, $y, 2, $xMin2, $xMax2)
					Next
					For $i2 = $xMax - 1 To $xMax2 - 1 Step 1
						If Read($i2, $y) = $__FF_iColArea Then $i2 = FF5($i2, $y, 2, $xMin2, $xMax2)
					Next
				EndIf
				$i = $xMax2 + 1 ; Wir wissen, dass man bis xMax2 laufen kann -> $i Abfrage überflüssig
			EndIf
		Next
	EndIf
	If $y < $iH - 1 Then
		For $i = $xMin + 1 To $xMinOffset - 1 Step 1
			If Read($i, $y + 1) = $__FF_iColArea Then
				Write($i, $y + 1, $__FF_iColFill)
				For $xMax2 = $i + 1 To $iW - 1 Step 1
					If Read($xMax2, $y + 1) <> $__FF_iColArea Then ExitLoop
					Write($xMax2, $y + 1, $__FF_iColFill)
				Next
				For $xMin2 = $i - 1 To 0 Step -1
					If Read($xMin2, $y + 1) <> $__FF_iColArea Then ExitLoop
					Write($xMin2, $y + 1, $__FF_iColFill)
				Next
				If $y >= 0 Then
					For $i2 = $xMin2 + 1 To $xMin - 1 Step 1
						If Read($i2, $y) = $__FF_iColArea Then $i2 = FF5($i2, $y, 1, $xMin2, $xMax2)
					Next
					For $i2 = $xMax - 1 To $xMax2 - 1 Step 1
						If Read($i2, $y) = $__FF_iColArea Then $i2 = FF5($i2, $y, 1, $xMin2, $xMax2)
					Next
				EndIf
				If $y < $iH - 2 Then
					For $i2 = $xMin2 + 1 To $xMin - 1 Step 1
						If Read($i2, $y + 2) = $__FF_iColArea Then $i2 = FF5($i2, $y + 2, 2, $xMin2, $xMax2)
					Next
					For $i2 = ($xMin > $xMin2 + 1 ? $xMin : $xMin2 + 1) To ($xMax - 1 > $xMax2 ? $xMax2 - 1 : $xMax - 2) Step 1
						If Read($i2, $y + 2) = $__FF_iColArea Then $i2 = FF5($i2, $y + 2, 2, $xMin2, $xMax2)
					Next
					For $i2 = $xMax - 1 To $xMax2 - 1 Step 1
						If Read($i2, $y + 2) = $__FF_iColArea Then $i2 = FF5($i2, $y + 2, 2, $xMin2, $xMax2)
					Next
				EndIf
				$i = $xMax2 + 1
			EndIf
		Next
		If $iDirection = 2 Then
			For $i = ($xMinOffset > $xMin + 1 ? $xMinOffset : $xMin + 1) To ($xMaxOffset - 1 > $xMax ? $xMax - 1 : $xMaxOffset - 2) Step 1
				If Read($i, $y + 1) = $__FF_iColArea Then
					Write($i, $y + 1, $__FF_iColFill)
					For $xMax2 = $i + 1 To $iW - 1 Step 1
						If Read($xMax2, $y + 1) <> $__FF_iColArea Then ExitLoop
						Write($xMax2, $y + 1, $__FF_iColFill)
					Next
					For $xMin2 = $i - 1 To 0 Step -1
						If Read($xMin2, $y + 1) <> $__FF_iColArea Then ExitLoop
						Write($xMin2, $y + 1, $__FF_iColFill)
					Next
					If $y >= 0 Then
						For $i2 = $xMin2 + 1 To $xMin - 1 Step 1
							If Read($i2, $y) = $__FF_iColArea Then $i2 = FF5($i2, $y, 1, $xMin2, $xMax2)
						Next
						For $i2 = $xMax - 1 To $xMax2 - 1 Step 1
							If Read($i2, $y) = $__FF_iColArea Then $i2 = FF5($i2, $y, 1, $xMin2, $xMax2)
						Next
					EndIf
					If $y < $iH - 2 Then
						For $i2 = $xMin2 + 1 To $xMin - 1 Step 1
							If Read($i2, $y + 2) = $__FF_iColArea Then $i2 = FF5($i2, $y + 2, 2, $xMin2, $xMax2)
						Next
						For $i2 = ($xMin > $xMin2 + 1 ? $xMin : $xMin2 + 1) To ($xMax - 1 > $xMax2 ? $xMax2 - 1 : $xMax - 2) Step 1
							If Read($i2, $y + 2) = $__FF_iColArea Then $i2 = FF5($i2, $y + 2, 2, $xMin2, $xMax2)
						Next
						For $i2 = $xMax - 1 To $xMax2 - 1 Step 1
							If Read($i2, $y + 2) = $__FF_iColArea Then $i2 = FF5($i2, $y + 2, 2, $xMin2, $xMax2)
						Next
					EndIf
					$i = $xMax2 + 1
				EndIf
			Next
		EndIf
		For $i = $xMaxOffset - 1 To $xMax - 1 Step 1
			If Read($i, $y + 1) = $__FF_iColArea Then
				Write($i, $y + 1, $__FF_iColFill)
				For $xMax2 = $i + 1 To $iW - 1 Step 1
					If Read($xMax2, $y + 1) <> $__FF_iColArea Then ExitLoop
					Write($xMax2, $y + 1, $__FF_iColFill)
				Next
				For $xMin2 = $i - 1 To 0 Step -1
					If Read($xMin2, $y + 1) <> $__FF_iColArea Then ExitLoop
					Write($xMin2, $y + 1, $__FF_iColFill)
				Next
				If $y >= 0 Then
					For $i2 = $xMin2 + 1 To $xMin - 1 Step 1
						If Read($i2, $y) = $__FF_iColArea Then $i2 = FF5($i2, $y, 1, $xMin2, $xMax2)
					Next
					For $i2 = $xMax - 1 To $xMax2 - 1 Step 1
						If Read($i2, $y) = $__FF_iColArea Then $i2 = FF5($i2, $y, 1, $xMin2, $xMax2)
					Next
				EndIf
				If $y < $iH - 2 Then
					For $i2 = $xMin2 + 1 To $xMin - 1 Step 1
						If Read($i2, $y + 2) = $__FF_iColArea Then $i2 = FF5($i2, $y + 2, 2, $xMin2, $xMax2)
					Next
					For $i2 = ($xMin > $xMin2 + 1 ? $xMin : $xMin2 + 1) To ($xMax - 1 > $xMax2 ? $xMax2 - 1 : $xMax - 2) Step 1
						If Read($i2, $y + 2) = $__FF_iColArea Then $i2 = FF5($i2, $y + 2, 2, $xMin2, $xMax2)
					Next
					For $i2 = $xMax - 1 To $xMax2 - 1 Step 1
						If Read($i2, $y + 2) = $__FF_iColArea Then $i2 = FF5($i2, $y + 2, 2, $xMin2, $xMax2)
					Next
				EndIf
				$i = $xMax2 + 1
			EndIf
		Next
	EndIf
	Return $xMax + 1
EndFunc   ;==>FF5

Func FF4x($x, $y, $iColFill) ; Initialisierung
	Local $iColArea = Read($x, $y)
	Write($x, $y, $iColFill)
	For $xMax = $x + 1 To $iW - 1 Step 1
		If Read($xMax, $y) <> $iColArea Then ExitLoop
		Write($xMax, $y, $iColFill)
	Next
	For $xMin = $x - 1 To 0 Step -1
		If Read($xMin, $y) <> $iColArea Then ExitLoop
		Write($xMin, $y, $iColFill)
	Next
	If $y > 0 Then
		For $i = $xMin + 1 To $xMax - 1 Step 1
			If Read($i, $y - 1) = $iColArea Then FF4($i, $y - 1, $iColFill, $iColArea, 1, $xMin, $xMax)
		Next
	EndIf
	If $y < $iH - 1 Then
		For $i = $xMin + 1 To $xMax - 1 Step 1
			If Read($i, $y + 1) = $iColArea Then FF4($i, $y + 1, $iColFill, $iColArea, 2, $xMin, $xMax)
		Next
	EndIf
EndFunc   ;==>FF4x

Func FF4($x, $y, $iColFill, $iColArea, $iDirection, $xMinOffset, $xMaxOffset) ; Rekursiver Teil
	Write($x, $y, $iColFill)
	For $xMax = $x + 1 To $iW - 1 Step 1
		If Read($xMax, $y) <> $iColArea Then ExitLoop
		Write($xMax, $y, $iColFill)
	Next
	For $xMin = $x - 1 To 0 Step -1
		If Read($xMin, $y) <> $iColArea Then ExitLoop
		Write($xMin, $y, $iColFill)
	Next
	If $y > 0 Then
		For $i = $xMin + 1 To $xMinOffset - 1 Step 1
			If Read($i, $y - 1) = $iColArea Then FF4($i, $y - 1, $iColFill, $iColArea, 1, $xMin, $xMax)
		Next
		If $iDirection = 1 Then
			For $i = ($xMinOffset > $xMin + 1 ? $xMinOffset : $xMin + 1) To ($xMaxOffset - 2 > $xMax - 1 ? $xMax - 1 : $xMaxOffset - 2) Step 1
				If Read($i, $y - 1) = $iColArea Then FF4($i, $y - 1, $iColFill, $iColArea, 1, $xMin, $xMax)
			Next
		EndIf
		For $i = $xMaxOffset - 1 To $xMax - 1 Step 1
			If Read($i, $y - 1) = $iColArea Then FF4($i, $y - 1, $iColFill, $iColArea, 1, $xMin, $xMax)
		Next
	EndIf
	If $y < $iH - 1 Then
		For $i = $xMin + 1 To $xMinOffset - 1 Step 1
			If Read($i, $y + 1) = $iColArea Then FF4($i, $y + 1, $iColFill, $iColArea, 2, $xMin, $xMax)
		Next
		If $iDirection = 2 Then
			For $i = ($xMinOffset > $xMin + 1 ? $xMinOffset : $xMin + 1) To ($xMaxOffset - 2 > $xMax - 1 ? $xMax - 1 : $xMaxOffset - 2) Step 1
				If Read($i, $y + 1) = $iColArea Then FF4($i, $y + 1, $iColFill, $iColArea, 2, $xMin, $xMax)
			Next
		EndIf
		For $i = $xMaxOffset - 1 To $xMax - 1 Step 1
			If Read($i, $y + 1) = $iColArea Then FF4($i, $y + 1, $iColFill, $iColArea, 2, $xMin, $xMax)
		Next
	EndIf

EndFunc   ;==>FF4

Func FF1($x, $y, $iColFill, $iColArea = 0) ; Aus dem Bilderbuch bzw. Wikipedia.
	Local $iColRead = Read($x, $y) ; Tempo    : Bummelbahn mit angezogener Handbremse
	If $iColArea = 0 Then $iColArea = $iColRead ; Rekursion: Sehr schnell sehr viele Rekursionen
	If $iColArea <> $iColRead Then Return ; Reads    : So viel wie möglich (schlecht)
	If $iColFill = $iColRead Then Return
	Write($x, $y, $iColFill)
	If $x > 0 Then FF1($x - 1, $y, $iColFill, $iColArea)
	If $x < $iW - 1 Then FF1($x + 1, $y, $iColFill, $iColArea)
	If $y > 0 Then FF1($x, $y - 1, $iColFill, $iColArea)
	If $y < $iH - 1 Then FF1($x, $y + 1, $iColFill, $iColArea)
EndFunc   ;==>FF1

Func FF2($x, $y, $iColFill, $iColArea = 0, $iLast = -1) ; Genau das gleiche wie FF1 nur, dass man nicht mehr dahingehen kann wo man herkommt.
	Local $iColRead = Read($x, $y) ; Tempo    : Bummelbahn
	If $iColArea = 0 Then $iColArea = $iColRead ; Rekursion: Sehr schnell sehr viele Rekursionen
	If $iColArea <> $iColRead Then Return ; Reads    : Weniger als FF1 und FF3
	If $iColFill = $iColRead Then Return
	Write($x, $y, $iColFill)
	If $iLast <> 0 And $x > 0 Then FF2($x - 1, $y, $iColFill, $iColArea, 2)
	If $iLast <> 2 And $x < $iW - 1 Then FF2($x + 1, $y, $iColFill, $iColArea, 0)
	If $iLast <> 3 And $y > 0 Then FF2($x, $y - 1, $iColFill, $iColArea, 1)
	If $iLast <> 1 And $y < $iH - 1 Then FF2($x, $y + 1, $iColFill, $iColArea, 3)
EndFunc   ;==>FF2

Func FF3($x, $y, $iColFill, $iColArea = 0) ; Spontan ausgedacht. Nachschlagen ergab, dass eine ähnliche Methode Scanline Flood Fill heißt.
	If $iColArea = 0 Then $iColArea = Read($x, $y) ; Tempo    : Mofa mit aufgebohrtem Zylinderkopf und zugepetztem Auspuff.
	Write($x, $y, $iColFill) ; Rekursion: Eine für jede "Linie" in jeder Zeile. Also irgendwas wie die CONST * AREAHEIGHT (sollte nicht so schnell wachsen)
	For $xMax = $x + 1 To $iW - 1 Step 1 ; Reads    : Weniger als FF1 und mehr als FF3
		$iColRead = Read($xMax, $y)
		If $iColRead <> $iColArea Then ExitLoop
		Write($xMax, $y, $iColFill)
	Next
	For $xMin = $x - 1 To 0 Step -1
		$iColRead = Read($xMin, $y)
		If $iColRead <> $iColArea Then ExitLoop
		Write($xMin, $y, $iColFill)
	Next
	$xMin += 1
	$xMax -= 1
	If $y > 0 Then
		For $i = $xMin To $xMax Step 1
			If Read($i, $y - 1) = $iColArea Then FF3($i, $y - 1, $iColFill, $iColArea)
		Next
	EndIf
	If $y < $iH - 1 Then
		For $i = $xMin To $xMax Step 1
			If Read($i, $y + 1) = $iColArea Then FF3($i, $y + 1, $iColFill, $iColArea)
		Next
	EndIf
EndFunc   ;==>FF3

Func Info()
	Local $iReads, $iWrites
	If $bInfoReadWrite Then ConsoleWrite('##################################### [ Reads | Writes ] ######################################' & @CRLF)
	For $y = 0 To $iH - 1 Step 1
		For $x = 0 To $iW - 1 Step 1
			$iReads += $aReads[$y][$x]
			$iWrites += $aWrites[$y][$x]
			If $bInfoReadWrite Then ConsoleWrite('[' & $aReads[$y][$x] & '|' & $aWrites[$y][$x] & '] ')
		Next
		If $bInfoReadWrite Then ConsoleWrite(@CRLF)
	Next
	ConsoleWrite('Reads:  ' & $iReads & ' (R/Px: ' & StringFormat('%.2f', $iReads/$iPixel) & ')' & @CRLF)
	ConsoleWrite('Writes: ' & $iWrites & @CRLF)
	If $bInfoReadWrite Then ConsoleWrite('###############################################################################################' & @CRLF)
EndFunc   ;==>Info

Func Read($x, $y)
	$aReads[$y][$x] += 1
	Return $aBitmap[$y][$x]
EndFunc   ;==>Read

Func Write($x, $y, $iCol)
	$aWrites[$y][$x] += 1
	$aBitmap[$y][$x] = $iCol
EndFunc   ;==>Write

Func rnd()
	If Not $bRandomize Then Return $aPos
	Local $a = [Random(0, $iW - 1, 1), Random(0, $iH - 1, 1)]
	Return $a
EndFunc   ;==>rnd