Показать полную графическую версию : [архив - Часть 2] AutoIt скрипты
Maza Faka, сначала отображается один файл, а затем все остальные, кроме файла, который отобразился в первый раз, почему так происходит?
Через StdOutRead можно читать данные те что доступны в момент выполнения (ком. строки).
Видимо отдаются не все данные сразу, можно их склеивать ;)
$foo = Run(@ComSpec & " /c @dir /b e:\", @SystemDir, @SW_HIDE, 4+2)
$line = ""
$Errline = ""
While 1
$line &= StdoutRead($foo)
If @error Then ExitLoop
Wend
While 1
FileWrite("c:\error.log", $line)
$Errline &= StderrRead($foo)
If @error Then ExitLoop
Wend
MsgBox(0, "STDERR read:", $line)
MsgBox(0, "STDOUT read:", $Errline)
Почему функция возвращает ноль?
По умолчанию функция так и возвращает если не задано значение по Return, видимо у тебя в функции дело не доходит до Return :) - MsgBox показывается перед выходом с функции?
Кстати, у тебя проверяется на папку, но проверять нужно содержится ли буква D в возвращённом значении от FileGetAttrib(), потому как папка может ещё иметь атрибут скрытый и т.п ;)
Angelus, загружает процессор на 100%????
Если нет процесса iexplore.exe и существует процесс wow.exe, то цикл продолжает без паузы, для предотвращения загрузкий ЦП нужна пауза хотябы в 10 мс.
Кстати, вместо Run('tskill...') можно использовать ProcessClose() ;)
Накалякал тут функцию для отображения MsgBox со счётчиком отсчёта + возможностью указывания hWnd (идентификатор окна к которому будет относится сообщение):
_MsgBoxCount(36, "Hello World!", "Hi!", 5, WinGetHandle(""))
Func _MsgBoxCount($Flag, $Title, $Text, $Time=0, $hWnd=0, $ButtonIDName='Button1')
Run(@AutoItExe & ' /ErrorStdOut /AutoIt3ExecuteLine "DllCall(''user32.dll'', ''int'', ''MessageBox'', ''hwnd'', ' & _
$hWnd & ', ''str'', ''' & $Text & ''', ''str'', ''' & $Title & ''', ''int'', ' & $Flag & '")')
Local $OldWTMM = Opt("WinTextMatchMode", 2)
If $Time > 0 Then
WinWait($Title, $Text)
Local $ButtonText = ControlGetText($Title, $Text, $ButtonIDName)
For $i = $Time To 1 Step -1
If Not WinExists($Title, $Text) Then ExitLoop
ControlSetText($Title, $Text, $ButtonIDName, $ButtonText & ' (' & $i & ')')
Sleep(1000)
Next
EndIf
Opt("WinTextMatchMode", $OldWTMM)
If WinExists($Title, $Text) Then ControlClick($Title, $Text, $ButtonIDName)
EndFunc
Вот только не знаю как организовать возвращаемое значение...
Пробовал через StdOutRead, но не выходит :( - Пример попытки через обычный MsgBox():
$Ret = _MsgBoxCount(36, "Hello World!", "Hi!", 5)
MsgBox(0, "", $Ret)
Func _MsgBoxCount($Flag, $Title, $Text, $Time=0, $ButtonIDName='Button1')
Local $Pid = Run(@AutoItExe & ' /ErrorStdOut /AutoIt3ExecuteLine "StdinWrite(''' & @AutoItPID & ''', MsgBox(' & _
$Flag & ', ''' & $Title & ''', ''' & $Text & ''',' & $Time & '))"', '', '', 6)
Local $OldWTMM = Opt("WinTextMatchMode", 2)
If $Time > 0 Then
WinWait($Title, $Text)
Local $ButtonText = ControlGetText($Title, $Text, $ButtonIDName)
For $i = $Time To 0 Step -1
If Not WinExists($Title, $Text) Then ExitLoop
ControlSetText($Title, $Text, $ButtonIDName, $ButtonText & ' (' & $i & ')')
Sleep(1000)
Next
EndIf
Opt("WinTextMatchMode", $OldWTMM)
Return StdoutRead($Pid)
EndFunc
Пробовал по разному использовать StdOutRad, StdinWrite, но так ничего и не вышло...
Maza Faka
25-08-2007, 09:02
Creat0R, По умолчанию функция так и возвращает если не задано значение по Return, видимо у тебя в функции дело не доходит до Return - MsgBox показывается перед выходом с функции?
Да, MsgBox показывается с путём C:\Program Files\IsqLite, но скрипт не завершает работу, а пару секунд, чего то там делает, и возвращает ноль. Такое ощущение, что после появления MsgBox скрипт продолжает работу.
Dim $path
MsgBox(64, "Done", WritePathToReg("icqlite.exe", @ProgramFilesDir))
Func WritePathToReg($icq, $path)
$search = FileFindFirstFile($path & "\*.*")
While 1
$file = FileFindNextFile($search)
If @error Then ExitLoop
$full_path = $path & "\" & $file
If StringInStr(FileGetAttrib($full_path), "D") Then WritePathToReg($icq, $full_path)
If $file = $icq Then
MsgBox(0, "", $path)
Return $path
EndIf
WEnd
FileClose($search)
EndFunc
Maza Faka,
скрипт не завершает работу, а пару секунд, чего то там делает, и возвращает ноль
Он ищет далее по папкам ;)
Какого назначение этой функции? сюдя по названию что-то пишет в реестер, но судя по содержанию, рекурсивно ищет определённый файл... :)
Во-первых у тебя при выходе не закрывается поиск, это уже ошибка.
Во-вторых, если ничего не найдено, нужно решить что возвращать, иначе будет 0... и тогда ты сможешь определить ошибку...
А в третьих, зачем обьявлять переменную $path в начале скрипта? она ведь используется как параметр в функции, обьявлять в этом случае незачем, имхо.
Func WritePathToReg($icq, $path)
$search = FileFindFirstFile($path & "\*.*")
While 1
$file = FileFindNextFile($search)
If @error Then ExitLoop
$full_path = $path & "\" & $file
If StringInStr(FileGetAttrib($full_path), "D") Then WritePathToReg($icq, $full_path)
If $file = $icq Then
FileClose($search)
Return $path
EndIf
WEnd
FileClose($search)
Return -1
EndFunc
После этого, я сразу вижу что функция ВСЕГДА возвращает значение -1, потому как цикл заканчивается (после рекурсива). Но я если честно даже не знаю что она на самом деле должна возвращать, все пути где найден файл, или что? или может писать в реестер каждый путь? :) - Тогда зачем возвращать значения путей?
Maza Faka
Почему функция возвращает ноль?
Кроме ошибки с атрибутами, на которую указал Creat0R у тебя в скрипте есть еще ряд мелких ошибок: используемые в функции переменные не объявлены как Local; выход из функции по Return происходит без закрытия хэндла FileClose().
Теперь к вопросу о возвращаемом значении… Во-первых, функция не является рекурсивной, так как нарушено одно из правил рекурсии: возвращаемое функцией значение должно передаваться по всей цепочке рекурсивных вызовов, у тебя же значение, возвращаемое WritePathToReg() вообще игнорируется… из этого имеем два следствия:
- дальше первого уровня подкаталогов функция и не пытается заглянуть, если бы файл лежал глубже чем на один уровень функция бы его не нашла;
- функция, осуществившая рекурсивный вызов не знает о результате этого вызова… поэтому даже если файл найден (как в твоем случае) на возвращаемое значение это никак не повлияет и результат будет зависеть только от содержимого текущего каталога ($path).
один из возможных вариантов,
ключевой переменной, передаваемой между рекурсивными вызовами является $sRetPath:MsgBox(64, "Done", _FindFile("icqlite.exe", @ProgramFilesDir))
Func _FindFile($sFile, $sPath)
Local $sRetPath='', $sFullPath
Local $hSearch = FileFindFirstFile($sPath & "\*.*"), $sName = FileFindNextFile($hSearch)
While @error=0 And $sRetPath = ''
$sFullPath = $sPath &'\'& $sName
If $sName = $sFile Then $sRetPath = $sPath
If StringInStr(FileGetAttrib($sFullPath), "D") Then $sRetPath = _FindFile($sFile, $sFullPath)
$sName = FileFindNextFile($hSearch)
WEnd
FileClose($hSearch)
Return $sRetPath
EndFunc
Maza Faka
25-08-2007, 10:46
amel27
Спасибо! Отличный код! Работает в 3 раза быстрее чем мой корявый код. :)
Maza Faka
Всегда пожалуйста :) ИМХО единственный случай, когда оправдано применение глобальных данных в рекурсии это массивы, во всех остальных случаях можно обойтись правильным выбором передаваемого значения.... И еще важное замечание - если в функции используются глобальные переменные их нужно обязательно объявлять в параметрах через ByRef, иначе потом легко забыть и запутаться.
Maza Faka
25-08-2007, 11:06
ключевой переменной, передаваемой между рекурсивными вызовами является $sRetPath:
If StringInStr(FileGetAttrib($sFullPath), "D") Then $sRetPath = _FindFile($sFile, $sFullPath)
Но ведь переменная $sRetPath заново обьявляется в начале функции:
Local $sRetPath='', $sFullPath, какой смысл присваивать ей значение?
Ммм...голова уже пухнет, кажется, что начинаю, что-то понимать, но оказывается, что понимаю не так. :)
какой смысл присваивать ей значение?
Что возвращает функция _FindFile() ?... либо "пусто" (файл в каталоге не найден), либо путь к каталогу с файлом, поэтому: при входе в функцию $sRetPath "пусто", далее устанавливаем его значение для каждого элемента каталога:
для файлов: просто проверяем условие - если подходит, то присваиваем значение $sRetPath = $sPath;
для каталогов: функция _FindFile() сама устанавливает требуемое значение $sRetPath.
Может тебе так будет понятней (пожалуй, это будет и правильней):MsgBox(64, "Done", _FindFile("icqlite.exe", @ProgramFilesDir))
Func _FindFile($sFile, $sPath)
Local $sRetPath='', $sFullPath
Local $hSearch = FileFindFirstFile($sPath &"\*"), $sName = FileFindNextFile($hSearch)
While @error=0 And $sRetPath = ''
$sFullPath = $sPath &'\'& $sName
If StringInStr(FileGetAttrib($sFullPath), "D") Then
$sRetPath = _FindFile($sFile, $sFullPath)
Else
If $sName = $sFile Then $sRetPath = $sPath
EndIf
$sName = FileFindNextFile($hSearch)
WEnd
FileClose($hSearch)
Return $sRetPath
EndFunc
голова уже пухнетдля рекурсий это нормально :)
Есть такая нестандартная задачка:
Имеется массив содержащий 6 значимых элементов:
Global $PlayersArray[7] = [6, "Вася", "Петя", "Паша", "Толик", "Лёня", "Кеша"]
Элементы массива, как видно, представляют имена игроков (скажем в настольный теннис :) ), нужно чтобы каждый игрок, поиграл со всеми остальными пятью игроками, но таким образом, чтобы все игроки ждали одинаковое количество игр между своими встречами, и при этом чтобы не получилось такого что один игрок играет более одной игры подряд :wacko: ...
Результат желательно вывести в качесте подобной таблицы:
Вася vs Паша
Лёня vs Петя
Толик vs Кеша
И т.д.
Пытался решить циклами типа такого:
Global $TotalPlayers = 6
Global $PlayersArray[$TotalPlayers+1] = [$TotalPlayers, "Вася", "Петя", "Паша", "Толик", "Лёня", "Кеша"]
$GamesList = ''
For $i = 1 To $TotalPlayers
$CurrentGameArr = GetRandomGame()
While StringInStr($GamesList, $CurrentGameArr[0] & " vs " & $CurrentGameArr[1]) Or _
StringInStr($GamesList, $CurrentGameArr[1] & " vs " & $CurrentGameArr[0])
$CurrentGameArr = GetRandomGame()
WEnd
$GamesList &= $CurrentGameArr[0] & " vs " & $CurrentGameArr[1] & @LF
Next
MsgBox(0, "", $GamesList)
Func GetRandomGame()
Local $Player_1 = $PlayersArray[Random(1, $TotalPlayers, 1)]
Local $Player_2 = $PlayersArray[Random(1, $TotalPlayers, 1)]
While $Player_2 = $Player_1
$Player_2 = $PlayersArray[Random(1, $TotalPlayers, 1)]
WEnd
Local $RetArr[2] = [$Player_1, $Player_2]
Return $RetArr
EndFunc
Но как видно результат не впечатляющий :(
Если кто то сможет решить задачку, буду очень благодарен, я если честно после трёхчасового просижывания потерял надежду на то что это вообще реально... оч нужно :blush2: ..
Maza Faka
25-08-2007, 16:56
amel27, ключевой переменной, передаваемой между рекурсивными вызовами является $sRetPath
Значит получается, что переменная совсем не пуста, и в ней хранятся временные данные при вызове функции?
Maza Faka
получается, что переменная совсем не пуста, и в ней хранятся временные данные при вызове функции?практически она все время пуста, как только ей присваивается значение функция немедленно завершает свою работу и возвращает это значение.... а если ничего не найдено, то возвращает значение инициализации - "пусто".
Creat0R
чтобы все игроки ждали одинаковое количество игр между своими встречамиЭто как понимать? Что-то мне подсказывает, что с таким условием задача не имеет решения... Как минимум, из этого следует, что для каждого игрока должен быть СВОЙ уникальный период ожидания, в противном случае игроки с одинаковым интервалом однажды встретившись играли бы только друг с другом... :)
ADD:Накалякал тут функцию для отображения MsgBox со счётчиком отсчёта + возможностью указывания hWndчем тебя не устраивает штатный GUI?.. хотелось бы знать причину
amel27,
Что-то мне подсказывает, что с таким условием задача не имеет решения
После двух дней колдования, я пришёл к тому же выводу :biggrin:
Всегда получается что кто-то ждёт дольше или меньше.. даже если речь идёт о 5-ти, и даже 4-тёх игроках...
В результате сделал типа такого (набросок с реальной бумаги :)) :
#include <Array.au3>
Global $PlayersString = "Вася|Петя|Паша|Толик|Лёня|Кеша"
Global $TotalPlayers = UBound(StringSplit($PlayersString, "|"))-1
Global $TotalGames = ($TotalPlayers * ($TotalPlayers-1)) / 2
Global $GamesListArr = GetRandomGames($PlayersString, $TotalPlayers, $TotalGames)
_ArrayDisplay($GamesListArr)
Func GetRandomGames($PlayersString, $TotalPlayers, $TotalGames)
Local $GamesList = ''
Local $PlayersArray = StringSplit($PlayersString, "|")
Local $SortArray[$TotalPlayers+1], $GamesStr = ''
For $i = 1 To $TotalPlayers
$SortArray[$i] = $PlayersArray[Random(1, $TotalPlayers, 1)]
While StringInStr($GamesStr, $SortArray[$i])
$SortArray[$i] = $PlayersArray[Random(1, $TotalPlayers, 1)]
WEnd
$GamesStr &= $SortArray[$i] & @CRLF
Next
Local $GamesListArr[$TotalGames+1]
Switch $TotalPlayers
Case 6
$GamesListArr[1] = $SortArray[1] & @Tab & " [vs] " & @Tab & $SortArray[3]
$GamesListArr[2] = $SortArray[2] & @Tab & " [vs] " & @Tab & $SortArray[4]
$GamesListArr[3] = $SortArray[5] & @Tab & " [vs] " & @Tab & $SortArray[6]
$GamesListArr[4] = $SortArray[1] & @Tab & " [vs] " & @Tab & $SortArray[4]
$GamesListArr[5] = $SortArray[3] & @Tab & " [vs] " & @Tab & $SortArray[2]
$GamesListArr[6] = $SortArray[4] & @Tab & " [vs] " & @Tab & $SortArray[6]
$GamesListArr[7] = $SortArray[1] & @Tab & " [vs] " & @Tab & $SortArray[5]
$GamesListArr[8] = $SortArray[2] & @Tab & " [vs] " & @Tab & $SortArray[6]
$GamesListArr[9] = $SortArray[4] & @Tab & " [vs] " & @Tab & $SortArray[3]
$GamesListArr[10] = $SortArray[1] & @Tab & " [vs] " & @Tab & $SortArray[2]
$GamesListArr[11] = $SortArray[5] & @Tab & " [vs] " & @Tab & $SortArray[4]
$GamesListArr[12] = $SortArray[6] & @Tab & " [vs] " & @Tab & $SortArray[3]
$GamesListArr[13] = $SortArray[2] & @Tab & " [vs] " & @Tab & $SortArray[5]
$GamesListArr[14] = $SortArray[1] & @Tab & " [vs] " & @Tab & $SortArray[6]
$GamesListArr[15] = $SortArray[3] & @Tab & " [vs] " & @Tab & $SortArray[5]
EndSwitch
Return $GamesListArr
EndFunc
Т.е сначала играет первый с третьим (разбросано по элементам массива [1] vs [3]), потом второй с четвёртым, и т.д... вобщем сначала я на бумаге расписал оптимальные(?) вариации, таким образом чтобы никто долго не ждал следующей игры, а также чтобы не получилось такого что кто-то играет много игр подряд... а потом всё это перенёс в формат массива.
Сделать всё это без бумаги (т.е программно сгененрировать оптимальные варианты) у меня не удалось, а оно очень помогло бы, т.к могут быть и не 6 игроков, а, скажем 7 или 5 и т.д... для каждого количества игроков я конечно могу также выкрутиться с бумагой (что я и сделал для 5-ти и 4-ёх игроков, для этого в принципе и оставлен Switch в функции ;)), но каждый раз так подбирать вручную весьма утомительно :( .
чем тебя не устраивает штатный GUI?.. хотелось бы знать причину
Во-первых мне просто как припятствие хотелось это решить :) (оно мне надо?!)...
А на счёт GUI, ну, у меня есть пару вариации с отсчётом и обычные, но дело в том, что довольно сложно подобрать оптимальный вариант когда речь идёт о размерах диалога MsgBox в соответствии с передаваемым текстом, т.е мне до сих пор не удалось просчитать точно какой размер должен иметь гуи, чтобы поместить в себе указанный текст, и при этом не "покрыть" кнопки текстом (ведь передаваться могут также и символы перевода строки, это само по себе припятствие), а также ещё не знаю на какой системный файл можно понадеятся чтобы украсть с него иконки для отображения :)
каждый раз так подбирать вручную весьма утомительноне вижу смысла в Random(), ИМХО нужно тупо перебрать все возможные варианты... Вообще-то ввиду критичности к скорости для таких переборов обычно используют ASM, но для отладки алгоритма вполне подойдет любой язык, а использование эвристических ограничений на перебор, найденных при анализе задачи может существенно сократить количество вариантов.
Вот вариант скрипта, пытающегося перебрать все варианты, в качестве условий я задал постоянство периода для одного игрока и разный период для разных игроков (найдены при анализе задачи). Удачной комбинацией считается использование всех возможных партий хотя бы по разу.Global Const $iCNT = 6 ; Количество игроков
Global Const $iMAX = _Factorial($iCNT) / (_Factorial($iCNT-2)*_Factorial(2)) ; Количество всевозможных пар игроков
; Массив "игроки"
; $aPlayers[$i][0] - кол-во сыгранных игроком партий
; $aPlayers[$i][1] - время последней партии игрока (индекс $aTimeLine[])
; $aPlayers[$i][2] - временной интервал между последней и предпоследней партиями игрока
Global $aPlayers[$iCNT+1][3]
; Массив "игровые пары"
; $aPatterns[$i][1] - битовый паттерн пары (не используется)
; $aPatterns[$i][2] - битовый паттерн 1-го игрока (не используется)
; $aPatterns[$i][3] - битовый паттерн 2-го игрока (не используется)
; $aPatterns[$i][4] - номер 1-го игрока
; $aPatterns[$i][5] - номер 2-го игрока
Global $aPatterns[$iMAX+1][6], $k=0
; Заполнение массива всевозможных пар
For $i=1 To $iCNT
For $j=$i+1 To $iCNT
$k+=1
$aPatterns[$k][4]=$i
$aPatterns[$k][5]=$j
$aPatterns[$k][2]=BitRotate(1, $i-1)
$aPatterns[$k][3]=BitRotate(1, $j-1)
$aPatterns[$k][1]=BitOR($aPatterns[$k][2],$aPatterns[$k][3])
Next
Next
; Массив "линия времени"
; $i - порядковый номер игры (aka "дискретное время")
; $aTimeLine[$i] - пара игроков (индекс массива $aPatterns)
Global $aTimeLine[2] = [1,0]
; Основной цикл перебор:
; выход по завершению перебора всех вариантов,
; либо при нахождении нужного
While $aTimeLine[0]>0 And Not(_CheckTimeLine())
$ret = _PatternNext() ; ищем следующего предендента
If $ret Then
_PatternAdd($ret)
$aTimeLine[0]+=1
Else
_PatternDel()
$aTimeLine[0]-=1
EndIf
ReDim $aTimeLine[$aTimeLine[0]+1]
; вывод промежуточного результата
_TimeLinePrint()
WEnd
; Поиск следующей партии, подходящей по условию
Func _PatternNext()
Local $i
For $i=$aTimeLine[$aTimeLine[0]]+1 To $iMAX
If _PatternCheck($i) Then Return $i
Next
Return 0
EndFunc
; Процедура удаления предыдущей комбинации:
; (все возможные партии исчерпаны)
Func _PatternDel()
Local $iDEL=$aTimeLine[$aTimeLine[0]] ; код последней проверенной партии
If $iDEL Then
Local $i, $aP[3]=[2, $aPatterns[$iDEL][4], $aPatterns[$iDEL][5]] ; номера игроков
; Обновляем характеристики игроков
For $i=1 To $aP[0]
$aPlayers[$aP[$i]][0]-=1 ; уменьшаем счетчик игр
$aPlayers[$aP[$i]][1]-=$aPlayers[$aP[$i]][2] ; расчет индекса предыдущей игры
Next
$aPatterns[$iDEL][0]-=1 ; уменьшаем счетчик для партии
EndIf
EndFunc
; Процедура формирования следующей комбинации:
; (добавление очередной партии)
Func _PatternAdd($iNext)
_PatternDel() ; удаление предыдущего вариата
$aPatterns[$iNext][0]+=1 ; увеличиваем счетчик для партии
$aTimeLine[$aTimeLine[0]]=$iNext ; устанавливаем новое значение партии
Local $aP[3]=[2, $aPatterns[$iNext][4], $aPatterns[$iNext][5]] ; номера игроков
; Обновляем характеристики игроков
For $i=1 To $aP[0]
$aPlayers[$aP[$i]][0]+=1 ; увеличиваем счетчик игр
If $aPlayers[$aP[$i]][0]=2 Then $aPlayers[$aP[$i]][2]=$aTimeLine[0]-$aPlayers[$aP[$i]][1] ; интервал игр
$aPlayers[$aP[$i]][1]=$aTimeLine[0] ; индекс последней игры
Next
EndFunc
; Условие на добавляемую в конец "линии времени"
; партию ("пару игроков")
Func _PatternCheck($iPattern)
Local $i, $k, $aL[3]=[2,0,0], $aB[3]=[2,0,0] ; интервалы и результат проверки игроков
Local $aP[3]=[2, $aPatterns[$iPattern][4], $aPatterns[$iPattern][5]] ; номера игроков
; Проверка параметров каждого игрока
For $k=1 To $aP[0]
If $aPlayers[$aP[$k]][0]=1 Then ; для 2-й партии
$aL[$k] = $aTimeLine[0]-$aPlayers[$aP[$k]][1] ; устанавливаем значение интервала
; Условия на интервал между играми:
If $aL[$k]=1 Then Return False ; запрет на непрерывную игру
For $i=1 To $iCNT ; запрет на одинаковые интервалы разных игроков
If $i<>$k Then
If $aL[$k]=$aPlayers[$i][2] Then Return False
EndIf
Next
ElseIf $aPlayers[$aP[$k]][0]>1 Then ; для последующих партий
If $aTimeLine[0]-$aPlayers[$aP[$k]][1]<>$aPlayers[$aP[$k]][2] Then Return False ; проверка на постоянство интервала
EndIf
Next
; проверка совместных параметров двух игроков
If $aPlayers[$aP[1]][0]=1 And $aPlayers[$aP[2]][0]=1 Then
If $aL[1]=$aL[2] Then Return False
EndIf
Return True
EndFunc
; Условие на всю последовательность игр, по выполнении которого
; программа считает, что искомый вариант найден
Func _CheckTimeLine()
Local $i
; проверка на использование всех возможных "пар игроков"
For $i=1 To $iMAX
If $aPatterns[$i][0]=0 Then Return False
Next
Return True
EndFunc
; Вывод на консоль обрабатываемого варианта
Func _TimeLinePrint()
Local $s1='', $s2=''
For $i=1 To $aTimeLine[0]
If $aTimeLine[$i] Then
$s1&=$aPatterns[$aTimeLine[$i]][4] &' '
$s2&=$aPatterns[$aTimeLine[$i]][5] &' '
EndIf
Next
If $aTimeLine[0] Then
ConsoleWrite($s1&@CRLF&$s2&@CRLF&@CRLF)
Else
ConsoleWrite("NULL"&@CRLF)
EndIf
EndFunc
; Расчет факториала
Func _Factorial($int)
Local $i, $res=1
For $i=1 To $int
$res*=$i
Next
Return $res
EndFunc
amel27,
не вижу смысла в Random()
Это для того чтобы каждый раз гинерировался разный список игр..
Вот вариант скрипта, пытающегося перебрать все варианты, в качестве условий я задал постоянство периода для одного игрока и разный период для разных игроков (найдены при анализе задачи). Удачной комбинацией считается использование всех возможных партий хотя бы по разу. Я намеренно закомментировал запрет на игры без отдыха (период=1), как видно это не спасает задачу - решения все равно нет.
Хм... что-то не могу понять как это теперь применить на действии, т.е как в результате этой обработки получить список предстоящих игр?
Я понимаю что задачка немного(?) может показаться смутной, возможно если я приведу пример того что я уже сделал в виде ГУИ интерфейса (где я уже использую выше-приведённый мной метод), это поможет иметь более чёткое представление о задаче?
; Количество всевозможных пар игроков
Это имеется в виду общее (максимальное) количество игр?
Мне кажется это можно подсчитать таким образом - (Количество игроков * (количество игроков - 1)) / 2... т.е типа такого:
$iMAX = ( $iCNT * ($iCNT-1) ) / 2
Ведь каждый должен сиграть с каждым, и тогда получается что при 6-ти игроках имеем 6 раз по 5, но так как сам с собой игрок играть не может :), игр на самом деле в два раза меньше.
не могу понять как это теперь применить на действииникак :), скрипт не генерит последовательности, а перебирает по очереди все возможные (по условию) из доступных до первого успешного варианта... если таких нет, то результат "NULL". В данном случае как раз так - нет ни одного варианта... Зато позволяет поиграть ограничительными условиями и посмотреть как это повлияет на результат.(см. - исправил ошибку)
Мне кажется это можно подсчитать таким образомугу, это тоже самое... вдруг в будущем понадобится подсчитать число игр "пара на пару"? ;)
amel27,
скрипт не генерит последовательности, а перебирает по очереди все возможные (по условию) из доступных до первого успешного варианта... если таких нет, то результат "NULL". В данном случае как раз так - нет ни одного варианта... Зато позволяет поиграть ограничительными условиями и посмотреть как это повлияет на результат
Т.е просто(?) проверка на "реальность" выполнения данной задачки (с указанными условиями)? Тоже полезное занятие :) Спасибо.
вдруг в будущем понадобится подсчитать число игр "пара на пару"?
Это уже слишком, пара на пару нечего считать, победители остаются :biggrin:
Чуть позже выложу скрипт с тем что я уже сделал, там всё вручную и никаких проверок, но зато я горжусь там одной функцией CalculateWinner() :yu: - функция для подсчёта победителей и очков у каждого в отдельности или у нескольких игроков сразу (если к примеру они делят первое-второе место, ну или другие места) на основе ввода результатов игр (1:0, 0:1 и т.д. для каждой сыгранной игры).
Creat0R
Т.е просто(?) проверка на "реальность" выполнения данной задачки (с указанными условиями)?да, как-то одно время увлекался решением различных головоломок на компьютере, почти все решаются аналогичным "лобовым" перебором с применением некоторых общих соображений... чтобы уложиться в осмысленные сроки :)
также ещё не знаю на какой системный файл можно понадеятся чтобы украсть с него иконки для отображенияну, логично предположить, что "user32.dll" ;)
amel27,
логично предположить, что "user32.dll"
Ок, вот что получилось с MsgBox (_GuiMsgBox() :) )...
#Include <GuiConstants.au3>
$Title = "My Custom MsgBox"
$Promt = "Are you sure?"
$CheckBoxText = "Don't show again"
$hWnd = WinGetHandle("")
$Ask = _GuiMsgBox(32, 2, $Title, $Promt, 330, 120, $CheckBoxText, 10, $hWnd, "OK", "Cancel")
$CheckBitAnd = BitAND($Ask, 8)
$Var = "Pressed "
Select
Case $Ask - $CheckBitAnd = 1
$Var &= "'OK'"
Case $Ask - $CheckBitAnd = 6
$Var &= "'Yes' or 'OK'"
Case $Ask - $CheckBitAnd = 7
$Var &= "'No' or 'Cancel'"
EndSelect
If $CheckBitAnd = 8 Then $Var &= @LF & "And CheckBox <" & $CheckBoxText & "> was Checked"
MsgBox(64, "Message", "Returned values:" & @LF & @LF & $Var)
Func _GuiMsgBox($IcoType,$Butt_Num,$Title,$Text,$Width,$Height,$CB_Text=-1,$Timer=-1,$hWnd=0,$B1Text=-1,$B2Text=-1,$ExStyle=-1)
Local $Yes, $No, $OK, $CheckBox=-1, $Gui, $GuiHeight = $Height, $TitleType = $WS_CAPTION+$WS_POPUP, $Msg, $ReturnVal = 0
Local $DefButton = $OK, $DefButtonText = $B1Text, $Counter
Switch $IcoType
Case 16
$IcoType = 103
Case 32
$IcoType = 102
Case 48
$IcoType = 101
Case 64
$IcoType = 104
Case Else
$IcoType = 102
EndSwitch
Local $Old_Opt_GOEM = Opt('GuiOnEventMode', 0)
Local $Old_Opt_GCOE = Opt('GUICloseOnESC', 0)
If $hWnd <> 0 Then WinSetState($hWnd, "", @SW_DISABLE)
If $Butt_Num = 1 Then $TitleType += $WS_SYSMENU
If $CB_Text <> -1 Then $GuiHeight += 25
If $B1Text = -1 Then $B1Text = 'OK'
If $B2Text = -1 Then $B2Text = 'Cancel'
$Gui = GuiCreate($Title, $Width, $GuiHeight, -1, -1, $TitleType, $ExStyle, $hWnd)
GUICtrlCreateIcon('user32.dll', $IcoType, 10, 10)
GUICtrlCreateLabel($Text, 70, 15, $Width-80, $Height-50)
Select
Case $Butt_Num = 2
$Yes = GUICtrlCreateButton($B1Text, ($Width/2)-90, $Height-35, 70, 20)
$DefButton = $Yes
$No = GUICtrlCreateButton($B2Text, ($Width/2)+20, $Height-35, 70, 20)
GUICtrlSetState($No, $GUI_ONTOP)
GUICtrlSetState($Yes, $GUI_ONTOP+$GUI_DEFBUTTON)
Case Else
$OK = GUICtrlCreateButton($B1Text, ($Width-70)/2, $Height-35, 70, 20)
GUICtrlSetState($OK, $GUI_DEFBUTTON+$GUI_ONTOP)
$DefButton = $OK
EndSelect
If $CB_Text <> -1 Then $CheckBox = GUICtrlCreateCheckbox($CB_Text, 15, $Height-10)
GuiSetState(@SW_SHOW, $Gui)
If $Timer > 0 Then
$Counter = $Timer
$Timer = TimerInit()
$DefButtonText = GUICtrlRead($DefButton)
GUICtrlSetData($DefButton, $DefButtonText & ' (' & $Counter & ')')
EndIf
While 1
$Msg = GUIGetMsg()
If $Timer > 0 And TimerDiff($Timer) >= 1000 Then
$Timer = TimerInit()
$Counter -= 1
GUICtrlSetData($DefButton, $DefButtonText & ' (' & $Counter & ')')
If $Counter < 0 Then $Msg = $DefButton
EndIf
Select
Case $Butt_Num = 2 And $Msg = $Yes
$ReturnVal = 6
ExitLoop
Case $Butt_Num = 2 And $Msg = $No
$ReturnVal = 7
ExitLoop
Case $Msg = -3 Or ($Msg = $OK And $Butt_Num <> 2)
$ReturnVal = 1
ExitLoop
EndSelect
Wend
If GUICtrlRead($CheckBox) = 1 Then $ReturnVal += 8
If $hWnd <> 0 Then WinSetState($hWnd, "", @SW_ENABLE)
GUIDelete($Gui)
Opt('GuiOnEventMode', $Old_Opt_GOEM)
Opt('GUICloseOnESC', $Old_Opt_GCOE)
Return $ReturnVal
EndFunc
Пока только 2 кнопки поддерживаются, на больше если честно сил не хватило.
Возвращаемое значение:
6 = Кнопка ОК / Yes была нажата.
7 = Кнопка Cancel / No была нажата.
6+8 = Кнопка ОК / Yes была нажата и была поставлена птичка.
7+8 = Кнопка Cancel / No была нажата и была поставлена птичка.
вот что получилось
вчепятляет... особенно количество параметров :)
по поводу системного окна можно предположить два варианта:
1. Запускать тот же скрипт в другом процессе с передачей ключевого параметра, но тогда возникает проблема с возвратом результата, ее можно решить (к примеру) передачей сообщения основному окну через SendMessage().
2. Запускать функцию в отдельном потоке того же процесса с использованием CallBack.
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.