Что нового

Переход с клетки на клетку в обпределённой области на примере сапёра

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
nsgenn
а в пвмяти поискать, пробывали? в хр находились мины и открытые цифры.
 

nsgenn

Новичок
Сообщения
52
Репутация
1
inververs

нет, не пробовал, пока еще не разбирался с вопросом работы в памяти, регулярные выражения разбирал. Да и не интересно в памяти этой игры искать, ибо можно сразу расставить флаги, нет эстетического удовольствия ))
 

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
Ну удовольствие получите тогда, когда напишите честный алгоритм раставляющий мины, зачем вы себя мучаете с пикселями? Пиксели на разных конфигурациях видеокарт будут разные, это путь в никуда. Мне кажется, лучше от пикселей сразу отказаться.
 

nsgenn

Новичок
Сообщения
52
Репутация
1
inververs [?]
Ну удовольствие получите тогда, когда напишите честный алгоритм раставляющий мины, зачем вы себя мучаете с пикселями? Пиксели на разных конфигурациях видеокарт будут разные, это путь в никуда. Мне кажется, лучше от пикселей сразу отказаться.

вдохновляет, правда слабо представляю как найти нужные адреса, по какому критерию отсев вообще делать? К примеру в играх где есть ресурсы - они могут уменьшаться, увеличиваться - тут не понятно вообще что.
 

C2H5OH

AutoIT Гуру
Сообщения
1,473
Репутация
333
inververs
А что такое "честный алгоритм раставляющий мины" ?
 

nsgenn

Новичок
Сообщения
52
Репутация
1
C2H5OH [?]
inverversА что такое "честный алгоритм раставляющий мины" ?

это когда знаешь где мины, но с памяти читаешь только цифры, что отображаются в окне игры.
 

рррреееееее

Новичок
Сообщения
4
Репутация
0
Код:
#cs
Бот для игры Сапёр (Windows XP, ru_RU).
Версия 1.0 by рррреееееее [Мы не ищем легких путей]
Отталкивался от исходника C2H5OH
#ce
;Глобальные переменные получают рандомные большие значения просто потому, что мы пока не умеем по другому
Global $poleSizeX=100, $poleSizeY=100   ; размер поля 1600x1600 нет таких экранов
;Global $MaxMineNumber = 667 ; болше-некуда, точное количество позже не нужно
;Global $MinesFound = 0 ; количество найденных мин
Global $OpenFlag = 1, $tiktak = 0 ; какой-то флажок
Global $posX1, $posX2, $posY1, $posY2 ; кубик 3на3
Global $Bomb =0, $Pusto = 0, $PustoAndBomb = 0 ;кол-во бомб и пустых клеток вокруг ячейки
Global $CentrColors[9] = [0xC0C0C0, _; 0 - открытое поле, рядом 0 мин
						   0x0000FF, _; 1 - открытое поле, рядом 1 мина
						   0x008000, _; 2 - открытое поле, рядом 2 мины
						   0xFF0000, _; 3 - открытое поле, рядом 3 мины
						   0x000080, _; 4 - открытое поле, рядом 4 мины
						   0x800000, _; 5 - открытое поле, рядом 5 мин
						   0x008080, _; 6 - открытое поле, рядом 6 мин
						   0x000000, _; 7 - открытое поле, рядом 7 мин
						   0x808080]; 8 -  открытое поле, рядом 8 мин
Global $CellColors[3] = [0xFFFFFF, _; 0- неоткрытое поле
						   0xC0C0C0, _; 1 - открытое поле
						   0xFF0000] ; 2 - подорванная мина (конец игре)
Global $pole[$poleSizeX][$poleSizeY]

Global $zX1=12 ;отступ для проверки состояния ячейки
Global $zX2=20 ;отступ для проверки содержимого ячейки
Global $zY1=55 ;отступ для проверки состояния ячейки
Global $a16=16 ;размер ячейки


HotKeySet("!{F11}", "Terminate")    ; Alt + F11


   Initialition()
   While $OpenFlag > 0
	  $OpenFlag=0
	  MineSweeperScan() ;1 Сканирование сапера в массив
	  MineCheckFinih()
	  MineCheckBomb() ;2 Ставим флажки бомб
	  MinesOpenRandom()
   WEnd


Func Initialition()
   If Not WinExists("Сапер") Then ;Проверка запущен ли сапер, попытка запуска
	  If MsgBox(4 + 32, "Error", "Сапер не запущен. Запустить?") = 6 Then
		  Run("C:\windows\system32\winmine.exe")
	  Else
		  MyExit()
	  EndIf
   EndIf
	  Sleep(3000)
   If Not WinExists("Сапер") Then
	  MsgBox(0,"Печаль","У вас нет Сапера")
	  MyExit()
   Else
	  WinActivate("Сапер")
	  Sleep(1000)
	  $aPos = WinGetClientSize("[Class:Сапер]"); Возвращает размер клиентской области (без заголовка и границ).
	  $poleSizeX = ($aPos[0]-20)/$a16;Сапер у нас получился 500 319, разница высоты 46
	  $poleSizeY = ($aPos[1]-63)/$a16
	  Opt("PixelCoordMode", 2) ; установили координаты относительно клиентской области
	  Opt("MouseCoordMode", 2) ; тоже самое для мыши
   EndIf
   Send("{F2}")
EndFunc

Func MineSweeperScan()
   #comments-start
   99 стоит флажек бомба
   100 неоткрытое поле
   0 открытое пустое
   #comments-end
   $tiktak = 0
    For $i = 0 To $poleSizeX-1
        For $j = 0 To $poleSizeY-1
            If PixelGetColor($zX1+$a16*$i,$zY1+$a16*$j) = $CellColors[0] Then ; если ячейку не вскрывали
			   If (PixelGetColor($zX2+$a16*$i,66+$a16*$j) = 0x000000) and _
				  (PixelGetColor($zX2+$a16*$i,60+$a16*$j) = 0xFF0000)Then ;Если стоит флажек(бомба)
				  $pole[$i][$j] = 99
				  ;MsgBox(0,"Флажек",$i&"ввв"&$j)
			   ElseIf (PixelGetColor($zX2+$a16*$i,66+$a16*$j) = 0x000000) and _
				  (PixelGetColor($zX2+$a16*$i,58+$a16*$j) = 0x000000) Then ;Если стоит вопрос убираем его
				  $pole[$i][$j] = 100
				  $tiktak +=1
				  MouseMove($zX2+$a16*$i,$zY1+$a16*$j,0)
				  Sleep(100)
				  MouseClick("Right", $zX2+$a16*$i,$zY1+$a16*$j)
			   Else
				  $pole[$i][$j] = 100
				  $tiktak +=1
			   EndIf
            Else
                $color = PixelGetColor($zX2+$a16*$i,63+$a16*$j)
                Switch $color
                    Case $CentrColors[0]
                        $pole[$i][$j] = 0
                    Case $CentrColors[1]
                        $pole[$i][$j] = 1
                    Case $CentrColors[2]
                        $pole[$i][$j] = 2
                    Case $CentrColors[3]
                        $pole[$i][$j] = 3
                    Case $CentrColors[4]
                        $pole[$i][$j] = 4
                    Case $CentrColors[5]
                        $pole[$i][$j] = 5
                    Case $CentrColors[6]
                        $pole[$i][$j] = 6
                    Case $CentrColors[7]
                        $pole[$i][$j] = 7
                    Case $CentrColors[8]
                        $pole[$i][$j] = 8
                EndSwitch
            EndIf
        Next
	 Next
 EndFunc

Func MineMatrix3x3($k,$l) ;передаем координаты какой-то клетки (перебором, да хоть как)
   $Bomb =0
   $Pusto = 0
   $PustoAndBomb = 0
   $posX1=$k-1
   $posX2=$k+1
   $posY1=$l-1
   $posY2=$l+1
	  if $posX1<0 Then
		 $posX1=0
	  EndIf
		 if $posX2>$poleSizeX Then
			$posX2=$poleSizeX
		 EndIf
	  if $posY1<0 Then
		 $posY1=0
	  EndIf
		 if $posY2>$poleSizeY Then
			$posY2=$poleSizeY
		 EndIf

	  For $i=$posX1 To $posX2
		 For $j=$posY1 To $posY2

			   If $pole[$i][$j] == 99 Then
				  $Bomb += 1
			   EndIf

			   If $pole[$i][$j] == 100 Then
				  $Pusto += 1
			   EndIf

		 Next
	  Next

   $PustoAndBomb = $Bomb + $Pusto

EndFunc

Func ClickBomb($k,$l)
	  If ($pole[$k][$l]=$PustoAndBomb) and ($pole[$k][$l]>0)  Then ;Открываем явные бомбы
		 ;MsgBox(0,"sdf",$Pusto)
		 For $i=$posX1 To $posX2
			For $j=$posY1 To $posY2
				  If $pole[$i][$j] = 100 Then
					 $pole[$i][$j] = 99
					 MouseMove($zX2+$a16*$i,$zY1+$a16*$j,0)
					 Sleep(100)
					 MouseClick("Right", $zX2+$a16*$i,$zY1+$a16*$j)
					 ConsoleWrite("Нашел бомбу, поставил вешку, покурили "&$i&","&$j&@CR)
					 MineCheckClose($zX1+$a16*$i,$zY1+$a16*$j)
					 $OpenFlag+=1
				  EndIf
				  ;MsgBox(0,"sdf",$i&$j)
			Next
		 Next
	  EndIf
EndFunc

Func ClickPusto($k,$l)
	  If ($pole[$k][$l]=$Bomb) and ($pole[$k][$l]>0) Then ;открываем явные пустышки
		 For $i=$posX1 To $posX2
			For $j=$posY1 To $posY2
				  If $pole[$i][$j] = 100 Then
					 $pole[$i][$j] = 0
					 MouseMove($zX2+$a16*$i,$zY1+$a16*$j,0)
					 Sleep(100)
					 MouseClick("Left", $zX2+$a16*$i,$zY1+$a16*$j)
					 ConsoleWrite("Этот квадрат безопасен "&$i&","&$j&@CR)
					 MineCheckClose($zX1+$a16*$i,$zY1+$a16*$j)
					 $OpenFlag+=1
				  EndIf
			Next
		 Next
	  EndIf
EndFunc

Func MineCheckBomb()
   For $i=0 To $poleSizeX-1
	  For $j=0 To $poleSizeY-1
		 if (Not ($pole[$i][$j] == 100)) and (Not ($pole[$i][$j] == 0)) Then
			MineMatrix3x3($i,$j)
			ClickBomb($i,$j)
			MineMatrix3x3($i,$j)
			ClickPusto($i,$j)
		 EndIf
	  Next
   Next
EndFunc

Func MinesOpenRandom()
    While $OpenFlag = 0
        $i = Random(0, $poleSizeX-1, 1)
        $j = Random(0, $poleSizeY-1, 1)
        If $pole[$i][$j] = 100 Then
            ConsoleWrite("(Другого пути нет!) Отправили смертника в квадрат "&$i&","&$j&@CR)
			   MouseMove($zX2+$a16*$i,$zY1+$a16*$j,0)
			   Sleep(100)
			   MouseClick("Left", $zX2+$a16*$i,$zY1+$a16*$j)
			   MineCheckClose($zX2+$a16*$i,$zY1+$a16*$j)
			   $OpenFlag += 1
            Return
        EndIf
    WEnd
EndFunc

Func MineCheckClose($i,$j)
   If PixelGetColor($i+2,$j+2) = $CellColors[2] Then
	  ConsoleWrite("Сапер подорвался на мине"&@CR&"-----------"&@CR)
	  Terminate()
   EndIf
EndFunc

Func MineCheckFinih()
   if $tiktak = 0 Then
	  ConsoleWrite("Минное поле очищено!"&@CR&"-----------"&@CR)
	  Terminate()
   EndIf
EndFunc

Func Terminate()
    ConsoleWrite("остановлено"&@CR&"-----------"&@CR)
    Exit 0
EndFunc
Открыл для себя AutoIt. Решил что нужно попрактиковаться. Есть мысль писать ботов ;D. Взял исходник C2H5OH, алгоритм не смотрел (не спортивно). Взял только конструкции. Бот получился примитивный, но работает на порядок быстрее (Даже слишком).Поле абсолютно любое и количество мин(больше 24X30X667 не выстивишь) Вопрос к C2H5OH - что отвечает за "висение" программы в памяти и запуск по F11 (запуск понятен)
 

