Sikuli - Как перебрать все совпадения с find
Я работаю над ботом для онлайн-игры. При входе в систему есть несколько серверов, из которых я должен выбрать. Каждый сервер имеет идентификатор "онлайн"/"оффлайн" рядом с именами серверов. Даже если есть несколько онлайн-серверов, бот будет выбирать только один из них, один и тот же каждый раз. И что странно, так это то, что сначала нужно найти другого, потому что на него надо нажать.
Я хочу настроить свой код, чтобы найти все "онлайн" экземпляры и выбрать один. Если это не удается подключиться, я хочу, чтобы он вернулся через меню и попробовал следующий потенциальный онлайн-сервер. Если серверу не удается подключиться или соединение с сервером потеряно, оно возвращается в главное меню с всплывающим окном "Потеря соединения с сервером". Ниже приведен код, с которым я работаю. Логика в основном проверяет любые проблемы, такие как потерянное соединение с сервером или смерть, и исправляет эти проблемы, прежде чем пытаться бороться.
BotOn = True
FighterBot = False
def runHotkey(event):
global BotOn
BotOn = False
Env.addHotkey(Key.ESC, KeyModifier.SHIFT, runHotkey)
def BotFighter(event):
global FighterBot
FighterBot = True
Env.addHotkey(Key.PAGE_UP,0, BotFighter)
def BotFighterOff(event):
global FighterBot
FighterBot = False
Env.addHotkey(Key.PAGE_DOWN,0, BotFighterOff)
while BotOn == True:
while FighterBot == True:
if exists("LostServerConnection.png"):
click("LostServerConnection.png")
wait(.5)
if exists("LoginFailed.png"):
click("LoginFailed.png")
wait(.5)
if exists("Login.png"):
click("Login.png")
wait(.5)
if exists("Play.png"):
click("Play.png")
wait(.5)
if exists("OnlineServer.png"):
click("OnlineServer.png")
wait(("AttackButton.png")or("LostServerConnection.png"),FOREVER)
if exists("AttackButton.png"):
#commands for moving to specific location
elif exists("LostServerConnection.png"):
click("LostServerConnection.png")
wait(.5)
if exists("Revive.png"):
click("Revive.png")
waitVanish("Revive.png")
wait("AttackButton.png")
#commands for moving to specific location
else:
#commands for fighting
Я прошу прощения, что это грубо написано. Я все еще учусь и пытаюсь разобраться в этом вопросе, прежде чем очистить его.
Мой идеальный результат - иметь функцию, которая будет проверять, сколько серверов подключено к сети, создавать для них индекс и иметь возможность циклически проходить через этот индекс, когда он пытается войти в тот, который действительно работает.
( Sikuli Проверьте несколько одинаковых изображений на экране) Однако я попробовал то, что сказал Юджин С. в этой ссылке, когда я вводил изображение в "части изображения" его кода, и Sikuli допустил ошибку в первой строке:
Edit1: я перечитал некоторую важную информацию, которую я пропустил и исправил код. Это не ошибка сейчас, но на самом деле ничего не нажимает. Я уверен, что что-то упустил, поэтому я продолжу изучать это в то же время. (спасибо Евгений)
def returnImageCount(image):
count = 0
for i in findAll(image):
count += 1
return count
imageCount = returnImageCount("OnlineServer.png")
if imageCount == 1:
click(buttonX.image)
elif imageCount == 2:
click(buttonY.image)
else:
pass
Edit2: я обновил ниже текущий код, с которым я работаю. Кажется, это намного ближе к тому, что я ищу. Но сейчас он находит все совпадения, затем нажимает на каждое, даже после того, как оно исчезает из загрузки первого, на которое оно щелкает. Я хотел бы иметь возможность делать то, что я добавил в своих комментариях. (спасибо Евгений)
wait(5)
OnlineServers = findAll(Pattern("OnlineServer.png").exact())
for Server in OnlineServers:
Server.click()#(only click the first match)
#wait for game to load OR server connection failed(wait as long as it takes)
#if game load
#proceed to standard actions
#elif server connection failed
#log in
#retry logic with next match in list
#(after it finishes going through all possible matches and fails each one, I want it to try again from the first match and go through the cycle again. So if there is only 1 match I want it to just keep trying that one.)
1 ответ
Я не осведомлен о вашей игровой логике, но если вам нужно работать с несколькими шаблонами, вы можете сделать это следующим образом:
Найдите их и сохраните в некотором списке:
resultsList = findAll("YOUR_FILE_NAME.png")
Затем для каждого найденного шаблона делайте с ним то, что вам нужно
for result in resultsList:
result.highlight(1)
#DO WHAT YOU NEED
В качестве альтернативы вы можете просто использовать первый элемент в списке и удалять его каждый раз, когда вам требуется следующий элемент:
NEXT_PATTERN = results.pop(0)
Вам придется подумать о стратегии, которая имеет смысл для вас, и реализовать ее, используя концепции, которые я упомянул. ИМХО, вы должны разбить все свои основные задачи на блоки, а затем построить свою основную логику. Например, вы можете реализовать такие функции:
def waitForGameToLoad():
# Wait sufficienttime and verify that the game has been actually successfully started
def isGameLoaded():
# Just and exmaple of another function that can be used internally inside waitForGameToLoad
def getNextAvailableServer():
# Get next available server from a list that you have previously created
В результате вы можете построить основной логический блок так, чтобы его было гораздо проще понять, например:
availableServersList = getAvailableServers() # getAvailableServers is a function that you will have to implement yourself
while True:
connectServer(availableServersList)
if connected():
break
НОТА
То, что я описал выше, является лишь общим предложением о том, как вы можете реализовать свою основную логику. Вам не нужно следовать этому напрямую. Попробуйте создать функции, которые будут иметь смысл для вас, а затем использовать их вместе для создания логического потока.