Game Of Life - Gui ActiveX html [V2.beta.3]

Post your working scripts, libraries and tools.
AHK_user
Posts: 515
Joined: 04 Dec 2015, 14:52
Location: Belgium

Game Of Life - Gui ActiveX html [V2.beta.3]

13 Feb 2022, 17:20

Conway's Game of Life is a cellular automaton devised by the British mathematician John Horton Conway in 1970.
https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life

1. Any live cell with two or three live neighbours survives.
2. Any dead cell with three live neighbours becomes a live cell.
3. All other live cells die in the next generation. Similarly, all other dead cells stay dead.

With different pixel shapes and some simple rules you get some interesting moving shapes

The rendering of this automaton is a little bit slow (2500 images), maybe interestin to create it with GDIP and see the difference in speed.

- Add the black_pixel.png to an Images folder.
- Disable the run checkbox and click on the white surface to draw your own images and press run to see them evolving and moving.

Update: changed controls to new gui
GOL.png
GOL.png (13.76 KiB) Viewed 2650 times

Code: Select all

#Requires AutoHotKey v2.0-beta.3
; when the pixels are high, best to prevent updating of activeX control
#SingleInstance force

A_MaxHotkeysPerInterval := 500
Speed := 00
NumbImages:=2
NumbLoops:= 10000000
xMax := 100
yMax := 100
Pixelsize := 8
global MyGui := Gui()
myGui.MarginX := 0
myGui.MarginY := 0
global WB := MyGui.Add("ActiveX", "w" xMax*Pixelsize " h" yMax*Pixelsize, "mshtml:").Value

; goEdSpeed := MyGui.AddSlider("yp xp+50 w100 Range0-1000 ToolTip", Speed)
; MyGui.Add("Button", "xm w50", "Clear").OnEvent("Click", ButtonClear)
; MyGui.Add("Button", "yp xp+60 w50", "Ex 1").OnEvent("Click", ButtonEx1)
; MyGui.Add("Button", "yp xp+60 w50", "Reload").OnEvent("Click", ButtonReload)
; goOutput := MyGui.AddEdit("w100", 0)
; goOutput2 := MyGui.AddEdit("w100", 0 )
MyGui.OnEvent("Close", Gui_Close)
MyGui.OnEvent("Escape", Gui_Close)

Gui3 := Gui("+AlwaysOnTop -DPIScale +ToolWindow")
Gui3.Title := "Settings"
Gui3.AddGroupBox("w100 h50", "Speed")
goSpeed := Gui3.AddSlider("yp+14 xp+6 w88 -Tabstop tooltip range0-1000", Speed)
goButtonRun := Gui3.AddButton("xm w100", "Stop")
goButtonRun.OnEvent("Click", ButtonRun)
goButtonClear := Gui3.AddButton("w100", "Clear")
goButtonClear.OnEvent("Click", ButtonClear)
goButtonReload := Gui3.AddButton("w100", "Reload")
goButtonReload.OnEvent("Click", ButtonReload)
goOutput := Gui3.AddEdit("w100", 0)
goOutput2 := Gui3.AddEdit("w100", 0)
goOutput3 := Gui3.AddEdit("w100", xMax "x" yMax)

global Pixels := Map()

; Construction the grid
loop xMax{
    xPos := A_Index
    Pixels[A_index] := Map()
    loop yMax {
        yPos := A_Index
        Pixels[xPos][yPos] := Object()
        Pixels[xPos][yPos].state := 0
        Pixels[xPos][yPos].state := Random(0,1)
        Pixels[xPos][yPos].state := (InStr(xPos, 1)) or (InStr(xPos, 1)) ? 1 : 0
        img := WB.CreateElement("img")
        img.style.position := "absolute"
        Pixels[xPos][yPos].img := img
        img.src := A_ScriptDir "\Images\Black_pixel.png"
        img.style.left := (xPos-1)*Pixelsize "px"
        img.style.top := (yPos-1)*Pixelsize "px"
        img.style.height := Pixelsize "px"
        img.style.width := Pixelsize "px"
        WB.Body.AppendChild(img)
        if !Pixels[xPos][yPos].state{
            img.style.visibility := "hidden"
        }
    }
}
; Pixels[2][1].state := 1
; Pixels[2][2].state := 1
; Pixels[2][3].state := 1

