Что нового

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

C2H5OH

AutoIT Гуру
Сообщения
1,473
Репутация
333
СН3СН2ОН
мне нифига не лень объяснить суть алгоритма, но когда разговор начинается со слов
"У вас в алгоритме грабли"
"ваш алгоритм зависает 4 из 5 случаев"
"мой скрипт умнее"
то, извините...

Вот результат работы вашего последнего скрипта
55df67da6a81.jpg

Есть клетки которые можно открыть, есть клетки, которые можно отметить как мины. Но ваш скрипт заявляет что
"(Другого пути нет!) Отправили смертника в квадрат 11,9"

Если вам кажется что мой алгоритм даёт сбои, то приложите скрин, на котором есть возможность сделать результативный ход, но мой скрипт вместо этого подорвался на мине.
А всякие неподкрепленные утверждения мне неинтересны.

И, да - комбинаторика.
На уровне средней школы.
Не помню уже в каком там классе проходят Принцип Дирихле.
 

СН3СН2ОН

Знающий
Сообщения
78
Репутация
12
Много копий мы сломали. :smile:
Мне что извиняться в каждом сообщении? Серьезней надо быть.
А теперь конкретика (блин чем я на работе занимаюсь :smile: ):
1. Нашел таки, почему твой скрипт 6,0 не хотел у меня работать, закралась недоработка
Код:
If PixelGetColor(22+16*$i,108+16*$j) = $CellColors[10] Then

Я поменял
Код:
If PixelGetColor(22+16*$i,108+16*$j) = $CellColors[7] Then

ну либо вместо 108 поставить 101
КОНЕШНО - это не ошибка (ставим стиль как у вас и все работает). У меня классический стиль на работе вот я и не воспринял серьезно скрипт.
2. Я не знаю почему мой скрипт так лажает, возможно тоже от того что стили разные. Попробуйте поставить классик.
3.[Цитата]Если вам кажется что мой алгоритм даёт сбои, то приложите скрин, на котором есть возможность сделать результативный ход, но мой скрипт вместо этого подорвался на мине.
А всякие неподкрепленные утверждения мне неинтересны.[/Цитата]
Пункт 2 и когда будет сообщение
Код:
MsgBox(0,'Это чудо !!!','После алгоритма водки сработал наш алгоритм !')

4. Ваш скрипт не лажает - заложенный функционал реализовывает.
5. Про Дирихле - спасибо. У меня в школе комбинаторики не было. Вам повезло.

p.s Может форум чё режет, вот исходник
http://rghost.ru/download/54601092/2578bc59b3d518951e9609df5e99d79a91b386fd/%D0%A1%D0%B0%D0%BF%D0%B5%D1%80_restyle.au3
 

СН3СН2ОН

Знающий
Сообщения
78
Репутация
12
Немного исправил, было неточное условие поиска.
Код:
#include <Array.au3>

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

;Глобальные переменные получают рандомные большие значения просто потому, что мы пока не умеем по другому
Global $poleSizeX=30, $poleSizeY=30   ; размер поля
Global $OpenFlag = 1, $tiktak = 0 , $FlagOpenArray =0, $py =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 = 100
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()
		 If $OpenFlag <> 0 Then
			$FlagOpenArray +=1
			$py +=1
		 EndIf
	  EndIf
	  if $OpenFlag = 0 Then
		 MineByC2H5OH()
		 If $OpenFlag <> 0 Then
			$py +=1
		 EndIf
	  EndIf
   	  if $OpenFlag = 0 Then
		 MineCheckShablon()
		 If $OpenFlag <> 0 Then
			;MsgBox(0,'Это чудо !!!','После алгоритма водки сработал наш алгоритм !')
			ConsoleWrite('Это чудо !!! После алгоритма водки сработал наш алгоритм !'&@CR)
			$py +=1
		 EndIf
	  EndIf
		 #comments-start
		 If ($py > 0) and ($OpenFlag = 0) Then
		 ;If $OpenFlag = 0 Then
			_ArrayTranspose($poleClean)
			_ArrayDisplay($poleClean)
		 EndIf
		 #comments-end
	  if $OpenFlag = 0 Then
		 ConsoleWrite("Доработать вероятность а пока шарашим рандомом РРРАААААААААААААЗ !!!"&@CR)
		 ;MsgBox(0,'рандом','')
		 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] < 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
 

C2H5OH

AutoIT Гуру
Сообщения
1,473
Репутация
333
Поставил в твоём скрипте показывать поле после сканирования
Код:
MineSweeperScan() ;1 Сканирование сапера в массив
	  _ArrayDisplay($Pole)


Твой скрипт распознаёт 3 и 1.
Твой скрипт не распознаёт 4 и 2.
Не пойму зачем ты изменил координаты контрольной точки для определения цвета.