C2H5OH

AutoIT Гуру
Сообщения
1,473
Репутация
333
Вот это отвечает
Код:
While 1
    Sleep(10000)
WEnd



Добавлено:
Сообщение автоматически объединено:

работает на порядок быстрее (Даже слишком).

:rofl: :rofl: :laugh:

Так это он не работает на порядок быстрее, это он слишком быстро подрывается на первой попавшейся мине.

bb0f6b7230c4.jpg
 

рррреееееее

Новичок
Сообщения
4
Репутация
0
Подрывается только при случайном выборе клетки, когда алгоритм бессилен. Но тут как повезет же. Алгоритм писался так, как будто это человек играет. У вас в алгоритме те же грабли
 

C2H5OH

AutoIT Гуру
Сообщения
1,473
Репутация
333
У меня нет граблей.
У меня рандомный клик происходит когда действительно уже ничего сделать нельзя.
А у вашего алгоритма вон сколько возможностей открыть клетки было...
 

СН3СН2ОН

Знающий
Сообщения
78
Репутация
12
Позволю себе не согласиться с вами.
И чтобы не быть голословным разберу ваш алгоритм.
Что нашел
1. На профессионале зависает 4 из 5 случаев.
2. Также при рандомном выборе вскрывает бомбу(ну это понятно), но почему не останавливается?
И да это рррреееееее говорит.
 

C2H5OH

AutoIT Гуру
Сообщения
1,473
Репутация
333
1. Покажите скрин что там у вас зависает.

2. ??? Вы считаете что рандомный клик не может вскрыть бомбу???????
 

C2H5OH

AutoIT Гуру
Сообщения
1,473
Репутация
333
У меня на работе нет возможности мультики смотреть.
В чем проблема скрин сделать?
А у себя я запускал десятки раз, у меня всё работает)
 

СН3СН2ОН

Знающий
Сообщения
78
Репутация
12
Работа над ошибками.
1.Извиняюсь перед C2H5OH. Я крутил у себя его версию скрипта 6.0 возможно при публикации что-то похерилось, а вот скрипт 2.1 работает причем хорошо (Но как? Я сломал мозг, но функция MinesweeperAdvansedOpenCell мне не поддалась).
2.Сапер вообще не простая игра...
3.Сделал версию своего скрипта 3.0. Теперь это более умный скрипт.
4. Особенность - ему все равно сколько мин, работаем вслепую, по настоящему.
Код:
#include <Array.au3>

;Бот для игры Сапёр (Windows XP, ru_RU).
;Версия 3.0 by СН3СН2ОН

;Глобальные переменные получают рандомные большие значения просто потому, что мы пока не умеем по другому
Global $poleSizeX=30, $poleSizeY=30   ; размер поля
Global $OpenFlag = 1, $tiktak = 0 ; какой-то флажок
Global $posX1, $posX2, $posY1, $posY2 ; кубик 3на3
Global $Bomb =0, $Pusto = 0, $PustoAndBomb = 0 ;кол-во бомб и пустых клеток вокруг ячейки
Global $CentrColors[9] = [0xC0C0C0, _; 0 - открытое поле, рядом 0 мин
                           0x0000FF, _; 1 - открытое поле, рядом 1 мина
                           0x008000, _; 2 - открытое поле, рядом 2 мины
                           0xFF0000, _; 3 - открытое поле, рядом 3 мины
                           0x000080, _; 4 - открытое поле, рядом 4 мины
                           0x800000, _; 5 - открытое поле, рядом 5 мин
                           0x008080, _; 6 - открытое поле, рядом 6 мин
                           0x000000, _; 7 - открытое поле, рядом 7 мин
                           0x808080]; 8 -  открытое поле, рядом 8 мин
Global $CellColors[3] = [0xFFFFFF, _; 0- неоткрытое поле
                           0xC0C0C0, _; 1 - открытое поле
                           0xFF0000] ; 2 - подорванная мина (конец игре)
;Шаблоны для раскрытия
Global $S121[3] = [1,2,1]
Global $S1221[4] = [1,2,2,1]
Global $S212[3] = [2,1,2]

Global $S1120[4] = [1,1,2,0]
Global $S0120[4] = [0,1,2,0]

Global $S1120_i[4] = [0,2,1,1]
Global $S0120_i[4] = [0,2,1,0]
;
Global $MassStatistic[2] = [0,0] ;как играет проверим 1 победа 2 поражение
Global $aPos[2]
Global $StatisticExit = 0
Global $pole[$poleSizeX][$poleSizeY]
Global $pole4time[$poleSizeX][$poleSizeY]
Global $poleVer[$poleSizeX][$poleSizeY]
Global $poleClean[$poleSizeX][$poleSizeY]
Global $timeSleeep = 1
Global $zX1=12 ;отступ для проверки состояния ячейки
Global $zX2=20 ;отступ для проверки содержимого ячейки
Global $zY1=55 ;отступ для проверки состояния ячейки
Global $a16=16 ;размер ячейки


HotKeySet("!{F11}", "Terminate")    ; Alt + F11
Go()
MsgBox(0,"Статистика"," Выиграл "&$MassStatistic[0]&" Проиграл "&$MassStatistic[1])
Terminate()

;111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
Func Go()
   $StatisticExit = 0
   $OpenFlag = 1
   $tiktak = 0
   $Bomb =0
   $Pusto = 0
   $PustoAndBomb = 0
   Initialition()
   While $OpenFlag > 0 ; пока могу решать
      $OpenFlag=0
	  MineCheckInit()
      MineSweeperScan() ;1 Сканирование сапера в массив
      if MineCheckFinih() Then ;Если нет вскрытой бомбы, от рукожопов и случайности
		 MineCheckBomb()
	  EndIf
   	  if $OpenFlag = 0 Then
		 MineCheckShablon()
	  EndIf
	  if $OpenFlag = 0 Then
		 ConsoleWrite("Доработать вероятность а пока шарашим рандомом РРРАААААААААААААЗ !!!"&@CR)
		 MinesOpenRandom()
	  EndIf
   WEnd
EndFunc
;111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111

Func Initialition()
   If Not WinExists("Сапер") Then ;Проверка запущен ли сапер, попытка запуска
      If MsgBox(4 + 32, "Error", "Сапер не запущен. Запустить?") = 6 Then
          Run("C:\windows\system32\winmine.exe")
      Else
          Terminate()
      EndIf
   EndIf
      Sleep(3000)
   If Not WinExists("Сапер") Then
      MsgBox(0,"Печаль","У вас нет Сапера")
      Terminate()
   Else
      WinActivate("Сапер")
      Sleep(1000)
      $aPos = WinGetClientSize("[Class:Сапер]"); Возвращает размер клиентской области (без заголовка и границ).
      $poleSizeX = ($aPos[0]-20)/$a16;Сапер у нас получился 500 319, разница высоты 46
      $poleSizeY = ($aPos[1]-63)/$a16
      Opt("PixelCoordMode", 2) ; установили координаты относительно клиентской области
      Opt("MouseCoordMode", 2) ; тоже самое для мыши
	  For $i = 0 To $poleSizeX-1
		 For $j = 0 To $poleSizeY-1
			$pole4time[$i][$j]=0
			$poleVer[$i][$j]=0
		 Next
	  Next
   EndIf
   Send("{F2}")
EndFunc

Func MineSweeperScan()
   #comments-start
   99 стоит флажек бомба
   100 неоткрытое поле
   1000 открытое пустое
   #comments-end
   $tiktak = 0
    For $i = 0 To $poleSizeX-1
        For $j = 0 To $poleSizeY-1
            If PixelGetColor($zX1+$a16*$i,$zY1+$a16*$j) = $CellColors[0] Then ; если ячейку не вскрывали
               If (PixelGetColor($zX2+$a16*$i,66+$a16*$j) = 0x000000) and _
                  (PixelGetColor($zX2+$a16*$i,60+$a16*$j) = 0xFF0000)Then ;Если стоит флажек(бомба)
                  $pole[$i][$j] = 99
                  ;MsgBox(0,"Флажек",$i&"ввв"&$j)
               ElseIf (PixelGetColor($zX2+$a16*$i,66+$a16*$j) = 0x000000) and _
                  (PixelGetColor($zX2+$a16*$i,58+$a16*$j) = 0x000000) Then ;Если стоит вопрос убираем его
                  $pole[$i][$j] = 100
                  $tiktak +=1
                  MouseMove($zX2+$a16*$i,$zY1+$a16*$j,0)
                  Sleep($timeSleeep)
                  MouseClick("Right", $zX2+$a16*$i,$zY1+$a16*$j)
               Else
                  $pole[$i][$j] = 100
                  $tiktak +=1
               EndIf
            Else
                $color = PixelGetColor($zX2+$a16*$i,63+$a16*$j)
                Switch $color
                    Case $CentrColors[0]
                        $pole[$i][$j] = 1000
                    Case $CentrColors[1]
                        $pole[$i][$j] = 1
                    Case $CentrColors[2]
                        $pole[$i][$j] = 2
                    Case $CentrColors[3]
                        $pole[$i][$j] = 3
                    Case $CentrColors[4]
                        $pole[$i][$j] = 4
                    Case $CentrColors[5]
                        $pole[$i][$j] = 5
                    Case $CentrColors[6]
                        $pole[$i][$j] = 6
                    Case $CentrColors[7]
                        $pole[$i][$j] = 7
                    Case $CentrColors[8]
                        $pole[$i][$j] = 8
                EndSwitch
            EndIf
        Next
     Next
 EndFunc

Func MineMatrix3x3($k,$l) ;передаем координаты какой-то клетки (перебором, да хоть как)
   $Bomb =0
   $Pusto = 0
   $PustoAndBomb = 0
   $sik = 0

   Coordinati3x3($k,$l)

      For $i=$posX1 To $posX2
         For $j=$posY1 To $posY2

               If $pole[$i][$j] = 99 Then
                  $Bomb += 1
               EndIf

               If $pole[$i][$j] = 100 Then
                  $Pusto += 1
				  $sik +=1
               EndIf

         Next
      Next

   $PustoAndBomb = $Bomb + $Pusto

   If $sik = 0 Then ; для дальнейшего ускорения скрипта, если нет вокруг неоткрытых, зачем сюда заходить?
	  $pole4time[$k][$l]=100
   EndIf

EndFunc

Func MineMatrix3x3_ver($k,$l) ;передаем координаты какой-то клетки (перебором, да хоть как)
   $Bomb =0
   $Pusto = 0
   $PustoAndBomb = 0
   $sik = 0

   Coordinati3x3($k,$l)

      For $i=$posX1 To $posX2
         For $j=$posY1 To $posY2

               If $pole[$i][$j] == 99 Then
                  $Bomb += 1
               EndIf

               If $pole[$i][$j] == 100 Then
                  $Pusto += 1
               EndIf

         Next
      Next


   If ($pusto > 0) Then
	  $sik = (($pole[$k][$l]-$bomb) / $Pusto)
	  ;MsgBox(0,"sik",$sik)
      For $i=$posX1 To $posX2
         For $j=$posY1 To $posY2

               If $pole[$i][$j] == 100 Then
                  $poleVer[$i][$j] += $sik
               EndIf

         Next
      Next
   EndIf

   			   ;_ArrayTranspose($poleVer)
			   ;_ArrayDisplay($poleVer)

EndFunc

Func ClickBomb($k,$l)
      If ($pole[$k][$l]=$PustoAndBomb) and ($pole[$k][$l]>0)  Then ;Открываем явные бомбы
         ;MsgBox(0,"sdf",$Pusto)
         For $i=$posX1 To $posX2
            For $j=$posY1 To $posY2
                  If $pole[$i][$j] = 100 Then
                     $pole[$i][$j] = 99
                     MouseMove($zX2+$a16*$i,$zY1+$a16*$j,0)
                     Sleep($timeSleeep)
                     MouseClick("Right", $zX2+$a16*$i,$zY1+$a16*$j)
                     ConsoleWrite("Нашел бомбу, поставил вешку, покурили "&$i&","&$j&@CR)
                     MineCheckClose($zX1+$a16*$i,$zY1+$a16*$j)
                     $OpenFlag+=1
                  EndIf
                  ;MsgBox(0,"sdf",$i&$j)
            Next
         Next
      EndIf