MyGui.Show("x10")
MyGui.GetPos(&XWin, &YWin, &WWin, &HWin)
Gui3.Show("NA w120 x" XWin + WWin " y" YWin)

loop xMax {
    xPos := A_Index
    loop yMax {
        yPos := A_Index
        if !Pixels[xPos][yPos].state {
            Pixels[xPos][yPos].img.style.visibility := "hidden"
        } else {
            Pixels[xPos][yPos].img.style.visibility := "visible"
        }
    }
}
Time := A_TickCount
loop{
    
    loop {
        if (goButtonRun.Text = "Stop") {
            break
        }
    }

    if (goSpeed.Value != 0) {
        Sleep(goSpeed.Value)
    }
    loop xMax {
        xPos := A_Index
        loop yMax {
            yPos := A_Index
            Neighbourgs := CountNeigbourgs(xPos, Ypos)
            if Pixels[xPos][yPos].state{ ; live cells stay alive if 2 or 3 neighbourgs
                if (Neighbourgs = 2 or Neighbourgs = 3) { 
                    Pixels[xPos][yPos].stateNew := 1
                } else {
                    Pixels[xPos][yPos].stateNew := 0
                }
            }
            else { ; Death cells come alive if 3 neighbourgs
                if (Neighbourgs = 3) {
                    Pixels[xPos][yPos].stateNew := 1
                } else {
                    Pixels[xPos][yPos].stateNew := 0
                }
            }

        }
    }
;update Pixels
    loop xMax {
        xPos := A_Index
        loop yMax {
            yPos := A_Index
            if (Pixels[xPos][yPos].stateNew != Pixels[xPos][yPos].state){
                if !Pixels[xPos][yPos].stateNew {
                    Pixels[xPos][yPos].img.style.visibility := "hidden"
                } else {
                    Pixels[xPos][yPos].img.style.visibility := "visible"
                } 
            }
            Pixels[xPos][yPos].state := Pixels[xPos][yPos].stateNew
        }
    }
    if (A_Tickcount != Time) {
        goOutput.Value := Round(1000 / (A_Tickcount - Time), 3)
        goOutput2.Value := (goOutput2.Value * (A_index - 1) + 1000 / (A_Tickcount - Time)) / A_index
    }

    Time := A_TickCount
}

Return

CountNeigbourgs(xPos,Ypos){
    Result := 0
    Try Result += Pixels[xPos - 1][yPos - 1].State
    Try Result += Pixels[xPos - 0][yPos - 1].State
    Try Result += Pixels[xPos + 1][yPos - 1].State
    Try Result += Pixels[xPos - 1][yPos + 0].State
    Try Result += Pixels[xPos + 1][yPos + 0].State
    Try Result += Pixels[xPos - 1][yPos + 1].State
    Try Result += Pixels[xPos + 0][yPos + 1].State
    Try Result += Pixels[xPos + 1][yPos + 1].State
    ;MsgBox(Result)
    return Result
}

~LButton::{
    global
    MouseGetPos(&MouseX1, &MouseY1, &MouseWin, &MouseControl)
    if (MouseControl = "AtlAxWin1") {
        ControlGetPos(&ControlX, &ControlY, , , MouseControl, MouseWin)
        MouseX := Round((MouseX1 - ControlX)/Pixelsize+.5)
        MouseY := Round((MouseY1 - ControlY) / Pixelsize+0.5)
        ;ToolTip(MouseX "," MouseY "-" Pixels[MouseX][MouseY].state)
        if(Pixels[MouseX][MouseY].HasOwnProp("state")) {
	        Pixels[MouseX][MouseY].state := !Pixels[MouseX][MouseY].state
        } else {
	        Pixels[MouseX][MouseY].state := true
        }
        if !Pixels[MouseX][MouseY].state {
            Pixels[MouseX][MouseY].img.style.visibility := "hidden"
        } else {
            Pixels[MouseX][MouseY].img.style.visibility := "visible"
        }
        

    }
}
ButtonClear(*){
    global
    goButtonRun.Text := "Start"
    Sleep(500)
    loop xMax {
        xPos := A_Index
        loop yMax {
            yPos := A_Index
            Pixels[xPos][yPos].state := 0
            if !Pixels[xPos][yPos].state {
                Pixels[xPos][yPos].img.style.visibility := "hidden"
            } else {
                Pixels[xPos][yPos].img.style.visibility := "visible"
            }
        }
    } 
}