Ну ты хоть раз выложи скрин с результатом работы твоего скрипта. Мы и посмотрим как выглядит сапёр, который ты используешь. Вот типа такого
04326cb52dfc.jpg
 

СН3СН2ОН

Знающий
Сообщения
78
Репутация
12
Все работает, смотрим так
Код:
MineSweeperScan() ;1 Сканирование сапера в массив
			_ArrayTranspose($pole)
			_ArrayDisplay($pole)


Не пойму зачем ты изменил координаты контрольной точки для определения цвета --> в твоем скрипте от темы оформления пляшут координаты, вот и менял чтобы протестить нормально

Скриншоты.



Оффтоп. C2H5OH может подскажешь к чему еще бота написать? (Может WOT который браузерный) Желательно с профитом и без глубоких познаний, я в игры вообще не играю.

Я таки не понял, что ни разу нормально скрипт не запустился? Я так-то вроде кросскомпьютерно (как мог) писал. Может кто нибудь протестить еще? WinXP, ru-RU
 

C2H5OH

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

Насчет офтопа.
Если некуда приложить свои силы, то вот тебя уже два года тема дожидается. :laugh:
http://autoit-script.ru/index.php/topic,10439.0.html


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

Ну, что я могу сказать...

1. Шаблоны - отстой! Шаблоны - не есть алгоритм, а просто заглушка, закрывающая лишь какой-то один вариант.

2. Чудес не бывает. Путем добавления в MinesweeperAdvansedOpenCell одной строки
Код:
$m = Ceiling($m)	; STOP SHABLON!

после открытия пустых клеток и перед отметкой мин, мы прекращаем всякие инсинуации.

3. Мысль с переходом на
Код:
Opt("PixelCoordMode", 2)
Opt("MouseCoordMode", 2)

очень неплоха. Скрипт сразу перестаёт быть зависимым от стиля.
Тут же возникла другая проблема - определение параметров игры.
Остановился на том чтобы зайти в меню и посмотреть. Но это вызывает переключение в режим "Особые". Что означает что результат не будет зафиксирован как рекорд.

Вобщем. Наш ответ плагиатчику.
Код:
#cs
	Бот для игры Сапёр.
	Версия 7
#ce
#include <Array.au3>
HotKeySet("!{F11}", "Terminate") ; Alt + F11
Func Terminate()
	ConsoleWrite("остановлено" & @CR & "-----------" & @CR)
	Exit 0
EndFunc   ;==>Terminate

HotKeySet("{F11}", "Minesweeper")

Global $poleSizeX, $poleSizeY, $MaxMineNumber
Global $MinesFound ; количество найденных мин
Global $OpenFlag
Global $pole[1][1]
Global $tmpCellColors[11]
Global $CellColors[11] = [0xC0C0C0, 0x0000FF, 0x008000, 0xFF0000, 0x000080, 0x800000, 0x008080, 0x000000, 0xFFFFFF, 0xFFFFFF, 0xFF0000]
; принятые значения полей
; 0 - открытое поле, рядом 0 мин
; 1 - открытое поле, рядом 1 мина
; 2 - открытое поле, рядом 2 мины
; 3 - открытое поле, рядом 3 мины
; 4 - открытое поле, рядом 4 мины
; 5 - открытое поле, рядом 5 мин
; 6 - открытое поле, рядом 6 мин
; 7 - открытое поле, рядом 7 мин
; 8 - мифичесоке открытое поле, рядом 8 мин
; 10 - неоткрытое необозначенное поле
; 11 - мина

#include <file.au3>

If _FileReadToArray("CellColors.dat", $tmpCellColors) Then
	For $i = 0 To 10
		$CellColors[$i] = Number($tmpCellColors[$i + 1])
	Next
EndIf

While 1
	Sleep(10000)
WEnd

