<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
	<title type="html"><![CDATA[Серый форум &mdash; AHK: игра «Жизнь» [Life]]]></title>
	<link rel="self" href="http://forum.script-coding.com/extern.php?action=feed&amp;tid=5749&amp;type=atom" />
	<updated>2011-12-12T09:47:00Z</updated>
	<generator>PunBB</generator>
	<id>http://forum.script-coding.com/viewtopic.php?id=5749</id>
		<entry>
			<title type="html"><![CDATA[Re: AHK: игра «Жизнь» [Life]]]></title>
			<link rel="alternate" href="http://forum.script-coding.com/viewtopic.php?pid=54503#p54503" />
			<content type="html"><![CDATA[<p>Ясно, спасибо.</p>]]></content>
			<author>
				<name><![CDATA[teadrinker]]></name>
				<uri>http://forum.script-coding.com/profile.php?id=24515</uri>
			</author>
			<updated>2011-12-12T09:47:00Z</updated>
			<id>http://forum.script-coding.com/viewtopic.php?pid=54503#p54503</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: игра «Жизнь» [Life]]]></title>
			<link rel="alternate" href="http://forum.script-coding.com/viewtopic.php?pid=54501#p54501" />
			<content type="html"><![CDATA[<p>Окно и туллтип обновляются раза в 3-4 медленнее.</p>]]></content>
			<author>
				<name><![CDATA[Grey]]></name>
				<uri>http://forum.script-coding.com/profile.php?id=25792</uri>
			</author>
			<updated>2011-12-12T09:35:00Z</updated>
			<id>http://forum.script-coding.com/viewtopic.php?pid=54501#p54501</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: игра «Жизнь» [Life]]]></title>
			<link rel="alternate" href="http://forum.script-coding.com/viewtopic.php?pid=54496#p54496" />
			<content type="html"><![CDATA[<div class="quotebox"><cite>Grey пишет:</cite><blockquote><p>Стоит ещё отметить, что в Win7 при активной теме со степенью прозрачности окантовки окон (<em>Aero</em>), наблюдаются <em>тормоза</em>, у программ Color Spy, InqSoft Window Scanner (использующих эту же подсистему для аналогичных целей) такого нет.</p></blockquote></div><p>А какие именно тормоза?</p>]]></content>
			<author>
				<name><![CDATA[teadrinker]]></name>
				<uri>http://forum.script-coding.com/profile.php?id=24515</uri>
			</author>
			<updated>2011-12-12T08:24:15Z</updated>
			<id>http://forum.script-coding.com/viewtopic.php?pid=54496#p54496</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: игра «Жизнь» [Life]]]></title>
			<link rel="alternate" href="http://forum.script-coding.com/viewtopic.php?pid=54476#p54476" />
			<content type="html"><![CDATA[<p>Честно говоря к библиотеке не обращался, на оффоруме попался скрипт с названием Analog Clock, вот там посмотрел пример использования, ну и + <a href="http://msdn.microsoft.com/en-us/library/ms533798(VS.85).aspx">MSDN</a>. Кстати конкретно по <a href="http://msdn.microsoft.com/en-us/library/ms535050(VS.85).aspx">пунктирам</a> в Gdip.ahk ни слова. Стоит ещё отметить, что в Win7 при активной теме со степенью прозрачности окантовки окон (<em>Aero</em>), наблюдаются <em>тормоза</em>, у программ Color Spy, InqSoft Window Scanner (использующих эту же подсистему для аналогичных целей) такого нет.</p>]]></content>
			<author>
				<name><![CDATA[Grey]]></name>
				<uri>http://forum.script-coding.com/profile.php?id=25792</uri>
			</author>
			<updated>2011-12-11T16:48:45Z</updated>
			<id>http://forum.script-coding.com/viewtopic.php?pid=54476#p54476</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: игра «Жизнь» [Life]]]></title>
			<link rel="alternate" href="http://forum.script-coding.com/viewtopic.php?pid=54472#p54472" />
			<content type="html"><![CDATA[<div class="quotebox"><cite>Grey пишет:</cite><blockquote><div class="quotebox"><cite>Zohann пишет:</cite><blockquote><p>...туториала на русском нет...</p></blockquote></div><p>Нет, но разобраться можно:</p></blockquote></div><p>Удобнее пользоваться уже написанной <a href="http://www.autohotkey.com/forum/topic32238.html">библиотекой</a>.</p>]]></content>
			<author>
				<name><![CDATA[teadrinker]]></name>
				<uri>http://forum.script-coding.com/profile.php?id=24515</uri>
			</author>
			<updated>2011-12-11T13:37:22Z</updated>
			<id>http://forum.script-coding.com/viewtopic.php?pid=54472#p54472</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: игра «Жизнь» [Life]]]></title>
			<link rel="alternate" href="http://forum.script-coding.com/viewtopic.php?pid=54468#p54468" />
			<content type="html"><![CDATA[<p>Увидев &quot;получение дескриптора созданого аппаратно-независимого растра&quot; стало не по себе малость). Спасибо, буду разбираться.</p>]]></content>
			<author>
				<name><![CDATA[Zohann]]></name>
				<uri>http://forum.script-coding.com/profile.php?id=26234</uri>
			</author>
			<updated>2011-12-11T07:10:16Z</updated>
			<id>http://forum.script-coding.com/viewtopic.php?pid=54468#p54468</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: игра «Жизнь» [Life]]]></title>
			<link rel="alternate" href="http://forum.script-coding.com/viewtopic.php?pid=54465#p54465" />
			<content type="html"><![CDATA[<div class="quotebox"><cite>Zohann пишет:</cite><blockquote><p>А, оказывается ANSI x86 надо было установить.</p></blockquote></div><p>ANSI версия - скрипт запускается в любой кодировке, Unicode версия - скрипт запускается только в UTF-8.<br /></p><div class="quotebox"><cite>Zohann пишет:</cite><blockquote><p>...туториала на русском нет...</p></blockquote></div><p>Нет, но разобраться можно:</p><div class="codebox"><pre><code>#NoEnv
SetBatchLines, -1
CoordMode, Pixel
CoordMode, Mouse
; установка единого курсора
SetDefinedCursor(32515) ; IDC_CROSS
; создание прозрачного окна
Gui, +AlwaysOnTop -Caption +E0x80000 +HwndGUIhWnd +Owner
Gui, Show, w150 h150, 10xZoom
WinMove, % &quot;ahk_id&quot;GUIhWnd,, A_ScreenWidth/2-76, A_ScreenHeight/2-76
; обработка клика по не клиентской области окна
OnMessage(0x201, &quot;WM_NCLBUTTONDOWN&quot;)
; загрузка нужной библиотеки
hModule:=DllCall(&quot;LoadLibrary&quot;, &quot;Str&quot;, &quot;gdiplus.dll&quot;)
; выделение памяти под структуру
VarSetCapacity(GdiplusStartupInput, 16, 0)
; инициализация структуры, вернее необходимого поля, остальные можно не декларировать
NumPut(1, GdiplusStartupInput, 0, &quot;Char&quot;) ; GdiplusVersion
; инициализация Windows GDI+ с получением указателя нужного, чтобы потом закрыть
DllCall(&quot;gdiplus\GdiplusStartup&quot;, &quot;UInt*&quot;, pToken, &quot;UInt&quot;, &amp;GdiplusStartupInput)
; выделение памяти под структуру
VarSetCapacity(BITMAPINFO, 40, 0)
; инициализация структуры
NumPut(40, BITMAPINFO, 0) ; biSize
NumPut(150, BITMAPINFO, 4) ; biWidth
NumPut(150,BITMAPINFO, 8) ; biHeight
NumPut(1, BITMAPINFO, 12, &quot;UShort&quot;) ; biPlanes
NumPut(32, BITMAPINFO, 14, &quot;UShort&quot;) ; biBitCount
NumPut(0, BITMAPINFO, 16) ; biCompression
; получение дескриптора созданого аппаратно-независимого растра (Device Independent Bitmap)
hBitmap:=DllCall(&quot;CreateDIBSection&quot;, &quot;UInt&quot;, hDC
                                   , &quot;UInt&quot;, &amp;BITMAPINFO
                                   , &quot;UInt&quot;, 0
                                   , &quot;UInt*&quot;, 0
                                   , &quot;UInt&quot;, 0
                                   , &quot;UInt&quot;, 0)
; высвобождение контекста устройства для других приложений
DllCall(&quot;ReleaseDC&quot;, &quot;UInt&quot;, 0, &quot;UInt&quot;, hDC)
; получение дескриптора памяти контекста устройства
hMemDC:=DllCall(&quot;CreateCompatibleDC&quot;, &quot;UInt&quot;, 0) ; current screen
; выбор объекта в заданный контекст устройства
DllCall(&quot;SelectObject&quot;, &quot;UInt&quot;, hMemDC, &quot;UInt&quot;, hBitmap)
; получение указателя объекта Graphics из дескриптора контекста устройства
DllCall(&quot;gdiplus\GdipCreateFromHDC&quot;, &quot;UInt&quot;, hMemDC, &quot;UInt*&quot;, pGraphics)
; создание двух переменных содержащих шестнадцатиричное число (степень прозрачности и цвет)
Color1:=0xFF000000, Color2:=0xFFFFFFFF ; argb
; создание объектов класса Pen
GdipCreatePen(Color1, pPen1) ; black line
GdipCreatePen(Color2, pPen2) ; white line
GdipCreatePen(Color1, pPen3) ; black dot rect
GdipCreatePen(Color1, pPen4) ; black rect
; назначение своего стиля объекту
DllCall(&quot;gdiplus\GdipSetPenDashStyle&quot;, &quot;UInt&quot;, pPen1
                                     , &quot;Char&quot;, 5) ; DashStyleCustom
; выделение памяти под структуру массива
VarSetCapacity(Array, 8, 0)
; инициализация структуры массива
NumPut(4, Array, 0, &quot;Float&quot;) ; dash lenght
NumPut(3, Array, 4, &quot;Float&quot;) ; space lenght
; присвоение массива объекту
DllCall(&quot;gdiplus\GdipSetPenDashArray&quot;, &quot;UInt&quot;, pPen1
                                     , &quot;Int&quot;, &amp;Array
                                     , &quot;Int&quot;, 2) ; count
; назначение стиля объекту
DllCall(&quot;gdiplus\GdipSetPenDashStyle&quot;, &quot;UInt&quot;, pPen3
                                     , &quot;Char&quot;, 2) ; DashStyleDot
; создание объекта класса Brush
DllCall(&quot;gdiplus\GdipCreateSolidFill&quot;, &quot;Int&quot;, Color1, &quot;UInt*&quot;, pBrush)
SetTimer, ChaseCursor, 10
OnExit, ExitScript
Return

ChaseCursor:
   MouseGetPos, XPos, YPos
; присвоение цвета и заливка объектов Brush
   Loop, 15
      GdipDrawLine(A_Index-1)
; отрисовка линий объектами Pen
   GdipDrawObject(&quot;Line&quot;, pPen2, 0, 75, 70, 75) ; white line
   GdipDrawObject(&quot;Line&quot;, pPen2, 80, 75, 150, 75)
   GdipDrawObject(&quot;Line&quot;, pPen2, 75, 0, 75, 70)
   GdipDrawObject(&quot;Line&quot;, pPen2, 75, 80, 75, 150)
   GdipDrawObject(&quot;Line&quot;, pPen1, 69, 75, 1, 75) ; black dash line
   GdipDrawObject(&quot;Line&quot;, pPen1, 81, 75, 147, 75)
   GdipDrawObject(&quot;Line&quot;, pPen1, 75, 69, 75, 1)
   GdipDrawObject(&quot;Line&quot;, pPen1, 75, 81, 75, 147)
; отрисовка прямоугольников объектами Pen
   GdipDrawObject(&quot;Rectangle&quot;, pPen2, 70, 70, 10, 10) ; white center rect
   GdipDrawObject(&quot;Rectangle&quot;, pPen3, 70, 70, 10, 10) ; black dot center rect
   GdipDrawObject(&quot;Rectangle&quot;, pPen4, 0, 0, 149, 149) ; black outside rect
; обновление многослойного окна
   DllCall(&quot;UpdateLayeredWindow&quot;, &quot;UInt&quot;, GUIhWnd
                                , &quot;UInt&quot;, 0
                                , &quot;UInt&quot;, 0
                                , &quot;Int64*&quot;, 0x09600000096 ; 150x150
                                , &quot;UInt&quot;, hMemDC
                                , &quot;Int64*&quot;, 0
                                , &quot;UInt&quot;, 0
                                , &quot;UInt*&quot;, 0x01FF0000 ; BLENDFUNCTION
                                , &quot;UInt&quot;, 2)
   Return

ExitScript:
; высвобождение ресурсов
   DllCall(&quot;gdiplus\GdiplusShutdown&quot;, &quot;UInt&quot;, pToken)
   DllCall(&quot;FreeLibrary&quot;, &quot;UInt&quot;, hModule)
; восстановление системных курсоров
   DllCall(&quot;SystemParametersInfo&quot;, &quot;UInt&quot;, 0x57 ; SPI_SETCURSORS
                                 , &quot;UInt&quot;, 0
                                 , &quot;UInt&quot;, 0
                                 , &quot;UInt&quot;, 0)
   ExitApp

WM_NCLBUTTONDOWN()
{
   global
   PostMessage, 0xA1, 2,,, % &quot;ahk_id&quot;GUIhWnd ; WM_NCLBUTTONDOWN, HTCAPTION
}

GdipDrawLine(Y)
{
   global
   Loop, 15
   {
      PixelGetColor, CurrentColor, XPos-7+A_Index-1, YPos-7+Y, RGB
      DllCall(&quot;gdiplus\GdipSetSolidFillColor&quot;, &quot;UInt&quot;, pBrush
                                             , &quot;UInt&quot;, CurrentColor|0xFF000000)
      DllCall(&quot;gdiplus\GdipFillRectangle&quot;, &quot;UInt&quot;, pGraphics
                                         , &quot;UInt&quot;, pBrush
                                         , &quot;Float&quot;, (A_Index-1)*10
                                         , &quot;Float&quot;, Y*10
                                         , &quot;Float&quot;, 10 ; w
                                         , &quot;Float&quot;, 10) ; h
   }
}

GdipCreatePen(PenColor, ByRef pPenN)
{
   global
   DllCall(&quot;gdiplus\GdipCreatePen1&quot;, &quot;Int&quot;, PenColor
                                   , &quot;Float&quot;, 1 ; width
                                   , &quot;Char&quot;, 2 ; unit - pixel
                                   , &quot;UInt*&quot;, pPenN)
}

GdipDrawObject(Kind, pPenN, FromX, FromY, IntoX, IntoY)
{
   global
   DllCall(&quot;gdiplus\GdipDraw&quot; . Kind, &quot;UInt&quot;, pGraphics
                                    , &quot;UInt&quot;, pPenN
                                    , &quot;Float&quot;, FromX
                                    , &quot;Float&quot;, FromY
                                    , &quot;Float&quot;, IntoX
                                    , &quot;Float&quot;, IntoY)
}

SetDefinedCursor(Cursor)
{
   SystemCursors:=&quot;
   ,32512,32513,32514,32515,32516,32640,32641,32642
   ,32643,32644,32645,32646,32648,32649,32650,32651&quot;
   Loop, Parse, SystemCursors, `,
   {
      If % A_Loopfield=Cursor
      {
         Loop, Parse, SystemCursors, `,
         {
            hCursor:=DllCall(&quot;LoadCursor&quot;, &quot;UInt&quot;, 0, &quot;Int&quot;, Cursor)
            hCursor:=DllCall(&quot;CopyImage&quot;, &quot;UInt&quot;, hCursor
                                        , &quot;UInt&quot;, 0x2 ; IMAGE_CURSOR
                                        , &quot;Int&quot;, 28 ; w
                                        , &quot;Int&quot;, 28 ; h
                                        , &quot;UInt&quot;, 0)
            DllCall(&quot;SetSystemCursor&quot;, &quot;UInt&quot;, hCursor
                                     , &quot;Int&quot;, A_Loopfield)
         }
      }
   }
}</code></pre></div><p>Это кусок кода для примера, плюс добавил комментарии.</p>]]></content>
			<author>
				<name><![CDATA[Grey]]></name>
				<uri>http://forum.script-coding.com/profile.php?id=25792</uri>
			</author>
			<updated>2011-12-11T00:10:43Z</updated>
			<id>http://forum.script-coding.com/viewtopic.php?pid=54465#p54465</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: игра «Жизнь» [Life]]]></title>
			<link rel="alternate" href="http://forum.script-coding.com/viewtopic.php?pid=54418#p54418" />
			<content type="html"><![CDATA[<p>А, оказывается ANSI x86 надо было установить.<br />Ну ваще крутяк! Чотко! Могете!<br />Одно замечание: Старт-Стоп-Старт и счетчик генерации опять с нуля.<br />Чую, сила в Gdip, да туториала на русском нет...</p>]]></content>
			<author>
				<name><![CDATA[Zohann]]></name>
				<uri>http://forum.script-coding.com/profile.php?id=26234</uri>
			</author>
			<updated>2011-12-10T11:00:05Z</updated>
			<id>http://forum.script-coding.com/viewtopic.php?pid=54418#p54418</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: игра «Жизнь» [Life]]]></title>
			<link rel="alternate" href="http://forum.script-coding.com/viewtopic.php?pid=54417#p54417" />
			<content type="html"><![CDATA[<p>Не запускается почему-то. AutoHotkey_L установил, в Lib Gdip положил, запускаю из той же папки.<br /></p><div class="codebox"><pre><code>Error:  Missing &quot;{&quot;

    Line#
    168: GuiControl,Parent:,StartStop,Start
    169: Loop,parse,Controls,|
    170: GuiControl,Parent:Enable,%A_LoopField%
    171: Break
    172: }
    174: For k,v in CurrentArray
    175: c := v.c, r := v.r, UpdateNextArray(r, c), CellArray[r][c].alive := v.alive  
---&gt;    177: }
    178: BitBlt(hFieldDC, 0, 0, FieldWidth, FieldHeight, hdc, 0, 0)  
    179: Sleep,Pause
    180: }
    180: Until,!StartStop
    181: StartStop := 0
    182: Return
    186: if StartStop  

