Что нового

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

CreatoR

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

Minesweeper.avi

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

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

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

SECTOR

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

dwerf

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

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



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

ynbIpb

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

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

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

dwerf

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

Garrett

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

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8 472
Репутация
2 401
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 472
Репутация
2 401
ynbIpb [?]
на англ. форуме много примеров есть, типа Minesweeper UDF
Там нет UDF.

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

Garrett

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

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8 472
Репутация
2 401
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
 
Верх