Meinst Du ein Graustufenbild zerhacken und jeweils kleine Teile mit möglichst passendem Grauwert verwenden ?
Dann müsste der Spaß noch gepuffert werden, ich glaube BitBlt ist langsamer als FillRect. Mal schauen
lg
Mars
Meinst Du ein Graustufenbild zerhacken und jeweils kleine Teile mit möglichst passendem Grauwert verwenden ?
Dann müsste der Spaß noch gepuffert werden, ich glaube BitBlt ist langsamer als FillRect. Mal schauen
lg
Mars
Ein kleines Beispiel wie eine "tanzende" XOR Textur aussieht
#include <GDIPlus.au3>
Opt('GUIOnEventMode', 1)
[/autoit] [autoit][/autoit] [autoit]Global $iSize = 32
[/autoit] [autoit][/autoit] [autoit]Global $hGUI, $hGFX, $hBMP, $hBUF, $hBRU, $iFrame, $iTimer = TimerInit(), $iFPS, $iFrameTimer = TimerInit(), $iCount = 0
[/autoit] [autoit][/autoit] [autoit]_GDIPlus_Startup()
[/autoit] [autoit][/autoit] [autoit]$hGUI = GUICreate('XOR Textur', 562, 562)
$hGFX = _GDIPlus_GraphicsCreateFromHWND($hGUI)
$hBMP = _GDIPlus_BitmapCreateFromGraphics(562, 562, $hGFX)
$hBUF = _GDIPlus_ImageGetGraphicsContext($hBMP)
$hBRU = _GDIPlus_BrushCreateSolid()
GUISetOnEvent(-3, '_Exit', $hGUI)
GUIRegisterMsg(0xF, 'WM_PAINT')
GUISetState(@SW_SHOW, $hGUI)
While Sleep(10)
_XOR_Tex()
WEnd
Func _XOR_Tex()
Local $iCol, $iTMP
Local Static $iSin = 0, $iMulti = 256 / $iSize, $2Multi = 2 * $iMulti
$iSin += 5 / (1000 / TimerDiff($iFrameTimer))
$iFrameTimer = TimerInit()
_GDIPlus_GraphicsClear($hBUF, 0xFF808080)
For $x = 0 To $iSize - 1 Step 1
$iTMP = 2 * $x * $iMulti
For $y = 0 To $iSize - 1 Step 1
$iCol = Hex(Int(BitXOR($x, $y) * $iMulti), 2)
DllCall($ghGDIPDll, "int", "GdipSetSolidFillColor", "handle", $hBRU, "dword", '0xFF' & $iCol & $iCol & $iCol)
DllCall($ghGDIPDll, "int", "GdipFillRectangleI", "handle", $hBUF, "handle", $hBRU, "int", 25 + 15 * Sin($y * $iMulti / 64 + $iSin) + $iTMP, "int", 15 * Cos($x * $iMulti / 64 + $iSin) + 25 + $y * $2Multi, "int", $2Multi, "int", $2Multi)
Next
Next
$iFPS += 1
If TimerDiff($iTimer) > 1000 Then
$iTimer = TimerInit()
WinSetTitle($hGUI, '', 'XOR Textur (' & $iFPS & 'FPS - ' & $iSize & 'x' & $iSize & ')')
$xFPS = $iFPS
$iFPS = 0
$iCount += 1
If $iCount = 10 Then
Do
$iTMP = 2 ^ Random(4, 6, 1)
Until $iTMP <> $iSize
$iSize = $iTMP
$iMulti = 256 / $iSize
$2Multi = 2 * $iMulti
$iCount = 0
EndIf
EndIf
WM_PAINT()
EndFunc ;==>_XOR_Tex
Func WM_PAINT()
_GDIPlus_GraphicsDrawImage($hGFX, $hBMP, 0, 0)
EndFunc ;==>WM_PAINT
Func _Exit()
_GDIPlus_GraphicsDispose($hBUF)
_GDIPlus_BitmapDispose($hBMP)
_GDIPlus_GraphicsDispose($hGFX)
_GDIPlus_BrushDispose($hBRU)
_GDIPlus_Shutdown()
Exit
EndFunc ;==>_Exit
lg
Mars
Das Problem besteht im Datentyp den du FileWrite übergibst.
Der Datentyp ist "String", somit wird in das JPG Bild der HexString geschrieben, anstatt der eigentliche Inhalt.
Dazu gibt es 2 Lösungen.
1. Benutzung von Binary to String ( mit '0x' & $result)
2. Casten zum korrekten Datentyp Binary('0x' & $result)
In Fall 1 wird das Problem umgangen indem der HexString manuell in den richtigen Inhalt umgewandelt wird.
In Fall 2 wird das Problem gelöst indem FileWrite Daten vom Typ Binary erhält die es anschließend auch richtig verwaltet.
Dim $result
[/autoit] [autoit][/autoit] [autoit]$data = FileOpen("logo.jpg", 16)
$hex = FileRead($data)
$binary = StringTrimLeft($hex, 2)
[/autoit] [autoit][/autoit] [autoit]FileWrite("string1.txt", $binary)
[/autoit] [autoit][/autoit] [autoit]$binary = HexToBinary($binary)
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]$aNumber = StringRegExp($binary, "\d{4}", 3)
[/autoit] [autoit][/autoit] [autoit]For $i = 0 To UBound($aNumber) - 1
$result &= BinaryToHex($aNumber[$i])
Next
FileWrite("string2.txt", $result)
[/autoit] [autoit][/autoit] [autoit]FileWrite("logo2_bin.jpg", Binary('0x' & $result))
FileWrite("logo2_bin2str.jpg", BinaryToString('0x' & $result))
Func HexToBinary($binary)
$binary = StringReplace($binary, "0", "0000")
$binary = StringReplace($binary, "1", "0001")
$binary = StringReplace($binary, "2", "0010")
$binary = StringReplace($binary, "3", "0011")
$binary = StringReplace($binary, "4", "0100")
$binary = StringReplace($binary, "5", "0101")
$binary = StringReplace($binary, "6", "0110")
$binary = StringReplace($binary, "7", "0111")
$binary = StringReplace($binary, "8", "1000")
$binary = StringReplace($binary, "9", "1001")
$binary = StringReplace($binary, "A", "1010")
$binary = StringReplace($binary, "B", "1011")
$binary = StringReplace($binary, "C", "1100")
$binary = StringReplace($binary, "D", "1101")
$binary = StringReplace($binary, "E", "1110")
$binary = StringReplace($binary, "F", "1111")
Return $binary
EndFunc
Func BinaryToHex($binary)
$binary = StringReplace($binary, "0000", "0")
$binary = StringReplace($binary, "0001", "1")
$binary = StringReplace($binary, "0010", "2")
$binary = StringReplace($binary, "0011", "3")
$binary = StringReplace($binary, "0100", "4")
$binary = StringReplace($binary, "0101", "5")
$binary = StringReplace($binary, "0110", "6")
$binary = StringReplace($binary, "0111", "7")
$binary = StringReplace($binary, "1000", "8")
$binary = StringReplace($binary, "1001", "9")
$binary = StringReplace($binary, "1010", "A")
$binary = StringReplace($binary, "1011", "B")
$binary = StringReplace($binary, "1100", "C")
$binary = StringReplace($binary, "1101", "D")
$binary = StringReplace($binary, "1110", "E")
$binary = StringReplace($binary, "1111", "F")
Return $binary
EndFunc
lg
Mars
Moin,
Habe grade ein seltsames Problem entdeckt.
In einer For schleife wird ein Continueloop aufgerufen (soweit so gut).
Interessanterweise spuckt der Interpreter bei AutoItVersion 3.3.8.1 einen Fehler aus:
--> Press Ctrl+Alt+F5 to Restart or Ctrl+Break to Stop
C:\Users\Marsi\Desktop\CookieKlick.au3 (51) : ==> "ContinueLoop" statement with no matching "While", "Do" or "For" statement.:
If ($iAnz = 0) Or ($iEin = 0) Or ($iPreis = 0) Then ContinueLoop
->02:26:30 AutoIt3.exe ended.rc:1
>Exit code: 1 Time: 3.005
In der Beta 3.3.9.17 läuft alles wie gewünscht. (Eventuell ist das Problem ja behoben worden.)
Da ich aber noch nie einen "echten" Fehler in AutoIt gefunden habe möchte ich, dass ihr das Skript mal mit der Stable ausführt und schaut ob der Fehler auch auftritt. (ggf hab ich ja auch einen Fehler im System und sehe ihn vor lauter Bäumen nicht, dann dürfte es in der .9.17 aber nicht so einfach laufen^^) Schreibt man den Einzeiligen Continueloop Teil in Zeile 50 zu einem Mehrzeiler um funktioniert es lustigerweise auch in der 8.1
Bevor Fragen auftauchen: Das Skript ist dazu gedacht das effizienteste Upgrade beim Spiel Cookie Clicker herauszufinden. Automatisiert wird nix, sollte also regelkonform sein (rechnen kann man ja keinem verbieten).
#include <Array.au3>
; Herausfinden welches Upgrade das beste ist.
[/autoit] [autoit][/autoit] [autoit]Global $iMsg
Global $hGUI = GUICreate('Cookie Klicker', 454, 224)
Global $aItems[9][4]
; 0 - Anzahl
; 1 - Einkommen (Kekse)
; 2 - Preis
; 3 - Name
; Die Kekse pro Item sind also [1]/[0]
; Der Preis pro Keks ist ([1]/[0])/[2]
Global $aInput[9][3]
; 0 - Anzahl
; 1 - Einkommen
; 2 - Preis
Global $aNamen[9]
Global $aPreisProKeks[9]
_SetNames()
_CreateLabels()
GUISetState(@SW_SHOW, $hGUI)
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]While True
$iMsg = GUIGetMsg()
Switch $iMsg
Case 0, -11, -7, -8, -9, -10, -4
Case -3
Exit
Case Else
If $iMsg > 0 Then _Calc()
EndSwitch
WEnd
Func _Calc()
Local $aPreisProKeks_Local[9]
Local $iAnz, $iEin, $iPreis
For $i = 0 To 8 Step 1
$iAnz = Int(GUICtrlRead($aItems[$i][0]))
$iEin = Int(GUICtrlRead($aItems[$i][1]))
$iPreis = Int(GUICtrlRead($aItems[$i][2]))
If ($iAnz = 0) Or ($iEin = 0) Or ($iPreis = 0) Then ContinueLoop
Next
EndFunc
[/autoit] [autoit][/autoit] [autoit]Func _CreateLabels()
GUICtrlCreateEdit('Anzahl', 85, 3, 80, 20, 2049)
GUICtrlSetFont(-1, 11, 500)
GUICtrlCreateEdit('Einkommen', 82 + 85, 3, 100, 20, 2049)
GUICtrlSetFont(-1, 11, 500)
GUICtrlCreateEdit('Preis', 102 + 82 + 85, 3, 100, 20, 2049)
GUICtrlSetFont(-1, 11, 500)
GUICtrlCreateEdit('Effizienz', 102+102 + 82 + 85, 3, 80, 20, 2049)
GUICtrlSetFont(-1, 11, 500)
For $i = 0 To 8 Step 1
$aNamen[$i] = GUICtrlCreateEdit($aItems[$i][3], 3, 25 + 22 * $i, 80, 20, 2049)
GUICtrlSetFont(-1, 11, 500)
$aInput[$i][0] = GUICtrlCreateEdit('', 85, 25 + 22 * $i, 80, 20, 1)
GUICtrlSetFont(-1, 10, 500)
$aInput[$i][1] = GUICtrlCreateEdit('', 82 + 85, 25 + 22 * $i, 100, 20, 1)
GUICtrlSetFont(-1, 10, 500)
$aInput[$i][2] = GUICtrlCreateEdit('', 184 + 85, 25 + 22 * $i, 100, 20, 1)
GUICtrlSetFont(-1, 10, 500)
$aPreisProKeks[$i] = GUICtrlCreateEdit('', 102+184 + 85, 25 + 22 * $i, 80, 20, 2049)
GUICtrlSetFont(-1, 10, 500)
Next
EndFunc ;==>_CreateLabels
Func _SetNames()
Local $a = StringSplit('Cursor,Grandma,Farm,Factory,Mine,Shipment,Alchemy lab,Portal,Time machine', ',', 2)
For $i = 0 To 8 Step 1
$aItems[$i][3] = $a[$i]
Next
EndFunc ;==>_SetNames
Edit 1: Hab grade eine Zeile(51) hinzugefügt. Kommentiert man diese aus schmiert das Skript bei der ersten Zahleneingabe ab. Lässt man die Zeile drinnen funktioniert alles nach Plan. Die Zeile hat aber nichts mit dem Continueloop zu tun...
#include <Array.au3>
; Herausfinden welches Upgrade das beste ist.
[/autoit] [autoit][/autoit] [autoit]Global $iMsg
Global $hGUI = GUICreate('Cookie Klicker', 454, 224)
Global $aItems[9][4]
; 0 - Anzahl
; 1 - Einkommen (Kekse)
; 2 - Preis
; 3 - Name
; Die Kekse pro Item sind also [1]/[0]
; Der Preis pro Keks ist ([1]/[0])/[2]
Global $aInput[9][3]
; 0 - Anzahl
; 1 - Einkommen
; 2 - Preis
Global $aNamen[9]
Global $aPreisProKeks[9]
_SetNames()
_CreateLabels()
GUISetState(@SW_SHOW, $hGUI)
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]While True
$iMsg = GUIGetMsg()
Switch $iMsg
Case 0, -11, -7, -8, -9, -10, -4
Case -3
Exit
Case Else
If $iMsg > 0 Then _Calc()
EndSwitch
WEnd
Func _Calc()
Local $aPreisProKeks_Local[9]
Local $iAnz, $iEin, $iPreis
For $i = 0 To 8 Step 1
$iAnz = Int(GUICtrlRead($aItems[$i][0]))
$iEin = Int(GUICtrlRead($aItems[$i][1]))
$iPreis = Int(GUICtrlRead($aItems[$i][2]))
If ($iAnz = 0) Or ($iEin = 0) Or ($iPreis = 0) Then ContinueLoop
;~ $aPreisProKeks_Local[$i] = ($iEin/$iAnz)/$iPreis
Next
EndFunc
[/autoit] [autoit][/autoit] [autoit]Func _CreateLabels()
GUICtrlCreateEdit('Anzahl', 85, 3, 80, 20, 2049)
GUICtrlSetFont(-1, 11, 500)
GUICtrlCreateEdit('Einkommen', 82 + 85, 3, 100, 20, 2049)
GUICtrlSetFont(-1, 11, 500)
GUICtrlCreateEdit('Preis', 102 + 82 + 85, 3, 100, 20, 2049)
GUICtrlSetFont(-1, 11, 500)
GUICtrlCreateEdit('Effizienz', 102+102 + 82 + 85, 3, 80, 20, 2049)
GUICtrlSetFont(-1, 11, 500)
For $i = 0 To 8 Step 1
$aNamen[$i] = GUICtrlCreateEdit($aItems[$i][3], 3, 25 + 22 * $i, 80, 20, 2049)
GUICtrlSetFont(-1, 11, 500)
$aInput[$i][0] = GUICtrlCreateEdit('', 85, 25 + 22 * $i, 80, 20, 1)
GUICtrlSetFont(-1, 10, 500)
$aInput[$i][1] = GUICtrlCreateEdit('', 82 + 85, 25 + 22 * $i, 100, 20, 1)
GUICtrlSetFont(-1, 10, 500)
$aInput[$i][2] = GUICtrlCreateEdit('', 184 + 85, 25 + 22 * $i, 100, 20, 1)
GUICtrlSetFont(-1, 10, 500)
$aPreisProKeks[$i] = GUICtrlCreateEdit('', 102+184 + 85, 25 + 22 * $i, 80, 20, 2049)
GUICtrlSetFont(-1, 10, 500)
Next
EndFunc ;==>_CreateLabels
Func _SetNames()
Local $a = StringSplit('Cursor,Grandma,Farm,Factory,Mine,Shipment,Alchemy lab,Portal,Time machine', ',', 2)
For $i = 0 To 8 Step 1
$aItems[$i][3] = $a[$i]
Next
EndFunc ;==>_SetNames
lg
Mars
Ich habe das richtig gelesen. Und meine (Triviale) Lösung reicht aus um den in Post 1 gegebenen String zu entschlüsseln.
Es gibt in der Mathematik eine ganz einfache Sache. Man kann nur Formeln aufstellen wenn man genügend Anhaltspunkte hat.
Z.b. gehen unendlich viele Funktionen vom Typ f(x) = ax² + bx + c durch den Punkt (7/3). Es ist unmöglich anhand eines Punktes die richtige Funktion zu bestimmen.
Genauso gibt es unendlich viele Lösungen für den String in Post 1. Ich bin jetzt kein Experte, aber ich glaube es ist unmöglich ohne weitere Anhaltspunkte etwas herauszufinden.
lg
Mars
Die Stringlänge wird kürzer, die (relative) Redundanz steigt. Da keine seltsamen Zeichen vorkommen gehe ich davon aus, dass keine Bitzerlegung und anschließendes Zusammensetzen stattgefunden hat. Bei einer Kompression fällt die Redundanz (irgendwann nicht mehr verlustfrei komprimierbar). Die Stringlänge fällt -> Es muss komprimiert worden sein. Irgendwie ergibt das ganze für mich einen großen Widerspruch.
Einzige logische Erklärungen:
1. Datenverlust
2. Sehr seltener Zufall (Redundanzsteigerung trotz Kompression ist sehr unwahrscheinlich)
3. Triviale Lösung
Global $x = 'Hello, World!'
[/autoit][autoit][/autoit][autoit]ConsoleWrite('Crypt: ' & _Crypt($x) & @CRLF)
ConsoleWrite('DeCrypt: ' & _Decrypt(_Crypt($x)) & @CRLF)
Func _Decrypt($s)
Return StringReplace($s, 'qrHgq"pdpp', 'Hello, World!', 0, 1)
EndFunc
Func _Crypt($s)
Return StringReplace($s, 'Hello, World!', 'qrHgq"pdpp', 0, 1)
EndFunc
lg
Mars
Edit: Schade, dass ich die 150 MB high poly Version nicht laden kann, würde garantiert gut aussehen.
Made my day
Es soll auch Supercomputer geben die n halbes Jahr das Universum simulieren. Die packen es villeicht ein 150MB Modell in AutoIt zu laden
Was ich immer wieder interessant finde: "geile Grafik" ist sowas von subjektiv.
Wenn ihr ein 3D Spiel mit allem drum und dran bauen wollt, besorgt euch die UE3 (gibts gratis) und versucht euer Glück.
Mit AutoIt wird man niemals auf den Stand kommen. Da Hilft auch warten nicht. Also ran an die UE !
lg
Mars
Ich bin teilweise dagegen, da sich einige hier (viel) Mühe mit der Erstellung des Logos gegeben haben (außer meine Wenigkeit) und man sollte deswegen abstimmen, obwohl sehr wahrscheinlich der Gewinner bereits feststeht.
Gruß,
UEZ
Das ist eben ein Wettbewerb
Es fehlt noch ein Robot Unicorn Attack Logo
Hmm... irgendwie sieht das auf dem dunkelblauen Hintergrund echt nach nix aus...
Ich kanns einfach nicht
Damit verbleibe ich mal hierbei:[Blockierte Grafik: http://i.imgur.com/GVPpbse.png]
(Sieht auf hellem Hintergrund ganz passabel aus finde ich)
(Die Messlatte liegt aber auch ziemlich hoch...^^)
Habs nochmal mit der Schrift versucht...
[Blockierte Grafik: http://i.imgur.com/Sjgeyhu.png]
Ohje, ich bin wohl ne absolute Niete im (große) Schrift basteln. (kommt von meinem Miniaturwahn^^)
[Blockierte Grafik: http://i.imgur.com/ihtYkGH.png][Blockierte Grafik: http://i.imgur.com/uxsc9iD.png]
Wenn die Schrift von "AutoIt.de" was taugen würde wäre schon die Hälfte geschafft^^
Wie findet ihr die Idee mit dem Zahlenstrahl ? (Ist ja ähnlich wie im aktuellen Bild)[Blockierte Grafik: http://i.imgur.com/MBIre6U.png]
Edit: Bei "Animation" Dachte ich an soetwas: [Blockierte Grafik: http://i.imgur.com/k9euQL0.png]
Da wird nur die Farbe von "2013" dezent variiert.
lg
Mars
Animationen als Apng lassen sich doch problemlos machen ?
Eine dezente Animation fände ich klasse und Apngs lassen sich als .png speichern und mit jedem Browser anzeigen (Abwärtskompatibel !)
Ich werde ggf auch was einreichen. Wird auch ggf. animiert, man kann ja auch einfach nur das erste Bild nehmen
lg
Mars
Ich hab schon n guten Plan wie man einen Algo bauen könnte, der gleichzeitig alle kürzesten Wege findet.
Vom Start und Ziel aus jeweils immer ein Feld weitergehen und demnach die Gewichtung vornehmen.
Anschließend die beiden Arrays (Structs) addieren. Die kürzesten Wege haben dann immer die gleiche Nummer. Dann kann man zusätzlich noch Abzweigungen und Wahrscheinlichkeiten einbauen
Mal schauen ob ich das heute Abend noch hinbekomme, scheint mir eigentlich recht simpel zu sein. Die Effizienz ist dabei wahrscheinlich nicht so berauschend, aber da das Verfahren sehr einfach ist kann ich das ja auch mal in ASM probieren
lg
Mars
Hmm... iwie läuft das nicht Absturzfrei. Umwege werden automatisch nicht benutzt (in deiner Version).
Hab hier mal den Prototyp. Der findet (nicht immer, aber immer öfter :D) den richtigen Weg mit Hindernissen.
Allerdings wird nicht immer der kürzeste Weg benutzt, sondern der erste der gefunden wird (nicht weiter schlimm, so ist das TD wenigstens etwas abwechselungsreicher^^)
Ab und an frisst er sich noch fest, da muss ich noch basteln.
Weiterhin wird noch eine Optimierung nachgeschaltet, da er an Hindernissen öfters mal unnötige Umwege geht.
Einfach mal drüberschauen, obs so genehm ist.
Mich würde dann auch ein vergleich zum A+ Algo interessieren, kann man den da iwie einfach einbauen ? (ohne Diagonalen)
PS: Das ist übrigens der effizienteste Weg zum Ziel
[Blockierte Grafik: http://i.imgur.com/1nQ2c2m.jpg]
#include <Array.au3>
[/autoit] [autoit][/autoit] [autoit]Global $__aArea[1][1], $__aAreaMap[1][1], $__aAreaUx, $__aAreaUy, $__aAreaStart[2], $__aAreaZiel[2], $__aMap = $__aArea
[/autoit] [autoit][/autoit] [autoit]; Nur zum Testen
Global $aLabel[1][1]
_Test()
[/autoit] [autoit][/autoit] [autoit]Func _Test()
Local $ix = 10, $iy = 10, $hBtn_Neu, $aStart[2], $aZiel[2], $t, $p, $aPosTest[2], $aBlock[2]
Local $hGUI = GUICreate('Test', 400, 445)
ReDim $aLabel[$iy][$ix]
_Area_SetSize($ix, $iy)
$hBtn_Neu = GUICtrlCreateButton('Neuer Weg', 10, 410, 100, 25)
[/autoit] [autoit][/autoit] [autoit]For $i = 0 To $ix - 1 Step 1
For $e = 0 To $iy - 1 Step 1
$aLabel[$e][$i] = GUICtrlCreateLabel('', $i * (400 / $ix), $e * (400 / $iy), (400 / $ix), (400 / $iy), 0x0201)
GUICtrlSetBkColor(-1, 0xD0D0D0 + IsInt(($e + $i) / 2) * 0x101010)
Next
Next
GUISetState()
[/autoit] [autoit][/autoit] [autoit]While True
Switch GUIGetMsg()
Case -3
Exit
Case $hBtn_Neu
_Area_Reset()
_Area_SetSize($ix, $iy)
$aStart[0] = $ix - 1
$aZiel[0] = 0
$aStart[1] = $iy - 1
$aZiel[1] = 0
;~ Do
;~ $aStart[0] = Random(0, $ix - 1, 1)
;~ $aZiel[0] = Random(0, $ix - 1, 1)
;~ $aStart[1] = Random(0, $iy - 1, 1)
;~ $aZiel[1] = Random(0, $iy - 1, 1)
;~ Until (Abs($aStart[0] - $aZiel[0]) + Abs($aStart[1] - $aZiel[1])) > (($ix ^ 2 + $iy ^ 2) ^ 0.5 / 2)
_Area_SetPath($aStart, $aZiel)
ConsoleWrite('Start: [' & $__aAreaStart[0] & '|' & $__aAreaStart[1] & ']')
ConsoleWrite(' - Ziel: [' & $__aAreaZiel[0] & '|' & $__aAreaZiel[1] & ']' & @CRLF)
For $i = 0 To Int(($ix ^ 2 + $iy ^ 2) ^ 0.5 * 1.5) Step 1
$aBlock[0] = Random(0, $ix - 1, 1)
$aBlock[1] = Random(0, $iy - 1, 1)
If ($aBlock[0] = $__aAreaStart[0] And $aBlock[1] = $__aAreaStart[1]) Or ($aBlock[0] = $__aAreaZiel[0] And $aBlock[1] = $__aAreaZiel[1]) Then
;~ ConsoleWrite($aBlock[0] & '|' & $aBlock[1] & @CRLF)
ContinueLoop
Else
_Area_SetTitle($aBlock[0], $aBlock[1], 1)
EndIf
Next
For $i = 0 To $ix - 1 Step 1
For $e = 0 To $iy - 1 Step 1
If $__aArea[$e][$i] Then
GUICtrlSetBkColor($aLabel[$e][$i], 0x404040)
Else
If $i = $aStart[0] And $e = $aStart[1] Then
GUICtrlSetBkColor($aLabel[$e][$i], 0x4040DD)
ElseIf $i = $aZiel[0] And $e = $aZiel[1] Then
GUICtrlSetBkColor($aLabel[$e][$i], 0xDD4040)
Else
GUICtrlSetBkColor($aLabel[$e][$i], 0xD0D0D0)
EndIf
EndIf
Next
Next
_Area_Calc()
For $i = 0 To $ix - 1 Step 1
For $e = 0 To $iy - 1 Step 1
GUICtrlSetData($aLabel[$e][$i], Round($__aAreaMap[$e][$i], 1))
Next
Next
$t = TimerInit()
$p = _Area_FindPath()
$t = TimerDiff($t)
ConsoleWrite('Pfad: ' & $p & ' (' & Round($t, 2) & 'ms)' & @CRLF)
;~ Sleep(1000)
$aPosTest = $__aAreaStart
$p = StringSplit($p, '', 2)
For $i = 0 To UBound($p) - 2 Step 1
Switch $p[$i]
Case 1 ; Links
$aPosTest[0] -= 1
Case 2 ; Oben
$aPosTest[1] -= 1
Case 3 ; Rechts
$aPosTest[0] += 1
Case 4 ; Unten
$aPosTest[1] += 1
EndSwitch
GUICtrlSetBkColor($aLabel[$aPosTest[1]][$aPosTest[0]], 0x40DD40)
Next
EndSwitch
WEnd
EndFunc ;==>_Test
[/autoit] [autoit][/autoit] [autoit]Func _Area_FindPath()
$__aMap = $__aArea
Return __Area_FindPathRec()
EndFunc
Func __Area_FindPathRec($aPos = $__aAreaStart, $aPosLast = $__aAreaStart)
If $aPos[0] = $__aAreaZiel[0] And $aPos[1] = $__aAreaZiel[1] Then Return
Local $sPath = ''
Local $aList = __Area_GetRichtung($aPos, $aPosLast), $tPos[2], $sTemp
__Area_SortArray2D($aList)
;~ If $aList[0][1] = 1 Then Return
;~ ConsoleWrite('Pos: [' & $aPos[0] & '|' & $aPos[1] & ']' & @CRLF)
;~ For $i = 0 To UBound($aList) - 1 Step 1
;~ If $aList[$i][1] Then ConsoleWrite($aList[$i][0] & ': ' & Round($aList[$i][1], 1) & @CRLF)
;~ Next
;~ ConsoleWrite(@CRLF)
For $i = 0 To UBound($aList) - 1 Step 1
If Not $aList[$i][1] Then ContinueLoop
$tPos = $aPos
Switch $aList[$i][0]
Case 1 ; Links
$tPos[0] -= 1
Case 2 ; Oben
$tPos[1] -= 1
Case 3 ; Rechts
$tPos[0] += 1
Case 4 ; Unten
$tPos[1] += 1
EndSwitch
If $tPos[0] = $__aAreaZiel[0] And $tPos[1] = $__aAreaZiel[1] Then Return $aList[$i][0]
$sPath = $aList[$i][0]
$aPosLast = $aPos
;~ Sleep(100)
;~ ConsoleWrite
;~ If Not $__aMap[$tPos[1]][$tPos[0]] Then GUICtrlSetBkColor($aLabel[$tPos[1]][$tPos[0]], 0x408D8D + _012() * 0x3030)
;~ ConsoleWrite('Map: ' & $__aMap[$aPos[1]][$aPos[0]] & @CRLF)
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]$sTemp = __Area_FindPathRec($tPos, $aPosLast)
;~ ConsoleWrite($sTemp & @CRLF)
If $sTemp > 0 Then Return $sPath & $sTemp
;~ If $aList[$i][1] Then ConsoleWrite($aList[$i][0] & ': ' & $aList[$i][1] & @CRLF)
Next
If Not $sPath Then
;~ _ArrayDisplay($aList)
Return -1
EndIf
EndFunc ;==>_Area_FindPath
Func _012()
Local Static $012 = 0
$012 += 1
If $012 = 3 Then $012 = 0
Return $012
EndFunc ;==>_012
Func __Area_SortArray2D(ByRef $a)
Local $c[2], $t[2]
For $i = 0 To UBound($a) - 1 Step 1
$t[0] = $a[$i][0]
$t[1] = $a[$i][1]
For $e = $i - 1 To 0 Step -1
$c[0] = $a[$e][0]
$c[1] = $a[$e][1]
If $t[1] >= $c[1] Then ExitLoop
$a[$e + 1][0] = $c[0]
$a[$e + 1][1] = $c[1]
Next
$a[$e + 1][0] = $t[0]
$a[$e + 1][1] = $t[1]
Next
EndFunc ;==>__Area_SortArray2D
Func __Area_GetRichtung($aPos, $aPosLast)
Local $a[4][2] = [[1],[2],[3],[4]] ; LORU
If ($aPos[0] > 0) And Not $__aMap[$aPos[1]][$aPos[0] - 1] And Not ((($aPos[0] - 1) = $aPosLast[0]) And ($aPos[1] = $aPosLast[1])) Then $a[0][1] = $__aAreaMap[$aPos[1]][$aPos[0] - 1]
If ($aPos[1] > 0) And Not $__aMap[$aPos[1] - 1][$aPos[0]] And Not (($aPos[0] = $aPosLast[0]) And (($aPos[1] - 1) = $aPosLast[1])) Then $a[1][1] = $__aAreaMap[$aPos[1] - 1][$aPos[0]]
If ($aPos[0] < $__aAreaUx - 1) And Not $__aMap[$aPos[1]][$aPos[0] + 1] And Not ((($aPos[0] + 1) = $aPosLast[0]) And ($aPos[1] = $aPosLast[1])) Then $a[2][1] = $__aAreaMap[$aPos[1]][$aPos[0] + 1]
If ($aPos[1] < $__aAreaUy - 1) And Not $__aMap[$aPos[1] + 1][$aPos[0]] And Not (($aPos[0] = $aPosLast[0]) And (($aPos[1] + 1) = $aPosLast[1])) Then $a[3][1] = $__aAreaMap[$aPos[1] + 1][$aPos[0]]
If 1*($a[0][1] <> '') + 1*($a[1][1] <> '') + 1*($a[2][1] <> '') + 1*($a[3][1] <> '') <= 1 Then $__aMap[$aPos[1]][$aPos[0]] += 1
Return $a
EndFunc ;==>__Area_GetRichtung
Func _Area_Calc()
If Not ($__aAreaStart[0] < $__aAreaUx And $__aAreaStart[1] < $__aAreaUy And $__aAreaZiel[0] < $__aAreaUx And $__aAreaZiel[1] < $__aAreaUy) Then Return -1
For $x = 0 To $__aAreaUx - 1 Step 1
For $y = 0 To $__aAreaUy - 1 Step 1
$__aAreaMap[$y][$x] = (($__aAreaZiel[0] - $x) ^ 2 + ($__aAreaZiel[1] - $y) ^ 2) ^ 0.5 + 1
Next
Next
EndFunc ;==>_Area_Calc
Func _Area_SetPath($aStart, $aZiel)
$__aAreaStart = $aStart
$__aAreaZiel = $aZiel
EndFunc ;==>_Area_SetPath
Func _Area_SetTitle($x, $y, $bBlocked)
If $x < $__aAreaUx And $y < $__aAreaUy Then $__aArea[$y][$x] = $bBlocked
EndFunc ;==>_Area_SetTitle
Func _Area_Reset()
ReDim $__aArea[1][1]
$__aArea[0][0] = ''
$__aAreaMap = $__aArea
$__aAreaUx = 1
$__aAreaUy = 1
$__aAreaStart[0] = ''
$__aAreaStart[1] = ''
$__aAreaZiel[0] = ''
$__aAreaZiel[1] = ''
EndFunc ;==>_Area_Reset
Func _Area_SetSize($x, $y)
_Area_Reset()
ReDim $__aArea[$y][$x]
$__aAreaMap = $__aArea
$__aAreaUx = $x
$__aAreaUy = $y
EndFunc ;==>_Area_SetSize
Normales Wegfinden dauert bei mir im Schnitt 1-3ms. Ob überhaupt ein Weg existiert merkt die Mühle nach 0-20ms (je nachdem ob die Blockade nah am Start oder nah am Ziel ist)
lg
Mars
Wie ich weiter verfahre weiß ich schon^^
Also das mit Blockierten Wegen ist schon geplant.
Und Andy zuliebe ersetzen wir die 1-Norm durch die 2-Norm
(($__aAreaZiel[0] - $x) ^ 2 + ($__aAreaZiel[1] - $y) ^ 2) ^ 0.5 + 1
[/autoit]#include <Array.au3>
[/autoit] [autoit][/autoit] [autoit]Global $__aArea[1][1], $__aAreaMap[1][1], $__aAreaUx, $__aAreaUy, $__aAreaStart[2], $__aAreaZiel[2]
[/autoit] [autoit][/autoit] [autoit]; Nur zum Testen
Global $aLabel[1][1]
_Test()
[/autoit] [autoit][/autoit] [autoit]Func _Test()
Local $ix = 10, $iy = 10, $hBtn_Neu, $aStart[2], $aZiel[2], $t, $p, $aPosTest[2]
Local $hGUI = GUICreate('Test', 400, 445)
ReDim $aLabel[$iy][$ix]
_Area_SetSize($ix, $iy)
$hBtn_Neu = GUICtrlCreateButton('Neuer Weg', 10, 410, 100, 25)
[/autoit] [autoit][/autoit] [autoit]For $i = 0 To $ix - 1 Step 1
For $e = 0 To $iy - 1 Step 1
$aLabel[$e][$i] = GUICtrlCreateLabel('', $i * (400 / $ix), $e * (400 / $iy), (400 / $ix), (400 / $iy), 0x0201)
GUICtrlSetBkColor(-1, 0xD0D0D0 + IsInt(($e + $i) / 2) * 0x101010)
Next
Next
GUISetState()
[/autoit] [autoit][/autoit] [autoit]While True
Switch GUIGetMsg()
Case -3
Exit
Case $hBtn_Neu
Do
For $i = 0 To 1 Step 1
$aStart[$i] = Random(0, $ix - 1, 1)
$aZiel[$i] = Random(0, $ix - 1, 1)
Next
Until (Abs($aStart[0] - $aZiel[0]) + Abs($aStart[1] - $aZiel[1])) > (($ix ^ 2 + $iy ^ 2) ^ 0.5 / 2)
_Area_SetPath($aStart, $aZiel)
For $i = 0 To $ix - 1 Step 1
For $e = 0 To $iy - 1 Step 1
If $i = $aStart[0] And $e = $aStart[1] Then
GUICtrlSetBkColor($aLabel[$e][$i], 0x4040DD)
ElseIf $i = $aZiel[0] And $e = $aZiel[1] Then
GUICtrlSetBkColor($aLabel[$e][$i], 0xDD4040)
Else
GUICtrlSetBkColor($aLabel[$e][$i], 0xD0D0D0)
EndIf
Next
Next
_Area_Calc()
For $i = 0 To $ix - 1 Step 1
For $e = 0 To $iy - 1 Step 1
GUICtrlSetData($aLabel[$e][$i], Round($__aAreaMap[$e][$i], 1))
Next
Next
$t = TimerInit()
$p = _Area_FindPath()
$t = TimerDiff($t)
ConsoleWrite('Pfad: ' & $p & ' (' & Round($t, 2) & 'ms)' & @CRLF)
$aPosTest = $__aAreaStart
$p = StringSplit($p, '', 2)
For $i = 0 To UBound($p) - 2 Step 1
Switch $p[$i]
Case 1 ; Links
$aPosTest[0] -= 1
Case 2 ; Oben
$aPosTest[1] -= 1
Case 3 ; Rechts
$aPosTest[0] += 1
Case 4 ; Unten
$aPosTest[1] += 1
EndSwitch
GUICtrlSetBkColor($aLabel[$aPosTest[1]][$aPosTest[0]], 0x40DD40)
Next
EndSwitch
WEnd
EndFunc ;==>_Test
[/autoit] [autoit][/autoit] [autoit]Func _Area_FindPath($aPos = $__aAreaStart)
If $aPos[0] = $__aAreaZiel[0] And $aPos[1] = $__aAreaZiel[1] Then Return
Local $sPath = ''
Local $aList = __Area_GetRichtung($aPos), $tPos[2], $sTemp
__Area_SortArray2D($aList)
;~ If $aList[0][1] = 1 Then Return
;~ ConsoleWrite('Pos: [' & $aPos[0] & '|' & $aPos[1] & ']' & @CRLF)
;~ For $i = 0 To UBound($aList) - 1 Step 1
;~ If $aList[$i][1] Then ConsoleWrite($aList[$i][0] & ': ' & $aList[$i][1] & @CRLF)
;~ Next
;~ ConsoleWrite(@CRLF)
For $i = 0 To UBound($aList) - 1 Step 1
If Not $aList[$i][1] Then ContinueLoop
$tPos = $aPos
Switch $aList[$i][0]
Case 1 ; Links
$tPos[0] -= 1
Case 2 ; Oben
$tPos[1] -= 1
Case 3 ; Rechts
$tPos[0] += 1
Case 4 ; Unten
$tPos[1] += 1
EndSwitch
If $tPos[0] = $__aAreaZiel[0] And $tPos[1] = $__aAreaZiel[1] Then Return $aList[$i][0]
$sPath = $aList[$i][0]
;~ Sleep(500)
;~ GUICtrlSetBkColor($aLabel[$tPos[1]][$tPos[0]], 0x40DD40)
;~ ConsoleWrite('tPos: [' & $tPos[0] & '|' & $tPos[1] & ']' & @CRLF)
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]$sTemp = _Area_FindPath($tPos)
If Not ($sTemp = -1) Then Return $sPath & $sTemp
;~ If $aList[$i][1] Then ConsoleWrite($aList[$i][0] & ': ' & $aList[$i][1] & @CRLF)
Next
If Not $sPath Then
;~ _ArrayDisplay($aList)
Return -1
EndIf
EndFunc ;==>_Area_FindPath
Func __Area_SortArray2D(ByRef $a)
Local $c[2], $t[2]
For $i = 0 To UBound($a) - 1 Step 1
$t[0] = $a[$i][0]
$t[1] = $a[$i][1]
For $e = $i - 1 To 0 Step -1
$c[0] = $a[$e][0]
$c[1] = $a[$e][1]
If $t[1] >= $c[1] Then ExitLoop
$a[$e + 1][0] = $c[0]
$a[$e + 1][1] = $c[1]
Next
$a[$e + 1][0] = $t[0]
$a[$e + 1][1] = $t[1]
Next
EndFunc ;==>__Area_SortArray2D
Func __Area_GetRichtung($aPos)
Local $a[4][2] = [[1],[2],[3],[4]] ; LORU
If $aPos[0] > 0 Then $a[0][1] = $__aAreaMap[$aPos[1]][$aPos[0] - 1]
If $aPos[1] > 0 Then $a[1][1] = $__aAreaMap[$aPos[1] - 1][$aPos[0]]
If $aPos[0] < $__aAreaUx - 1 Then $a[2][1] = $__aAreaMap[$aPos[1]][$aPos[0] + 1]
If $aPos[1] < $__aAreaUy - 1 Then $a[3][1] = $__aAreaMap[$aPos[1] + 1][$aPos[0]]
Return $a
EndFunc ;==>__Area_GetRichtung
Func _Area_Calc()
If Not ($__aAreaStart[0] < $__aAreaUx And $__aAreaStart[1] < $__aAreaUy And $__aAreaZiel[0] < $__aAreaUx And $__aAreaZiel[1] < $__aAreaUy) Then Return -1
For $x = 0 To $__aAreaUx - 1 Step 1
For $y = 0 To $__aAreaUy - 1 Step 1
$__aAreaMap[$y][$x] = (($__aAreaZiel[0] - $x) ^ 2 + ($__aAreaZiel[1] - $y) ^ 2) ^ 0.5 + 1
Next
Next
EndFunc ;==>_Area_Calc
Func _Area_SetPath($aStart, $aZiel)
$__aAreaStart = $aStart
$__aAreaZiel = $aZiel
EndFunc ;==>_Area_SetPath
Func _Area_SetTitle($x, $y, $bBlocked)
If $x < $__aAreaUx And $y < $__aAreaUy Then $__aArea[$y][$x] = $bBlocked
EndFunc ;==>_Area_SetTitle
Func _Area_Reset()
ReDim $__aArea[1][1]
$__aArea[0][0] = ''
$__aAreaMap = $__aArea
$__aAreaUx = 1
$__aAreaUy = 1
$__aAreaStart[0] = ''
$__aAreaStart[1] = ''
$__aAreaZiel[0] = ''
$__aAreaZiel[1] = ''
EndFunc ;==>_Area_Reset
Func _Area_SetSize($x, $y)
_Area_Reset()
ReDim $__aArea[$y][$x]
$__aAreaMap = $__aArea
$__aAreaUx = $x
$__aAreaUy = $y
EndFunc ;==>_Area_SetSize
Edit:
Es ging eigentlich darum, ob es einen effizienteren Ansatz gibt. Verwendet wird: Gewichtung und anschließendes Entscheiden.
lg
Mars
Moin,
Ich wusste nicht so recht, ob der Thread in H&U oder in Skripte gehört, denn eigentlich habe ich eine Frage
Da es aber schon ein funktionsfähiges (aber ziemlich primitives) Skript gibt habe ich mich für Skripte entschieden.
Da ich irgendwann mal wieder ein TD basteln möchte was ggf mehr kann als meine bisherigen brauche ich natürlich erstmal eine ganze Menge Funktionen die mir das ermöglichen. Eine davon ist die Wegfindungsfunktion. Sie soll im 2D Raum den kürzesten Weg vom Start zum Ziel finden. Diagonales Laufen ist nicht möglich. Andys A* Algo habe ich mir schon angesehen, aber nicht gänzlich verstanden (Er beinhaltet auch Diagonales gehen). Zudem möchte ich nicht mit Kanonen auf Spatzen schießen. Es handelt sich um ein kleines Spielfeld (im Endeffekt wird es zwischen 12x12 und 16x16 Felder groß, ggf auch nicht gleichseitig), daher wird kein Algo benötigt der unnötig komplex ist um bei großen Wegen Zeit zu sparen, der aber bei kleinen Wegen unnötigen Overhead mitführt.
Das Skript anbei findet schon den Weg in akzeptabeler Geschwindigkeit. Ich bin mir aber nicht sicher, ob mein Ansatz (annähernd) optimal ist. Da zusätzlich noch Rücksicht auf Hindernisse genommen werden muss, was ich noch nicht vollständig implementiert habe möchte ich vor dem Weiterbasteln wissen, ob es villeicht einen effizienteren Ansatz zum Ziel gibt. Dann würde ich mich diesem widmen und mein bisheriges Skript als kleine Übung abtun. Das Skript sollte leicht verständlich sein, sodass Schwächen schnell erkannt werden können. Daher bitte ich um eure Meinung
Hier mein kleiner Test:
#include <Array.au3>
#include <GDIPlus.au3>
Global $__aArea[1][1], $__aAreaMap[1][1], $__aAreaUx, $__aAreaUy, $__aAreaStart[2], $__aAreaZiel[2], $__aMap = $__aArea
[/autoit] [autoit][/autoit] [autoit]; Nur zum Testen
Global $aLabel[1][1]
_Test()
[/autoit] [autoit][/autoit] [autoit]Func _Test()
_GDIPlus_Startup()
Local $ix = 25, $iy = 25, $hBtn_Neu, $aStart[2], $aZiel[2], $t, $p, $aPosTest[2], $aBlock[2], $iMsg, $iTimer, $iTime, $iVersuche
Local $hGUI = GUICreate('Test', 400, 445), $hGFX = _GDIPlus_GraphicsCreateFromHWND($hGUI), $hBRU = _GDIPlus_BrushCreateSolid()
ReDim $aLabel[$iy][$ix]
_Area_SetSize($ix, $iy)
$hBtn_Neu = GUICtrlCreateButton('Neuer Weg', 10, 410, 100, 25)
GUISetState()
$iTimer = TimerInit()
While True
$iMsg = GUIGetMsg()
If TimerDiff($iTimer) > 1500 Then
$iMsg = $hBtn_Neu
$iTimer = TimerInit()
EndIf
Switch $iMsg
Case -3
ExitLoop
Case $hBtn_Neu
_Area_Reset()
_Area_SetSize($ix, $iy)
$aStart[0] = $ix - 1
$aZiel[0] = 0
$aStart[1] = $iy - 1
$aZiel[1] = 0
_Area_SetPath($aStart, $aZiel)
ConsoleWrite('Start: [' & $__aAreaStart[0] & '|' & $__aAreaStart[1] & ']')
ConsoleWrite(' - Ziel: [' & $__aAreaZiel[0] & '|' & $__aAreaZiel[1] & ']' & @CRLF)
For $i = 0 To Int(($ix ^ 2 + $iy ^ 2) ^ 0.5 / 2) Step 1
$aBlock[0] = Random(0, $ix - 1, 1)
$aBlock[1] = Random(0, $iy - 1, 1)
If ($aBlock[0] = $__aAreaStart[0] And $aBlock[1] = $__aAreaStart[1]) Or ($aBlock[0] = $__aAreaZiel[0] And $aBlock[1] = $__aAreaZiel[1]) Then
ContinueLoop
Else
_Area_SetTitle($aBlock[0], $aBlock[1], 1)
_Area_SetTitle($aBlock[0]+1, $aBlock[1], 1)
_Area_SetTitle($aBlock[0], $aBlock[1]+1, 1)
_Area_SetTitle($aBlock[0]+1, $aBlock[1]+1, 1)
_Area_SetTitle($aBlock[0]+2, $aBlock[1], 1)
_Area_SetTitle($aBlock[0], $aBlock[1]+2, 1)
_Area_SetTitle($aBlock[0]+2, $aBlock[1]+1, 1)
_Area_SetTitle($aBlock[0]+1, $aBlock[1]+2, 1)
_Area_SetTitle($aBlock[0]+2, $aBlock[1]+2, 1)
EndIf
Next
For $i = 0 To Int(($ix ^ 2 + $iy ^ 2) ^ 0.5 / 2) Step 1
$aBlock[0] = Random(0, $ix - 1, 1)
$aBlock[1] = Random(0, $iy - 1, 1)
If ($aBlock[0] = $__aAreaStart[0] And $aBlock[1] = $__aAreaStart[1]) Or ($aBlock[0] = $__aAreaZiel[0] And $aBlock[1] = $__aAreaZiel[1]) Then
ContinueLoop
Else
_Area_SetTitle($aBlock[0], $aBlock[1], 1)
_Area_SetTitle($aBlock[0]+1, $aBlock[1], 1)
_Area_SetTitle($aBlock[0], $aBlock[1]+1, 1)
_Area_SetTitle($aBlock[0]+1, $aBlock[1]+1, 1)
EndIf
Next
For $i = 0 To Int(($ix ^ 2 + $iy ^ 2) ^ 0.5 / 2) Step 1
$aBlock[0] = Random(0, $ix - 1, 1)
$aBlock[1] = Random(0, $iy - 1, 1)
If ($aBlock[0] = $__aAreaStart[0] And $aBlock[1] = $__aAreaStart[1]) Or ($aBlock[0] = $__aAreaZiel[0] And $aBlock[1] = $__aAreaZiel[1]) Then
ContinueLoop
Else
_Area_SetTitle($aBlock[0], $aBlock[1], 1)
EndIf
Next
For $i = 0 To $ix - 1 Step 1
For $e = 0 To $iy - 1 Step 1
If $__aArea[$e][$i] Then
DllCall($ghGDIPDll, "int", "GdipSetSolidFillColor", "handle", $hBRU, "dword", 0xFF404040)
Else
If $i = $aStart[0] And $e = $aStart[1] Then
DllCall($ghGDIPDll, "int", "GdipSetSolidFillColor", "handle", $hBRU, "dword", 0xFF4040DD)
ElseIf $i = $aZiel[0] And $e = $aZiel[1] Then
DllCall($ghGDIPDll, "int", "GdipSetSolidFillColor", "handle", $hBRU, "dword", 0xFFDD4040)
Else
DllCall($ghGDIPDll, "int", "GdipSetSolidFillColor", "handle", $hBRU, "dword", 0xFFD0D0D0)
EndIf
EndIf
DllCall($ghGDIPDll, "int", "GdipFillRectangleI", "handle", $hGFX, "handle", $hBRU, "int", $i * (400 / $ix), "int", $e * (400 / $iy), "int", (400 / $ix), "int", (400 / $iy))
Next
Next
_Area_Calc()
$t = TimerInit()
$p = _Area_FindPath()
$t = TimerDiff($t)
ConsoleWrite('Pfad: ' & $p & ' (' & Round($t, 2) & 'ms)' & @CRLF)
If Int(StringLeft($p, 3)) > 0 Then
$iTime += $t
$iVersuche += 1
ToolTip('Dauer: ' & Round($iTime / $iVersuche, 2) & 'ms')
EndIf
$aPosTest = $__aAreaStart
$p = StringSplit($p, '', 2)
For $i = 0 To UBound($p) - 2 Step 1
Switch $p[$i]
Case 1 ; Links
$aPosTest[0] -= 1
Case 2 ; Oben
$aPosTest[1] -= 1
Case 3 ; Rechts
$aPosTest[0] += 1
Case 4 ; Unten
$aPosTest[1] += 1
EndSwitch
DllCall($ghGDIPDll, "int", "GdipSetSolidFillColor", "handle", $hBRU, "dword", 0xFF154015 + Int('0xFF' & Hex(Int(($i*0.75)^0.8), 2) & Hex(Int(($i*2)^0.83), 2) & Hex(Int(($i*0.75)^0.8), 2)))
DllCall($ghGDIPDll, "int", "GdipFillRectangleI", "handle", $hGFX, "handle", $hBRU, "int", $aPosTest[0] * (400 / $ix), "int", $aPosTest[1] * (400 / $iy), "int", (400 / $ix), "int", (400 / $iy))
Next
EndSwitch
WEnd
_GDIPlus_BrushDispose($hBRU)
_GDIPlus_GraphicsDispose($hGFX)
_GDIPlus_Shutdown()
EndFunc ;==>_Test
Func _Area_FindPath()
$__aMap = $__aArea
Return __Area_FindPathRec()
EndFunc
Func __Area_FindPathRec($aPos = $__aAreaStart, $aPosLast = $__aAreaStart)
Local $aList = __Area_GetRichtung($aPos, $aPosLast), $tPos[2], $sTemp, $iSum = 1*($aList[0][1] > 0) + 1*($aList[1][1] > 0) + 1*($aList[2][1] > 0) + 1*($aList[3][1] > 0)
If $iSum < 2 Then
$__aMap[$aPos[1]][$aPos[0]] += 1
If $iSum = 0 Then Return -1
EndIf
__Area_SortArray2D($aList)
For $i = 0 To UBound($aList) - 1 Step 1
If Not $aList[$i][1] Then ContinueLoop
$tPos = $aPos
Switch $aList[$i][0]
Case 1 ; Links
$tPos[0] -= 1
Case 2 ; Oben
$tPos[1] -= 1
Case 3 ; Rechts
$tPos[0] += 1
Case 4 ; Unten
$tPos[1] += 1
EndSwitch
If $tPos[0] = $__aAreaZiel[0] And $tPos[1] = $__aAreaZiel[1] Then Return $aList[$i][0]
$aPosLast = $aPos
$sTemp = __Area_FindPathRec($tPos, $aPosLast)
If $sTemp > 0 Then Return $aList[$i][0] & $sTemp
Next
EndFunc ;==>_Area_FindPath
Func __Area_SortArray2D(ByRef $a)
Local $c[2], $t[2]
For $i = 0 To UBound($a) - 1 Step 1
$t[0] = $a[$i][0]
$t[1] = $a[$i][1]
For $e = $i - 1 To 0 Step -1
$c[0] = $a[$e][0]
$c[1] = $a[$e][1]
If $t[1] >= $c[1] Then ExitLoop
$a[$e + 1][0] = $c[0]
$a[$e + 1][1] = $c[1]
Next
$a[$e + 1][0] = $t[0]
$a[$e + 1][1] = $t[1]
Next
EndFunc ;==>__Area_SortArray2D
Func __Area_GetRichtung($aPos, $aPosLast)
Local $a[4][2] = [[1],[2],[3],[4]] ; LORU
If ($aPos[0] > 0) And Not $__aMap[$aPos[1]][$aPos[0] - 1] And Not ((($aPos[0] - 1) = $aPosLast[0]) And ($aPos[1] = $aPosLast[1])) Then $a[0][1] = $__aAreaMap[$aPos[1]][$aPos[0] - 1]
If ($aPos[1] > 0) And Not $__aMap[$aPos[1] - 1][$aPos[0]] And Not (($aPos[0] = $aPosLast[0]) And (($aPos[1] - 1) = $aPosLast[1])) Then $a[1][1] = $__aAreaMap[$aPos[1] - 1][$aPos[0]]
If ($aPos[0] < $__aAreaUx - 1) And Not $__aMap[$aPos[1]][$aPos[0] + 1] And Not ((($aPos[0] + 1) = $aPosLast[0]) And ($aPos[1] = $aPosLast[1])) Then $a[2][1] = $__aAreaMap[$aPos[1]][$aPos[0] + 1]
If ($aPos[1] < $__aAreaUy - 1) And Not $__aMap[$aPos[1] + 1][$aPos[0]] And Not (($aPos[0] = $aPosLast[0]) And (($aPos[1] + 1) = $aPosLast[1])) Then $a[3][1] = $__aAreaMap[$aPos[1] + 1][$aPos[0]]
Return $a
EndFunc ;==>__Area_GetRichtung
Func _Area_Calc()
If Not ($__aAreaStart[0] < $__aAreaUx And $__aAreaStart[1] < $__aAreaUy And $__aAreaZiel[0] < $__aAreaUx And $__aAreaZiel[1] < $__aAreaUy) Then Return -1
For $x = 0 To $__aAreaUx - 1 Step 1
For $y = 0 To $__aAreaUy - 1 Step 1
$__aAreaMap[$y][$x] = (($__aAreaZiel[0] - $x) ^ 2 + ($__aAreaZiel[1] - $y) ^ 2) ^ 0.5 + 1
Next
Next
EndFunc ;==>_Area_Calc
Func _Area_SetPath($aStart, $aZiel)
$__aAreaStart = $aStart
$__aAreaZiel = $aZiel
EndFunc ;==>_Area_SetPath
Func _Area_SetTitle($x, $y, $bBlocked)
If $x < $__aAreaUx And $y < $__aAreaUy Then $__aArea[$y][$x] = $bBlocked
EndFunc ;==>_Area_SetTitle
Func _Area_Reset()
ReDim $__aArea[1][1]
$__aArea[0][0] = ''
$__aAreaMap = $__aArea
$__aAreaUx = 1
$__aAreaUy = 1
$__aAreaStart[0] = ''
$__aAreaStart[1] = ''
$__aAreaZiel[0] = ''
$__aAreaZiel[1] = ''
EndFunc ;==>_Area_Reset
Func _Area_SetSize($x, $y)
_Area_Reset()
ReDim $__aArea[$y][$x]
$__aAreaMap = $__aArea
$__aAreaUx = $x
$__aAreaUy = $y
EndFunc ;==>_Area_SetSize
Edit: Hier mal das was ich bisher habe. Nach meiner Überprüfung findet die Funktion immer einen Weg, sofern einer existiert. (aber nur selten den optimalen, was aber nicht weiter schlimm ist). Wie kann man verifizieren, dass dies tatsächlich der Fall ist ? Habe hunderte Male den Weg in einer Zufallslandschaft finden lassen, und beim Fehlschlag immer visuell festgestellt, dass kein Weg möglich war. Leider sind 100 Beispiele kein Beweis.
lg
Mars
Ob Andy es herausgefordert hat ?
[autoit]Dim $s = 7, $b = $s, $g = 0
While $b <> -3 * Assign('b', GUIGetMsg())
If (Not ($b > 2 And $b < 52)) And $g <> 0 Then ContinueLoop
$g = GUICreate('Lottozahlen', $s ^ 3, $s ^ 3 + GUIDelete($g) * 0)
Dim $a[$s ^ 2], $z = 0 ;variablen definieren
Do
$r = Random(0, $s ^ 2 - 1, 1) ;zufallszahl erzeugen
If Not $a[$r] Then $a[$r] = $s + Assign('z', $z + 1) * 0 * ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $rnd = ' & $r & @CRLF & '>Error code: ' & @error & @CRLF)
Until $z = $s - 1 ;solange bis anzahl =6
For $i = 0 To $s ^ 2 - 1 ;buttons erstellen
$z = GUICtrlCreateButton($i + 1, (Mod($i, $s)) * $s ^ 2, Int($i / $s) * $s ^ 2, $s ^ 2, $s ^ 2) + (($a[$i] <> '') And GUICtrlSetBkColor(-1, 0xFF0000)) + (($i = $s ^ 2 - 1) And GUISetState()) ; GuiSetState wird nur 1x ausgeführt
Next
WEnd
Dim $s=7,$b=$s,$g=0; - - - - |
While $b<>-3*Assign('b' _; - |
,GUIGetMsg()); - - - - - - - |
If(Not($b>2 And $b<52)) _; - |
And $g<>0 Then ContinueLoop; |
$g=GUICreate('Lottozahlen' _;|
,$s^3,$s^3+GUIDelete($g)*0); |
Dim $a[$s^2],$z=0; - - - - - |
Do; - - - - - - - - - - - - -|
$r=Random(0,$s^2-1,1); - - - |
If Not $a[$r] Then $a[$r]= _;|
$s+Assign('z',$z+1); - - - - |
Until $z=$s-1; - - - - - - - |
For $i=0 To $s^2-1; - - - - -|
$z=GUICtrlCreateButton($i+ _;|
1,(Mod($i,$s))*$s^2,Int($i _;|
/$s)*$s^2,$s^2,$s^2)+(($a[ _;|
$i]<>'')And _; - - - - - - - |
GUICtrlSetBkColor(-1, _; - - |
0xFF0000))+(($i=$s^2-1) _; - |
And GUISetState()); - - - - -|
Next; - - - - - - - - - - - -|
WEnd; - - - - - - - - - - - -|
lg
Mars
Off-Topic:
Wie kommst du eigentlich auf die 13 Stellen? Ein MD5 Hash hat 128 Bit, also wären es doch 32 Stellen, oder nicht? Deine Rechnung (falls diese stimmt) würde dann 0 ergeben.
Scheint aber, als würden nur 13 Stellen benutzt um den Link klein zu halten.
In jeder URL meiner bisher hochgeladenen Bilder sind 13 Stellen.
Wenn der Hash unterschiedlich ist, ist auch das Bild unterschiedlich. Bei 13 Stelligem Hex Hash gibts 16^13 Möglichkeiten. In Wahrscheinlichkeitsrechnen bin ich grade nicht so fit, aber ich glaube folgendes stimmt: Klick Mich. Demnach wären es bei 1Mia Bildern ca 0.01% Wahrscheinlichkeit einer Kollision.
Daher schließe ich mich dem an, einfach das Bild zu zeigen, sollte der Hash schon vorhanden sein. Falls es Probleme gibt hat halt einer von 5Mia Leuten pech
Funktioniert wunderbar
[Blockierte Grafik: http://image.devsome.com/pics/5208ba66ee7fd.png]
Das Einzige was mir auffällt, ist dass (bei mir jedenfalls) Transparenz durch ein graues Fenster aufgefüllt wird.
Der Upload ging enorm schnell und die Weiterleitung war auch ohne Zeitverzögerung.
Ob man das mit dem Grau besser machen kann weiß ich nicht, mir fällt auch keine andere Lösung ein...
Edit: Mir ist grade noch was eingefallen, aber ich weiß nicht wie schwierig es ist sowas einzubauen. (kenne mich mit Webentwicklung nicht aus)
Vllt eine Art Archiv mit in dem man alle Bilder durchblättern kann die hochgeladen wurden. (ähnlich wie Pr0gramm mit Kommentarfunktion usw).
Die Thumbnails sind dafür ja schon vorhanden.