Func Minesweeper()
	If Not WinExists("Сапер") Then MsgBox(4096, "Error", "Сапер не запущен")
	WinActivate("Сапер")
	Sleep(1000)
	; Новичок
	;	$poleSizeX = 9
	;	$poleSizeY = 9
	;	$MaxMineNumber = 10
	; Любитель
	;	$poleSizeX = 16
	;	$poleSizeY = 16
	;	$MaxMineNumber = 40
	; Профи
	;	$poleSizeX = 30
	;	$poleSizeY = 16
	;	$MaxMineNumber = 99
	; Особые
		Send("{F10}")
		Send("{DOWN 5}")
		Send("{ENTER}")
		$oText = WinGetText("Специальное поле")
		Send("{ESC}")
		ConsoleWrite($oText)
		$aParam = StringRegExp($oText, ".*?(\d+).*?", 3)
		$poleSizeY = $aParam[0]
		$poleSizeX = $aParam[1]
		$MaxMineNumber = $aParam[2]

	ReDim $pole[$poleSizeX][$poleSizeY]

	Opt("PixelCoordMode", 2)
	Opt("MouseCoordMode", 2)

	Send("{F2}")
	ConsoleWrite("start" & @CR)

	While 1
		If MinesweeperExplosion() Then ;если подорвался
			ConsoleWrite("подорвался" & @CR)
			Return
		EndIf
		MinesweeperScan() ; Шаг 1
		MinesweeperCheckCells() ; Шаг 2
		$MinesFound = MinesweeperCalculateMines() ; посчитать найденные мины
		If $MinesFound = $MaxMineNumber Then ; если все мины найдены
			MinesweeperOpenAllClearCells() ; то открываем все оставшиеся клетки
			ConsoleWrite("всё открыл" & @CR)
			Return
		EndIf
		MinesweeperOpenCells() ; Шаг 3

		If Not $OpenFlag Then ; Шаг 3.5
			For $i = 0 To $poleSizeX - 1
				For $j = 0 To $poleSizeY - 1
					If MinesweeperAdvansedOpenCell($pole, $i, $j) Then
						$OpenFlag = True
						ExitLoop 2
					EndIf
				Next
			Next
		EndIf

		If Not $OpenFlag Then MinesweeperOpenRandomCell() ; Шаг 4
	WEnd
EndFunc   ;==>Minesweeper

Func MinesweeperScan()
	Local $x
	For $i = 0 To $poleSizeX - 1
		For $j = 0 To $poleSizeY - 1
			If PixelGetColor(12 + 16 * $i, 56 + 16 * $j) = 0xFFFFFF Then
				If PixelGetColor(19 + 16 * $i, 59 + 16 * $j) = $CellColors[10] Then
					$pole[$i][$j] = 11
				Else
					$pole[$i][$j] = 10
				EndIf
			Else
				$color = PixelGetColor(19 + 16 * $i, 59 + 16 * $j)
				Switch $color
					Case $CellColors[0]
						$pole[$i][$j] = 0
					Case $CellColors[1]
						$pole[$i][$j] = 1
					Case $CellColors[2]
						$pole[$i][$j] = 2
					Case $CellColors[3]
						$pole[$i][$j] = 3
					Case $CellColors[4]
						$pole[$i][$j] = 4
					Case $CellColors[5]
						$pole[$i][$j] = 5
					Case $CellColors[6]
						$pole[$i][$j] = 6
					Case $CellColors[7]
						$pole[$i][$j] = 7
					Case $CellColors[8]
						$pole[$i][$j] = 8
					Case Else
						MouseMove(20 + 16 * $i, 60 + 16 * $j, 0)
						$x = InputBox("error", "Неизвестное количество мин в поле " & $i & "x" & $j & @CR & "цвет 0x" & Hex($color, 6) & @CR & "введите количество мин, которое изображено в этой клетке" & @CR & "0 - открытая пустая клетка" & @CR & "9 - неоткрытое поле")
						$CellColors[$x] = $color
						$pole[$i][$j] = $x
						If $x > 8 Then $pole[$i][$j] += 1 ; для констант обозначающих пустое поле и мину
						$file = FileOpen("CellColors.dat", 2)
						For $t = 0 To 10
							FileWriteLine($file, "0x" & Hex($CellColors[$t], 6))
						Next
						FileClose($file)
				EndSwitch
			EndIf
		Next
	Next
EndFunc   ;==>MinesweeperScan

Func MinesweeperCheckCells()
	Local $m
	For $x = 0 To $poleSizeX - 1
		For $y = 0 To $poleSizeY - 1
			If $pole[$x][$y] < 10 Then
				$m = 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 $pole[$x + $i][$y + $j] >= 10 Then $m += 1
					Next
				Next
			EndIf
			If $pole[$x][$y] = $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 $pole[$x + $i][$y + $j] = 10 Then
							MouseMove(19 + 16 * ($x + $i), 61 + 16 * ($y + $j), 0)
							Sleep(100)
							MouseClick("Right", 19 + 16 * ($x + $i), 61 + 16 * ($y + $j))
							$pole[$x + $i][$y + $j] = 11
						EndIf
					Next
				Next
			EndIf
		Next
	Next
EndFunc   ;==>MinesweeperCheckCells