EndFunc

Func ClickPusto($k,$l)
      If ($pole[$k][$l]=$Bomb) and ($pole[$k][$l]>0) Then ;открываем явные пустышки
         For $i=$posX1 To $posX2
            For $j=$posY1 To $posY2
                  If $pole[$i][$j] = 100 Then
                     $pole[$i][$j] = 1000
                     MouseMove($zX2+$a16*$i,$zY1+$a16*$j,0)
                     Sleep($timeSleeep)
                     MouseClick("Left", $zX2+$a16*$i,$zY1+$a16*$j)
                     ConsoleWrite("Этот квадрат безопасен "&$i&","&$j&@CR)
                     MineCheckClose($zX1+$a16*$i,$zY1+$a16*$j)
                     $OpenFlag+=1
                  EndIf
            Next
         Next
      EndIf
EndFunc

Func Pusto($i,$j)

   $pole[$i][$j] = 1000
   MouseMove($zX2+$a16*$i,$zY1+$a16*$j,0)
   Sleep($timeSleeep)
   MouseClick("Left", $zX2+$a16*$i,$zY1+$a16*$j)
   ConsoleWrite("Этот квадрат безопасен "&$i&","&$j&@CR)
   MineCheckClose($zX1+$a16*$i,$zY1+$a16*$j)
   $OpenFlag+=1

EndFunc

Func Bomb($i,$j)

   $pole[$i][$j] = 99
   MouseMove($zX2+$a16*$i,$zY1+$a16*$j,0)
   Sleep($timeSleeep)
   MouseClick("Right", $zX2+$a16*$i,$zY1+$a16*$j)
   ConsoleWrite("Этот квадрат безопасен "&$i&","&$j&@CR)
   MineCheckClose($zX1+$a16*$i,$zY1+$a16*$j)
   $OpenFlag+=1

EndFunc

Func MineCheckBomb()
   For $i=0 To $poleSizeX-1
      For $j=0 To $poleSizeY-1
         if ($pole[$i][$j] < 100) and ($pole4time[$i][$j] < 100) Then
            MineMatrix3x3($i,$j)
            ClickBomb($i,$j)
            MineMatrix3x3($i,$j)
            ClickPusto($i,$j)
         EndIf
      Next
   Next

EndFunc

Func MinesOpenRandom()
    While $OpenFlag = 0
        $i = Random(0, $poleSizeX-1, 1)
        $j = Random(0, $poleSizeY-1, 1)
        If $pole[$i][$j] = 100 Then
            ConsoleWrite("(Другого пути нет!) Отправили смертника в квадрат "&$i&","&$j&@CR)
               MouseMove($zX2+$a16*$i,$zY1+$a16*$j,0)
               Sleep($timeSleeep)
               MouseClick("Left", $zX2+$a16*$i,$zY1+$a16*$j)
               MineCheckClose($zX2+$a16*$i,$zY1+$a16*$j)
               $OpenFlag += 1
            Return
        EndIf
    WEnd
EndFunc

Func MineCheckClose($i,$j)
   If PixelGetColor($i+2,$j+2) = $CellColors[2] Then
      ConsoleWrite("Сапер подорвался на мине"&@CR&"-----------"&@CR)
	  $MassStatistic[1]+=1

	  For $i = 0 To $poleSizeX-1
		 For $j = 0 To $poleSizeY-1
			$pole[$i][$j]=0
			$pole4time[$i][$j]=0
			$poleVer[$i][$j]=0
		 Next
	  Next

	  $StatisticExit = 1
	  $OpenFlag = 0
	  ;Send("{F2}")
      Terminate()
	  Return
   EndIf
EndFunc

Func MineCheckFinih() ;Если нет вскрытой бомбы, от рукожопов и случайности
   if $tiktak = 0 Then
      ConsoleWrite("Минное поле очищено!"&@CR&"-----------"&@CR)
	  $MassStatistic[0]+=1

	  For $i = 0 To $poleSizeX-1
		 For $j = 0 To $poleSizeY-1
			$pole[$i][$j]=0
			$pole4time[$i][$j]=0
			$poleVer[$i][$j]=0
		 Next
	  Next

	  $OpenFlag = 0
	  ;Send("{F2}")
      Terminate()
	  Return False
   EndIf
   Return True
EndFunc

Func Terminate()
    ConsoleWrite("остановлено"&@CR&"-----------"&@CR)
    Exit 0
 EndFunc

Func MineCheckInit()  ; проверка активно ли окно сапера
   If Not WinActive("Сапер") Then
      Terminate()
   EndIf
EndFunc

Func MineCheckVeroyatnost()

   If $OpenFlag = 0 Then
	  For $i = 0 To $poleSizeX-1
		 For $j = 0 To $poleSizeY-1
			$poleVer[$i][$j]=0
		 Next
	  Next
			  ; _ArrayTranspose($poleVer)
			   ;_ArrayDisplay($poleVer)
	  For $i = 0 To $poleSizeX-1
		 For $j = 0 To $poleSizeY-1
			If ($pole[$i][$j] < 99) and ($pole4time[$i][$j] < 100) Then
			   MineMatrix3x3_ver($i,$j)
			EndIf
		 Next
	  Next

	  $maxV=0
	  $minV=1000
	  $maxX=0
	  $maxY=0
	  $minX=0
	  $minY=0
	  $minCheck=0

	  For $i = 0 To $poleSizeX-1
		 For $j = 0 To $poleSizeY-1
			If ($poleVer[$i][$j] = 3/2) or ($poleVer[$i][$j] = 3) Then
			;if $poleVer[$i][$j]>$maxV Then
			   $maxV=$poleVer[$i][$j]
			   $maxX=$i
			   $maxY=$j
			EndIf
			if ($poleVer[$i][$j]<$minV) and ($poleVer[$i][$j]>0) Then
			   $minV=$poleVer[$i][$j]
			   $minX=$i
			   $minY=$j
			EndIf
		 Next
	  Next

	  For $i = 0 To $poleSizeX-1
		 For $j = 0 To $poleSizeY-1
			if ($poleVer[$i][$j]=$minV) and ($poleVer[$i][$j]>0) Then
			   $minCheck+=1
			EndIf
		 Next
	  Next

	  if ($minV < (1/5)) and ($minV > (1/8)) Then
			   $pole[$minX][$minY] = 1000
			   MouseMove($zX2+$a16*$minX,$zY1+$a16*$minY,0)
			   Sleep($timeSleeep)
			   MouseClick("Left", $zX2+$a16*$minX,$zY1+$a16*$minY)
			   ConsoleWrite("(Вероятность ------------------ "&$minV&" ------------------) Нашел пустое место методом исключения, вскрыли, покурили "&$minX&","&$minY&@CR)
			   MineCheckClose($zX1+$a16*$minX,$zY1+$a16*$minY)
			   $OpenFlag += 1
			   ;_ArrayTranspose($poleVer)
			   ;_ArrayDisplay($poleVer)
			   Return
	  EndIf


	  ;If ($maxV > (8/5)) Then
	  If ($maxV = 3/2) or ($maxV = 3) Then
		 $pole[$maxX][$maxY] = 99
		 MouseMove($zX2+$a16*$maxX,$zY1+$a16*$maxY,0)
		 Sleep($timeSleeep)
		 MouseClick("Right", $zX2+$a16*$maxX,$zY1+$a16*$maxY)
		 ConsoleWrite("(Вероятность ------------------ "&$maxV&" ------------------)Нашел бомбу методом исключения, поставил вешку, покурили "&$maxX&","&$maxY&@CR)
		 MineCheckClose($zX1+$a16*$maxX,$zY1+$a16*$maxY)
		 $OpenFlag += 1
		 ;_ArrayTranspose($poleVer)
		 ;_ArrayDisplay($poleVer)
		 Return
	  EndIf


   MinesOpenRandom()

   EndIf
EndFunc

Func MineMatrixShablonClean($k,$l) ; очистка $poleClean от пересечений, в идеале на выхоте единицы и двойки
   $Bomb =0
   $Pusto = 0
   $PustoAndBomb = 0
   $sik = 0
   $posX1=$k-1
   $posX2=$k+1
   $posY1=$l-1
   $posY2=$l+1
      if $posX1<0 Then
         $posX1=0
      EndIf
         if $posX2>($poleSizeX-1) Then
            $posX2=$poleSizeX-1
         EndIf
      if $posY1<0 Then
         $posY1=0
      EndIf
         if $posY2>($poleSizeY-1) Then
            $posY2=$poleSizeY-1
         EndIf

      For $i=$posX1 To $posX2
         For $j=$posY1 To $posY2

               If $pole[$i][$j] == 99 Then
                  $Bomb += 1
               EndIf

         Next
      Next


   If ($Bomb > 0) Then
	  $poleClean[$k][$l]-=$bomb
   EndIf


EndFunc

Func MineCheckShablon() ;Шаблонные подстановки
   If $OpenFlag = 0 Then
	  For $i = 0 To $poleSizeX-1
		 For $j = 0 To $poleSizeY-1
			if ($pole[$i][$j] == 1000) Or ($pole[$i][$j] == 99) Then
			   $poleClean[$i][$j] = 0
			Else
			   $poleClean[$i][$j]=$pole[$i][$j]
			EndIf
		 Next
	  Next

	  For $i = 0 To $poleSizeX-1
		 For $j = 0 To $poleSizeY-1
			If ($poleClean[$i][$j] > 0) and ($poleClean[$i][$j] < 99) Then
			   MineMatrixShablonClean($i,$j)
			EndIf
		 Next
	  Next

	  For $i = 0 To $poleSizeX-1
		 For $j = 0 To $poleSizeY-1
			If ($poleClean[$i][$j] > 0) and ($poleClean[$i][$j] < 3) Then
			   MineFindShablon($i,$j)
			   If $OpenFlag > 0 Then
				  Return
			   EndIf
			EndIf
		 Next
	  Next


   			   ;_ArrayTranspose($poleClean)
			   ;_ArrayDisplay($poleClean)

   EndIf
EndFunc

Func MineFindShablon($k,$l)

