Что нового

Прохождение Сапёра за 60 Секунд

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Это видео не монтаж, я его сам снял на своей системе (XP SP3):

Minesweeper.avi

Началось всё с того что я случайно на работе, проходя мимо сидящего за компьютером охранника, играющего в Сапёра, решил ему помочь.
Он мне стал доказывать что иногда в Сапёре бывают тупики, и решить без риска не получается. Я почему то был уверен что оно не так, думал есть алгоритм по которому можно пройти любую сессию в игре, кто прав до сих пор неизвестно...

Но факт остаётся фактом, как видно на видео, я прошёл игру меньше чем за 60 секунд, что в принципе нереально не зная заранее рабочего и 100%-ного алгоритма.

Как я это сделал? Жду обсуждение, ваши мысли по этой теме, в конце обещаю раскрыть секрет, намекну только на то, что AutoIt тут в стороне не стоял :laugh:
 

SECTOR

Продвинутый
Сообщения
399
Репутация
59
Да, видно что не человек работал :D
 

dwerf

Использует ArchLinux
Сообщения
478
Репутация
219
Видео такое уже видел.

Встречная задачка.

077768b1f460.jpg


Это фото тоже не монтаж, я тоже снял его сам.
В окне вручную ничего не изменялось, AutoIt вообще не использовался.
 

ynbIpb

Скриптер
Сообщения
399
Репутация
110
CreatoR [?]
Он мне стал доказывать что иногда в Сапёре бывают тупики, и решить без риска не получается.
Тупики действительно бывают, если бы их не было, то не придумали бы игру на деньги
а по поводу автоматизации сапёра, на англ. форуме много примеров есть, типа Minesweeper UDF

dwerf [?]
Встречная задачка.
Это через чтение памяти делается. есть скрипт на англ. форуме.
з.ы.
Вот этот я имел ввиду: Godly Minesweeper Bot

Может ты вмешался в файл сейвов сапёра?
 

dwerf

Использует ArchLinux
Сообщения
478
Репутация
219
Память не читал, окна не правил, в работающий процесс нестандартными методами не вмешивался.
 

Garrett

Модератор
Локальный модератор
Сообщения
3,999
Репутация
967
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Garrett
Так не интересно, дал бы другим помучаться, не все умеют гуглить :laugh:

Это что-то многовато
Можешь быстрее? :whistle:
 

SyDr

Сидра
Сообщения
651
Репутация
158
Ну ладно, вот ещё пару вариантов:
1) Сапёр - NP-полная задача
http://ru.wikipedia.org/wiki/NP-%D0%BF%D0%BE%D0%BB%D0%BD%D0%B0%D1%8F_%D0%B7%D0%B0%D0%B4%D0%B0%D1%87%D0%B0
http://en.wikipedia.org/wiki/Minesweeper_(computer_game)#cite_ref-Kaye00_3-0
2) Вторая 1 в первой строке. Независимо от выбранного алгоритма там могла быть мина, а это значит, что задача решалась не без помощи стороннего софта.
3) Я уже молчу про сам метод решения: вести построчно мышку, клацать в центре каждого квадратика правой или левой кнопкой мыши.
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
ynbIpb [?]
на англ. форуме много примеров есть, типа Minesweeper UDF
Там нет UDF.

dwerf
Вашу недрогнувшую при прохождении руку тоже не видно
Но я же показал видео, или не вериш мне? Я слова на ветер не бросаю, я кажется написал в первом сообщений что раскажу как это сделал. Просто мне с трудом верится что оно возможно за одну/две/три секунду/ы.
 

Garrett