Func MinesweeperOpenCells()
	Local $m
	$OpenFlag = False
	For $x = 0 To $poleSizeX - 1
		For $y = 0 To $poleSizeY - 1
			If $pole[$x][$y] < 10 Then
				$m = 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 $pole[$x + $i][$y + $j] = 11 Then $m += 1
					Next
				Next
			EndIf
			If $pole[$x][$y] = $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 $pole[$x + $i][$y + $j] = 10 Then
							If PixelGetColor(12 + 16 * ($x + $i), 56 + 16 * ($y + $j)) = 0xFFFFFF Then
								MouseMove(19 + 16 * ($x + $i), 61 + 16 * ($y + $j), 0)
								Sleep(100)
								MouseClick("Left", 19 + 16 * ($x + $i), 61 + 16 * ($y + $j))
								$OpenFlag = True
							EndIf
						EndIf
					Next
				Next
			EndIf
		Next
	Next
EndFunc   ;==>MinesweeperOpenCells

Func MinesweeperCalculateMines()
	Local $m = 0
	For $x = 0 To $poleSizeX - 1
		For $y = 0 To $poleSizeY - 1
			If $pole[$x][$y] = 11 Then $m += 1
		Next
	Next
	Return $m
EndFunc   ;==>MinesweeperCalculateMines

Func MinesweeperOpenRandomCell()
	While 1
		$x = Random(0, $poleSizeX - 1, 1)
		$y = Random(0, $poleSizeY - 1, 1)
		If $pole[$x][$y] = 10 Then
			ConsoleWrite("рандомный клик " & $x & "," & $y & @CR)
			MouseMove(19 + 16 * ($x), 61 + 16 * ($y), 0)
			Sleep(100)
			MouseClick("Left", 19 + 16 * $x, 61 + 16 * $y)
			Return
		EndIf
	WEnd
EndFunc   ;==>MinesweeperOpenRandomCell

Func MinesweeperOpenAllClearCells()
	For $x = 0 To $poleSizeX - 1
		For $y = 0 To $poleSizeY - 1
			If $pole[$x][$y] = 10 Then
				MouseMove(19 + 16 * ($x), 61 + 16 * ($y), 0)
				Sleep(100)
				MouseClick("Left", 19 + 16 * $x, 61 + 16 * $y)
			EndIf
		Next
	Next
EndFunc   ;==>MinesweeperOpenAllClearCells

Func MinesweeperExplosion()
	If PixelGetColor(16 + 16 * Floor($poleSizeX / 2), 32) = 0x000000 Then
		Return True
	Else
		Return False
	EndIf
EndFunc   ;==>MinesweeperExplosion

Func MinesweeperAdvansedOpenCell($aPole, $cellX, $cellY)
	;ConsoleWrite("вокруг "&$cellX&","&$cellY&@CR)
	If $aPole[$cellX][$cellY] = 0 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] = 11 Then $sum11 += 1
			If $aPole[$cellX + $i][$cellY + $j] = 10 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] = 10 Then $aPole[$cellX + $i][$cellY + $j] = 1 / $sum10
		Next
	Next

	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] = 11 Then $m += 1
						If $aPole[$x + $i][$y + $j] = 10 Then $s += 1
						If $aPole[$x + $i][$y + $j] < 1 Then $m += $aPole[$x + $i][$y + $j]
					Next
				Next

				If $aPole[$x][$y] = $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] = 10 Then
								If PixelGetColor(12 + 16 * ($x + $i), 56 + 16 * ($y + $j)) = 0xFFFFFF Then
									MouseMove(19 + 16 * ($x + $i), 61 + 16 * ($y + $j), 0)
									Sleep(100)
									MouseClick("Left", 19 + 16 * ($x + $i), 61 + 16 * ($y + $j))
									ConsoleWrite("вокруг " & $cellX & "," & $cellY & " [" & $aPole[$cellX][$cellY] & "] клетка " & $x & "," & $y & " [" & $aPole[$x][$y] & "] открыта" & @CR)
									Return True
								EndIf
							EndIf
						Next
					Next
				EndIf

				$m = Ceiling($m)	; STOP SHABLON !

				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] = 10 Then
								If PixelGetColor(12 + 16 * ($x + $i), 56 + 16 * ($y + $j)) = 0xFFFFFF Then
									MouseMove(19 + 16 * ($x + $i), 61 + 16 * ($y + $j), 0)
									Sleep(100)
									MouseClick("Right", 19 + 16 * ($x + $i), 61 + 16 * ($y + $j))
									ConsoleWrite("вокруг " & $cellX & "," & $cellY & " [" & $aPole[$cellX][$cellY] & "] клетка " & $x & "," & $y & " [" & $aPole[$x][$y] & "] отмечена" & @CR)
									Return True
								EndIf
							EndIf
						Next
					Next
				EndIf

			EndIf
		Next
	Next
	Return False
EndFunc   ;==>MinesweeperAdvansedOpenCell
 
Верх