Jump to content

Conway's Game of Life - help on graphical improvement


Recommended Posts

Hello, I tried to adapt the script from this link (https://rosettacode.org/wiki/Conway's_Game_of_Life#BASIC256) to AutoIt.
Even though it works, the graphics are not fluid and tend to flicker
is there any graphics expert who can suggest a way to get a better result?
Thanks in advance to those who want to help.

; Conway's_Game_of_Life
; code from https://rosettacode.org/wiki/Conway%27s_Game_of_Life#BASIC256

#include <GDIPlus.au3>

_GDIPlus_Startup()
OnAutoItExitRegister("_Terminate")

Global $iX = 59, $iY = 35, $iH = 8

; fastgraphics
Global $graphwidth = $iX * $iH
Global $graphheight = $iY * $iH
Global $color, $hMain
Global Enum $black, $purple, $green, $red, $yellow
Global $aColors[] = [0xFF000000, 0xFFFF00FF, 0xFF00FF00, 0xFFFF0000, 0xFFFFFF00]

Global $hGraphics, $hColor

_GraphSize($graphwidth, $graphheight)

Global $aC[$iX][$iY], $aCN[$iX][$iY], $aCL[$iX][$iY]

; Thunderbird methuselah
$aC[$iX / 2 - 1][$iY / 3 + 1] = 1
$aC[$iX / 2][$iY / 3 + 1] = 1
$aC[$iX / 2 + 1][$iY / 3 + 1] = 1
$aC[$iX / 2][$iY / 3 + 3] = 1
$aC[$iX / 2][$iY / 3 + 4] = 1
$aC[$iX / 2][$iY / 3 + 5] = 1

$iS = 0
Do
    $color = $black
    rect(0, 0, $graphwidth, $graphheight) ; erase the screen
    $alive = 0
    $stable = 1
    $iS = $iS + 1
    For $y = 0 To $iY - 1
        For $x = 0 To $iX - 1
            $xm1 = Mod(($x - 1 + $iX), $iX)
            $xp1 = Mod(($x + 1 + $iX), $iX)
            $ym1 = Mod(($y - 1 + $iY), $iY)
            $yp1 = Mod(($y + 1 + $iY), $iY)
            $aCN[$x][$y] = $aC[$xm1][$y] + $aC[$xp1][$y]
            $aCN[$x][$y] = $aC[$xm1][$ym1] + $aC[$x][$ym1] + $aC[$xp1][$ym1] + $aCN[$x][$y]
            $aCN[$x][$y] = $aC[$xm1][$yp1] + $aC[$x][$yp1] + $aC[$xp1][$yp1] + $aCN[$x][$y]
            If $aC[$x][$y] = 1 Then
                If $aCN[$x][$y] < 2 Or $aCN[$x][$y] > 3 Then
                    $aCN[$x][$y] = 0
                Else
                    $aCN[$x][$y] = 1
                    $alive = $alive + 1
                EndIf
            Else
                If $aCN[$x][$y] = 3 Then
                    $aCN[$x][$y] = 1
                    $alive = $alive + 1
                Else
                    $aCN[$x][$y] = 0
                EndIf
            EndIf
            If $aC[$x][$y] Then
                If $aCN[$x][$y] Then
                    If $aCL[$x][$y] Then $color = $purple ; adult
                    If Not $aCL[$x][$y] Then $color = $green ; newborn
                Else
                    If $aCL[$x][$y] Then $color = $red ; old
                    If Not $aCL[$x][$y] Then $color = $yellow ; shortlived
                EndIf
                rect($x * $iH, $y * $iH, $iH, $iH)
            EndIf
        Next ; $x
    Next ; $y
    ; refresh
    ; pause 0.06
    ; Copy arrays
    For $i = 0 To $iX - 1
        For $j = 0 To $iY - 1
            If $aCL[$i][$j] <> $aCN[$i][$j] Then $stable = 0
            $aCL[$i][$j] = $aC[$i][$j]
            $aC[$i][$j] = $aCN[$i][$j]
        Next ; $j
    Next ; $i
Until Not $alive Or $stable

If Not $alive Then
    $sMsg = "Died in " & $iS & " iterations"
    ; $color = $black
    ; rect(0, 0, $graphwidth, $graphheight)
    ; refresh
Else
    $sMsg = "Stabilized in " & ($iS - 2) & " iterations"
EndIf

MsgBox(0, "job done", $sMsg)

Func _GraphSize($graphwidth, $graphheight)
    $hMain = GUICreate("Conway's_Game_of_Life", $graphwidth, $graphheight)
    GUISetBkColor(0)
    GUISetState(@SW_SHOW, $hMain)
    $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hMain) ; create a graphics on the gui
    $hColor = _GDIPlus_BrushCreateSolid(0xFFFFFFFF) ; create a brush