Модератор
Локальный модератор
Сообщения
3,999
Репутация
967
CreatoR [?]
Так не интересно, дал бы другим помучаться, не все умеют гуглить
Sorry! :-[
Руками, было дело, за пять 5 сек. открыл :smile:
Сегодня вспомнил старое, уложился за семь!
Написать скрипт не пробовал, я этот фокус знал давно, и эта тема заставила вспомнить! Правда, скажу честно, комбинацию клавиш вспоминал долго, но так и не вспомнил, и не долга думая, всё же полез в Google! :whistle:
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
dwerf [?]
Значит кто то уже делал подобное, но я честно этого раньше не видел. Кстати там быстрее из за того, что в отличий от моего метода, флажки на минах там не ставятся.
 

dronet

Знающий
Сообщения
46
Репутация
8
Жаль не могу сравнитса :whistle: Потому-что после установки OS игры у меня сразу в слетают так как - не нужные для меня. Но всё-же интерестно, подожду ответа. Наверняка самое простое решение ;D
 

`p r o x y

«Улыбайтесь, господа!»
Команда форума
Глобальный модератор
Сообщения
596
Репутация
157
OffTopic:
Это только я один не люблю сапер и развлекаюсь исключительно только в маджонг?
 

SyDr

Сидра
Сообщения
651
Репутация
158
Ладно, вот мой вариант, 43 секунды. Никаких манипуляций с памятью процесса:
http://www.youtube.com/watch?v=iLHAtRSxV4w
 

`p r o x y

«Улыбайтесь, господа!»
Команда форума
Глобальный модератор
Сообщения
596
Репутация
157
SyDr
Но явно ж используется какое-то средство автоматизации - иммею ввиду типа AutoIt?
 

SyDr

Сидра
Сообщения
651
Репутация
158
Ну да. Но в чём подвох в моём случае? :smile:

В первом видео - это просто чтение из памяти процесса значений и клики в нужны местах. А что у меня?
 

sss

Продвинутый
Сообщения
332
Репутация
96
Работает только на XP. Профи за 7 секунд. запускаем прогу и жмем Ctrl+Alt+ноль ))
Код:
#include <WinAPI.au3>
#include <Constants.au3>
#include <WindowsConstants.au3>



Global Const $DataPtr = 0x1005330
Global Const $MinesPtr = 0x1005340
Global $MineSweeper_PID = Run("winmine.exe") ;run it
Global $hProcess = _WinAPI_OpenProcess(0x1F0FFF, 1, $MineSweeper_PID, True) ;open it

dim $read
HotKeySet('^!0','MinesweeperSolve')
HotKeySet('^!-','_Exit')
while 1
WEnd
func _exit()
	ProcessClose('winmine.exe')
	Exit
EndFunc
func MinesweeperSolve()
WinWait("Сапер") ;wait for the minesweeper to load.

$DataStruct = DllStructCreate("dword mines;dword width;dword height")
_WinAPI_ReadProcessMemory($hProcess, $DataPtr, DllStructGetPtr($DataStruct), DllStructGetSize($DataStruct), $read) ;Get widht, height and number of mines :)


ConsoleWrite(DllStructGetData($DataStruct, "mines") &  " Mines in a  " & DllStructGetData($DataStruct, "width") & " by " & DllStructGetData($DataStruct, "height") &  " grid " & @CRLF)

WinActivate("Сапер")

$pos=WinGetPos("Сапер")

$Width = DllStructGetData($DataStruct, "width") - 1
$Height = DllStructGetData($DataStruct, "height") - 1

For $y = 0 To $Height
    For $x = 0 To $Width
        Switch _IsMine($x,$y)
			Case -1 ;Already open
                ContinueLoop
            Case 0 ;Safe to click on
                ControlClick("Сапер", "", "", "left", 1, 20 + ($x *16),(16 * $y) + 60)
            Case 1 ;MINE!!!!
                ControlClick("Сапер", "", "", "right", 1, 20 + ($x *16),(16 * $y) + 60)
        EndSwitch
        ;Sleep(25) ;Looks cool :P
    Next
Next

endfunc
Func _IsMine($x, $y)
    $buffer = DllStructCreate("ubyte mine")
    _WinAPI_ReadProcessMemory($hProcess, $MinesPtr + (32 * ($y + 1)) + ($x + 1) , DllStructGetPtr($buffer), DllStructGetSize($buffer), $read)
    If DllStructGetData($buffer, "mine") = 0x40 Then
        Return -1
    ElseIf DllStructGetData($buffer, "mine") = 0x0F Then
        Return 0
    ElseIf DllStructGetData($buffer, "mine") = 0x8f Then
        Return 1
    EndIf
EndFunc
 
Верх