;Global $S121[3] = [1,2,1]
;Global $S1221[4] = [1,2,2,1]
;Global $S212[3] = [2,1,2]

	  ;вертикальный поиск 121 212
	  if $l < ($poleSizeY-2) Then
			$i=$k
			$pps = 0
			$pps2 = 0
			$ppsPusto1 = 0
			$ppsPusto2 = 0
			$CheckII = 0
			$m = 0
			For $j=$l To $l+2

			   If $poleClean[$i][$j] == 100 Then
				  ExitLoop
			   EndIf

				  If $i == 0 Then
					 If $poleClean[$i+1][$j] == 100 Then
						$ppsPusto2+=1
					 EndIf
				  ElseIf $i == $poleSizeX-1 Then
					 If $poleClean[$i-1][$j] == 100 Then
						$ppsPusto1+=1
					 EndIf
				  Else
					 If $poleClean[$i-1][$j] == 100 Then
						$ppsPusto1+=1
					 EndIf
					 If $poleClean[$i+1][$j] == 100 Then
						$ppsPusto2+=1
					 EndIf
				  EndIf

			   If $poleClean[$i][$j] == $S121[$m] Then
				  ;ConsoleWrite("i j m poleClean "&$i&","&$j&","&$m&","&$poleClean[$i][$j]&@CR)
				  $pps+=1
			   EndIf
			   If $poleClean[$i][$j] == $S212[$m] Then
				  $pps2+=1
			   EndIf
			   $m += 1

			Next

			   If (($pps == 3) Or ($pps2 == 3)) and _
				  ( ($ppsPusto1==0 And $ppsPusto2==3) Or ($ppsPusto1==3 And $ppsPusto2==0) ) Then ;нашли шаблон опаопаопапапа
				  If $l == 0 Then
					 If $poleClean[$i][$l+3]==100 Then
						$CheckII += 1
					 EndIf
				  ElseIf ($l+2) == $poleSizeY-1 Then
					 If $poleClean[$i][$l-1]==100 Then
						$CheckII += 1
					 EndIf
				  Else
					 If $poleClean[$i][$l-1]==100 Then
						$CheckII += 1
					 EndIf
					 If $poleClean[$i][$l+3]==100 Then
						$CheckII += 1
					 EndIf
				  EndIf

				  If $pps == 3 Then ;121
					  ;MsgBox(0,"Вертикаль",$k&","&$l)
					 ConsoleWrite("Вертикаль шаблон "&$k&","&$l&@CR)
					 If $ppsPusto1==3 Then
						Bomb($k-1,$l)
						Pusto($k-1,$l+1)
						Bomb($k-1,$l+2)
					 Else
						Bomb($k+1,$l)
						Pusto($k+1,$l+1)
						Bomb($k+1,$l+2)
					 EndIf
					 Return
				  EndIf

				  If $CheckII==0 Then
					 ;MsgBox(0,"Вертикаль",$k&","&$l)
					 ConsoleWrite("Вертикаль шаблон "&$k&","&$l&@CR)
					 If $pps2 == 3 Then ;212
						If $ppsPusto1==3 Then
						   Pusto($k-1,$l)
						   Bomb($k-1,$l+1)
						   Pusto($k-1,$l+2)
						Else
						   Pusto($k+1,$l)
						   Bomb($k+1,$l+1)
						   Pusto($k+1,$l+2)
						EndIf
					 EndIf
					 Return
				  EndIf


			   EndIf

	  EndIf
	  ;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

	  ;горизонтальный поиск 121 212
	  if $k < ($poleSizeX-2) Then
			$j=$l
			$pps = 0
			$pps2 = 0
			$ppsPusto1 = 0
			$ppsPusto2 = 0
			$CheckII = 0
			$m = 0
			For $i=$k To $k+2

			   If $poleClean[$i][$j] == 100 Then
				  ExitLoop
			   EndIf

				  If $j == 0 Then
					 If $poleClean[$i][$j+1] == 100 Then
						$ppsPusto2+=1
					 EndIf
				  ElseIf $j == $poleSizeY-1 Then
					 If $poleClean[$i][$j-1] == 100 Then
						$ppsPusto1+=1
					 EndIf
				  Else
					 If $poleClean[$i][$j-1] == 100 Then
						$ppsPusto1+=1
					 EndIf
					 If $poleClean[$i][$j+1] == 100 Then
						$ppsPusto2+=1
					 EndIf
				  EndIf

			   If $poleClean[$i][$j] == $S121[$m] Then
				  ;ConsoleWrite("i j m poleClean "&$i&","&$j&","&$m&","&$poleClean[$i][$j]&@CR)
				  $pps+=1
			   EndIf
			   If $poleClean[$i][$j] == $S212[$m] Then
				  $pps2+=1
			   EndIf
			   $m += 1

			Next

			   If (($pps == 3) Or ($pps2 == 3)) and _
				  ( ($ppsPusto1==0 And $ppsPusto2==3) Or ($ppsPusto1==3 And $ppsPusto2==0) ) Then ;нашли шаблон опаопаопапапа
				  If $k == 0 Then
					 If $poleClean[$k+3][$l]==100 Then
						$CheckII += 1
					 EndIf
				  ElseIf ($k+2) == $poleSizeX-1 Then
					 If $poleClean[$k-1][$l]==100 Then
						$CheckII += 1
					 EndIf
				  Else
					 If $poleClean[$k-1][$l]==100 Then
						$CheckII += 1
					 EndIf
					 If $poleClean[$k+3][$l]==100 Then
						$CheckII += 1
					 EndIf
				  EndIf

				  If $pps == 3 Then ;121
					 ;MsgBox(0,"Горизонт",$k&","&$l)
					 ConsoleWrite("Горизонт шаблон "&$k&","&$l&@CR)
					 If $ppsPusto1==3 Then
						Bomb($k,$l-1)
						Pusto($k+1,$l-1)
						Bomb($k+2,$l-1)
					 Else
						Bomb($k,$l+1)
						Pusto($k+1,$l+1)
						Bomb($k+2,$l+1)
					 EndIf
					 Return
				  EndIf

				  If $CheckII==0 Then
					 ;MsgBox(0,"Горизонт",$k&","&$l)
					 ConsoleWrite("Горизонт шаблон "&$k&","&$l&@CR)
					 If $pps2 == 3 Then ;212
						If $ppsPusto1==3 Then
						   Pusto($k,$l-1)
						   Bomb($k+1,$l-1)
						   Pusto($k+1,$l-1)
						Else
						   Pusto($k,$l+1)
						   Bomb($k+1,$l+1)
						   Pusto($k+1,$l+1)
						EndIf
					 EndIf
					 Return
				  EndIf


			   EndIf

	  EndIf

	  ;вертикальный поиск 1221
	  if $l < ($poleSizeY-3) Then
			$i=$k
			$pps = 0
			$pps2 = 0
			$ppsPusto1 = 0
			$ppsPusto2 = 0
			$CheckII = 0
			$m = 0
			For $j=$l To $l+3

			   If $poleClean[$i][$j] == 100 Then
				  ExitLoop
			   EndIf

				  If $i == 0 Then
					 If $poleClean[$i+1][$j] == 100 Then
						$ppsPusto2+=1
					 EndIf
				  ElseIf $i == $poleSizeX-1 Then
					 If $poleClean[$i-1][$j] == 100 Then
						$ppsPusto1+=1
					 EndIf
				  Else
					 If $poleClean[$i-1][$j] == 100 Then
						$ppsPusto1+=1
					 EndIf
					 If $poleClean[$i+1][$j] == 100 Then
						$ppsPusto2+=1
					 EndIf
				  EndIf

			   If $poleClean[$i][$j] == $S1221[$m] Then
				  $pps+=1
			   EndIf

			   $m += 1

			Next

			   If ($pps == 4) and _
				  ( ($ppsPusto1==0 And $ppsPusto2==4) Or ($ppsPusto1==4 And $ppsPusto2==0) ) Then ;нашли шаблон опаопаопапапа
					 ;MsgBox(0,"Вертикаль",$k&","&$l)
					 ConsoleWrite("Вертикаль шаблон 1221 "&$k&","&$l&@CR)
					 ;MsgBox(0,"","")
					 If $pps == 4 Then ;1221
						If $ppsPusto1==4 Then
						   Bomb($k-1,$l+1)
						   Bomb($k-1,$l+2)
						Else
						   Bomb($k+1,$l+1)
						   Bomb($k+1,$l+2)
						EndIf
					 EndIf
					 Return
			   EndIf

	  EndIf
	  ;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

	  	  ;горизонтальный поиск 1221
	  if $k < ($poleSizeX-3) Then
			$j=$l
			$pps = 0
			$pps2 = 0
			$ppsPusto1 = 0
			$ppsPusto2 = 0
			$CheckII = 0
			$m = 0
			For $i=$k To $k+3

			   If $poleClean[$i][$j] == 100 Then
				  ExitLoop
			   EndIf

				  If $j == 0 Then
					 If $poleClean[$i][$j+1] == 100 Then
						$ppsPusto2+=1
					 EndIf
				  ElseIf $j == $poleSizeY-1 Then
					 If $poleClean[$i][$j-1] == 100 Then
						$ppsPusto1+=1
					 EndIf
				  Else
					 If $poleClean[$i][$j-1] == 100 Then
						$ppsPusto1+=1
					 EndIf
					 If $poleClean[$i][$j+1] == 100 Then
						$ppsPusto2+=1
					 EndIf
				  EndIf

			   If $poleClean[$i][$j] == $S1221[$m] Then
				  $pps+=1
			   EndIf

			   $m += 1

			Next

			   If ($pps == 4) and _
				  ( ($ppsPusto1==0 And $ppsPusto2==4) Or ($ppsPusto1==4 And $ppsPusto2==0) ) Then ;нашли шаблон опаопаопапапа
					 ConsoleWrite("Горизонт шаблон 1221 "&$k&","&$l&@CR)
					 ;MsgBox(0,"","")
					 If $pps == 4 Then ;1221
						If $ppsPusto1==4 Then
						   Bomb($k+1,$l-1)
						   Bomb($k+2,$l-1)
						Else
						   Bomb($k+1,$l+1)
						   Bomb($k+2,$l+1)
						EndIf
					 EndIf
					 Return
			   EndIf

	  EndIf

	  ;вертикальный поиск 1120 0120 0211 0210
	  if $l < ($poleSizeY-3) Then
			$i=$k
			$pps = 0
			$pps2 = 0
			$pps3 = 0
			$pps4 = 0
			$ppsPusto1 = 0
			$ppsPusto2 = 0
			$CheckII = 0
			$m = 0

			For $j=$l To $l+3

			   If $poleClean[$i][$j] == 100 Then
				  ExitLoop
			   EndIf

				  If $i == 0 Then
					 If $poleClean[$i+1][$j] == 100 Then
						$ppsPusto2+=1
					 EndIf
				  ElseIf $i == $poleSizeX-1 Then
					 If $poleClean[$i-1][$j] == 100 Then
						$ppsPusto1+=1
					 EndIf
				  Else
					 If $poleClean[$i-1][$j] == 100 Then
						$ppsPusto1+=1
					 EndIf
					 If $poleClean[$i+1][$j] == 100 Then
						$ppsPusto2+=1
					 EndIf
				  EndIf

			   If $poleClean[$i][$j] == $S1120[$m] Then
				  $pps+=1
			   ElseIf ($m=3) and ($pps=3) Then
				  $pps+=1
			   Else
				  $pps=0
			   EndIf

			   If $poleClean[$i][$j] == $S0120[$m] Then
				  $pps2+=1
			   ElseIf ($m=3) and ($pps2=3) Then
				  $pps2+=1
			   Else
				  $pps2=0
			   EndIf

			   If $poleClean[$i][$j] == $S1120_i[$m] Then
				  $pps3+=1
			   ElseIf ($m=0) and ($pps3=0) Then
				  $pps3+=1
			   Else
				  $pps3=0
			   EndIf

			   If $poleClean[$i][$j] == $S0120_i[$m] Then
				  $pps4+=1
			   ElseIf ($m=0) and ($pps4=0) Then
				  $pps4+=1
			   Else
				  $pps4=0
			   EndIf

			   $m += 1

			Next

			   If (($pps == 4) Or ($pps2 == 4)) and _
				  ( ($ppsPusto1==0 And $ppsPusto2==4) Or ($ppsPusto1==4 And $ppsPusto2==0) ) Then ;нашли шаблон опаопаопапапа
					 ConsoleWrite("Вертикаль шаблон 0120 1120 "&$k&","&$l&@CR)
					 ;MsgBox(0,"","")
						If $ppsPusto1==4 Then
						   Pusto($k-1,$l)
						   Bomb($k-1,$l+3)
						Else
						   Pusto($k+1,$l)
						   Bomb($k+1,$l+3)
						EndIf
					 Return
			   EndIf

			   If (($pps3 == 4) Or ($pps4 == 4)) and _
				  ( ($ppsPusto1==0 And $ppsPusto2==4) Or ($ppsPusto1==4 And $ppsPusto2==0) ) Then ;нашли шаблон опаопаопапапа
					 ConsoleWrite("Вертикаль шаблон 0210 0211 "&$k&","&$l&@CR)
					 ;MsgBox(0,"","")
						If $ppsPusto1==4 Then
						   Bomb($k-1,$l)
						   Pusto($k-1,$l+3)
						Else
						   Bomb($k+1,$l)
						   Pusto($k+1,$l+3)
						EndIf
					 Return
			   EndIf

	  EndIf
	  ;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

	  ;горизонтальный поиск 1120 0120 0210 0211
	  if $k < ($poleSizeX-3) Then
			$j=$l
			$pps = 0
			$pps2 = 0
			$pps3 = 0
			$pps4 = 0
			$ppsPusto1 = 0
			$ppsPusto2 = 0
			$CheckII = 0
			$m = 0
			For $i=$k To $k+3

			   If $poleClean[$i][$j] == 100 Then
				  ExitLoop
			   EndIf

				  If $j == 0 Then
					 If $poleClean[$i][$j+1] == 100 Then
						$ppsPusto2+=1
					 EndIf
				  ElseIf $j == $poleSizeY-1 Then
					 If $poleClean[$i][$j-1] == 100 Then
						$ppsPusto1+=1
					 EndIf
				  Else
					 If $poleClean[$i][$j-1] == 100 Then
						$ppsPusto1+=1
					 EndIf
					 If $poleClean[$i][$j+1] == 100 Then
						$ppsPusto2+=1
					 EndIf
				  EndIf

			   If $poleClean[$i][$j] == $S1120[$m] Then
				  $pps+=1
			   ElseIf ($m=3) and ($pps=3) Then
				  $pps+=1
			   Else
				  $pps=0
			   EndIf

			   If $poleClean[$i][$j] == $S0120[$m] Then
				  $pps2+=1
			   ElseIf ($m=3) and ($pps2=3) Then
				  $pps2+=1
			   Else
				  $pps2=0
			   EndIf

			   If $poleClean[$i][$j] == $S1120_i[$m] Then
				  $pps3+=1
			   ElseIf ($m=0) and ($pps3=0) Then
				  $pps3+=1
			   Else
				  $pps3=0
			   EndIf

			   If $poleClean[$i][$j] == $S0120_i[$m] Then
				  $pps4+=1
			   ElseIf ($m=0) and ($pps4=0) Then
				  $pps4+=1
			   Else
				  $pps4=0
			   EndIf

			   $m += 1

			Next

			   If (($pps == 4) Or ($pps2 == 4)) and _
				  ( ($ppsPusto1==0 And $ppsPusto2==4) Or ($ppsPusto1==4 And $ppsPusto2==0) ) Then ;нашли шаблон опаопаопапапа
					 ConsoleWrite("Горизонт шаблон 1120 0120 "&$k&","&$l&@CR)
					 ;MsgBox(0,"","")
						If $ppsPusto1==4 Then
						   Pusto($k,$l-1)
						   Bomb($k+3,$l-1)
						Else
						   Pusto($k,$l+1)
						   Bomb($k+3,$l+1)
						EndIf
					 Return
			   EndIf

			   If (($pps3 == 4) Or ($pps4 == 4)) and _
				  ( ($ppsPusto1==0 And $ppsPusto2==4) Or ($ppsPusto1==4 And $ppsPusto2==0) ) Then ;нашли шаблон опаопаопапапа
					 ConsoleWrite("Горизонт шаблон 0210 0211 "&$k&","&$l&@CR)
					 ;MsgBox(0,"","")
						If $ppsPusto1==4 Then
						   Bomb($k,$l-1)
						   Pusto($k+3,$l-1)
						Else
						   Bomb($k,$l+1)
						   Pusto($k+3,$l+1)
						EndIf
					 Return
			   EndIf

	  EndIf