ButtonEx1(*){
    global
    GOL_Clean()
    Pixels[2][9].state := 1
    Pixels[3][7].state := 1
    Pixels[3][9].state := 1
    Pixels[4][8].state := 1
    Pixels[4][9].state := 1
    GOL_Update()
}

ButtonRun(*) {
    if (goButtonRun.text = "Stop") {
        goButtonRun.text := "Start"
    } else {
        goButtonRun.text := "Stop"
    }
}

Gui_Close(*) {
    ExitApp
}
ButtonReload(*) {
    Reload
}

GOL_Clean() {
    global
    loop xMax {
        xPos := A_Index
        loop yMax {
            yPos := A_Index
            Pixels[xPos][yPos].state := 0
        }
    }
}

GOL_Update(){
    global
    loop xMax {
        xPos := A_Index
        loop yMax {
            yPos := A_Index
            
            if !Pixels[xPos][yPos].state {
                Pixels[xPos][yPos].img.style.visibility := "hidden"
            } else {
                Pixels[xPos][yPos].img.style.visibility := "visible"
            }
            
        }
    }
}
Attachments
Black_pixel.png
Black_pixel.png (83 Bytes) Viewed 2650 times
Last edited by AHK_user on 06 Mar 2022, 14:39, edited 2 times in total.
User avatar
Joe Glines
Posts: 771
Joined: 30 Sep 2013, 20:49
Location: Dallas
Contact:

Re: Game Of Life - Gui ActiveX html [V2.beta.3]

13 Feb 2022, 21:20