EndFunc   ;==>_GraphSize

Func rect($x, $y, $w, $h)
    _GDIPlus_BrushSetSolidColor($hColor, $aColors[$color])
    _GDIPlus_GraphicsFillRect($hGraphics, _
            $x, _ ;  Horizontal pixel position
            $y, _ ;  Vertical pixel position
            $w, $h, _ ; pixel sides
            $hColor)
EndFunc   ;==>rect

Func _Terminate()
    ; Clean up resources
    _GDIPlus_GraphicsDispose($hGraphics)
    _GDIPlus_BrushDispose($hColor)
    _GDIPlus_Shutdown()
    Exit
EndFunc   ;==>_Terminate

 

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Link to post
Share on other sites

Try this:

; Conway's_Game_of_Life
; code from https://rosettacode.org/wiki/Conway%27s_Game_of_Life#BASIC256

#include <GDIPlus.au3>
#include <WindowsConstants.au3>

_GDIPlus_Startup()
OnAutoItExitRegister("_Terminate")

Global $iX = 59, $iY = 35, $iH = 8

; fastgraphics
Global $graphwidth = $iX * $iH
Global $graphheight = $iY * $iH
Global $color, $hMain
Global Enum $black, $purple, $green, $red, $yellow
Global $aColors[] = [0xFF000000, 0xFFFF00FF, 0xFF00FF00, 0xFFFF0000, 0xFFFFFF00]

Global $hGraphics, $hColor, $hDC, $hHBitmap, $hDC_backbuffer, $DC_obj

_GraphSize($graphwidth, $graphheight)

Global $aC[$iX][$iY], $aCN[$iX][$iY], $aCL[$iX][$iY]

; Thunderbird methuselah
$aC[$iX / 2 - 1][$iY / 3 + 1] = 1
$aC[$iX / 2][$iY / 3 + 1] = 1
$aC[$iX / 2 + 1][$iY / 3 + 1] = 1
$aC[$iX / 2][$iY / 3 + 3] = 1
$aC[$iX / 2][$iY / 3 + 4] = 1
$aC[$iX / 2][$iY / 3 + 5] = 1

$iS = 0
Do
    $color = $black
    ;rect(0, 0, $graphwidth, $graphheight) ; erase the screen
    _WinAPI_BitBlt($hDC_backbuffer, 0, 0, $graphwidth, $graphheight, $hDC_backbuffer, 0, 0, $BLACKNESS)
    $alive = 0
    $stable = 1
    $iS = $iS + 1
    For $y = 0 To $iY - 1
        For $x = 0 To $iX - 1
            $xm1 = Mod(($x - 1 + $iX), $iX)
            $xp1 = Mod(($x + 1 + $iX), $iX)
            $ym1 = Mod(($y - 1 + $iY), $iY)
            $yp1 = Mod(($y + 1 + $iY), $iY)
            $aCN[$x][$y] = $aC[$xm1][$y] + $aC[$xp1][$y]
            $aCN[$x][$y] = $aC[$xm1][$ym1] + $aC[$x][$ym1] + $aC[$xp1][$ym1] + $aCN[$x][$y]
            $aCN[$x][$y] = $aC[$xm1][$yp1] + $aC[$x][$yp1] + $aC[$xp1][$yp1] + $aCN[$x][$y]
            If $aC[$x][$y] = 1 Then
                If $aCN[$x][$y] < 2 Or $aCN[$x][$y] > 3 Then
                    $aCN[$x][$y] = 0
                Else
                    $aCN[$x][$y] = 1
                    $alive = $alive + 1
                EndIf
            Else
                If $aCN[$x][$y] = 3 Then
                    $aCN[$x][$y] = 1
                    $alive = $alive + 1
                Else
                    $aCN[$x][$y] = 0
                EndIf
            EndIf
            If $aC[$x][$y] Then
                If $aCN[$x][$y] Then
                    If $aCL[$x][$y] Then $color = $purple ; adult
                    If Not $aCL[$x][$y] Then $color = $green ; newborn
                Else
                    If $aCL[$x][$y] Then $color = $red ; old
                    If Not $aCL[$x][$y] Then $color = $yellow ; shortlived
                EndIf