EndFunc

Func Coordinati3x3($k,$l) ;координаты кубика вокруг к л
	  ;Координаты кубика
      If $k==0 Then
         $posX1=0
		 $posX2=$k+1
	  ElseIf $k == ($poleSizeX-1) Then
		 $posX1=$k-1
		 $posX2=$poleSizeX-1
	  Else
		 $posX1=$k-1
		 $posX2=$k+1
	  EndIf

      if $l==0 Then
         $posY1=0
		 $posY2=$l+1
	  ElseIf $l == ($poleSizeY-1) Then
		 $posY1=$l-1
		 $posY2=$poleSizeY-1
	  Else
		 $posY1=$l-1
		 $posY2=$l+1
      EndIf
EndFunc
 

C2H5OH

AutoIT Гуру
Сообщения
1,473
Репутация
333
Странно. Я взял выложенный на форуме код версии 6 и запустил. Сразу заработало. (напоминаю что для старта надо F11 нажать)
Версия 6 отличается от версии 2.1 главным образом тем что сама определяет на каком поле играет. В версии 2.1 в скрипте нужно было указывать размер поля и количество мин. Остальные изменения не касаются этапа старта игры.

Функция MinesweeperAdvansedOpenCell, например, вот в такой вот ситуации откроет отмеченную клетку
16bd0ef55d42.jpg

Ну не совсем в такой, а если ничего сделать уже нельзя и остались только клетки как в правом нижнем углу на картинке.

Насчет работать вслепую.
Если у тебя осталось Х неоткрытых клеток и Х ненайденных мин, то мой скрипт выиграет, а твой подорвется.

Кстати, на форуме не работают кнопки тегов. Все [ и ] приходится руками набирать.
 

СН3СН2ОН

Знающий
Сообщения
78
Репутация
12
C2H5OH сказал(а):
Насчет работать вслепую.
Если у тебя осталось Х неоткрытых клеток и Х ненайденных мин, то мой скрипт выиграет, а твой подорвется.
:smile:
Ой, не надо поспешных выводов. Если я правильно понял:
Ставим бомбы, открываем пустые, если все то смотрим нет ли такой ситуации(как на картинке)(случай странный я его еще исследую), если нет то делаем рандом.
Если алгоритм такой, то у меня для вас плохи новости - мой скрипт умнее(хотя такие угловые комбинации я не рассматривал).
Я его еще доработаю. Добавим теории вероятности.
А стресс тестирование устроим.
p.s. Ситуация на картинке- случай шаблон. т.е справа и внизу или пусто или стена. Или это частный случай алгоритма?
 

C2H5OH

AutoIT Гуру
Сообщения
1,473
Репутация
333
Мой код полностью перед вами, смотрите.

Вот результат работы вашего скрипта
"(Другого пути нет!) Отправили смертника в квадрат 19,0"
eee5b4fc201f.jpg

Вывод очевиден.
Не стоит подпитывать моё самомнение, оно и так завышенное.
 

C2H5OH

AutoIT Гуру
Сообщения
1,473
Репутация
333
Для полноты картины.
Вот в такой ситуации MinesweeperAdvansedOpenCell отметит указанную клетку как мину.
137afde9600f.jpg
 

СН3СН2ОН

Знающий
Сообщения
78
Репутация
12
C2H5OH - снимаю перед вами шляпу.
Вы действительно нашли удивительный алгоритм. Я тоже ходил вокруг да около (это видно по неактивным функциям в предыдущих скриптах), но закономерность никак не мог найти. Я понимаю, лень объяснять такому овощу как я суть алгоритма, проще ткнуть в код. Суть его я понял, но математическое обоснование...
Если вас не затруднит, скажите хотя бы область математики - комбинаторика, группы, вероятность.. дальше я сам.
Хотел дать описание для новичков, но зачем, раздел закрытый - никто не увидит.
И да не надо на меня обижаться: Я люблю трудные задачи и специально "раскачиваю".
Про количество мин не буду спорить, но вот вам мой алгоритм версии 4.0.
Я включил вашу удивительную функцию перед своим шаблонизатором. Так вот он иногда срабатывает. Т.е ваш алгоритм говорит все - делаем рандом, а мой еще что-то находит(иногда!!!!). О чем я? Для сапера нет совершенного алгоритма.
Код:
#include <Array.au3>

;Бот для игры Сапёр (Windows XP, ru_RU).
;Версия 4.0 by СН3СН2ОН

;Глобальные переменные получают рандомные большие значения просто потому, что мы пока не умеем по другому
Global $poleSizeX=30, $poleSizeY=30   ; размер поля
Global $OpenFlag = 1, $tiktak = 0 ; какой-то флажок
Global $posX1, $posX2, $posY1, $posY2 ; кубик 3на3
Global $Bomb =0, $Pusto = 0, $PustoAndBomb = 0 ;кол-во бомб и пустых клеток вокруг ячейки
Global $CentrColors[9] = [0xC0C0C0, _; 0 - открытое поле, рядом 0 мин
                           0x0000FF, _; 1 - открытое поле, рядом 1 мина
                           0x008000, _; 2 - открытое поле, рядом 2 мины
                           0xFF0000, _; 3 - открытое поле, рядом 3 мины
                           0x000080, _; 4 - открытое поле, рядом 4 мины
                           0x800000, _; 5 - открытое поле, рядом 5 мин
                           0x008080, _; 6 - открытое поле, рядом 6 мин
                           0x000000, _; 7 - открытое поле, рядом 7 мин
                           0x808080]; 8 -  открытое поле, рядом 8 мин
Global $CellColors[3] = [0xFFFFFF, _; 0- неоткрытое поле
                           0xC0C0C0, _; 1 - открытое поле
                           0xFF0000] ; 2 - подорванная мина (конец игре)
;Шаблоны для раскрытия
Global $S121[3] = [1,2,1]
Global $S1221[4] = [1,2,2,1]
Global $S212[3] = [2,1,2]

Global $S1120[4] = [1,1,2,0]
Global $S0120[4] = [0,1,2,0]

Global $S1120_i[4] = [0,2,1,1]
Global $S0120_i[4] = [0,2,1,0]
;
Global $MassStatistic[2] = [0,0] ;как играет проверим 1 победа 2 поражение
Global $aPos[2]
Global $StatisticExit = 0
Global $pole[$poleSizeX][$poleSizeY]
Global $pole4time[$poleSizeX][$poleSizeY]
Global $poleVer[$poleSizeX][$poleSizeY]
Global $poleClean[$poleSizeX][$poleSizeY]
Global $timeSleeep = 1
Global $zX1=12 ;отступ для проверки состояния ячейки
Global $zX2=20 ;отступ для проверки содержимого ячейки
Global $zY1=55 ;отступ для проверки состояния ячейки
Global $a16=16 ;размер ячейки


HotKeySet("!{F11}", "Terminate")    ; Alt + F11
Go()
MsgBox(0,"Статистика"," Выиграл "&$MassStatistic[0]&" Проиграл "&$MassStatistic[1])
Terminate()

;111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
Func Go()
   $StatisticExit = 0
   $OpenFlag = 1
   $tiktak = 0
   $Bomb =0
   $Pusto = 0
   $PustoAndBomb = 0
   Initialition()
   While $OpenFlag > 0 ; пока могу решать
      $OpenFlag=0
	  MineCheckInit()
      MineSweeperScan() ;1 Сканирование сапера в массив
      if MineCheckFinih() Then ;Если нет вскрытой бомбы, от рукожопов и случайности
		 MineCheckBomb()
	  EndIf
	  if $OpenFlag = 0 Then
		 MineByC2H5OH()
	  EndIf
   	  if $OpenFlag = 0 Then
		 MineCheckShablon()
		 If $OpenFlag <> 0 Then
			MsgBox(0,'Это чудо !!!','После алгоритма водки сработал наш алгоритм !')
		 EndIf
	  EndIf
	  if $OpenFlag = 0 Then
		 ConsoleWrite("Доработать вероятность а пока шарашим рандомом РРРАААААААААААААЗ !!!"&@CR)
		 MinesOpenRandom()
	  EndIf
   WEnd
EndFunc
;111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111

Func Initialition()
   If Not WinExists("Сапер") Then ;Проверка запущен ли сапер, попытка запуска
      If MsgBox(4 + 32, "Error", "Сапер не запущен. Запустить?") = 6 Then
          Run("C:\windows\system32\winmine.exe")
      Else
          Terminate()
      EndIf
   EndIf
      Sleep(3000)
   If Not WinExists("Сапер") Then
      MsgBox(0,"Печаль","У вас нет Сапера")
      Terminate()
   Else
      WinActivate("Сапер")
      Sleep(1000)
      $aPos = WinGetClientSize("[Class:Сапер]"); Возвращает размер клиентской области (без заголовка и границ).
      $poleSizeX = ($aPos[0]-20)/$a16;Сапер у нас получился 500 319, разница высоты 46
      $poleSizeY = ($aPos[1]-63)/$a16
      Opt("PixelCoordMode", 2) ; установили координаты относительно клиентской области
      Opt("MouseCoordMode", 2) ; тоже самое для мыши
	  For $i = 0 To $poleSizeX-1
		 For $j = 0 To $poleSizeY-1
			$pole4time[$i][$j]=0
			$poleVer[$i][$j]=0
		 Next
	  Next
   EndIf
   Send("{F2}")
EndFunc