The program will exit.</code></pre></div>]]></content>
			<author>
				<name><![CDATA[Zohann]]></name>
				<uri>http://forum.script-coding.com/profile.php?id=26234</uri>
			</author>
			<updated>2011-12-10T10:58:28Z</updated>
			<id>http://forum.script-coding.com/viewtopic.php?pid=54417#p54417</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: игра «Жизнь» [Life]]]></title>
			<link rel="alternate" href="http://forum.script-coding.com/viewtopic.php?pid=54413#p54413" />
			<content type="html"><![CDATA[<p>Добил, наконец, если ещё кому-то интересно! <img src="//forum.script-coding.com/img/smilies/smile.png" width="15" height="15" /></p><p>Требует <a href="http://l.autohotkey.net/#Get_It">AHK_L</a>; файла <a href="http://www.autohotkey.net/~tic/Gdip.ahk">Gdip.ahk</a>, находящегося в любой из перечисленных ниже папок:</p><div class="quotebox"><blockquote><p>%A_ScriptDir%\Lib\&nbsp; ; Local library - requires AHK_L 42+.<br />%A_MyDocuments%\AutoHotkey\Lib\&nbsp; ; User library.<br />path-to-the-currently-running-AutoHotkey.exe\Lib\&nbsp; ; Standard library.</p></blockquote></div><p>Рисовать фигуры можно, кликая по полю (отдельные точки), и проводкой (линии и прямоугольники), удерживая левую кнопку мыши; удерживая Alt можно рисовать диагонали. Всё то же самое плюс Ctrl — стирание нарисованного. Для полной очистки поля воспользуйтесь Clear во время, когда движение фигур полностью остановлено (кнопка Stop, она же Start)</p><p>Нарисованные фигуры можно сохранять и в дальнейшем загружать. Сохранённая фигура загружается в видимый центр игрового поля, до нажатия кнопки OK её можно сдвигать в нужное место клавишами стрелок. Само поле можно двигать правой кнопкой мыши. Чтобы отцентровать поле, нажмите Center.<br /></p><div class="codebox"><pre><code>   #NoEnv
   SetBatchLines, -1
   SetWinDelay, 0

   IniName := A_ScriptDir &quot;\&quot; RegExReplace(A_ScriptName, &quot;(.*\.).*&quot;, &quot;$1ini&quot;)
   Columns = 500
   Rows := Round(Columns*A_ScreenHeight/A_ScreenWidth)

   IniRead, Cell, % IniName, Settings, Cell, 8   ; размер клетки
   FieldWidth := Columns*Cell - 1   ; полная ширина игрового поля
   FieldHeight := Rows*Cell - 1     ; полная высота игрового поля
   ButtonField = 55   ; область с элементами управления
   AliveBrush1 := 0xFF2A5EA9   ; цвет живых клеток в монохромном режиме

   Gosub, CreateWindow

   CellArray := []  ; в этом двумерном массиве будут все клетки поля, их координаты и состояние
   Loop % Columns
      CellArray[A_Index] := []

   Loop % Rows
   {
      r := A_Index
      Loop % Columns
         CellArray[r][A_Index] := {x: Cell*(A_Index - 1), y: Cell*(r - 1), alive: 0}
   }

   NextArray := {}  ; здесь будут клетки, изменённые в предыдущей итерации и их соседи
                    ; в цикле будем рассматривать только их
   OnMessage(0x201, &quot;WM_LBUTTONDOWN&quot;)
   OnMessage(0x200, &quot;WM_MOUSEMOVE&quot;)
   OnMessage(0x202, &quot;WM_LBUTTONUP&quot;)
   OnMessage(0x111, &quot;WM_COMMAND&quot;)
   OnMessage(0x00F, &quot;WM_PAINT&quot;)
   OnExit, Exit
   Return

CreateWindow:
   pToken := Gdip_Startup()

   SysGet, GuiW, % SM_CXFULLSCREEN := 16
   SysGet, GuiH, % SM_CYFULLSCREEN := 17
   SysGet, WBorder, % SM_CXSIZEFRAME := 32
   SysGet, HBorder, % SM_CYSIZEFRAME := 33
   IniRead, FieldW, % IniName, Size, FieldW, % GuiW - 2*WBorder
   IniRead, FieldH, % IniName, Size, FieldH, % GuiH - 2*HBorder - ButtonField
   IniRead, GuiX, % IniName, Size, GuiX, 0
   IniRead, GuiY, % IniName, Size, GuiY, 0
   IniRead, Pause, % IniName, Settings, Pause, 10
   IniRead, Multicolor, % IniName, Settings, Multicolor, 0

   Gui, Parent: +hwndhParent +Resize  ; родительское окно с элементами управления
   Gui, Parent:Default
   Gui, Color, D4D0C8
   Gui, Font, s8, Verdana
   Gui, Add, Pic, % &quot;vPic x0 y0 w&quot; FieldW &quot; h&quot; FieldH &quot; hwndhPic&quot;   ; будет родительским окном для игрового поля
   Gui, Add, Button, % &quot;vStartStop x10 y&quot; FieldH+(ButtonField//2 - 23//2) &quot; w57 h23 gStart&quot;, Start
   Gui, Add, Button, vNext xp+61 yp wp hp gCycle, Next
   Gui, Add, Button, vClear xp+61 yp wp hp gClear, Clear
   Gui, Add, Button, vCenter xp+61 yp wp hp gCenter, Center
   Gui, Add, Button, vSave xp+77 yp wp hp gSave hwndhSaveButton, Save
   Gui, Add, Button, vLoad xp+61 yp wp hp gLoad hwndhLoadButton, Load
   Gui, Add, Text, % &quot;vTextSpeed xp+75 yp+&quot; TextD := 5, Speed:

   Options := &quot;xp+40 w100 yp-3 h20 Range1-50 ToolTip AltSubmit&quot;
   Gui, Add, Slider, vSlider gSpeedSet %Options%, % Speed := Round(51 - Pause/10)
   Gui, Add, Text, vSpeed xp+100 yp+3, % Speed
   Gui, Add, Text, vTextSize xp+30 yp, Cell size:
   Gui, Add, DDL, vDDLSize gDDLSize xp+58 yp-4 h20 w35 r8
      , % RegExReplace(&quot;4|5|6|7|8|9|10|11&quot;, &quot;(&quot; Cell &quot;)&quot;, Cell = 11 ? &quot;$1||&quot; : &quot;$1|&quot;)
   Gui, Add, Checkbox, % &quot;vMulticolor gMulticolor xp+58 yp+5&quot; (Multicolor ? &quot; Checked&quot; : &quot;&quot;), Multicolor
   trn := FieldW &lt; 898
   Gui, Add, Text, % &quot;vTextGen gClearGen x&quot; (trn ? 788 : FieldW - 110) &quot; yp&quot;, Generation
   Gui, Font, s9
   Gui, Add, Text, % &quot;vGen gClearGen x&quot; (trn ? 858 : FieldW - 40) &quot; yp-1 w35&quot;, 0

   Gui, Child: -Caption +hwndhField +Parent%hPic%  ; окно с игровым полем

   hFieldDC := GetDC(hField)
   hbm := CreateDIBSection(FieldWidth, FieldHeight)
   hdc := CreateCompatibleDC()
   obm := SelectObject(hdc, hbm)
   G := Gdip_GraphicsFromHDC(hdc)

   pAliveBrush1 := Gdip_BrushCreateSolid(Multicolor ? 0xFF30B29E : AliveBrush1)
   pAliveBrush2 := Gdip_BrushCreateSolid(0xFFFFC400)
   pAliveBrush3 := Gdip_BrushCreateSolid(0xFFC930B8)
   pBackBrush := Gdip_BrushCreateSolid(0xFFFFFFFF)
   Gosub, FillBackground

   Gui, Show, % &quot;x&quot; GuiX &quot; y&quot; GuiY &quot; w&quot; FieldW &quot; h&quot; FieldH + ButtonField
   GuiControlGet, Pic, Pos, Pic
   x_val := PicW//2 - FieldWidth//2
   y_val := PicH//2 - FieldHeight//2
   Gui, Child:Show, % &quot;x&quot; x_val &quot; y&quot; y_val &quot; w&quot; FieldWidth &quot; h&quot; FieldHeight
   BitBlt(hFieldDC, 0, 0, FieldWidth, FieldHeight, hdc, 0, 0)
   Controls = Next|Clear|DDLSize|Save|Load
   Return

FillBackground:
   Gdip_FillRectangle(G, pBackBrush, -1, -1, FieldWidth+2, FieldHeight+2)   ; заливаем бэкграунд

   TransparentCell := (0x45 + (Cell - 5)*7)&lt;&lt;24
   TransparentGrid := (0x75 + (Cell - 5)*7)&lt;&lt;24
   pCellPen := Gdip_CreatePen(TransparentCell|0x7C7A77, 1)
   pGridPen := Gdip_CreatePen(TransparentGrid|0x7C7A77, 1)
   Loop % Rows - 1
      Gdip_DrawLine(G,  mod(A_Index, 10) ? pCellPen : pGridPen
         , 0, A_Index * Cell - 1, FieldWidth, A_Index * Cell - 1)   ; рисуем горизонтали

   Loop % Columns - 1
      Gdip_DrawLine(G, mod(A_Index, 10) ? pCellPen : pGridPen
         , A_Index * Cell - 1, 0, A_Index * Cell - 1, FieldHeight)   ; рисуем вертикали
   Gdip_DeletePen(pCellPen), Gdip_DeletePen(pGridPen)
   Return

#If WinActive(&quot;ahk_id &quot; hParent)
Enter::
Start:
   if WinExist(&quot;ahk_id&quot; hLoad)
      Return

   GuiControl, Parent:, StartStop, % (StartStop := !StartStop) ? &quot;Stop&quot; : &quot;Start&quot;
   Loop, parse, Controls, |
      GuiControl, % &quot;Parent:&quot; (StartStop ? &quot;Disable&quot; : &quot;Enable&quot;), %A_LoopField%
   if !StartStop
      Return

   GuiControl, Parent:, Gen, % Gen := 0
   SetTimer, Cycle, -1
   Return

Cycle:
   Loop
   {
      color := Multicolor ? Mod(Ceil(A_Index/20), 3) : 1
      CurrentBrush := color = 1 ? pAliveBrush1 : color = 2 ? pAliveBrush2 : pAliveBrush3
      GuiControl, Parent:, Gen, % ++Gen

      CurrentArray := {}  ; здесь будут клетки, которые изменятся в этой итерации
      for k, v in NextArray
      {
         i := 0, r := v.r, c := v.c
         Loop 3   ; проверяем количество живых и мёртвых соседей у претендентов на смену статуса
         {
            n := c + (p := A_Index) - 2
            Loop 3
            {
               if (p = 2 &amp;&amp; A_Index = 2)
                  Continue

               m := r + A_Index - 2
               if (CellArray[m][n].alive &amp;&amp; ++i = 4)  ; достаточно досчитать до четырёх
                  Break 2
            }
         }
         o := CellArray[r][c], x := o.x, y := o.y
         if o.alive
         {
            if (i &lt; 2 || i = 4) ; если живых соседей меньше двух или больше трёх — живая умирает
               CurrentArray[A_Index] := {r: r, c: c, alive: 0}
               , Gdip_FillRectangle(G, pBackBrush, x, y, Cell - 1, Cell - 1)
         }
         Else if i = 3   ; если соседей трое — мёртвая оживает
            CurrentArray[A_Index] := {r: r, c: c, alive: 1}
            , Gdip_FillRectangle(G, CurrentBrush, x, y, Cell - 1, Cell - 1)
      }
      NextArray := {}   ; опустошаем массив

      if !CurrentArray.GetCapacity()  ; если ничего не изменилось, значит цикл закончен
      {
         GuiControl, Parent:, StartStop, Start
         Loop, parse, Controls, |
            GuiControl, Parent:Enable, %A_LoopField%
         Break
      }

      for k, v in CurrentArray   ; заносим в массив NextArray изменившиеся клетки и
      {                           ; соседние с ними для проверки в следующей итерации
         c := v.c, r := v.r, UpdateNextArray(r, c)
         , CellArray[r][c].alive := v.alive   ; вносим изменения в основной массив
      }
      BitBlt(hFieldDC, 0, 0, FieldWidth, FieldHeight, hdc, 0, 0)
      Sleep, Pause
   } Until !StartStop
   StartStop := 0
   Return

Del::
Clear:
   if StartStop
      Return
   GuiControl, Parent:, Gen, % Gen := 0
   for k, v in CellArray
      for n, m in v
         if m.alive
            Update_hDC(m)
   BitBlt(hFieldDC, 0, 0, FieldWidth, FieldHeight, hdc, 0, 0)
   Return

Center:
   GuiControlGet, Pic, Parent:Pos, Pic
   x_val := PicW//2 - FieldWidth//2
   y_val := PicH//2 - FieldHeight//2
   Gui, Child:Show, % &quot;x&quot; x_val &quot; y&quot; y_val &quot; w&quot; FieldWidth &quot; h&quot; FieldHeight
   BitBlt(hFieldDC, 0, 0, FieldWidth, FieldHeight, hdc, 0, 0)
   Return

Save:
   Critical

   if !FileExist(A_ScriptDir &quot;\Figures&quot;)
      FileCreateDir, %A_ScriptDir%\Figures

   Gui, Parent: +OwnDialogs
   WinGetPos,, Y_Pic,,, ahk_id %hPic%
   WinGetPos, XButt,,,, ahk_id %hSaveButton%

   GuiControlGet, Field, Parent:Pos, Pic

   Loop
   {
      InputBox, FigureName, Save, Type a Name:,, 200, 120, XButt, Y_Pic + FieldH - 120
      if ErrorLevel
         Return

      BitBlt(hFieldDC, 0, 0, FieldWidth, FieldHeight, hdc, 0, 0)
      FigureName = %FigureName%
      if (FigureName = &quot;&quot;)
         MsgBox, Введите название фигуры!
      else if found := FileExist(A_ScriptDir &quot;\Figures\&quot; FigureName &quot;.life&quot;)
      {
         MsgBox, 0x34, Название существует, Название фигуры &quot;%FigureName%&quot; уже существует!`nЗаменить?
         IfMsgBox, Yes
            Break
         else
            FigureName =
      }
   } Until FigureName

   for r, v in CellArray
   {
      for c, m in v
      {
         if m.alive
         {
            if !once
               r_min := r, once := 1
            Figure .= r &quot;,&quot; c &quot;|&quot;
         }
      }
   }

   Figure := SubStr(Figure, 1, -1)
   c_min := 1000000000
   Loop, parse, Figure, |
   {
      r_new := RegExReplace(A_LoopField, &quot;(.*),.*&quot;, &quot;$1&quot;) - r_min
      NewFigure .= RegExReplace(A_LoopField, &quot;.*(,.*)&quot;, r_new &quot;$1&quot;) . &quot;|&quot;
      if ((n := RegExReplace(A_LoopField, &quot;.*,(.*)&quot;, &quot;$1&quot;)) &lt; c_min)
         c_min := n
   }
   NewFigure := SubStr(NewFigure, 1, -1), Figure := &quot;&quot;

   Loop, parse, NewFigure, |
   {
      c_new := RegExReplace(A_LoopField, &quot;.*,(.*)&quot;, &quot;$1&quot;) - c_min
      Figure .= RegExReplace(A_LoopField, &quot;(.*,).*&quot;, &quot;$1&quot; c_new) . &quot;|&quot;
   }
   Figure := SubStr(Figure, 1, -1)

   FileDelete, % A_ScriptDir &quot;\Figures\&quot; FigureName &quot;.life&quot;
   FileAppend, % Figure, % A_ScriptDir &quot;\Figures\&quot; FigureName &quot;.life&quot;
   Figure := NewFigure := once := &quot;&quot;
   BitBlt(hFieldDC, 0, 0, FieldWidth, FieldHeight, hdc, 0, 0)
   Notify(&quot;Фигура сохранена в файл`n&quot; A_ScriptDir &quot;\Figures\&quot; FigureName &quot;.life&quot;
      , 0xFF0055BB, &quot;Arial&quot;, &quot;s15 x15 y12 cFFFFFFFF Italic&quot;, 1500)
   Return

Load:
   Gui, Load: New, +OwnerParent +hwndhLoad
   Gui, Load: Default
   Gui, Margin, 15, 10
   Gui, Font, s10 q5, Verdana
   Gui, Add, DDL, vDDLNames gDDLNames hwndhDDLNames w150 h23 r15, Select a Name:||
   Gui, Font, s8, Verdana
   Gui, Add, Button, % &quot;x&quot; (150+30-125)//2 &quot; w60 h23&quot;, OK
   Gui, Add, Button, xp+65 w60 h23&quot;, Cancel
   GuiControl, Focus, OK
   WinGetPos,, Y_Pic,,, ahk_id %hPic%
   WinGetPos, XButt,,,, ahk_id %hLoadButton%
   GuiControlGet, Field, Parent:Pos, Pic
   Gui, Show, Hide, Load
   DetectHiddenWindows, On
   WinGetPos,,,, LoadH, ahk_id %hLoad%
   Gui, Show, % &quot;x&quot; XButt &quot; y&quot; Y_Pic + FieldH - LoadH, Load
   Return

DDLNames:
   Critical

   GuiControlGet, DDLNames, Load:, DDLNames
   if DDLNames = No Files
      Return

   if CurrentFigure
      Loop, parse, CurrentFigure, |
      {
         r := RegExReplace(A_LoopField, &quot;(.*),.*&quot;, &quot;$1&quot;) + CurrentRow
         c := RegExReplace(A_LoopField, &quot;.*,(.*)&quot;, &quot;$1&quot;) + CurrentColumn
         CellArray[r][c].alive := 1, UpdateNextArray(r, c)
      }

   if !hMemoryBm
   {
      hMemoryBm := CreateDIBSection(FieldWidth, FieldHeight)
      hMemoryDC := CreateCompatibleDC()
      oMemoryBm := SelectObject(hMemoryDC, hMemoryBm)
      GMemory := Gdip_GraphicsFromHDC(hMemoryDC)
   }
   BitBlt(hMemoryDC, 0, 0, FieldWidth, FieldHeight, hdc, 0, 0)

   FileRead, CurrentFigure, % A_ScriptDir &quot;\Figures\&quot; DDLNames &quot;.life&quot;
   max_r := max_c := 0
   Loop, parse, CurrentFigure, |
   {
      max_r := (r := RegExReplace(A_LoopField, &quot;(.*),.*&quot;, &quot;$1&quot;)) &gt; max_r ? r : max_r
      max_c := (c := RegExReplace(A_LoopField, &quot;.*,(.*)&quot;, &quot;$1&quot;)) &gt; max_c ? c : max_c
   }

   WinGetPos, X_Field, Y_Field,,, ahk_id %hField%
   WinGetPos, X_Pic, Y_Pic, W_Pic, H_Pic, ahk_id %hPic%

   XPosField := X_Pic - X_Field
   YPosField := Y_Pic - Y_Field

   FirstVisibleRow := Ceil(YPosField/Cell) + 1
   LastVisibleRow := Ceil((YPosField + H_Pic)/Cell)

   FirstVisibleColumn := Ceil(XPosField/Cell) + 1
   LastVisibleColumn := Ceil((XPosField + W_Pic)/Cell)

   CurrentRow := StartRow := (LastVisibleRow + FirstVisibleRow - max_r)//2
   CurrentColumn := StartColumn := (LastVisibleColumn + FirstVisibleColumn - max_c)//2

   Loop, parse, CurrentFigure, |
   {
      r := RegExReplace(A_LoopField, &quot;(.*),.*&quot;, &quot;$1&quot;) + StartRow
      c := RegExReplace(A_LoopField, &quot;.*,(.*)&quot;, &quot;$1&quot;) + StartColumn
      x := CellArray[r][c].x, y := CellArray[r][c].y
      Gdip_FillRectangle(G, pAliveBrush1, x, y, Cell - 1, Cell - 1)
   }
   BitBlt(hFieldDC, 0, 0, FieldWidth, FieldHeight, hdc, 0, 0)

   Hotkey, IfWinExist, ahk_id %hLoad%
   Hotkey, Left, MoveFigure, On
   Hotkey, Right, MoveFigure, On
   Hotkey, Up, MoveFigure, On
   Hotkey, Down, MoveFigure, On
   Return

MoveFigure:
   While GetKeyState(A_ThisHotkey, &quot;P&quot;) || GetKeyState(A_PriorHotkey, &quot;P&quot;)
   {
      GetKeyState(&quot;UP&quot;, &quot;P&quot;) ? (--CurrentRow = 0 ? ++CurrentRow : CurrentRow)
      GetKeyState(&quot;Down&quot;, &quot;P&quot;) ? (++CurrentRow = Rows + 1 ? --CurrentRow : CurrentRow)
      GetKeyState(&quot;Left&quot;, &quot;P&quot;) ? (--CurrentColumn = 0 ? ++CurrentColumn : CurrentColumn)
      GetKeyState(&quot;Right&quot;, &quot;P&quot;) ? (++CurrentColumn = Columns + 1 ? --CurrentColumn : CurrentColumn)

      BitBlt(hdc, 0, 0, FieldWidth, FieldHeight, hMemoryDC, 0, 0)
      Loop, parse, CurrentFigure, |
      {
         r := RegExReplace(A_LoopField, &quot;(.*),.*&quot;, &quot;$1&quot;) + CurrentRow
         c := RegExReplace(A_LoopField, &quot;.*,(.*)&quot;, &quot;$1&quot;) + CurrentColumn
         x := CellArray[r][c].x, y := CellArray[r][c].y
         Gdip_FillRectangle(G, pAliveBrush1, x, y, Cell - 1, Cell - 1)
      }
      BitBlt(hFieldDC, 0, 0, FieldWidth, FieldHeight, hdc, 0, 0)
      Sleep, 50
   }
   Return

#If WinExist(&quot;ahk_id&quot; hLoad)
Enter::
LoadButtonOK:
   if !CurrentFigure
   {
      Gui, Load:Destroy
      Return
   }

   Loop, parse, CurrentFigure, |
   {
      r := RegExReplace(A_LoopField, &quot;(.*),.*&quot;, &quot;$1&quot;) + CurrentRow
      c := RegExReplace(A_LoopField, &quot;.*,(.*)&quot;, &quot;$1&quot;) + CurrentColumn
      CellArray[r][c].alive := 1, UpdateNextArray(r, c)
   }

Esc::
LoadGuiClose:
LoadButtonCancel:
   Gui, Load:Destroy
   if !CurrentFigure
      Return

   if (A_ThisLabel ~= &quot;Load(ButtonCancel|GuiClose)&quot; || A_ThisHotkey = &quot;Esc&quot;)
      BitBlt(hdc, 0, 0, FieldWidth, FieldHeight, hMemoryDC, 0, 0)
      , BitBlt(hFieldDC, 0, 0, FieldWidth, FieldHeight, hdc, 0, 0)
   Hotkey, Left, Off
   Hotkey, Right, Off
   Hotkey, Up, Off
   Hotkey, Down, Off
   SelectObject(hMemoryDC, oMemoryBm), DeleteObject(hMemoryBm)
   DeleteDC(hMemoryDC), Gdip_DeleteGraphics(GMemory)
   hMemoryBm := CurrentFigure := &quot;&quot;
   Return

SpeedSet:
   GuiControl, Parent:, Speed, % Slider
   Pause := (51 - Slider)*10
   Return

DDLSize:
   Gui, Child:Show, Hide
   GuiControlGet, Cell, Parent:, DDLSize

   FieldWidth := Columns*Cell - 1
   FieldHeight := Rows*Cell - 1

   hPrevbm := hbm
   hbm := CreateDIBSection(FieldWidth, FieldHeight)
   SelectObject(hdc, hbm), DeleteObject(hPrevbm), Gdip_DeleteGraphics(G)
   G := Gdip_GraphicsFromHDC(hdc)

   Gosub, FillBackground
   Loop % Rows
   {
      r := A_Index
      Loop % Columns
      {
         oCell := CellArray[r][A_Index]
         oCell.x := Cell*(A_Index - 1), oCell.y := Cell*(r - 1)
         if oCell.alive
            Gdip_FillRectangle(G, pAliveBrush1, oCell.x, oCell.y, Cell - 1, Cell - 1)
      }
   }

   GuiControlGet, Pic, Pos, Pic
   x_val := PicW//2 - FieldWidth//2
   y_val := PicH//2 - FieldHeight//2
   Gui, Child:Show, % &quot;x&quot; x_val &quot; y&quot; y_val &quot; w&quot; FieldWidth &quot; h&quot; FieldHeight
   SetTimer, Paint1, -10
   Return

Multicolor:
   GuiControlGet, Multicolor, Parent:, Multicolor
   Gdip_DeleteBrush(pAliveBrush1)
   pAliveBrush1 := Gdip_BrushCreateSolid(Multicolor ? 0xFF30B29E : AliveBrush1)
   Return

ClearGen:
   GuiControl, Parent:, Gen, % Gen := 0
   Return

ParentGuiSize:
   Gui, Parent:Default
   GuiControl, Move, Pic, % &quot;w&quot; A_GuiWidth &quot; h&quot; A_GuiHeight - ButtonField
   d := A_GuiHeight - ButtonField//2 - 23//2
   Controls2 := Controls . &quot;|StartStop|Center&quot;
   Loop, parse, Controls2, |
      GuiControl, Move, %A_LoopField%, % &quot;y&quot; d
   GuiControl, Move, TextSpeed, % &quot;y&quot; d + TextD
   GuiControl, Move, Slider, % &quot;y&quot; d + 2
   GuiControl, Move, Speed, % &quot;y&quot; d + TextD
   GuiControl, Move, TextSize, % &quot;y&quot; d + TextD
   GuiControl, Move, Multicolor, % &quot;y&quot; d + TextD
   trn := A_GuiWidth &lt; 898
   GuiControl, MoveDraw, TextGen, % &quot;x&quot; (trn ? 788 : A_GuiWidth - 110) &quot; y&quot; d + 5
   GuiControl, MoveDraw, Gen, % &quot;x&quot; (trn ? 858 : A_GuiWidth - 40) &quot; y&quot; d + 4
   Return

#If !WinExist(&quot;ahk_id&quot; hLoad) &amp;&amp; WinActive(&quot;ahk_id&quot; hParent)
Esc::
ParentGuiClose:
   ExitApp

Exit:
   WinGetPos, X, Y,,, ahk_id %hParent%
   WinGet, MinMax, MinMax, ahk_id %hParent%
   GuiControlGet, Pic, Parent:Pos, Pic
   Gui, Parent:Destroy

   Gdip_DeleteBrush(pBackBrush), Gdip_DeleteBrush(pAliveBrush1)
   Gdip_DeleteBrush(pAliveBrush2), Gdip_DeleteBrush(pAliveBrush3)
   SelectObject(hdc, obm), DeleteObject(hbm), DeleteDC(hdc), Gdip_DeleteGraphics(G)
   ReleaseDC(hFieldDC, hField), Gdip_Shutdown(pToken)

   IniWrite, % MinMax = -1 ? 0 : X, % IniName, Size, GuiX
   IniWrite, % MinMax = -1 ? 0 : Y, % IniName, Size, GuiY
   IniWrite, % MinMax = -1 ? 800 : PicW, % IniName, Size, FieldW
   IniWrite, % MinMax = -1 ? 500 : PicH, % IniName, Size, FieldH
   IniWrite, % Pause, % IniName, Settings, Pause
   IniWrite, % Cell, % IniName, Settings, Cell
   IniWrite, % Multicolor, % IniName, Settings, Multicolor
   ExitApp

#If WinActive(&quot;ahk_id&quot; hParent)
RButton:: SendInput, {LButton Down}
RButton Up::
   SendInput, {LButton Up}
   SetTimer, Move, -20
   Return

Move:
   WinGetPos, X_Field, Y_Field,,, ahk_id %hField%
   WinGetPos, X_Pic, Y_Pic, W_Pic, H_Pic, ahk_id %hPic%

   if (X_Field - X_Pic &gt; 0 &amp;&amp; Y_Field - Y_Pic &gt; 0)
      WinMove, ahk_id %hField%,, 0, 0

   else if (X_Field + FieldWidth &lt; X_Pic + W_Pic &amp;&amp; Y_Field + FieldHeight &lt; Y_Pic + H_Pic)
      WinMove, ahk_id %hField%,, W_Pic - FieldWidth, H_Pic - FieldHeight

   else if (X_Field - X_Pic &gt; 0 &amp;&amp; !(Y_Field + FieldHeight &lt; Y_Pic + H_Pic))
      WinMove, ahk_id %hField%,, 0, Y_Field - Y_Pic

   else if (X_Field - X_Pic &gt; 0 &amp;&amp; Y_Field + FieldHeight &lt; Y_Pic + H_Pic)
      WinMove, ahk_id %hField%,, 0, H_Pic - FieldHeight

   else if (Y_Field - Y_Pic &gt; 0 &amp;&amp; !(X_Field + FieldWidth &lt; X_Pic + W_Pic))
      WinMove, ahk_id %hField%,, X_Field - X_Pic, 0

   else if (Y_Field - Y_Pic &gt; 0 &amp;&amp; X_Field + FieldWidth &lt; X_Pic + W_Pic)
      WinMove, ahk_id %hField%,, W_Pic - FieldWidth, 0

   else if (X_Field + FieldWidth &lt; X_Pic + W_Pic)
      WinMove, ahk_id %hField%,, W_Pic - FieldWidth, Y_Field - Y_Pic

   else if (Y_Field + FieldHeight &lt; Y_Pic + H_Pic)
      WinMove, ahk_id %hField%,, X_Field - X_Pic, H_Pic - FieldHeight

   BitBlt(hFieldDC, 0, 0, FieldWidth, FieldHeight, hdc, 0, 0)
   Return

WM_PAINT()   ; поддержка изображения при перерисовке окна
{
   global
   SetTimer, Paint1, -10
   Return

Paint1:
   BitBlt(hFieldDC, 0, 0, FieldWidth, FieldHeight, hdc, 0, 0)
   SetTimer, Paint2, -50
   Return

Paint2:
   BitBlt(hFieldDC, 0, 0, FieldWidth, FieldHeight, hdc, 0, 0)
   Return
}

Update_hDC(oCell)
{
   global
   if oCell.alive := !oCell.alive
      Gdip_FillRectangle(G, pAliveBrush1, oCell.x, oCell.y, Cell - 1, Cell - 1)
   Else
      Gdip_FillRectangle(G, pBackBrush, oCell.x, oCell.y, Cell - 1, Cell - 1)
}

WM_LBUTTONDOWN(wp, lp, msg, hwnd)
{
   local x, y, c, r, n, m, Time, Figures
   static PrevTime = 0
   Critical

   if A_GuiControl = DDLNames
   {
      Loop, %A_ScriptDir%\Figures\*.life
         Figures .= (A_Index = 1 ? &quot;&quot; : &quot;|&quot;) . RegExReplace(A_LoopFileName, &quot;(.*)\..*&quot;, &quot;$1&quot;)
      Sort, Figures, D|
      GuiControl,, DDLNames, % Figures ? &quot;|&quot; Figures : &quot;|No Files&quot;
      Return
   }
   else if A_GuiControl = Pic
   {
      if GetKeyState(&quot;RButton&quot;, &quot;P&quot;)
      {
         PostMessage, WM_NCLBUTTONDOWN := 0xA1, HTCAPTION := 2,, AutoHotkeyGUI1
         Return
      }
   }
   Else if A_GuiControl =
   {
      PostMessage, WM_NCLBUTTONDOWN := 0xA1, HTCAPTION := 2
      Return
   }

   Time := A_TickCount

   if (StartStop || hwnd != hField || Time - PrevTime &lt; 100)
      Return

   PrevTime := Time
   x := lp &amp; 0xFFFF, y := lp &gt;&gt; 16
   c := Ceil(x/Cell), r := Ceil(y/Cell)

   UpdateNextArray(r, c), Update_hDC(CellArray[r][c])
   , BitBlt(hFieldDC, 0, 0, FieldWidth, FieldHeight, hdc, 0, 0)
   , StartX := CellArray[r][c].x, StartY := CellArray[r][c].y, StartC := c, StartR := r

   if !hPaintDC
   {
      hPaintDC := GetDC(hPic)
      GuiControlGet, Pic, Parent:Pos, Pic
      hPaintBm := CreateDIBSection(PicW, PicH)
      , hPaintMDC := CreateCompatibleDC()
      , oPaintBm := SelectObject(hPaintMDC, hPaintBm)
      , GPaint := Gdip_GraphicsFromHDC(hPaintMDC)
      WinGetPos, X_Field, Y_Field,,, ahk_id %hField%
      WinGetPos, X_Pic, Y_Pic,,, ahk_id %hPic%
      XPosField := X_Pic - X_Field, YPosField := Y_Pic - Y_Field
   }
}

WM_MOUSEMOVE(wp, lp, msg, hwnd)
{
   local x, y, c, r, p, m, n, k
   static c_prev, r_prev
   if (hwnd != hField || StartStop || !GetKeyState(&quot;LButton&quot;, &quot;P&quot;) || !StartR || !StartX)
      Return

   x := lp &amp; 0xFFFF, y := lp &gt;&gt; 16
   last_c := c := Ceil(x/Cell), last_r := r := Ceil(y/Cell)

   if ((c = c_prev &amp;&amp; r = r_prev) || !hPaintMDC)
      Return

   c_prev := c, r_prev := r

   BitBlt(hPaintMDC, 0, 0, PicW, PicH, hdc, XPosField, YPosField)

   Brush := (CtrlState := GetKeyState(&quot;Ctrl&quot;, &quot;P&quot;)) ? pBackBrush : pAliveBrush1

   m := Abs(r - StartR) + 1, n := Abs(c - StartC) + 1

   if GetKeyState(&quot;Alt&quot;, &quot;P&quot;) &amp;&amp; Var := 1
      Loop % ToolTipShow((k := m &gt; n ? m : n) . &quot; diagonal&quot;, k)
         Gdip_FillRectangle(GPaint, Brush
            , StartX + (c &gt; StartC ? 1 : -1)*Cell*(A_Index - 1) - XPosField
            , StartY + (r &gt; StartR ? 1 : -1)*Cell*(A_Index - 1) - YPosField
            , Cell - 1, Cell - 1)

   Else if !GetKeyState(&quot;Alt&quot;, &quot;P&quot;) &amp;&amp; Var := 2
   {
      Loop % m
      {
         p := A_Index
         Loop % ToolTipShow(p . &quot; row`n&quot; . n . &quot; column&quot;, n)
            Gdip_FillRectangle(GPaint, Brush
               , StartX + (c &gt; StartC ? 1 : -1)*Cell*(A_Index - 1) - XPosField
               , StartY + (r &gt; StartR ? 1 : -1)*Cell*(p - 1) - YPosField
               , Cell - 1, Cell - 1)
      }
   }
   BitBlt(hFieldDC, XPosField, YPosField, PicW, PicH, hPaintMDC, 0, 0)
}

WM_LBUTTONUP(wp, lp, msg, hwnd)
{
   local n, m, p
   if (hwnd != hField || StartStop)
      Return

   ToolTip
   Critical

   m := Abs(last_r - StartR) + 1, n := Abs(last_c - StartC) + 1
   if Var = 1
      Loop % m &gt; n ? m : n
         CurrentR := StartR + (last_r &gt; StartR ? 1 : -1)*(A_Index - 1)
         , CurrentC := StartC + (last_c &gt; StartC ? 1 : -1)*(A_Index - 1)
         , CellArray[CurrentR][CurrentC].alive := !CtrlState
         , UpdateNextArray(CurrentR, CurrentC)

   else if Var = 2
   {
      Loop % m
      {
         p := A_Index
         Loop % n
            CurrentR := StartR + (last_r &gt; StartR ? 1 : -1)*(p - 1)
            , CurrentC := StartC + (last_c &gt; StartC ? 1 : -1)*(A_Index - 1)
            , CellArray[CurrentR][CurrentC].alive := !CtrlState
            , UpdateNextArray(CurrentR, CurrentC)
      }
   }

   if !(Var &amp;&amp; hPaintDC)
      Return

   BitBlt(hdc, XPosField, YPosField, PicW, PicH, hPaintMDC, 0, 0)
   , SelectObject(hPaintMDC, oPaintBm), DeleteObject(hPaintBm), DeleteDC(hPaintMDC)
   , Gdip_DeleteGraphics(GPaint), ReleaseDC(hPaintDC, hPic)
   , hPaintDC := Var := StartR := StartX := CtrlState := &quot;&quot;
}

UpdateNextArray(r, c)
{
   global NextArray
   Loop 3
   {
      n := c + A_Index - 2
      Loop 3
      {
         m := r + A_Index - 2
         if !NextArray.HasKey(m &quot;|&quot; n)
            NextArray[m &quot;|&quot; n] := {r: m, c: n}
      }
   }
}

ToolTipShow(Text, Value)
{
   ToolTip % Text
   Return Value
}

Notify(Text, ColorWin, FontName, Options, timeout, Alpha = 255, Token = 1)
{
   Options .= &quot; q4&quot;
   If !Token &amp;&amp; !pToken := Gdip_Startup()
   {
      MsgBox, 48, Ошибка GDI+, Убедитесь в наличии gdiplus.dll в вашей системе!
      ExitApp
   }

   AllStyles = Italic|Bold|Underline|Strikeout
   Loop, parse, AllStyles, |
      if InStr(Options, A_LoopField)
         Styles .= A_LoopField

   if !RegExMatch(Options, &quot;i).*s(\d+).*&quot;, Found)
   {
      MsgBox, 0x1010, Notify Error, Не задан размер шрифта!
      ExitApp
   }
   s := Found1

   x := RegExMatch(Options, &quot;i).*x(\d+).*&quot;, Found) ? Found1 : (10, Options .= &quot; x10&quot;)
   y := RegExMatch(Options, &quot;i).*y(\d+).*&quot;, Found) ? Found1 : (10, Options .= &quot; y10&quot;)
   c := RegExMatch(Options, &quot;i).*c([0-9A-Fa-f]+)( |$)&quot;, Found) ? Found1 : (&quot;FF000000&quot;, Options .= &quot; cFF000000&quot;)

   ; WS_EX_LAYERED := 0x80000, WS_EX_TRANSPARENT := 0x20
   Gui, Notyfy:New, -Caption +E0x80020 +AlwaysOnTop +ToolWindow +Owner +HwndID
   Gui, Notyfy:Show, NA

   hbm := CreateDIBSection(1, 1), hdc := CreateCompatibleDC()
   obm := SelectObject(hdc, hbm), G := Gdip_GraphicsFromHDC(hdc)

   MeasureString(G, Text, FontName, Styles, s, WText, HText)
   Width := WText + 2*x, Height := HText + 2*y
   SelectObject(hdc, obm), DeleteObject(hbm), Gdip_DeleteGraphics(G)

   hbm := CreateDIBSection(Width, Height)
   obm := SelectObject(hdc, hbm), G := Gdip_GraphicsFromHDC(hdc), Gdip_SetSmoothingMode(G, 4)

   pBrush := Gdip_BrushCreateSolid(ColorWin)

   Gdip_FillRoundedRectangle(G, pBrush, 0, 0, Width-1, Height-1, Height//2 &gt; 20 ? 20 : Height//2)
   Gdip_DeleteBrush(pBrush)

   Gdip_TextToGraphics(G, Text, Options, FontName, Width, Height)

   Alpha_ := -10
   Loop
   {
      Alpha_+=10
      UpdateLayeredWindow(ID, hdc
         , (A_ScreenWidth-Width)//2, (A_ScreenHeight-Height)//2, Width, Height, Alpha_)
      Sleep, 10
   } Until Alpha_ + 10 &gt; Alpha

   UpdateLayeredWindow(ID, hdc
      , (A_ScreenWidth-Width)//2, (A_ScreenHeight-Height)//2, Width, Height, Alpha)

   Sleep, timeout

   Alpha_ := Alpha
   Loop
   {
      Alpha_-=10
      UpdateLayeredWindow(ID, hdc
         , (A_ScreenWidth-Width)//2, (A_ScreenHeight-Height)//2, Width, Height, Alpha_)
      Sleep, 10
   } Until Alpha_ - 10 &lt; 0

   UpdateLayeredWindow(ID, hdc
      , (A_ScreenWidth-Width)//2, (A_ScreenHeight-Height)//2, Width, Height, 0)

   Gui, Notify:Destroy

   SelectObject(hdc, obm), DeleteObject(hbm), DeleteDC(hdc), Gdip_DeleteGraphics(G)
   if !Token
      Gdip_Shutdown(pToken)
}

MeasureString(G, Text, FontName, Styles, Size, ByRef WText, ByRef HText)
{
   Style = 0
   StyleArray := [[&quot;Bold&quot;, 1], [&quot;Italic&quot;, 2], [&quot;Underline&quot;, 4], [&quot;Strikeout&quot;, 8]]
   for key, value in StyleArray
      if InStr(Styles, value.1)
         Style += value.2

   if !hFamily := Gdip_FontFamilyCreate(FontName)
   {
      MsgBox, Указанный шрифт не поддерживается системой!
      ExitApp
   }
   hFont := Gdip_FontCreate(hFamily, Size, Style)
   FormatStyle := NoWrap ? 0x4000 | 0x1000 : 0x4000
   hFormat := Gdip_StringFormatCreate(FormatStyle)
   VarSetCapacity(RectF, 16)
   Result := Gdip_MeasureString(G, Text, hFont, hFormat, RectF)

   Gdip_DeleteStringFormat(hFormat)
   Gdip_DeleteFont(hFont)
   Gdip_DeleteFontFamily(hFamily)

   WText := RegExReplace(Result, &quot;(.*?\|){2}(.*?)\|.*&quot;, &quot;$2&quot;)
   HText := RegExReplace(Result, &quot;(.*?\|){3}(.*?)\|.*&quot;, &quot;$2&quot;)
}

WM_COMMAND(wp, lp)
{
   global hDDLNames
   CBN_CLOSEUP := 8
   if ((wp &gt;&gt; 16 = CBN_CLOSEUP) &amp;&amp; lp = hDDLNames)
   {
      Gui, Load:Default
      GuiControl, Focus, OK
      GuiControlGet, Choose,, DDLNames
      if !Choose
         GuiControl,, DDLNames, Select a Name:||
   }
}</code></pre></div><p>Здесь я использовал <a href="http://ru.wikipedia.org/wiki/%D0%98%D0%B3%D1%80%D0%B0_%D0%B6%D0%B8%D0%B7%D0%BD%D1%8C#.D0.9A.D0.BE.D0.BC.D0.BF.D1.8C.D1.8E.D1.82.D0.B5.D1.80.D0.BD.D0.B0.D1.8F_.D1.80.D0.B5.D0.B0.D0.BB.D0.B8.D0.B7.D0.B0.D1.86.D0.B8.D1.8F">второй, рациональный</a> алгоритм из <a href="http://ru.wikipedia.org/wiki/%D0%98%D0%B3%D1%80%D0%B0_%D0%B6%D0%B8%D0%B7%D0%BD%D1%8C">Википедии</a>. В коде он реализуется по метке <strong>Cycle:</strong>, насколько возможно, откомментирован. Если у кого-то возникнут мысли по оптимизации, поделитесь!<br /><a href="http://onemove.ru/63117/">Фигура</a> для загрузки на пробу. Папка Figures должна быть помещена в директорию скрипта.</p>]]></content>
			<author>
				<name><![CDATA[teadrinker]]></name>
				<uri>http://forum.script-coding.com/profile.php?id=24515</uri>
			</author>
			<updated>2011-12-09T22:03:35Z</updated>
			<id>http://forum.script-coding.com/viewtopic.php?pid=54413#p54413</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: игра «Жизнь» [Life]]]></title>
			<link rel="alternate" href="http://forum.script-coding.com/viewtopic.php?pid=53829#p53829" />
			<content type="html"><![CDATA[<p>Будет, будет! Просто ещё до ума довести нужно, а времени не очень много.</p>]]></content>
			<author>
				<name><![CDATA[teadrinker]]></name>
				<uri>http://forum.script-coding.com/profile.php?id=24515</uri>
			</author>
			<updated>2011-11-25T08:46:08Z</updated>
			<id>http://forum.script-coding.com/viewtopic.php?pid=53829#p53829</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: игра «Жизнь» [Life]]]></title>
			<link rel="alternate" href="http://forum.script-coding.com/viewtopic.php?pid=53828#p53828" />
			<content type="html"><![CDATA[<div class="quotebox"><cite>teadrinker пишет:</cite><blockquote><p>Я ж говорю, уже сделал. Со сложностями не столкнулся, использовал массивы. Работает довольно шустренько, даже в больших колониях. Ну, не в таких больших, как на роликах. <img src="//forum.script-coding.com/img/smilies/smile.png" width="15" height="15" /></p></blockquote></div><p>И шож, где игруля?</p>]]></content>
			<author>
				<name><![CDATA[Zohann]]></name>
				<uri>http://forum.script-coding.com/profile.php?id=26234</uri>
			</author>
			<updated>2011-11-25T08:42:51Z</updated>
			<id>http://forum.script-coding.com/viewtopic.php?pid=53828#p53828</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: игра «Жизнь» [Life]]]></title>
			<link rel="alternate" href="http://forum.script-coding.com/viewtopic.php?pid=53760#p53760" />
			<content type="html"><![CDATA[<div class="quotebox"><cite>Zohann пишет:</cite><blockquote><p>...присвоить мне статус разработчика...</p></blockquote></div><p>OFF: Цель форума не в получении статуса. <img src="//forum.script-coding.com/img/smilies/wink.png" width="15" height="15" /></p>]]></content>
			<author>
				<name><![CDATA[Grey]]></name>
				<uri>http://forum.script-coding.com/profile.php?id=25792</uri>
			</author>
			<updated>2011-11-21T21:43:35Z</updated>
			<id>http://forum.script-coding.com/viewtopic.php?pid=53760#p53760</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: игра «Жизнь» [Life]]]></title>
			<link rel="alternate" href="http://forum.script-coding.com/viewtopic.php?pid=53758#p53758" />
			<content type="html"><![CDATA[<p><strong>Zohann</strong>, не надо жертв!</p>]]></content>
			<author>
				<name><![CDATA[DD]]></name>
				<uri>http://forum.script-coding.com/profile.php?id=25263</uri>
			</author>
			<updated>2011-11-21T20:24:21Z</updated>
			<id>http://forum.script-coding.com/viewtopic.php?pid=53758#p53758</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: игра «Жизнь» [Life]]]></title>
			<link rel="alternate" href="http://forum.script-coding.com/viewtopic.php?pid=53731#p53731" />
			<content type="html"><![CDATA[<div class="quotebox"><cite>teadrinker пишет:</cite><blockquote><p>В благодарностях <strong>Александр_</strong>&#039;а не упомянул! <img src="//forum.script-coding.com/img/smilies/smile.png" width="15" height="15" /></p></blockquote></div><p>Ну если это только единственная причина не присвоить мне статус разработчика, то уже исправил! <img src="//forum.script-coding.com/img/smilies/smile.png" width="15" height="15" /></p>]]></content>
			<author>
				<name><![CDATA[Zohann]]></name>
				<uri>http://forum.script-coding.com/profile.php?id=26234</uri>
			</author>
			<updated>2011-11-21T07:16:30Z</updated>
			<id>http://forum.script-coding.com/viewtopic.php?pid=53731#p53731</id>
		</entry>
</feed>
