Langton-Ameise

  • Hi,

    basierend auf einem alten FreeBasic - Programm von mir, habe ich die Langton-Ameise nach AutoIt portiert :D
    Wer keine Ahnung hat was eine Langton-Ameise ist -> Wikipedia

    Die erste Version flackert sehr stark, deswegen hab ich noch eine in GDI gemacht, würde mich trotzdem mal interessieren warum das so ist. Und noch eine Frage: Ist Doublebuffering in AutoIt möglich ?

    GUICtrlCreateGraphic - (!)Flackert stark(!)

    Spoiler anzeigen
    [autoit]

    ;#NoTrayIcon

    [/autoit] [autoit][/autoit] [autoit]

    Opt("MustDeclareVars",1)
    Opt("GUIOnEventMode",1)

    [/autoit] [autoit][/autoit] [autoit]

    Const $GUICLOSE = -3

    [/autoit] [autoit][/autoit] [autoit]

    Const $GUI_GR_COLOR = 8
    Const $GUI_GR_RECT = 10
    Const $GUI_GR_REFRESH = 22

    [/autoit] [autoit][/autoit] [autoit]

    Const $TITLE = "template"
    Const $WIDTH = 500
    Const $HEIGHT = 500

    [/autoit] [autoit][/autoit] [autoit]

    Const $STEP = 50
    Const $RECTSIZE = 5

    [/autoit] [autoit][/autoit] [autoit]

    Local $Graphics

    [/autoit] [autoit][/autoit] [autoit]

    Const $WHITE = "0xFFFFFF"
    Const $BLACK = "0x000000"
    Local $Matrix[Round($WIDTH/$RECTSIZE)][Round($HEIGHT/$RECTSIZE)]

    [/autoit] [autoit][/autoit] [autoit]

    Enum $DOWN,$RIGHT,$UP,$LEFT
    Local $Direction = 0
    Local $Pos[2]
    Local $Max[2] = [UBound($Matrix,1)-1,UBound($Matrix,2)-1]

    [/autoit] [autoit][/autoit] [autoit]

    main()
    Func main()

    For $x=0 To $Max[0] Step 1
    For $y=0 To $Max[1] Step 1
    $Matrix[$x][$y] = $WHITE
    Next
    Next
    $Pos[0] = Round($Max[0]/2)
    $Pos[1] = Round($Max[1]/2)
    $Matrix[$Pos[0]][$Pos[1]] = $BLACK

    [/autoit] [autoit][/autoit] [autoit]

    GUICreate($TITLE,$WIDTH,$HEIGHT)
    GUISetOnEvent($GUICLOSE,"_EXIT")

    $Graphics = GUICtrlCreateGraphic(0,0,$WIDTH,$HEIGHT)
    GUICtrlSetBkColor ( $Graphics, $WHITE )

    AdlibEnable("_MOVE",$STEP)

    GUISetState(@SW_SHOWNORMAL)
    While 1
    Sleep(1000)
    GUICtrlSetGraphic($Graphics,$GUI_GR_REFRESH)
    WEnd
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _EXIT()
    Exit
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _MOVE()
    Switch $Direction
    Case $DOWN
    $Pos[1] += 1
    Case $RIGHT
    $Pos[0] += 1
    Case $UP
    $Pos[1] -= 1
    Case $LEFT
    $Pos[0] -= 1
    EndSwitch

    If $Pos[0] >= $Max[0] Or $Pos[0] <= 0 Or $Pos[1] >= $Max[1] Or $Pos[1] <= 0 Then
    MsgBox(32,$TITLE,"Ende der Simulation...")
    _EXIT()
    EndIf

    If $Matrix[$Pos[0]][$Pos[1]] == $BLACK Then
    $Matrix[$Pos[0]][$Pos[1]] = $WHITE
    GUICtrlSetGraphic($Graphics,$GUI_GR_COLOR,$WHITE,$WHITE)
    GUICtrlSetGraphic($Graphics,$GUI_GR_RECT,$Pos[0]*$RECTSIZE,$Pos[1]*$RECTSIZE,$RECTSIZE,$RECTSIZE)

    If $Direction == $LEFT Then
    $Direction = $DOWN
    Else
    $Direction += 1
    EndIf
    Else
    $Matrix[$Pos[0]][$Pos[1]] = $BLACK
    GUICtrlSetGraphic($Graphics,$GUI_GR_COLOR,$BLACK,$BLACK)
    GUICtrlSetGraphic($Graphics,$GUI_GR_RECT,$Pos[0]*$RECTSIZE,$Pos[1]*$RECTSIZE,$RECTSIZE,$RECTSIZE)

    If $Direction == $DOWN Then
    $Direction = $LEFT
    Else
    $Direction -= 1
    EndIf
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    GUICtrlSetGraphic($Graphics,$GUI_GR_REFRESH)
    EndFunc

    [/autoit]

    GDI+
    - hier ist es möglich mit STRG+J Schritte zu überspringen (man hat ja nicht den ganzen Tag Zeit :D )

    Spoiler anzeigen
    [autoit]

    ;#NoTrayIcon
    #Include <GDIPlus.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Opt("MustDeclareVars",1)
    Opt("GUIOnEventMode",1)
    _GDIPlus_Startup()

    [/autoit] [autoit][/autoit] [autoit]

    Const $GUI_EVENT_CLOSE = -3
    Const $GUI_EVENT_RESTORE = -5

    [/autoit] [autoit][/autoit] [autoit]

    Const $TITLE = "Langton-Ameise"
    Const $WIDTH = 500
    Const $HEIGHT = 500

    [/autoit] [autoit][/autoit] [autoit]

    ; Geschwindigkeit der Steps (kleiner ist schneller)
    Const $STEP = 50
    ; Größe der Klötze in pixel
    Const $RECTSIZE = 5

    [/autoit] [autoit][/autoit] [autoit]

    ; Interne Berechnung
    Local $Matrix[Round($WIDTH/$RECTSIZE)][Round($HEIGHT/$RECTSIZE)]
    Enum $DOWN,$RIGHT,$UP,$LEFT
    Local $Direction = 0
    Local $Pos[2]
    Local $Max[2] = [UBound($Matrix,1)-1,UBound($Matrix,2)-1]

    [/autoit] [autoit][/autoit] [autoit]

    ; Ausgabe (GDI+)
    Local $Graphics
    Enum $BLACK,$WHITE
    Local $Brushes[2] = [_GDIPlus_BrushCreateSolid("0xFF000000"),_GDIPlus_BrushCreateSolid("0xFFFFFFFF")]

    [/autoit] [autoit][/autoit] [autoit]

    main()
    Func main()
    Local $timer

    For $x=0 To $Max[0] Step 1
    For $y=0 To $Max[1] Step 1
    $Matrix[$x][$y] = $WHITE
    Next
    Next
    $Pos[0] = Round($Max[0]/2)
    $Pos[1] = Round($Max[1]/2)
    $Matrix[$Pos[0]][$Pos[1]] = $BLACK

    [/autoit] [autoit][/autoit] [autoit]

    $Graphics = _GDIPlus_GraphicsCreateFromHWND(GUICreate($TITLE,$WIDTH,$HEIGHT))
    GUISetOnEvent($GUI_EVENT_CLOSE,"_EXIT")
    GUISetOnEvent($GUI_EVENT_RESTORE,"_RESTORE")
    GUISetBkColor("0xFFFFFF")

    AdlibEnable("_MOVE",$STEP)

    HotKeySet("^j","jump")
    GUISetState(@SW_SHOWNORMAL)
    While 1
    Sleep(1000)
    WEnd
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _EXIT()
    _GDIPlus_Shutdown()
    Exit
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _MOVE()
    Switch $Direction
    Case $DOWN
    $Pos[1] += 1
    Case $RIGHT
    $Pos[0] += 1
    Case $UP
    $Pos[1] -= 1
    Case $LEFT
    $Pos[0] -= 1
    EndSwitch

    If $Pos[0] >= $Max[0] Or $Pos[0] <= 0 Or $Pos[1] >= $Max[1] Or $Pos[1] <= 0 Then
    If MsgBox(36,$TITLE,"Ende der Simulation"&@CRLF&"Nochmal?") == 6 Then
    For $x=0 To $Max[0] Step 1
    For $y=0 To $Max[1] Step 1
    $Matrix[$x][$y] = $WHITE
    Next
    Next
    $Pos[0] = Round($Max[0]/2)
    $Pos[1] = Round($Max[1]/2)
    $Matrix[$Pos[0]][$Pos[1]] = $BLACK
    _RESTORE()
    Return
    Else
    _EXIT()
    EndIf
    EndIf

    If $Matrix[$Pos[0]][$Pos[1]] == $BLACK Then
    $Matrix[$Pos[0]][$Pos[1]] = $WHITE
    _GDIPlus_GraphicsFillRect($Graphics,$Pos[0]*$RECTSIZE,$Pos[1]*$RECTSIZE,$RECTSIZE,$RECTSIZE,$Brushes[$WHITE])

    If $Direction == $LEFT Then
    $Direction = $DOWN
    Else
    $Direction += 1
    EndIf
    Else
    $Matrix[$Pos[0]][$Pos[1]] = $BLACK
    _GDIPlus_GraphicsFillRect($Graphics,$Pos[0]*$RECTSIZE,$Pos[1]*$RECTSIZE,$RECTSIZE,$RECTSIZE,$Brushes[$BLACK])

    If $Direction == $DOWN Then
    $Direction = $LEFT
    Else
    $Direction -= 1
    EndIf
    EndIf
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _RESTORE()
    AdlibDisable()
    For $x=0 To $Max[0] Step 1
    For $y=0 To $Max[1] Step 1
    If $Matrix[$x][$y] == $BLACK Then
    _GDIPlus_GraphicsFillRect($Graphics,$x*$RECTSIZE,$y*$RECTSIZE,$RECTSIZE,$RECTSIZE,$Brushes[$BLACK])
    Else
    _GDIPlus_GraphicsFillRect($Graphics,$x*$RECTSIZE,$y*$RECTSIZE,$RECTSIZE,$RECTSIZE,$Brushes[$WHITE])
    EndIf
    Next
    Next
    AdlibEnable("_MOVE",$STEP)
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func jump()
    Local $input

    AdlibDisable()
    $input = InputBox($TITLE,"Wie viele Schritte sollen Übersprungen werden?","","",120,140)
    If $input <> "" Then
    $input = Number($input)
    If $input <> 0 Then

    For $i=0 To $input Step 1
    _MOVE()
    Next
    _RESTORE()

    [/autoit] [autoit][/autoit] [autoit]

    EndIf
    EndIf
    AdlibEnable("_MOVE",$STEP)
    EndFunc

    [/autoit]

    2 Mal editiert, zuletzt von bluelamp (28. Oktober 2008 um 21:26)

  • ich glaube wenn die ameise den Rand des Fensters erreicht entsteht ein Fehler.

    Sonst aber sehr gut!

    gruß
    jendrik

  • Zitat

    ich glaube wenn die ameise den Rand des Fensters erreicht entsteht ein Fehler.

    Du hast wahrscheinlich das erste Script ausprobiert... das flackert sowieso, lohnt sich also nicht da eine Abfrage einzubauen, beim zweiten ist der Fehler schon behoben und man bekommt die Frage gestellt ob man die Simulation wiederholen möchte.