Func MineSweeperScan()
   #comments-start
   99 стоит флажек бомба
   100 неоткрытое поле
   1000 открытое пустое
   #comments-end
   $tiktak = 0
    For $i = 0 To $poleSizeX-1
        For $j = 0 To $poleSizeY-1
            If PixelGetColor($zX1+$a16*$i,$zY1+$a16*$j) = $CellColors[0] Then ; если ячейку не вскрывали
               If (PixelGetColor($zX2+$a16*$i,66+$a16*$j) = 0x000000) and _
                  (PixelGetColor($zX2+$a16*$i,60+$a16*$j) = 0xFF0000)Then ;Если стоит флажек(бомба)
                  $pole[$i][$j] = 99
                  ;MsgBox(0,"Флажек",$i&"ввв"&$j)
               ElseIf (PixelGetColor($zX2+$a16*$i,66+$a16*$j) = 0x000000) and _
                  (PixelGetColor($zX2+$a16*$i,58+$a16*$j) = 0x000000) Then ;Если стоит вопрос убираем его
                  $pole[$i][$j] = 100
                  $tiktak +=1
                  MouseMove($zX2+$a16*$i,$zY1+$a16*$j,0)
                  Sleep($timeSleeep)
                  MouseClick("Right", $zX2+$a16*$i,$zY1+$a16*$j)
               Else
                  $pole[$i][$j] = 100
                  $tiktak +=1
               EndIf
            Else
                $color = PixelGetColor($zX2+$a16*$i,63+$a16*$j)
                Switch $color
                    Case $CentrColors[0]
                        $pole[$i][$j] = 1000
                    Case $CentrColors[1]
                        $pole[$i][$j] = 1
                    Case $CentrColors[2]
                        $pole[$i][$j] = 2
                    Case $CentrColors[3]
                        $pole[$i][$j] = 3
                    Case $CentrColors[4]
                        $pole[$i][$j] = 4
                    Case $CentrColors[5]
                        $pole[$i][$j] = 5
                    Case $CentrColors[6]
                        $pole[$i][$j] = 6
                    Case $CentrColors[7]
                        $pole[$i][$j] = 7
                    Case $CentrColors[8]
                        $pole[$i][$j] = 8
                EndSwitch
            EndIf
        Next
     Next
 EndFunc

Func MineMatrix3x3($k,$l) ;передаем координаты какой-то клетки (перебором, да хоть как)
   $Bomb =0
   $Pusto = 0
   $PustoAndBomb = 0
   $sik = 0

   Coordinati3x3($k,$l)

      For $i=$posX1 To $posX2
         For $j=$posY1 To $posY2

               If $pole[$i][$j] = 99 Then
                  $Bomb += 1
               EndIf

               If $pole[$i][$j] = 100 Then
                  $Pusto += 1
				  $sik +=1
               EndIf

         Next
      Next

   $PustoAndBomb = $Bomb + $Pusto

   If $sik = 0 Then ; для дальнейшего ускорения скрипта, если нет вокруг неоткрытых, зачем сюда заходить?
	  $pole4time[$k][$l]=100
   EndIf

EndFunc

Func MineMatrix3x3_ver($k,$l) ;передаем координаты какой-то клетки (перебором, да хоть как)
   $Bomb =0
   $Pusto = 0
   $PustoAndBomb = 0
   $sik = 0

   Coordinati3x3($k,$l)

      For $i=$posX1 To $posX2
         For $j=$posY1 To $posY2

               If $pole[$i][$j] == 99 Then
                  $Bomb += 1
               EndIf

               If $pole[$i][$j] == 100 Then
                  $Pusto += 1
               EndIf

         Next
      Next


   If ($pusto > 0) Then
	  $sik = (($pole[$k][$l]-$bomb) / $Pusto)
	  ;MsgBox(0,"sik",$sik)
      For $i=$posX1 To $posX2
         For $j=$posY1 To $posY2

               If $pole[$i][$j] == 100 Then
                  $poleVer[$i][$j] += $sik
               EndIf

         Next
      Next
   EndIf

   			   ;_ArrayTranspose($poleVer)
			   ;_ArrayDisplay($poleVer)

EndFunc

Func ClickBomb($k,$l)
      If ($pole[$k][$l]=$PustoAndBomb) and ($pole[$k][$l]>0)  Then ;Открываем явные бомбы
         ;MsgBox(0,"sdf",$Pusto)
         For $i=$posX1 To $posX2
            For $j=$posY1 To $posY2
                  If $pole[$i][$j] = 100 Then
                     $pole[$i][$j] = 99
                     MouseMove($zX2+$a16*$i,$zY1+$a16*$j,0)
                     Sleep($timeSleeep)
                     MouseClick("Right", $zX2+$a16*$i,$zY1+$a16*$j)
                     ConsoleWrite("Нашел бомбу, поставил вешку, покурили "&$i&","&$j&@CR)
                     MineCheckClose($zX1+$a16*$i,$zY1+$a16*$j)
                     $OpenFlag+=1
                  EndIf
                  ;MsgBox(0,"sdf",$i&$j)
            Next
         Next
      EndIf
EndFunc

Func ClickPusto($k,$l)
      If ($pole[$k][$l]=$Bomb) and ($pole[$k][$l]>0) Then ;открываем явные пустышки
         For $i=$posX1 To $posX2
            For $j=$posY1 To $posY2
                  If $pole[$i][$j] = 100 Then
                     $pole[$i][$j] = 1000
                     MouseMove($zX2+$a16*$i,$zY1+$a16*$j,0)
                     Sleep($timeSleeep)
                     MouseClick("Left", $zX2+$a16*$i,$zY1+$a16*$j)
                     ConsoleWrite("Этот квадрат безопасен "&$i&","&$j&@CR)
                     MineCheckClose($zX1+$a16*$i,$zY1+$a16*$j)
                     $OpenFlag+=1
                  EndIf
            Next
         Next
      EndIf
EndFunc

Func Pusto($i,$j)

   $pole[$i][$j] = 1000
   MouseMove($zX2+$a16*$i,$zY1+$a16*$j,0)
   Sleep($timeSleeep)
   MouseClick("Left", $zX2+$a16*$i,$zY1+$a16*$j)
   ConsoleWrite("Этот квадрат безопасен "&$i&","&$j&@CR)
   MineCheckClose($zX1+$a16*$i,$zY1+$a16*$j)
   $OpenFlag+=1

EndFunc

Func Bomb($i,$j)

   $pole[$i][$j] = 99
   MouseMove($zX2+$a16*$i,$zY1+$a16*$j,0)
   Sleep($timeSleeep)
   MouseClick("Right", $zX2+$a16*$i,$zY1+$a16*$j)
   ConsoleWrite("Этот квадрат безопасен "&$i&","&$j&@CR)
   MineCheckClose($zX1+$a16*$i,$zY1+$a16*$j)
   $OpenFlag+=1

EndFunc

Func MineCheckBomb()
   For $i=0 To $poleSizeX-1
      For $j=0 To $poleSizeY-1
         if ($pole[$i][$j] < 100) and ($pole4time[$i][$j] < 100) Then
            MineMatrix3x3($i,$j)
            ClickBomb($i,$j)
            MineMatrix3x3($i,$j)
            ClickPusto($i,$j)
         EndIf
      Next
   Next

EndFunc

Func MinesOpenRandom()
    While $OpenFlag = 0
        $i = Random(0, $poleSizeX-1, 1)
        $j = Random(0, $poleSizeY-1, 1)
        If $pole[$i][$j] = 100 Then
            ConsoleWrite("(Другого пути нет!) Отправили смертника в квадрат "&$i&","&$j&@CR)
               MouseMove($zX2+$a16*$i,$zY1+$a16*$j,0)
               Sleep($timeSleeep)
               MouseClick("Left", $zX2+$a16*$i,$zY1+$a16*$j)
               MineCheckClose($zX2+$a16*$i,$zY1+$a16*$j)
               $OpenFlag += 1
            Return
        EndIf
    WEnd
EndFunc

Func MineCheckClose($i,$j)
   If PixelGetColor($i+2,$j+2) = $CellColors[2] Then
      ConsoleWrite("Сапер подорвался на мине"&@CR&"-----------"&@CR)
	  $MassStatistic[1]+=1

	  For $i = 0 To $poleSizeX-1
		 For $j = 0 To $poleSizeY-1
			$pole[$i][$j]=0
			$pole4time[$i][$j]=0
			$poleVer[$i][$j]=0
		 Next
	  Next

	  $StatisticExit = 1
	  $OpenFlag = 0
	  ;Send("{F2}")
      Terminate()
	  Return
   EndIf
EndFunc

Func MineCheckFinih() ;Если нет вскрытой бомбы, от рукожопов и случайности
   if $tiktak = 0 Then
      ConsoleWrite("Минное поле очищено!"&@CR&"-----------"&@CR)
	  $MassStatistic[0]+=1

	  For $i = 0 To $poleSizeX-1
		 For $j = 0 To $poleSizeY-1
			$pole[$i][$j]=0
			$pole4time[$i][$j]=0
			$poleVer[$i][$j]=0
		 Next
	  Next

	  $OpenFlag = 0
	  ;Send("{F2}")
      Terminate()
	  Return False
   EndIf
   Return True
EndFunc

Func Terminate()
    ConsoleWrite("остановлено"&@CR&"-----------"&@CR)
    Exit 0
 EndFunc

Func MineCheckInit()  ; проверка активно ли окно сапера
   If Not WinActive("Сапер") Then
      Terminate()
   EndIf
EndFunc

Func MineCheckVeroyatnost()

   If $OpenFlag = 0 Then
	  For $i = 0 To $poleSizeX-1
		 For $j = 0 To $poleSizeY-1
			$poleVer[$i][$j]=0
		 Next
	  Next
			  ; _ArrayTranspose($poleVer)
			   ;_ArrayDisplay($poleVer)
	  For $i = 0 To $poleSizeX-1
		 For $j = 0 To $poleSizeY-1
			If ($pole[$i][$j] < 99) and ($pole4time[$i][$j] < 100) Then
			   MineMatrix3x3_ver($i,$j)
			EndIf
		 Next
	  Next

	  $maxV=0
	  $minV=1000
	  $maxX=0
	  $maxY=0
	  $minX=0
	  $minY=0
	  $minCheck=0

	  For $i = 0 To $poleSizeX-1
		 For $j = 0 To $poleSizeY-1
			If ($poleVer[$i][$j] = 3/2) or ($poleVer[$i][$j] = 3) Then
			;if $poleVer[$i][$j]>$maxV Then
			   $maxV=$poleVer[$i][$j]
			   $maxX=$i
			   $maxY=$j
			EndIf
			if ($poleVer[$i][$j]<$minV) and ($poleVer[$i][$j]>0) Then
			   $minV=$poleVer[$i][$j]
			   $minX=$i
			   $minY=$j
			EndIf
		 Next
	  Next

	  For $i = 0 To $poleSizeX-1
		 For $j = 0 To $poleSizeY-1
			if ($poleVer[$i][$j]=$minV) and ($poleVer[$i][$j]>0) Then
			   $minCheck+=1
			EndIf
		 Next
	  Next

	  if ($minV < (1/5)) and ($minV > (1/8)) Then
			   $pole[$minX][$minY] = 1000
			   MouseMove($zX2+$a16*$minX,$zY1+$a16*$minY,0)
			   Sleep($timeSleeep)
			   MouseClick("Left", $zX2+$a16*$minX,$zY1+$a16*$minY)
			   ConsoleWrite("(Вероятность ------------------ "&$minV&" ------------------) Нашел пустое место методом исключения, вскрыли, покурили "&$minX&","&$minY&@CR)
			   MineCheckClose($zX1+$a16*$minX,$zY1+$a16*$minY)
			   $OpenFlag += 1
			   ;_ArrayTranspose($poleVer)
			   ;_ArrayDisplay($poleVer)
			   Return
	  EndIf


	  ;If ($maxV > (8/5)) Then
	  If ($maxV = 3/2) or ($maxV = 3) Then
		 $pole[$maxX][$maxY] = 99
		 MouseMove($zX2+$a16*$maxX,$zY1+$a16*$maxY,0)
		 Sleep($timeSleeep)
		 MouseClick("Right", $zX2+$a16*$maxX,$zY1+$a16*$maxY)
		 ConsoleWrite("(Вероятность ------------------ "&$maxV&" ------------------)Нашел бомбу методом исключения, поставил вешку, покурили "&$maxX&","&$maxY&@CR)
		 MineCheckClose($zX1+$a16*$maxX,$zY1+$a16*$maxY)
		 $OpenFlag += 1
		 ;_ArrayTranspose($poleVer)
		 ;_ArrayDisplay($poleVer)
		 Return
	  EndIf


   MinesOpenRandom()

   EndIf