Dimitri showed these to me during this video (Game of life starts at 24:31.

So cool!
Sign-up for the 🅰️HK Newsletter

ImageImageImageImage:clap:
AHK Tutorials:Web Scraping | | Webservice APIs | AHK and Excel | Chrome | RegEx | Functions
Training: AHK Webinars Courses on AutoHotkey :ugeek:
YouTube

:thumbup: Quick Access Popup, the powerful Windows folders, apps and documents launcher!
User avatar
tadamm
Posts: 40
Joined: 27 Sep 2020, 11:41

Re: Game Of Life - Gui ActiveX html [V2.beta.3]

16 Feb 2022, 15:40

Got this error. Once I dismiss it it works fine for some reason. Cool game though. Also cant get to pick where I want my dots.
pixels[mouseX][MouseY].state := !pixel[mouseX][MouseY].state
Attachments
Capture.JPG
Capture.JPG (36.27 KiB) Viewed 2439 times
Capture.JPG
Capture.JPG (36.27 KiB) Viewed 2439 times
AHK_user
Posts: 515
Joined: 04 Dec 2015, 14:52
Location: Belgium

Re: Game Of Life - Gui ActiveX html [V2.beta.3]

21 Feb 2022, 12:04

I have also created a GDIP version that works even better.
It also has build in interesting shapes when you rightclick (it is advised to add these when pausing the game)
- This needs de GDIP_All library https://raw.githubusercontent.com/mmikeww/AHKv2-Gdip/master/Gdip_All.ahk
- No image files
GOL_GDIP.png
GOL_GDIP.png (45.17 KiB) Viewed 2367 times

Code: Select all

;Written by AHK_User
#SingleInstance Force
;#NoEnv
;SetBatchLines -1

; Uncomment if Gdip.ahk is not in your standard library
#Include ../Gdip_All.ahk

; Start gdi+
If !pToken := Gdip_Startup()
{
	MsgBox "Gdiplus failed to start. Please ensure you have gdiplus on your system"
	ExitApp
}

OnExit(Gui_Close)


xMax := 100
yMax := 100
Pixelsize := 8
speed:= 0

global Pixels := Map()
; Construction the grid
loop xMax {
   xPos := A_Index
   Pixels[A_index] := Map()
   loop yMax {
      yPos := A_Index
      Pixels[xPos][yPos] := Object()
      Pixels[xPos][yPos].state := 0
      Pixels[xPos][yPos].state := Random(0, 1)
      Pixels[xPos][yPos].state := (InStr(xPos,1)) or (InStr(xPos, 1)) ? 1 : 0
   }
}

; Create a layered window (+E0x80000 : must be used for UpdateLayeredWindow to work!) that is always on top (+AlwaysOnTop), has no taskbar entry or caption
;AHK v1

Gui1 := Gui("+AlwaysOnTop -DPIScale +Resize")
Gui1.Width := xMax * Pixelsize
Gui1.Height := yMax * Pixelsize

; Set the width and height we want as our drawing area, to draw everything in. This will be the dimensions of our bitmap
Gui1.OnEvent("Close", Gui_Close)
Gui1.OnEvent("Escape", Gui_Close)
Gui1.OnEvent("Size", Gui_Size)


Gui2 := Gui("+Parent" Gui1.hwnd " -Caption +E0x80000 +LastFound +ToolWindow +OwnDialogs")
Gui2.OnEvent("Close", Gui_Close)
Gui2.OnEvent("Escape", Gui_Close)


Gui3 := Gui("+AlwaysOnTop -DPIScale +ToolWindow")
Gui3.Opt("+Owner" Gui1.hwnd)
Gui3.Title := "Settings"
Gui3.AddGroupBox("w100 h50","Speed")


goSpeed := Gui3.AddSlider("yp+14 xp+6 w88 -Tabstop tooltip range0-1000", Speed)
goButtonRun := Gui3.AddButton("xm w100","Stop")
goButtonRun.OnEvent("Click", ButtonRun)
goButtonClear := Gui3.AddButton("w100","Clear")
goButtonClear.OnEvent("Click", ButtonClear)
goButtonReload := Gui3.AddButton("w100", "Reload")
goButtonReload.OnEvent("Click", ButtonReload)
goOutput := Gui3.AddEdit("w100", 0)
goOutput2 := Gui3.AddEdit("w100", 0)
goOutput3 := Gui3.AddEdit("w100", xMax "x" yMax)
; Initialisation of GDIP
; Create a gdi bitmap with width and height of what we are going to draw into it. This is the entire drawing area for everything
hbm := CreateDIBSection(A_ScreenWidth+20, A_ScreenHeight+20)

; Get a device context compatible with the screen
hdc := CreateCompatibleDC()

; Select the bitmap into the device context
obm := SelectObject(hdc, hbm)

; Get a pointer to the graphics of the bitmap, for use with drawing functions
G := Gdip_GraphicsFromHDC(hdc)

; Set the smoothing mode to antialias = 4 to make shapes appear smother (only used for vector drawing and filling)
Gdip_SetSmoothingMode(G, 0)

; Create a slightly transparent (66) blue brush (ARGB = Transparency, red, green, blue) to draw a rectangle
pBrush := Gdip_BrushCreateSolid(0xff000000)
pBrushDeath := Gdip_BrushCreateSolid(0xffffffff)

Gui1.Show("NA w" Gui1.Width " h" Gui1.Height)
Gui1.GetPos(&XWin, &YWin, &WWin, &HWin)
Gui2.Show("NA")
; Add variables to keep track of offset
Gui3.OffsetX := WWin +10
Gui3.OffsetXRight := 10
Gui3.OffsetY := 0
Gui3.Show("NA w120 x" XWin + Gui3.OffsetX " y" YWin +Gui3.OffsetY)
OnMessage(0x0003, WM_MOVE)
GOL_Update()
GOL_UpdateStates()

Return

;#######################################################################

ButtonClear(*){
     global
     goButtonRun.Text := "Start"
     Sleep(500)
     loop xMax {
        xPos := A_Index
        loop yMax {
           yPos := A_Index
           Pixels[xPos][yPos].state := 0
        }
     } 
     GOL_Update()
     
}

ButtonReload(*){
   Reload
}
ButtonRun(*){
   if (goButtonRun.text = "Stop"){
      goButtonRun.text :="Start"
   }
   else{
         goButtonRun.text := "Stop"
   }
}

Escape::{
   Gui_Close()
   return
}
Gui_Close(*){
   global
   ; Delete the brush as it is no longer needed and wastes memory
   ; Gdip_DeleteBrush(pBrush)
   ; Gdip_DeleteBrush(pBrushDeath)
   ; Select the object back into the hdc
   SelectObject(Gui2.hwnd, obm)
   ; Now the bitmap may be deleted
   DeleteObject(hbm)
   ; Also the device context related to the bitmap may be deleted
   DeleteDC(hdc)
   ; The graphics may now be deleted
   ; Gdip_DeleteGraphics(G)
   Gdip_Shutdown(pToken)
   ExitApp
}

CountNeigbourgs(xPos, Ypos) {
   Result := 0
   Try Result += Pixels[xPos - 1][yPos - 1].State
   Try Result += Pixels[xPos - 0][yPos - 1].State
   Try Result += Pixels[xPos + 1][yPos - 1].State
   Try Result += Pixels[xPos - 1][yPos + 0].State
   Try Result += Pixels[xPos + 1][yPos + 0].State
   Try Result += Pixels[xPos - 1][yPos + 1].State
   Try Result += Pixels[xPos + 0][yPos + 1].State
   Try Result += Pixels[xPos + 1][yPos + 1].State
   ;MsgBox(Result)
   return Result
}

GOL_Update() {
   global
   loop xMax {
      xPos := A_Index
      loop yMax {
         yPos := A_Index
         Gdip_FillRectangle(G, pBrush, (xPos - 1) * Pixelsize, (yPos - 1) * Pixelsize, Pixelsize, Pixelsize)
         if !Pixels[xPos][yPos].state {
            Gdip_FillRectangle(G, pBrushDeath, (xPos - 1) * Pixelsize, (yPos - 1) * Pixelsize, Pixelsize, Pixelsize)
         }
      }
   }
   UpdateLayeredWindow(Gui2.hwnd, hdc, 0, 0, Gui1.Width, Gui1.Height)
}

GOL_UpdateStates(*){
   global
 Time :=A_TickCount
   loop {
      loop {
         if (goButtonRun.Text = "Stop") {
            break
         }
      }

      if (goSpeed.Value!=0){
         Sleep(goSpeed.Value)
      }
      
      loop xMax {
         xPos := A_Index
         loop yMax {
            yPos := A_Index
            Neighbourgs := CountNeigbourgs(xPos, Ypos)
            Pixels[xPos][yPos].stateNew := Pixels[xPos][yPos].state ? (Neighbourgs = 2 or Neighbourgs = 3 ? 1 : 0) : (Neighbourgs = 3 ? 1 : 0)
         }
      }
      Gdip_FillRectangle(G, pBrushDeath, 0, 0, xMax*Pixelsize, ymax*Pixelsize)
      loop xMax {
         xPos := A_Index
         loop yMax {
            yPos := A_Index
            if Pixels[xPos][yPos].stateNew {
               Gdip_FillRectangle(G, pBrush, (xPos - 1) * Pixelsize, (yPos - 1) * Pixelsize, Pixelsize, Pixelsize)
            }
            Pixels[xPos][yPos].state := Pixels[xPos][yPos].stateNew
         }
      }
      UpdateLayeredWindow(Gui2.hwnd, hdc, 0, 0, Gui1.Width, Gui1.Height)
      if (A_Tickcount !=Time){
         goOutput.Value := Round(1000 / (A_Tickcount - Time), 3)
         goOutput2.Value := (goOutput2.Value * (A_index - 1) + 1000 / (A_Tickcount - Time)) / A_index
      }
      
      Time := A_TickCount
   }

}

Gui_Size(GuiObj , MinMax, Width, Height){
   global

   GOL_UpdateSize(Width, Height)
   
   try{
      Gui3.Move(XWin + Gui3.OffsetX, YWin + Gui3.OffsetY)
   }
   
}

~LButton:: {
   global
   MouseGetPos(&MouseX1, &MouseY1, &MouseWinID, &MouseControl)
   
   if (WinGetTitle("ahk_id " MouseWinID) = Gui1.Title) {

      Gui1.GetPos(&XWin, &YWin, &WWin, &HWin)
      MouseX := Round((MouseX1) / Pixelsize + 0.5)
      MouseY := Round((MouseY1) / Pixelsize + 0.5)
      
      if (0< MouseX and MouseX < xMax and 0 < MouseY and MouseY < ymax){
         ;ToolTip(MouseX "," MouseY "-" Pixels[MouseX][MouseY].state)
         Pixels[MouseX][MouseY].state := !Pixels[MouseX][MouseY].state
         if !Pixels[MouseX][MouseY].state {
            Gdip_FillRectangle(G, pBrushDeath, (MouseX - 1) * Pixelsize, (MouseY - 1) * Pixelsize, Pixelsize, Pixelsize)
         } else {
            Gdip_FillRectangle(G, pBrush, (MouseX - 1) * Pixelsize, (MouseY - 1) * Pixelsize, Pixelsize, Pixelsize)
         }
         UpdateLayeredWindow(Gui2.hwnd, hdc, 0, 0, Gui1.Width, Gui1.Height)
      }
   }
}

~RButton:: {
   global
   MouseGetPos(&MouseX1, &MouseY1, &MouseWinID, &MouseControl)

   if (WinGetTitle("ahk_id " MouseWinID) = Gui1.Title) {

      Gui1.GetPos(&XWin, &YWin, &WWin, &HWin)
      MouseX := Round((MouseX1) / Pixelsize + 0.5)
      MouseY := Round((MouseY1) / Pixelsize + 0.5)

      if (0 < MouseX and MouseX < xMax and 0 < MouseY and MouseY < ymax) {
         MyMenu := Menu()
         MyMenu.Add("Block", AddGOL.Bind(MouseX,MouseY,"0000`n0110`n0110`n0000"))
         MyMenu.Add("Blinker", AddGOL.Bind(MouseX,MouseY,"00000`n00000`n01110`n00000`n00000"))
         MyMenu.Add("Toad", AddGOL.Bind(MouseX,MouseY,"000000`n000000`n001110`n011100`n000000"))
         MyMenu.Add("Glider", AddGOL.Bind(MouseX,MouseY,"00000`n00010`n010100`n0011100`n000000`n000000"))
         MyMenu.Add("R-pentomino", AddGOL.Bind(MouseX,MouseY,"000000`n00110`n01100`n00100`n000000"))
         MyMenu.Add("Lightweight spaceship", AddGOL.Bind(MouseX, MouseY, "0000000`n0011000`n0111100`n0110110`n0001100`n00000000"))
         MyMenu.Add("Infinitive growth 1", AddGOL.Bind(MouseX, MouseY, "0000000000`n0000000100`n0000010110`n0000010100`n0000010000`n0001000000`n010100000000`n0000000000"))
         MyMenu.Add("Gosper glider gun", AddGOL.Bind(MouseX, MouseY,"00000000000000000000000000000000000000`n00000000000000000000000001000000000000`n00000000000000000000000101000000000000`n00000000000001100000011000000000000110`n00000000000010001000011000000000000110`n01100000000100000100011000000000000000`n01100000000100010110000101000000000000`n00000000000100000100000001000000000000`n00000000000010001000000000000000000000`n00000000000001100000000000000000000000`n00000000000000000000000000000000000000`n" ))

         MyMenu.Show()
      }
   }
}

AddGOL(x , y, Shape, ItemName , ItemPos, MyMenu){

   Loop Parse Shape, "`n"{
      yPos := y+A_index-1
      Loop Parse A_LoopField{
         xpos := x - 1 + A_index
         if (A_LoopField=1){
            Pixels[xpos][yPos].state := 1
            Gdip_FillRectangle(G, pBrush, (xpos - 1) * Pixelsize, (yPos - 1) * Pixelsize, Pixelsize, Pixelsize)
         }else{
            Pixels[xpos][yPos].state := 0
            Gdip_FillRectangle(G, pBrushDeath, (xpos - 1) * Pixelsize, (yPos - 1) * Pixelsize, Pixelsize, Pixelsize)
         }
      }
   }
   UpdateLayeredWindow(Gui2.hwnd, hdc, 0, 0, Gui1.Width, Gui1.Height)
}

GOL_UpdateSize(Width , Height){
   global

   Gui1.GetPos(&XWin, &YWin, &WWin, &HWin)
   xMaxNew := Round((WWin -16)/ Pixelsize)
   yMaxNew := Round((HWin -40)/ Pixelsize)
   if (xMaxNew != xMax or yMaxNew != yMax) {

      Gui1.Width := WWin
      Gui1.Height := HWin
      goOutput3.Value:= xMaxNew "x" yMaxNew
      GOL_UpdatePixels(xMaxNew, yMaxNew)
   }
}

GOL_UpdatePixels(xMaxNew,YMaxNew){
   global
   xMax := xMaxNew
   yMax := YMaxNew

   if !IsObject(Pixels){
      Pixels := Map()
   }
   
   ; Construction the grid
   loop xMax {
      xPos := A_Index
      if !Pixels.Has(A_Index){
         Pixels[A_index] := Map()
      }
     
      loop yMax {
         yPos := A_Index
         if !Pixels[xPos].Has(yPos) {
            Pixels[xPos][yPos] := Object()
            Pixels[xPos][yPos].state := 0
            Pixels[xPos][yPos].stateNew := 0
            Gdip_FillRectangle(G, pBrush, (xPos - 1) * Pixelsize, (yPos - 1) * Pixelsize, Pixelsize, Pixelsize)
            if !Pixels[xPos][yPos].state {
               Gdip_FillRectangle(G, pBrushDeath, (xPos - 1) * Pixelsize, (yPos - 1) * Pixelsize, Pixelsize, Pixelsize)
            }
         }         
      }
   }
}

WM_MOVE(wParam , lParam, msg, hwnd){
   global
   if (Gui1.hwnd=hwnd){
      Gui1.GetPos(&XWin, &YWin, &WWin, &HWin)
      Gui3.GetPos(&XWin3, &YWin3, &WWin3, &HWin3)
      GOL_UpdateSize(WWin, HWin)
      if(A_ScreenWidth<Gui3.OffsetX+WWin3) or (A_ScreenWidth < -Gui3.OffsetX + WWin){
         Gui3.OffsetX := Gui3.OffsetX >0 ? WWin-WWin3 -10 : 10
         Gui3.OffsetY := 40
      }

      Gui3.Move(XWin+Gui3.OffsetX, YWin+Gui3.OffsetY)
   }
   if (Gui3.hwnd = hwnd) {
      Gui1.GetPos(&XWin, &YWin, &WWin, &HWin)
      Gui3.GetPos(&XWin3, &YWin3, &WWin3, &HWin3)
      Gui3.OffsetX := XWin3 - XWin
      Gui3.OffsetY := YWin3 - YWin

   }
}
AHK_user
Posts: 515
Joined: 04 Dec 2015, 14:52
Location: Belgium

Re: Game Of Life - Gui ActiveX html [V2.beta.3]

21 Feb 2022, 12:06

tadamm wrote:
16 Feb 2022, 15:40
Got this error. Once I dismiss it it works fine for some reason. Cool game though. Also cant get to pick where I want my dots.
pixels[mouseX][MouseY].state := !pixel[mouseX][MouseY].state
@tadamm : I modified the first post, see if the error is gone. And see how the Gdip version works.
vmech
Posts: 361
Joined: 25 Aug 2019, 13:03

Re: Game Of Life - Gui ActiveX html [V2.beta.3]

21 Feb 2022, 15:50

GDIP version do not work because posted GDIP_All.ahk not compatible with Autohotkey v2.0-beta. :wtf:
Shot
Last edited by vmech on 22 Feb 2022, 02:13, edited 1 time in total.
Please post your script code inside [code] ... [/code] block. Thank you.
User avatar
Joe Glines
Posts: 771
Joined: 30 Sep 2013, 20:49
Location: Dallas
Contact:

Re: Game Of Life - Gui ActiveX html [V2.beta.3]

21 Feb 2022, 22:15

More great work!
I uploaded our video here
Sign-up for the 🅰️HK Newsletter

ImageImageImageImage:clap:
AHK Tutorials:Web Scraping | | Webservice APIs | AHK and Excel | Chrome | RegEx | Functions
Training: AHK Webinars Courses on AutoHotkey :ugeek:
YouTube

:thumbup: Quick Access Popup, the powerful Windows folders, apps and documents launcher!
vmech
Posts: 361
Joined: 25 Aug 2019, 13:03

Re: Game Of Life - Gui ActiveX html [V2.beta.3]

22 Feb 2022, 18:28

@AHK_user
Why you coded Glider as this

Code: Select all

MyMenu.Add("Glider", AddGOL.Bind(MouseX, MouseY, "00000`n00010`n010100`n0011100`n000000`n000000"))
when Glider is just this

Code: Select all

MyMenu.Add("Glider", AddGOL.Bind(MouseX, MouseY, "010`n001`n111"))
?
Please post your script code inside [code] ... [/code] block. Thank you.
AHK_user
Posts: 515
Joined: 04 Dec 2015, 14:52
Location: Belgium

Re: Game Of Life - Gui ActiveX html [V2.beta.3]

22 Feb 2022, 18:58

vmech wrote:
22 Feb 2022, 18:28
@AHK_user
Why you coded Glider as this

Code: Select all

MyMenu.Add("Glider", AddGOL.Bind(MouseX, MouseY, "00000`n00010`n010100`n0011100`n000000`n000000"))
when Glider is just this

Code: Select all

MyMenu.Add("Glider", AddGOL.Bind(MouseX, MouseY, "010`n001`n111"))
?
It indeed does not matter if you start from a white grid, I guess I wanted to set the pixels arround white in case some black pixels are present, It can`t hurt.
I like this extreme simple and easy way to add shapes to the grid.
At first I tried setting the pixels one by one :crazy: , but soon improved to this method.
Of course I start to type it with real linefeeds when programming complex shapes so you can check the shape.
vmech
Posts: 361
Joined: 25 Aug 2019, 13:03

Re: Game Of Life - Gui ActiveX html [V2.beta.3]

23 Feb 2022, 05:08

@AHK_user
Extremely shortened shapes (without extra zeros around shape) cause much less index bound errors such as this:
Index bound error
Example of short simple shapes
Please post your script code inside [code] ... [/code] block. Thank you.
User avatar
xianii
Posts: 5
Joined: 27 Sep 2014, 12:53
Contact:

Re: Game Of Life - Gui ActiveX html [V2.beta.3]

06 Mar 2022, 14:17

tadamm wrote:
16 Feb 2022, 15:40
Got this error. Once I dismiss it it works fine for some reason. Cool game though. Also cant get to pick where I want my dots.
pixels[mouseX][MouseY].state := !pixel[mouseX][MouseY].state
Trying replace that line with the code below.

Code: Select all

if(Pixels[MouseX][MouseY].HasOwnProp("state")) {
	Pixels[MouseX][MouseY].state := !Pixels[MouseX][MouseY].state
} else {
	Pixels[MouseX][MouseY].state := true
}
AHK_user
Posts: 515
Joined: 04 Dec 2015, 14:52
Location: Belgium

Re: Game Of Life - Gui ActiveX html [V2.beta.3]

06 Mar 2022, 16:10

xianii wrote:
06 Mar 2022, 14:17
tadamm wrote:
16 Feb 2022, 15:40
Got this error. Once I dismiss it it works fine for some reason. Cool game though. Also cant get to pick where I want my dots.
pixels[mouseX][MouseY].state := !pixel[mouseX][MouseY].state
Trying replace that line with the code below.

Code: Select all

if(Pixels[MouseX][MouseY].HasOwnProp("state")) {
	Pixels[MouseX][MouseY].state := !Pixels[MouseX][MouseY].state
} else {
	Pixels[MouseX][MouseY].state := true
}
I changed this in the first post
AHK_user
Posts: 515
Joined: 04 Dec 2015, 14:52
Location: Belgium

Re: Game Of Life - Gui ActiveX html [V2.beta.3]

06 Mar 2022, 16:11

I have also tried to make a version where the innerHTML is changed in one go, strangely, this is a lot slower.

Return to “Scripts and Functions (v2)”

Who is online

Users browsing this forum: No registered users and 13 guests