;~                 rect($x * $iH, $y * $iH, $iH, $iH)
                _GDIPlus_BrushSetSolidColor($hColor, $aColors[$color])
                DllCall($__g_hGDIPDll, "int", "GdipFillEllipse", "handle", $hGraphics, "handle", $hColor, "float", $x * $iH, "float", $y * $iH, _
                           "float", $iH, "float", $iH)
            EndIf
        Next ; $x
    Next ; $y
    _WinAPI_BitBlt($hDC, 0, 0, $graphwidth, $graphheight, $hDC_backbuffer, 0, 0, $SRCCOPY) ;blit drawn bitmap to GUI
    ; refresh
    ; pause 0.06
    Sleep(50)
    ; Copy arrays
    For $i = 0 To $iX - 1
        For $j = 0 To $iY - 1
            If $aCL[$i][$j] <> $aCN[$i][$j] Then $stable = 0
            $aCL[$i][$j] = $aC[$i][$j]
            $aC[$i][$j] = $aCN[$i][$j]
        Next ; $j
    Next ; $i
Until Not $alive Or $stable

If Not $alive Then
    $sMsg = "Died in " & $iS & " iterations"
    ; $color = $black
    ; rect(0, 0, $graphwidth, $graphheight)
    ; refresh
Else
    $sMsg = "Stabilized in " & ($iS - 2) & " iterations"
EndIf

MsgBox(0, "job done", $sMsg)

Func _GraphSize($graphwidth, $graphheight)
    $hMain = GUICreate("Conway's_Game_of_Life", $graphwidth, $graphheight)
    GUISetBkColor(0)
    GUISetState(@SW_SHOW, $hMain)
    $hDC = _WinAPI_GetDC($hMain)
    $hHBitmap = _WinAPI_CreateCompatibleBitmap($hDC, $graphwidth, $graphheight)
    $hDC_backbuffer = _WinAPI_CreateCompatibleDC($hDC)
    $DC_obj = _WinAPI_SelectObject($hDC_backbuffer, $hHBitmap)
    $hGraphics = _GDIPlus_GraphicsCreateFromHDC($hDC_backbuffer)
    _GDIPlus_GraphicsSetSmoothingMode($hGraphics, $GDIP_SMOOTHINGMODE_HIGHQUALITY)
    _GDIPlus_GraphicsSetPixelOffsetMode($hGraphics, $GDIP_PIXELOFFSETMODE_HIGHQUALITY)
    $hColor = _GDIPlus_BrushCreateSolid(0xFFFFFFFF) ; create a brush
EndFunc   ;==>_GraphSize

Func rect($x, $y, $w, $h)
;~     _GDIPlus_BrushSetSolidColor($hColor, $aColors[$color])
;~     _GDIPlus_GraphicsFillRect($hGraphics, _
;~             $x, _ ;  Horizontal pixel position
;~             $y, _ ;  Vertical pixel position
;~             $w, $h, _ ; pixel sides
;~             $hColor)
EndFunc   ;==>rect

Func _Terminate()
    ; Clean up resources
    _WinAPI_SelectObject($hDC_backbuffer, $DC_obj)
    _WinAPI_DeleteDC($hDC_backbuffer)
    _WinAPI_DeleteObject($hHBitmap)
    _WinAPI_ReleaseDC($hMain, $hDC)
    _GDIPlus_GraphicsDispose($hGraphics)
    _GDIPlus_BrushDispose($hColor)
    _GDIPlus_Shutdown()
    GUIDelete($hColor)
    Exit
EndFunc   ;==>_Terminate

😉

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...