EndFunc

Func MineMatrixShablonClean($k,$l) ; очистка $poleClean от пересечений, в идеале на выхоте единицы и двойки
   $Bomb =0
   $Pusto = 0
   $PustoAndBomb = 0
   $sik = 0
   $posX1=$k-1
   $posX2=$k+1
   $posY1=$l-1
   $posY2=$l+1
      if $posX1<0 Then
         $posX1=0
      EndIf
         if $posX2>($poleSizeX-1) Then
            $posX2=$poleSizeX-1
         EndIf
      if $posY1<0 Then
         $posY1=0
      EndIf
         if $posY2>($poleSizeY-1) Then
            $posY2=$poleSizeY-1
         EndIf

      For $i=$posX1 To $posX2
         For $j=$posY1 To $posY2

               If $pole[$i][$j] == 99 Then
                  $Bomb += 1
               EndIf

         Next
      Next


   If ($Bomb > 0) Then
	  $poleClean[$k][$l]-=$bomb
   EndIf


EndFunc

Func MineCheckShablon() ;Шаблонные подстановки
   If $OpenFlag = 0 Then
	  For $i = 0 To $poleSizeX-1
		 For $j = 0 To $poleSizeY-1
			if ($pole[$i][$j] == 1000) Or ($pole[$i][$j] == 99) Then
			   $poleClean[$i][$j] = 0
			Else
			   $poleClean[$i][$j]=$pole[$i][$j]
			EndIf
		 Next
	  Next

	  For $i = 0 To $poleSizeX-1
		 For $j = 0 To $poleSizeY-1
			If ($poleClean[$i][$j] > 0) and ($poleClean[$i][$j] < 99) Then
			   MineMatrixShablonClean($i,$j)
			EndIf
		 Next
	  Next

	  For $i = 0 To $poleSizeX-1
		 For $j = 0 To $poleSizeY-1
			If ($poleClean[$i][$j] > 0) and ($poleClean[$i][$j] < 3) Then
			   MineFindShablon($i,$j)
			   If $OpenFlag > 0 Then
				  Return
			   EndIf
			EndIf
		 Next
	  Next


   			   ;_ArrayTranspose($poleClean)
			   ;_ArrayDisplay($poleClean)

   EndIf
EndFunc

Func MineFindShablon($k,$l)

;Global $S121[3] = [1,2,1]
;Global $S1221[4] = [1,2,2,1]
;Global $S212[3] = [2,1,2]

	  ;вертикальный поиск 121 212
	  if $l < ($poleSizeY-2) Then
			$i=$k
			$pps = 0
			$pps2 = 0
			$ppsPusto1 = 0
			$ppsPusto2 = 0
			$CheckII = 0
			$m = 0
			For $j=$l To $l+2

			   If $poleClean[$i][$j] == 100 Then
				  ExitLoop
			   EndIf

				  If $i == 0 Then
					 If $poleClean[$i+1][$j] == 100 Then
						$ppsPusto2+=1
					 EndIf
				  ElseIf $i == $poleSizeX-1 Then
					 If $poleClean[$i-1][$j] == 100 Then
						$ppsPusto1+=1
					 EndIf
				  Else
					 If $poleClean[$i-1][$j] == 100 Then
						$ppsPusto1+=1
					 EndIf
					 If $poleClean[$i+1][$j] == 100 Then
						$ppsPusto2+=1
					 EndIf
				  EndIf

			   If $poleClean[$i][$j] == $S121[$m] Then
				  ;ConsoleWrite("i j m poleClean "&$i&","&$j&","&$m&","&$poleClean[$i][$j]&@CR)
				  $pps+=1
			   EndIf
			   If $poleClean[$i][$j] == $S212[$m] Then
				  $pps2+=1
			   EndIf
			   $m += 1

			Next

			   If (($pps == 3) Or ($pps2 == 3)) and _
				  ( ($ppsPusto1==0 And $ppsPusto2==3) Or ($ppsPusto1==3 And $ppsPusto2==0) ) Then ;нашли шаблон опаопаопапапа
				  If $l == 0 Then
					 If $poleClean[$i][$l+3]==100 Then
						$CheckII += 1
					 EndIf
				  ElseIf ($l+2) == $poleSizeY-1 Then
					 If $poleClean[$i][$l-1]==100 Then
						$CheckII += 1
					 EndIf
				  Else
					 If $poleClean[$i][$l-1]==100 Then
						$CheckII += 1
					 EndIf
					 If $poleClean[$i][$l+3]==100 Then
						$CheckII += 1
					 EndIf
				  EndIf

				  If $pps == 3 Then ;121
					  ;MsgBox(0,"Вертикаль",$k&","&$l)
					 ConsoleWrite("Вертикаль шаблон "&$k&","&$l&@CR)
					 If $ppsPusto1==3 Then
						Bomb($k-1,$l)
						Pusto($k-1,$l+1)
						Bomb($k-1,$l+2)
					 Else
						Bomb($k+1,$l)
						Pusto($k+1,$l+1)
						Bomb($k+1,$l+2)
					 EndIf
					 Return
				  EndIf

				  If $CheckII==0 Then
					 ;MsgBox(0,"Вертикаль",$k&","&$l)
					 ConsoleWrite("Вертикаль шаблон "&$k&","&$l&@CR)
					 If $pps2 == 3 Then ;212
						If $ppsPusto1==3 Then
						   Pusto($k-1,$l)
						   Bomb($k-1,$l+1)
						   Pusto($k-1,$l+2)
						Else
						   Pusto($k+1,$l)
						   Bomb($k+1,$l+1)
						   Pusto($k+1,$l+2)
						EndIf
					 EndIf
					 Return
				  EndIf


			   EndIf

	  EndIf
	  ;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

	  ;горизонтальный поиск 121 212
	  if $k < ($poleSizeX-2) Then
			$j=$l
			$pps = 0
			$pps2 = 0
			$ppsPusto1 = 0
			$ppsPusto2 = 0
			$CheckII = 0
			$m = 0
			For $i=$k To $k+2

			   If $poleClean[$i][$j] == 100 Then
				  ExitLoop
			   EndIf

				  If $j == 0 Then
					 If $poleClean[$i][$j+1] == 100 Then
						$ppsPusto2+=1
					 EndIf
				  ElseIf $j == $poleSizeY-1 Then
					 If $poleClean[$i][$j-1] == 100 Then
						$ppsPusto1+=1
					 EndIf
				  Else
					 If $poleClean[$i][$j-1] == 100 Then
						$ppsPusto1+=1
					 EndIf
					 If $poleClean[$i][$j+1] == 100 Then
						$ppsPusto2+=1
					 EndIf
				  EndIf

			   If $poleClean[$i][$j] == $S121[$m] Then
				  ;ConsoleWrite("i j m poleClean "&$i&","&$j&","&$m&","&$poleClean[$i][$j]&@CR)
				  $pps+=1
			   EndIf
			   If $poleClean[$i][$j] == $S212[$m] Then
				  $pps2+=1
			   EndIf
			   $m += 1

			Next

			   If (($pps == 3) Or ($pps2 == 3)) and _
				  ( ($ppsPusto1==0 And $ppsPusto2==3) Or ($ppsPusto1==3 And $ppsPusto2==0) ) Then ;нашли шаблон опаопаопапапа
				  If $k == 0 Then
					 If $poleClean[$k+3][$l]==100 Then
						$CheckII += 1
					 EndIf
				  ElseIf ($k+2) == $poleSizeX-1 Then
					 If $poleClean[$k-1][$l]==100 Then
						$CheckII += 1
					 EndIf
				  Else
					 If $poleClean[$k-1][$l]==100 Then
						$CheckII += 1
					 EndIf
					 If $poleClean[$k+3][$l]==100 Then
						$CheckII += 1
					 EndIf
				  EndIf

				  If $pps == 3 Then ;121
					 ;MsgBox(0,"Горизонт",$k&","&$l)
					 ConsoleWrite("Горизонт шаблон "&$k&","&$l&@CR)
					 If $ppsPusto1==3 Then
						Bomb($k,$l-1)
						Pusto($k+1,$l-1)
						Bomb($k+2,$l-1)
					 Else
						Bomb($k,$l+1)
						Pusto($k+1,$l+1)
						Bomb($k+2,$l+1)
					 EndIf
					 Return
				  EndIf

				  If $CheckII==0 Then
					 ;MsgBox(0,"Горизонт",$k&","&$l)
					 ConsoleWrite("Горизонт шаблон "&$k&","&$l&@CR)
					 If $pps2 == 3 Then ;212
						If $ppsPusto1==3 Then
						   Pusto($k,$l-1)
						   Bomb($k+1,$l-1)
						   Pusto($k+1,$l-1)
						Else
						   Pusto($k,$l+1)
						   Bomb($k+1,$l+1)
						   Pusto($k+1,$l+1)
						EndIf
					 EndIf
					 Return
				  EndIf


			   EndIf

	  EndIf

	  ;вертикальный поиск 1221
	  if $l < ($poleSizeY-3) Then
			$i=$k
			$pps = 0
			$pps2 = 0
			$ppsPusto1 = 0
			$ppsPusto2 = 0
			$CheckII = 0
			$m = 0
			For $j=$l To $l+3

			   If $poleClean[$i][$j] == 100 Then
				  ExitLoop
			   EndIf

				  If $i == 0 Then
					 If $poleClean[$i+1][$j] == 100 Then
						$ppsPusto2+=1
					 EndIf
				  ElseIf $i == $poleSizeX-1 Then
					 If $poleClean[$i-1][$j] == 100 Then
						$ppsPusto1+=1
					 EndIf
				  Else
					 If $poleClean[$i-1][$j] == 100 Then
						$ppsPusto1+=1
					 EndIf
					 If $poleClean[$i+1][$j] == 100 Then
						$ppsPusto2+=1
					 EndIf
				  EndIf

			   If $poleClean[$i][$j] == $S1221[$m] Then
				  $pps+=1
			   EndIf

			   $m += 1

			Next

			   If ($pps == 4) and _
				  ( ($ppsPusto1==0 And $ppsPusto2==4) Or ($ppsPusto1==4 And $ppsPusto2==0) ) Then ;нашли шаблон опаопаопапапа
					 ;MsgBox(0,"Вертикаль",$k&","&$l)
					 ConsoleWrite("Вертикаль шаблон 1221 "&$k&","&$l&@CR)
					 ;MsgBox(0,"","")
					 If $pps == 4 Then ;1221
						If $ppsPusto1==4 Then
						   Bomb($k-1,$l+1)
						   Bomb($k-1,$l+2)
						Else
						   Bomb($k+1,$l+1)
						   Bomb($k+1,$l+2)
						EndIf
					 EndIf
					 Return
			   EndIf

	  EndIf
	  ;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

	  	  ;горизонтальный поиск 1221
	  if $k < ($poleSizeX-3) Then
			$j=$l
			$pps = 0
			$pps2 = 0
			$ppsPusto1 = 0
			$ppsPusto2 = 0
			$CheckII = 0
			$m = 0
			For $i=$k To $k+3

			   If $poleClean[$i][$j] == 100 Then
				  ExitLoop
			   EndIf

				  If $j == 0 Then
					 If $poleClean[$i][$j+1] == 100 Then
						$ppsPusto2+=1
					 EndIf
				  ElseIf $j == $poleSizeY-1 Then
					 If $poleClean[$i][$j-1] == 100 Then
						$ppsPusto1+=1
					 EndIf
				  Else
					 If $poleClean[$i][$j-1] == 100 Then
						$ppsPusto1+=1
					 EndIf
					 If $poleClean[$i][$j+1] == 100 Then
						$ppsPusto2+=1
					 EndIf
				  EndIf

			   If $poleClean[$i][$j] == $S1221[$m] Then
				  $pps+=1
			   EndIf

			   $m += 1

			Next

			   If ($pps == 4) and _
				  ( ($ppsPusto1==0 And $ppsPusto2==4) Or ($ppsPusto1==4 And $ppsPusto2==0) ) Then ;нашли шаблон опаопаопапапа
					 ConsoleWrite("Горизонт шаблон 1221 "&$k&","&$l&@CR)
					 ;MsgBox(0,"","")
					 If $pps == 4 Then ;1221
						If $ppsPusto1==4 Then
						   Bomb($k+1,$l-1)
						   Bomb($k+2,$l-1)
						Else
						   Bomb($k+1,$l+1)
						   Bomb($k+2,$l+1)
						EndIf
					 EndIf
					 Return
			   EndIf

	  EndIf

	  ;вертикальный поиск 1120 0120 0211 0210
	  if $l < ($poleSizeY-3) Then
			$i=$k
			$pps = 0
			$pps2 = 0
			$pps3 = 0
			$pps4 = 0
			$ppsPusto1 = 0
			$ppsPusto2 = 0
			$CheckII = 0
			$m = 0

			For $j=$l To $l+3

			   If $poleClean[$i][$j] == 100 Then
				  ExitLoop
			   EndIf

				  If $i == 0 Then
					 If $poleClean[$i+1][$j] == 100 Then
						$ppsPusto2+=1
					 EndIf
				  ElseIf $i == $poleSizeX-1 Then
					 If $poleClean[$i-1][$j] == 100 Then
						$ppsPusto1+=1
					 EndIf
				  Else
					 If $poleClean[$i-1][$j] == 100 Then
						$ppsPusto1+=1
					 EndIf
					 If $poleClean[$i+1][$j] == 100 Then
						$ppsPusto2+=1
					 EndIf
				  EndIf

			   If $poleClean[$i][$j] == $S1120[$m] Then
				  $pps+=1
			   ElseIf ($m=3) and ($pps=3) Then
				  $pps+=1
			   Else
				  $pps=0
			   EndIf

			   If $poleClean[$i][$j] == $S0120[$m] Then
				  $pps2+=1
			   ElseIf ($m=3) and ($pps2=3) Then
				  $pps2+=1
			   Else
				  $pps2=0
			   EndIf

			   If $poleClean[$i][$j] == $S1120_i[$m] Then
				  $pps3+=1
			   ElseIf ($m=0) and ($pps3=0) Then
				  $pps3+=1
			   Else
				  $pps3=0
			   EndIf

			   If $poleClean[$i][$j] == $S0120_i[$m] Then
				  $pps4+=1
			   ElseIf ($m=0) and ($pps4=0) Then
				  $pps4+=1
			   Else
				  $pps4=0
			   EndIf

			   $m += 1

			Next

			   If (($pps == 4) Or ($pps2 == 4)) and _
				  ( ($ppsPusto1==0 And $ppsPusto2==4) Or ($ppsPusto1==4 And $ppsPusto2==0) ) Then ;нашли шаблон опаопаопапапа
					 ConsoleWrite("Вертикаль шаблон 0120 1120 "&$k&","&$l&@CR)
					 ;MsgBox(0,"","")
						If $ppsPusto1==4 Then
						   Pusto($k-1,$l)
						   Bomb($k-1,$l+3)
						Else
						   Pusto($k+1,$l)
						   Bomb($k+1,$l+3)
						EndIf
					 Return
			   EndIf

			   If (($pps3 == 4) Or ($pps4 == 4)) and _
				  ( ($ppsPusto1==0 And $ppsPusto2==4) Or ($ppsPusto1==4 And $ppsPusto2==0) ) Then ;нашли шаблон опаопаопапапа
					 ConsoleWrite("Вертикаль шаблон 0210 0211 "&$k&","&$l&@CR)
					 ;MsgBox(0,"","")
						If $ppsPusto1==4 Then
						   Bomb($k-1,$l)
						   Pusto($k-1,$l+3)
						Else
						   Bomb($k+1,$l)
						   Pusto($k+1,$l+3)
						EndIf
					 Return
			   EndIf

	  EndIf
	  ;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

	  ;горизонтальный поиск 1120 0120 0210 0211
	  if $k < ($poleSizeX-3) Then
			$j=$l
			$pps = 0
			$pps2 = 0
			$pps3 = 0
			$pps4 = 0
			$ppsPusto1 = 0
			$ppsPusto2 = 0
			$CheckII = 0
			$m = 0
			For $i=$k To $k+3

			   If $poleClean[$i][$j] == 100 Then
				  ExitLoop
			   EndIf

				  If $j == 0 Then
					 If $poleClean[$i][$j+1] == 100 Then
						$ppsPusto2+=1
					 EndIf
				  ElseIf $j == $poleSizeY-1 Then
					 If $poleClean[$i][$j-1] == 100 Then
						$ppsPusto1+=1
					 EndIf
				  Else
					 If $poleClean[$i][$j-1] == 100 Then
						$ppsPusto1+=1
					 EndIf
					 If $poleClean[$i][$j+1] == 100 Then
						$ppsPusto2+=1
					 EndIf
				  EndIf

			   If $poleClean[$i][$j] == $S1120[$m] Then
				  $pps+=1
			   ElseIf ($m=3) and ($pps=3) Then
				  $pps+=1
			   Else
				  $pps=0
			   EndIf

			   If $poleClean[$i][$j] == $S0120[$m] Then
				  $pps2+=1
			   ElseIf ($m=3) and ($pps2=3) Then
				  $pps2+=1
			   Else
				  $pps2=0
			   EndIf

			   If $poleClean[$i][$j] == $S1120_i[$m] Then
				  $pps3+=1
			   ElseIf ($m=0) and ($pps3=0) Then
				  $pps3+=1
			   Else
				  $pps3=0
			   EndIf

			   If $poleClean[$i][$j] == $S0120_i[$m] Then
				  $pps4+=1
			   ElseIf ($m=0) and ($pps4=0) Then
				  $pps4+=1
			   Else
				  $pps4=0
			   EndIf

			   $m += 1

			Next

			   If (($pps == 4) Or ($pps2 == 4)) and _
				  ( ($ppsPusto1==0 And $ppsPusto2==4) Or ($ppsPusto1==4 And $ppsPusto2==0) ) Then ;нашли шаблон опаопаопапапа
					 ConsoleWrite("Горизонт шаблон 1120 0120 "&$k&","&$l&@CR)
					 ;MsgBox(0,"","")
						If $ppsPusto1==4 Then
						   Pusto($k,$l-1)
						   Bomb($k+3,$l-1)
						Else
						   Pusto($k,$l+1)
						   Bomb($k+3,$l+1)
						EndIf
					 Return
			   EndIf

			   If (($pps3 == 4) Or ($pps4 == 4)) and _
				  ( ($ppsPusto1==0 And $ppsPusto2==4) Or ($ppsPusto1==4 And $ppsPusto2==0) ) Then ;нашли шаблон опаопаопапапа
					 ConsoleWrite("Горизонт шаблон 0210 0211 "&$k&","&$l&@CR)
					 ;MsgBox(0,"","")
						If $ppsPusto1==4 Then
						   Bomb($k,$l-1)
						   Pusto($k+3,$l-1)
						Else
						   Bomb($k,$l+1)
						   Pusto($k+3,$l+1)
						EndIf
					 Return
			   EndIf

	  EndIf

EndFunc

Func Coordinati3x3($k,$l) ;координаты кубика вокруг к л
	  ;Координаты кубика
      If $k==0 Then
         $posX1=0
		 $posX2=$k+1
	  ElseIf $k == ($poleSizeX-1) Then
		 $posX1=$k-1
		 $posX2=$poleSizeX-1
	  Else
		 $posX1=$k-1
		 $posX2=$k+1
	  EndIf

      if $l==0 Then
         $posY1=0
		 $posY2=$l+1
	  ElseIf $l == ($poleSizeY-1) Then
		 $posY1=$l-1
		 $posY2=$poleSizeY-1
	  Else
		 $posY1=$l-1
		 $posY2=$l+1
      EndIf
EndFunc

Func MineByC2H5OH()
      ; Шаг 3.5
   For $i = 0 To $poleSizeX-1
	  For $j = 0 To $poleSizeY-1
		 If ($pole[$i][$j] > 0) and ($pole[$i][$j] < 8) Then
			If MineSwepperAdvansedOpenCell($Pole, $i, $j) Then
			  $OpenFlag += 1
			  Return
			EndIf
		 EndIf
	  Next
   Next
EndFunc

Func MineSwepperAdvansedOpenCell($aPole, $cellX, $cellY)
    ;ConsoleWrite("вокруг "&$cellX&","&$cellY&@CR)
    If $aPole[$cellX][$cellY] = 1000  Then Return False
    If $aPole[$cellX][$cellY] > 8  Then Return False

    Local $sum10 = 0, $sum11 = 0
    For $i = -1 To 1
        If $cellX+$i < 0 Then ContinueLoop
        If $cellX+$i > $poleSizeX-1 Then ContinueLoop
        For $j = -1 To 1
            If $cellY+$j < 0 Then ContinueLoop
            If $cellY+$j > $poleSizeY-1 Then ContinueLoop
            If $aPole[$cellX+$i][$cellY+$j] = 99 Then $sum11 += 1
            If $aPole[$cellX+$i][$cellY+$j] = 100 Then $sum10 += 1
        Next
    Next

    If $aPole[$cellX][$cellY] <> $sum11+1 Then Return False
    If $sum10 = 0 Then Return False

    For $i = -1 To 1
        If $cellX+$i < 0 Then ContinueLoop
        If $cellX+$i > $poleSizeX-1 Then ContinueLoop
        For $j = -1 To 1
            If $cellY+$j < 0 Then ContinueLoop
            If $cellY+$j > $poleSizeY-1 Then ContinueLoop
            If $aPole[$cellX+$i][$cellY+$j] = 100 Then $aPole[$cellX+$i][$cellY+$j] = 1 / $sum10
        Next
    Next

    ;_ArrayDisplay($aPole)

    Local $m, $s
    For $x = $cellX-2 To $cellX+2
        If $x < 0 Then ContinueLoop
        If $x > $poleSizeX-1 Then ContinueLoop
        For $y = $cellY-2 To $cellY+2
            If $y < 0 Then ContinueLoop
            If $y > $poleSizeY-1 Then ContinueLoop

            If ($aPole[$x][$y] < 10) And ($aPole[$x][$y] >= 1) Then
                $m = 0
                $s = 0
                For $i = -1 To 1
                    If $x+$i < 0 Then ContinueLoop
                    If $x+$i > $poleSizeX-1 Then ContinueLoop
                    For $j = -1 To 1
                        If $y+$j < 0 Then ContinueLoop
                        If $y+$j > $poleSizeY-1 Then ContinueLoop
                        If $aPole[$x+$i][$y+$j] = 99 Then $m += 1
                        If $aPole[$x+$i][$y+$j] = 100 Then $s += 1
                        If $aPole[$x+$i][$y+$j] < 1 Then $m += $aPole[$x+$i][$y+$j]
                    Next
                Next

                ConsoleWrite("вокруг ("&$aPole[$cellX][$cellY]&")"&$cellX&","&$cellY&" сейчас "&$x&","&$y&" сумма "&$aPole[$x][$y]&" из "&$m&@CR)

                If $aPole[$x][$y] = $m  Then
                    ;_ArrayDisplay($aPole)
                    For $i = -1 To 1
                        If $x+$i < 0 Then ContinueLoop
                        If $x+$i > $poleSizeX-1 Then ContinueLoop
                        For $j = -1 To 1
                            If $y+$j < 0 Then ContinueLoop
                            If $y+$j > $poleSizeY-1 Then ContinueLoop
                            If $aPole[$x+$i][$y+$j] = 100 Then
								    Pusto($x+$i,$y+$j)
                                    Return True
                            EndIf
                        Next
                    Next
                EndIf

                If $aPole[$x][$y] = ($s+$m)  Then
                    For $i = -1 To 1
                        If $x+$i < 0 Then ContinueLoop
                        If $x+$i > $poleSizeX-1 Then ContinueLoop
                        For $j = -1 To 1
                            If $y+$j < 0 Then ContinueLoop
                            If $y+$j > $poleSizeY-1 Then ContinueLoop
                            If $aPole[$x+$i][$y+$j] = 100 Then
							  Bomb($x+$i,$y+$j)
							  Return True
                            EndIf
                        Next
                    Next
                EndIf

            EndIf
        Next
    Next
    Return False
EndFunc
 
Верх